diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2004-07-26 22:23:34 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2004-07-26 22:23:34 +0000 |
commit | dfa7cc55e0b7646a82a21b0d6b7c8bb99ac42584 (patch) | |
tree | 2934417e2c281251089b7e4e311bf11a92c29ac3 | |
parent | e7e06fffe8992cf912b62c8d6bf51581647471b1 (diff) | |
download | xine-lib-dfa7cc55e0b7646a82a21b0d6b7c8bb99ac42584.tar.gz xine-lib-dfa7cc55e0b7646a82a21b0d6b7c8bb99ac42584.tar.bz2 |
experimental time stretching plugin
CVS patchset: 6855
CVS date: 2004/07/26 22:23:34
-rw-r--r-- | src/post/audio/Makefile.am | 10 | ||||
-rw-r--r-- | src/post/audio/audio_filters.c | 42 | ||||
-rw-r--r-- | src/post/audio/stretch.c | 689 | ||||
-rw-r--r-- | src/post/audio/upmix.c | 29 |
4 files changed, 738 insertions, 32 deletions
diff --git a/src/post/audio/Makefile.am b/src/post/audio/Makefile.am index da2de7440..5268a1636 100644 --- a/src/post/audio/Makefile.am +++ b/src/post/audio/Makefile.am @@ -4,10 +4,10 @@ noinst_HEADERS = dsp.h filter.h window.h libdir = $(XINE_PLUGINDIR)/post -lib_LTLIBRARIES = xineplug_post_audio_filter_upmix.la +lib_LTLIBRARIES = xineplug_post_audio_filters.la -xineplug_post_audio_filter_upmix_la_SOURCES = \ - upmix.c filter.c window.c -xineplug_post_audio_filter_upmix_la_LIBADD = $(XINE_LIB) -xineplug_post_audio_filter_upmix_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ -lm +xineplug_post_audio_filters_la_SOURCES = \ + upmix.c filter.c window.c stretch.c audio_filters.c +xineplug_post_audio_filters_la_LIBADD = $(XINE_LIB) +xineplug_post_audio_filters_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ -lm diff --git a/src/post/audio/audio_filters.c b/src/post/audio/audio_filters.c new file mode 100644 index 000000000..23621e688 --- /dev/null +++ b/src/post/audio/audio_filters.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2000-2004 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: audio_filters.c,v 1.1 2004/07/26 22:23:34 miguelfreitas Exp $ + * + * catalog for audio filter plugins + */ + + +#include "xine_internal.h" +#include "xineutils.h" +#include "post.h" + +void *upmix_init_plugin(xine_t *xine, void *data); +post_info_t upmix_special_info = { XINE_POST_TYPE_AUDIO_FILTER }; + +void *stretch_init_plugin(xine_t *xine, void *data); +post_info_t stretch_special_info = { XINE_POST_TYPE_AUDIO_FILTER }; + + +plugin_info_t xine_plugin_info[] = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_POST, 9, "upmix", XINE_VERSION_CODE, &upmix_special_info, &upmix_init_plugin }, + { PLUGIN_POST, 9, "stretch", XINE_VERSION_CODE, &stretch_special_info, &stretch_init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; diff --git a/src/post/audio/stretch.c b/src/post/audio/stretch.c new file mode 100644 index 000000000..f34172b72 --- /dev/null +++ b/src/post/audio/stretch.c @@ -0,0 +1,689 @@ +/* + * Copyright (C) 2000-2004 the xine project + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Time stretch by a given factor, optionally preserving pitch + * + * $Id: stretch.c,v 1.1 2004/07/26 22:23:34 miguelfreitas Exp $ + * + */ + +#include <stdio.h> + +#include "xine_internal.h" +#include "xineutils.h" +#include "post.h" +#include "dsp.h" +#include "resample.h" + + +#define AUDIO_FRAGMENT 120/1000 /* ms of audio */ + +#define CLIP_INT16(s) ((s) < INT16_MIN) ? INT16_MIN : \ + (((s) > INT16_MAX) ? INT16_MAX : (s)) + +/* + * *************************************************** + * stretchable unix System Clock Reference + * use stretch factor to calculate speed + * *************************************************** + */ + +struct stretchscr_s { + scr_plugin_t scr; + + struct timeval cur_time; + int64_t cur_pts; + int xine_speed; + double speed_factor; + double *stretch_factor; + + pthread_mutex_t lock; + +}; + +typedef struct stretchscr_s stretchscr_t; + +static int stretchscr_get_priority (scr_plugin_t *scr) { + return 10; /* high priority */ +} + +/* Only call this when already mutex locked */ +static void stretchscr_set_pivot (stretchscr_t *this) { + + struct timeval tv; + int64_t pts; + double pts_calc; + + gettimeofday(&tv, NULL); + pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; + pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; + pts = this->cur_pts + pts_calc; + +/* This next part introduces a one off inaccuracy + * to the scr due to rounding tv to pts. + */ + this->cur_time.tv_sec=tv.tv_sec; + this->cur_time.tv_usec=tv.tv_usec; + this->cur_pts=pts; + + return ; +} + +static int stretchscr_set_speed (scr_plugin_t *scr, int speed) { + stretchscr_t *this = (stretchscr_t*) scr; + + pthread_mutex_lock (&this->lock); + + stretchscr_set_pivot( this ); + this->xine_speed = speed; + this->speed_factor = (double) speed * 90000.0 / 4.0 / + (*this->stretch_factor); + + pthread_mutex_unlock (&this->lock); + + return speed; +} + +static void stretchscr_adjust (scr_plugin_t *scr, int64_t vpts) { + stretchscr_t *this = (stretchscr_t*) scr; + struct timeval tv; + + pthread_mutex_lock (&this->lock); + + gettimeofday(&tv, NULL); + this->cur_time.tv_sec=tv.tv_sec; + this->cur_time.tv_usec=tv.tv_usec; + this->cur_pts = vpts; + + pthread_mutex_unlock (&this->lock); +} + +static void stretchscr_start (scr_plugin_t *scr, int64_t start_vpts) { + stretchscr_t *this = (stretchscr_t*) scr; + + pthread_mutex_lock (&this->lock); + + gettimeofday(&this->cur_time, NULL); + this->cur_pts = start_vpts; + + pthread_mutex_unlock (&this->lock); + + stretchscr_set_speed (&this->scr, XINE_SPEED_NORMAL); +} + +static int64_t stretchscr_get_current (scr_plugin_t *scr) { + stretchscr_t *this = (stretchscr_t*) scr; + + struct timeval tv; + int64_t pts; + double pts_calc; + pthread_mutex_lock (&this->lock); + + gettimeofday(&tv, NULL); + + pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; + pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; + + pts = this->cur_pts + pts_calc; + + pthread_mutex_unlock (&this->lock); + + return pts; +} + +static void stretchscr_exit (scr_plugin_t *scr) { + stretchscr_t *this = (stretchscr_t*) scr; + + pthread_mutex_destroy (&this->lock); + free(this); +} + +static stretchscr_t* stretchscr_init (double *stretch_factor) { + stretchscr_t *this; + + this = (stretchscr_t *) xine_xmalloc(sizeof(stretchscr_t)); + + this->scr.interface_version = 2; + this->scr.get_priority = stretchscr_get_priority; + this->scr.set_speed = stretchscr_set_speed; + this->scr.adjust = stretchscr_adjust; + this->scr.start = stretchscr_start; + this->scr.get_current = stretchscr_get_current; + this->scr.exit = stretchscr_exit; + + pthread_mutex_init (&this->lock, NULL); + + this->stretch_factor = stretch_factor; + stretchscr_set_speed (&this->scr, XINE_SPEED_PAUSE); + + return this; +} + +/*****************************************************/ + + +typedef struct post_plugin_stretch_s post_plugin_stretch_t; + +typedef struct post_class_stretch_s post_class_stretch_t; + +struct post_class_stretch_s { + post_class_t post_class; + + xine_t *xine; +}; + + +typedef struct stretch_parameters_s { + int preserve_pitch; + double factor; +} stretch_parameters_t; + +/* + * description of params struct + */ +START_PARAM_DESCR( stretch_parameters_t ) +PARAM_ITEM( POST_PARAM_TYPE_BOOL, preserve_pitch, NULL, 0, 1, 0, + "Preserve pitch" ) +PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, factor, NULL, 0.5, 1.5, 0, + "Time stretch factor (<1.0 shorten duration)" ) +END_PARAM_DESCR( param_descr ) + +/* plugin structure */ +struct post_plugin_stretch_s { + post_plugin_t post; + + stretchscr_t* scr; + + /* private data */ + stretch_parameters_t params; + xine_post_in_t params_input; + int params_changed; + + int channels; + int bytes_per_frame; + + void *audiofrag; /* audio fragment to work on */ + void *outfrag; /* processed audio fragment */ + _ftype_t *w; + int frames_per_frag; + int frames_per_outfrag; + int num_frames; /* current # of frames on audiofrag */ + + int64_t pts; /* pts for audiofrag */ + + pthread_mutex_t lock; +}; + +/************************************************************************** + * stretch parameters functions + *************************************************************************/ +static int set_parameters (xine_post_t *this_gen, void *param_gen) { + post_plugin_stretch_t *this = (post_plugin_stretch_t *)this_gen; + stretch_parameters_t *param = (stretch_parameters_t *)param_gen; + + pthread_mutex_lock (&this->lock); + memcpy( &this->params, param, sizeof(stretch_parameters_t) ); + this->params_changed = 1; + pthread_mutex_unlock (&this->lock); + + return 1; +} +static int get_parameters (xine_post_t *this_gen, void *param_gen) { + post_plugin_stretch_t *this = (post_plugin_stretch_t *)this_gen; + stretch_parameters_t *param = (stretch_parameters_t *)param_gen; + + pthread_mutex_lock (&this->lock); + memcpy( param, &this->params, sizeof(stretch_parameters_t) ); + pthread_mutex_unlock (&this->lock); + + return 1; +} + +static xine_post_api_descr_t * get_param_descr (void) { + return ¶m_descr; +} + +static char * get_help (void) { + return _("This filter will perform a time stretch, playing the " + "stream faster or slower by a factor. Pitch is optionally " + "preserved, so it is possible, for example, to use it to " + "watch a movie in less time than it was originaly shot.\n" + ); +} + +static xine_post_api_t post_api = { + set_parameters, + get_parameters, + get_param_descr, + get_help, +}; + + + +/************************************************************************** + * xine audio post plugin functions + *************************************************************************/ + +static int stretch_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, + uint32_t bits, uint32_t rate, int mode) { + + post_audio_port_t *port = (post_audio_port_t *)port_gen; + post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post; + int64_t time; + + _x_post_rewire(&this->post); + _x_post_inc_usage(port); + + port->stream = stream; + port->bits = bits; + port->rate = rate; + port->mode = mode; + + /* register our own scr provider */ + time = port->stream->xine->clock->get_current_time(port->stream->xine->clock); + this->scr = stretchscr_init(&this->params.factor); + this->scr->scr.start(&this->scr->scr, time); + port->stream->xine->clock->register_scr(port->stream->xine->clock, &this->scr->scr); + + /* force updating on stretch_port_put_buffer */ + this->params_changed = 1; + + return port->original_port->open(port->original_port, stream, bits, rate, mode); +} + +static void stretch_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) { + + post_audio_port_t *port = (post_audio_port_t *)port_gen; + post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post; + + if (this->scr) { + port->stream->xine->clock->unregister_scr(port->stream->xine->clock, &this->scr->scr); + this->scr->scr.exit(&this->scr->scr); + } + + if(this->audiofrag) { + free(this->audiofrag); + this->audiofrag = NULL; + } + + if(this->outfrag) { + free(this->outfrag); + this->outfrag = NULL; + } + + if(this->w) { + free(this->w); + this->w = NULL; + } + + port->stream = NULL; + + port->original_port->close(port->original_port, stream ); + + _x_post_dec_usage(port); +} + +static void stretch_process_fragment( post_audio_port_t *port, + xine_stream_t *stream, extra_info_t *extra_info ) +{ + post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post; + + audio_buffer_t *outbuf; + void *data_out = this->outfrag; + int num_frames_in = this->num_frames; + int num_frames_out = this->num_frames * this->frames_per_outfrag / + this->frames_per_frag; + + if( !this->params.preserve_pitch ) { + if( this->channels == 2 ) + _x_audio_out_resample_stereo(this->audiofrag, num_frames_in, + this->outfrag, num_frames_out); + else if( this->channels == 1 ) + _x_audio_out_resample_mono(this->audiofrag, num_frames_in, + this->outfrag, num_frames_out); + } else { + if( num_frames_in > num_frames_out ) + { + /* + * time compressing strategy + * + * input chunk has two halves, A and B. + * output chunk is composed as follow: + * - some frames copied directly from A + * - some frames copied from A merged with frames from B + * weighted by an increasing factor (0 -> 1.0) + * - frames from A weighted by a decreasing factor (1.0 -> 0) + * merged with frames copied from B + * - some frames copied directly from B + */ + + int merge_frames = num_frames_in - num_frames_out; + int copy_frames; + int16_t *src = this->audiofrag; + int16_t *dst = this->outfrag; + int i, j; + + if( merge_frames > num_frames_out ) + merge_frames = num_frames_out; + copy_frames = num_frames_out - merge_frames; + + memcpy(dst, src, copy_frames/2 * this->bytes_per_frame); + dst += copy_frames/2 * this->channels; + src += copy_frames/2 * this->channels; + + for( i = 0; i < merge_frames/2; i++ ) + { + for( j = 0; j < this->channels; j++, src++, dst++ ) { + + int32_t s = (int32_t) ((_ftype_t) src[0] + + src[merge_frames * this->channels] * this->w[i]); + *dst = CLIP_INT16(s); + } + } + + for( ; i < merge_frames; i++ ) + { + for( j = 0; j < this->channels; j++, src++, dst++ ) { + + int32_t s = (int32_t) ((_ftype_t) src[0] * this->w[i] + + src[merge_frames * this->channels]); + *dst = CLIP_INT16(s); + } + } + + src += merge_frames * this->channels; + + memcpy(dst, src, (copy_frames - copy_frames/2) * + this->bytes_per_frame); + + } else { + /* + * time expansion strategy + * + * output chunk is composed of two versions of the + * input chunk: + * - first part copied directly from input, and then + * merged with the second (delayed) part using a + * decreasing factor (1.0 -> 0) + * - the delayed version of the input is merged with + * an increasing factor (0 -> 1.0) and then (when + * factor reaches 1.0) just copied until the end. + */ + + int merge_frames = num_frames_out - num_frames_in; + int copy_frames = num_frames_out - merge_frames; + int16_t *src1 = this->audiofrag; + int16_t *src2; + int16_t *dst = this->outfrag; + int i, j; + + memcpy(dst, src1, copy_frames/2 * this->bytes_per_frame); + dst += copy_frames/2 * this->channels; + src1 += copy_frames/2 * this->channels; + src2 = src1 - merge_frames * this->channels; + + for( i = 0; i < merge_frames/2; i++ ) + { + for( j = 0; j < this->channels; j++, src1++, src2++, dst++ ) { + + int32_t s = (int32_t) ((_ftype_t) *src1 + + *src2 * this->w[i]); + *dst = CLIP_INT16(s); + } + } + + for( ; i < merge_frames; i++ ) + { + for( j = 0; j < this->channels; j++, src1++, src2++, dst++ ) { + + int32_t s = (int32_t) ((_ftype_t) *src1 * this->w[i] + + *src2); + *dst = CLIP_INT16(s); + } + } + + memcpy(dst, src2, (copy_frames - copy_frames/2) * + this->bytes_per_frame); + + } + } + + /* copy processed fragment into multiple audio buffers, if needed */ + while( num_frames_out ) { + outbuf = port->original_port->get_buffer(port->original_port); + + outbuf->num_frames = outbuf->mem_size / this->bytes_per_frame; + if( outbuf->num_frames > num_frames_out ) + outbuf->num_frames = num_frames_out; + + memcpy( outbuf->mem, data_out, + outbuf->num_frames * this->bytes_per_frame ); + num_frames_out -= outbuf->num_frames; + data_out += outbuf->num_frames * this->bytes_per_frame; + + outbuf->vpts = this->pts; + this->pts = 0; + outbuf->stream = stream; + outbuf->format.bits = port->bits; + outbuf->format.rate = port->rate; + outbuf->format.mode = port->mode; + + _x_extra_info_merge( outbuf->extra_info, extra_info ); + + port->original_port->put_buffer(port->original_port, outbuf, stream ); + } + + this->num_frames = 0; +} + +static void stretch_port_put_buffer (xine_audio_port_t *port_gen, + audio_buffer_t *buf, xine_stream_t *stream) { + + post_audio_port_t *port = (post_audio_port_t *)port_gen; + post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post; + void *data_in; + + pthread_mutex_lock (&this->lock); + + + if( this->params_changed ) { + int64_t audio_step; + + if( this->num_frames && this->audiofrag && this->outfrag ) { + /* output whatever we have before changing parameters */ + stretch_process_fragment( port, stream, buf->extra_info ); + } + + this->channels = _x_ao_mode2channels(port->mode); + this->bytes_per_frame = port->bits / 8 * this->channels; + + audio_step = ((int64_t)90000 * (int64_t)32768) / (int64_t)port->rate; + audio_step = (int64_t) ((double)audio_step / this->params.factor); + stream->metronom->set_audio_rate(stream->metronom, audio_step); + + stretchscr_set_speed(&this->scr->scr, this->scr->xine_speed); + + if(this->audiofrag) { + free(this->audiofrag); + this->audiofrag = NULL; + } + + if(this->outfrag) { + free(this->outfrag); + this->outfrag = NULL; + } + + if(this->w) { + free(this->w); + this->w = NULL; + } + + this->frames_per_frag = port->rate * AUDIO_FRAGMENT; + this->frames_per_outfrag = (int) ((double)this->params.factor * this->frames_per_frag); + + if( this->frames_per_frag != this->frames_per_outfrag ) { + int wsize; + + this->audiofrag = malloc( this->frames_per_frag * this->bytes_per_frame ); + this->outfrag = malloc( this->frames_per_outfrag * this->bytes_per_frame ); + + if( this->frames_per_frag > this->frames_per_outfrag ) + wsize = this->frames_per_frag - this->frames_per_outfrag; + else + wsize = this->frames_per_outfrag - this->frames_per_frag; + + this->w = (_ftype_t*) malloc( wsize * sizeof(_ftype_t) ); + triang(wsize, this->w); + } + + this->num_frames = 0; + this->pts = 0; + + this->params_changed = 0; + } + + pthread_mutex_unlock (&this->lock); + + /* just pass data through if we have nothing to do */ + if( this->frames_per_frag == this->frames_per_outfrag || + /* FIXME: we only handle 1 or 2 channels, 16 bits for now */ + (this->channels != 1 && this->channels != 2) || + port->bits != 16 ) { + + port->original_port->put_buffer(port->original_port, buf, stream ); + + return; + } + + /* update pts for our current audio fragment */ + if( buf->vpts ) + this->pts = buf->vpts - (this->num_frames * 90000 / port->rate); + + data_in = buf->mem; + while( buf->num_frames ) { + int frames_to_copy = this->frames_per_frag - this->num_frames; + + if( frames_to_copy > buf->num_frames ) + frames_to_copy = buf->num_frames; + + /* copy up to one fragment from input buf to our buffer */ + memcpy( this->audiofrag + this->num_frames * this->bytes_per_frame, + data_in, frames_to_copy * this->bytes_per_frame ); + + data_in += frames_to_copy * this->bytes_per_frame; + this->num_frames += frames_to_copy; + buf->num_frames -= frames_to_copy; + + /* check if we have a complete audio fragment to process */ + if( this->num_frames == this->frames_per_frag ) { + stretch_process_fragment( port, stream, buf->extra_info ); + } + } + + buf->num_frames=0; /* UNDOCUMENTED, but hey, it works! Force old audio_out buffer free. */ + port->original_port->put_buffer(port->original_port, buf, stream ); + + return; +} + +static void stretch_dispose(post_plugin_t *this_gen) +{ + post_plugin_stretch_t *this = (post_plugin_stretch_t *)this_gen; + + if (_x_post_dispose(this_gen)) { + free(this); + } +} + +/* plugin class functions */ +static post_plugin_t *stretch_open_plugin(post_class_t *class_gen, int inputs, + xine_audio_port_t **audio_target, + xine_video_port_t **video_target) +{ + post_plugin_stretch_t *this = (post_plugin_stretch_t *)xine_xmalloc(sizeof(post_plugin_stretch_t)); + post_in_t *input; + post_out_t *output; + xine_post_in_t *input_api; + post_audio_port_t *port; + stretch_parameters_t init_params; + + if (!this || !audio_target || !audio_target[0] ) { + free(this); + return NULL; + } + + _x_post_init(&this->post, 1, 0); + + init_params.preserve_pitch = 1; + init_params.factor = 1.01; + + pthread_mutex_init (&this->lock, NULL); + + set_parameters ((xine_post_t *)&this->post, &init_params); + + port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); + port->new_port.open = stretch_port_open; + port->new_port.close = stretch_port_close; + port->new_port.put_buffer = stretch_port_put_buffer; + + input_api = &this->params_input; + input_api->name = "parameters"; + input_api->type = XINE_POST_DATA_PARAMETERS; + input_api->data = &post_api; + xine_list_append_content(this->post.input, input_api); + + this->post.xine_post.audio_input[0] = &port->new_port; + + this->post.dispose = stretch_dispose; + + return &this->post; +} + +static char *stretch_get_identifier(post_class_t *class_gen) +{ + return "stretch"; +} + +static char *stretch_get_description(post_class_t *class_gen) +{ + return "Time stretch by a given factor, optionally preserving pitch"; +} + +static void stretch_class_dispose(post_class_t *class_gen) +{ + free(class_gen); +} + +/* plugin class initialization function */ +void *stretch_init_plugin(xine_t *xine, void *data) +{ + post_class_stretch_t *class = (post_class_stretch_t *)malloc(sizeof(post_class_stretch_t)); + + if (!class) + return NULL; + + class->post_class.open_plugin = stretch_open_plugin; + class->post_class.get_identifier = stretch_get_identifier; + class->post_class.get_description = stretch_get_description; + class->post_class.dispose = stretch_class_dispose; + + class->xine = xine; + + return class; +} diff --git a/src/post/audio/upmix.c b/src/post/audio/upmix.c index e08174995..2fb42a409 100644 --- a/src/post/audio/upmix.c +++ b/src/post/audio/upmix.c @@ -23,7 +23,7 @@ * It simply creates output channels to match the speaker arrangement. * E.g. Converts Stereo into Surround 5.1 * - * $Id: upmix.c,v 1.14 2004/05/29 14:45:25 mroi Exp $ + * $Id: upmix.c,v 1.15 2004/07/26 22:23:34 miguelfreitas Exp $ * */ @@ -34,12 +34,6 @@ #include "post.h" #include "dsp.h" -#define FPS 20 - -#define FOO_WIDTH 320 -#define FOO_HEIGHT 240 - -#define NUMSAMPLES 512 typedef struct post_plugin_upmix_s post_plugin_upmix_t; @@ -103,16 +97,10 @@ struct post_plugin_upmix_s { pthread_mutex_t lock; xine_post_in_t params_input; upmix_parameters_t params; - double ratio; - int data_idx; - short data [2][NUMSAMPLES]; audio_buffer_t *buf; /* dummy buffer just to hold a copy of audio data */ af_sub_t *sub; int channels; int channels_out; - int sample_counter; - int samples_per_frame; - }; /************************************************************************** @@ -183,7 +171,6 @@ static int upmix_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, port->mode = mode; capabilities = port->original_port->get_capabilities(port->original_port); - this->ratio = (double)FOO_WIDTH/(double)FOO_HEIGHT; this->channels = _x_ao_mode2channels(mode); /* FIXME: Handle all desired output formats */ if ((capabilities & AO_CAP_MODE_5_1CHANNEL) && (capabilities & AO_CAP_FLOAT32)) { @@ -212,8 +199,6 @@ static int upmix_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, return 0; } - this->samples_per_frame = rate / FPS; - this->data_idx = 0; pthread_mutex_unlock (&this->lock); return port->original_port->open(port->original_port, stream, bits, rate, mode ); @@ -446,7 +431,7 @@ static void upmix_class_dispose(post_class_t *class_gen) } /* plugin class initialization function */ -static void *upmix_init_plugin(xine_t *xine, void *data) +void *upmix_init_plugin(xine_t *xine, void *data) { post_class_upmix_t *class = (post_class_upmix_t *)malloc(sizeof(post_class_upmix_t)); @@ -462,13 +447,3 @@ static void *upmix_init_plugin(xine_t *xine, void *data) return class; } - -/* plugin catalog information */ -/* post_info_t upmix_special_info = { XINE_POST_TYPE_AUDIO_VISUALIZATION }; */ -post_info_t upmix_special_info = { XINE_POST_TYPE_AUDIO_FILTER }; - -plugin_info_t xine_plugin_info[] = { - /* type, API, "name", version, special_info, init_function */ - { PLUGIN_POST, 9, "upmix", XINE_VERSION_CODE, &upmix_special_info, &upmix_init_plugin }, - { PLUGIN_NONE, 0, "", 0, NULL, NULL } -}; |