summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/input_dvd.c8
-rw-r--r--src/post/audio/stretch.c10
-rw-r--r--src/post/goom/xine_goom.c112
-rw-r--r--src/video_out/video_out_xcbxv.c2
-rw-r--r--src/video_out/video_out_xv.c2
-rw-r--r--src/xine-engine/audio_out.c30
-rw-r--r--src/xine-engine/configfile.c39
-rw-r--r--src/xine-engine/resample.c115
-rw-r--r--src/xine-engine/resample.h17
9 files changed, 219 insertions, 116 deletions
diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c
index c55ff8726..4f1fc3fb2 100644
--- a/src/input/input_dvd.c
+++ b/src/input/input_dvd.c
@@ -1482,14 +1482,14 @@ static int dvd_plugin_open (input_plugin_t *this_gen) {
dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen;
dvd_input_class_t *class = (dvd_input_class_t*)this_gen->input_class;
- char *locator;
+ char *locator, *locator_orig;
char *title_part;
xine_cfg_entry_t region_entry, lang_entry, cfg_entry;
trace_print("Called\n");
/* we already checked the "dvd:/" MRL before */
- locator = strdup (this->mrl + (sizeof("dvd:") - 1));
+ locator_orig = locator = strdup (this->mrl + (sizeof("dvd:") - 1));
/* FIXME: call a generic xine-lib MRL parser here to pre-parse
* the MRL for ?title=<title>&part=<part> stuff and to expand
@@ -1505,11 +1505,11 @@ static int dvd_plugin_open (input_plugin_t *this_gen) {
_x_message(this->stream, XINE_MSG_READ_ERROR,
/* FIXME: see FIXME in dvd_parse_try_open() */
(strlen(locator) && !(locator[0] == '/' && locator[1] == '\0')) ? locator : class->dvd_device, NULL);
- free (locator);
+ free (locator_orig);
return 0;
}
- free (locator);
+ free (locator_orig);
dvdnav_get_title_string(this->dvdnav, &this->dvd_name);
if(this->dvd_name)
diff --git a/src/post/audio/stretch.c b/src/post/audio/stretch.c
index a1e921e03..054468517 100644
--- a/src/post/audio/stretch.c
+++ b/src/post/audio/stretch.c
@@ -225,6 +225,8 @@ struct post_plugin_stretch_s {
int frames_per_frag;
int frames_per_outfrag;
int num_frames; /* current # of frames on audiofrag */
+
+ int16_t last_sample[RESAMPLE_MAX_CHANNELS];
int64_t pts; /* pts for audiofrag */
@@ -353,12 +355,16 @@ static void stretch_process_fragment( post_audio_port_t *port,
if( !this->params.preserve_pitch ) {
if( this->channels == 2 )
- _x_audio_out_resample_stereo(this->audiofrag, num_frames_in,
+ _x_audio_out_resample_stereo(this->last_sample, 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,
+ _x_audio_out_resample_mono(this->last_sample, this->audiofrag, num_frames_in,
this->outfrag, num_frames_out);
} else {
+ if (this->channels == 2)
+ memcpy (this->last_sample, &this->audiofrag[(num_frames_in - 1) * 2], 2 * sizeof (this->last_sample[0]));
+ else if (this->channels == 1)
+ memcpy (this->last_sample, &this->audiofrag[num_frames_in - 1], sizeof (this->last_sample[0]));
if( num_frames_in > num_frames_out )
{
/*
diff --git a/src/post/goom/xine_goom.c b/src/post/goom/xine_goom.c
index 5871618e0..7c2939105 100644
--- a/src/post/goom/xine_goom.c
+++ b/src/post/goom/xine_goom.c
@@ -82,13 +82,12 @@ struct post_plugin_goom_s {
/* goom context */
PluginInfo *goom;
- int data_idx;
+ int data_idx;
gint16 data [2][NUMSAMPLES];
audio_buffer_t buf; /* dummy buffer just to hold a copy of audio data */
int channels;
int sample_rate;
- int sample_counter;
int samples_per_frame;
int width, height;
int width_back, height_back;
@@ -96,6 +95,11 @@ struct post_plugin_goom_s {
int fps;
int csc_method;
+
+ int do_samples_skip; /* true = skipping samples, false reading samples*/
+ int left_to_read; /* data to read before switching modes*/
+
+
yuv_planes_t yuv;
/* frame skipping */
@@ -282,7 +286,6 @@ static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs,
this->ratio = (double)this->width_back/(double)this->height_back;
- this->sample_counter = 0;
this->buf.mem = NULL;
this->buf.mem_size = 0;
@@ -386,9 +389,11 @@ static int goom_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,
this->sample_rate = rate;
this->samples_per_frame = rate / this->fps;
this->data_idx = 0;
- this->sample_counter = 0;
init_yuv_planes(&this->yuv, this->width, this->height);
this->skip_frame = 0;
+
+ this->do_samples_skip = 0;
+ this->left_to_read = NUMSAMPLES;
this->vo_port->open(this->vo_port, XINE_ANON_STREAM);
this->metronom->set_master(this->metronom, stream->metronom);
@@ -422,11 +427,12 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen,
uint8_t *goom_frame, *goom_frame_end;
int16_t *data;
int8_t *data8;
- int samples_used = 0;
int64_t pts = buf->vpts;
int i, j;
uint8_t *dest_ptr;
int width, height;
+
+ int current_sample = 0;
/* make a copy of buf data for private use */
if( this->buf.mem_size < buf->mem_size ) {
@@ -444,59 +450,73 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen,
* to the fifo of free audio buffers. just use our private copy instead.
*/
buf = &this->buf;
-
- this->sample_counter += buf->num_frames;
j = (this->channels >= 2) ? 1 : 0;
- do {
-
+
+ while (current_sample < buf->num_frames) {
+
+ if (this->do_samples_skip) {
+ if (current_sample + this->left_to_read > buf->num_frames) {
+ this->left_to_read -= (buf->num_frames-current_sample);
+ break;
+ } else {
+ current_sample+=this->left_to_read;
+ this->left_to_read = NUMSAMPLES;
+ this->do_samples_skip = 0;
+
+ }
+ } else {
+
if( port->bits == 8 ) {
data8 = (int8_t *)buf->mem;
- data8 += samples_used * this->channels;
+ data8 += current_sample * this->channels;
/* scale 8 bit data to 16 bits and convert to signed as well */
- for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES;
- i++, this->data_idx++, data8 += this->channels ) {
+ for ( i=current_sample ; this->data_idx < NUMSAMPLES && i < buf->num_frames;
+ i++, this->data_idx++,data8 += this->channels) {
+
this->data[0][this->data_idx] = ((int16_t)data8[0] << 8) - 0x8000;
this->data[1][this->data_idx] = ((int16_t)data8[j] << 8) - 0x8000;
}
} else {
data = buf->mem;
- data += samples_used * this->channels;
-
- for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES;
- i++, this->data_idx++, data += this->channels ) {
+ data += current_sample * this->channels;
+
+ for ( i=current_sample ; this->data_idx < NUMSAMPLES && i < buf->num_frames;
+ i++, this->data_idx++,data += this->channels) {
+
this->data[0][this->data_idx] = data[0];
this->data[1][this->data_idx] = data[j];
}
}
-
- if( this->sample_counter >= this->samples_per_frame ) {
-
- samples_used += this->samples_per_frame;
+
+ if (this->data_idx < NUMSAMPLES) {
+ this->left_to_read = NUMSAMPLES - this->data_idx;
+ break;
+ } else {
+ _x_assert(this->data_idx == NUMSAMPLES);
+ this->data_idx = 0;
+
+ if (this->samples_per_frame > NUMSAMPLES) {
+ current_sample += NUMSAMPLES;
+ this->do_samples_skip = 1;
+ this->left_to_read = this->samples_per_frame - NUMSAMPLES;
+ } else {
+ current_sample += this->samples_per_frame;
+ this->left_to_read = NUMSAMPLES;
+ }
frame = this->vo_port->get_frame (this->vo_port, this->width_back, this->height_back,
- this->ratio, XINE_IMGFMT_YUY2,
- VO_BOTH_FIELDS);
+ this->ratio, XINE_IMGFMT_YUY2,
+ VO_BOTH_FIELDS);
frame->extra_info->invalid = 1;
- /* frame is marked as bad if we don't have enough samples for
- * updating the viz plugin (calculations may be skipped).
- * we must keep the framerate though. */
- if( this->data_idx == NUMSAMPLES ) {
- frame->bad_frame = 0;
- this->data_idx = 0;
- } else {
- frame->bad_frame = 1;
- }
frame->duration = 90000 * this->samples_per_frame / this->sample_rate;
frame->pts = pts;
this->metronom->got_video_frame(this->metronom, frame);
- this->sample_counter -= this->samples_per_frame;
-
- if (!this->skip_frame && !frame->bad_frame) {
+ if (!this->skip_frame) {
/* Try to be fast */
goom_frame = (uint8_t *)goom_update (this->goom, this->data, 0, 0, NULL, NULL);
@@ -561,21 +581,25 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen,
} else {
frame->bad_frame = 1;
frame->draw(frame, XINE_ANON_STREAM);
- this->skip_frame--;
+
+ _x_assert(this->skip_frame>0);
+ this->skip_frame--;
}
+
frame->free(frame);
width = this->width;
height = this->height;
if ((width != this->width_back) || (height != this->height_back)) {
- goom_close(this->goom);
- this->goom = goom_init (this->width, this->height);
- this->width_back = width;
- this->height_back = height;
- this->ratio = (double)width/(double)height;
- free_yuv_planes(&this->yuv);
- init_yuv_planes(&this->yuv, this->width, this->height);
- }
+ goom_close(this->goom);
+ this->goom = goom_init (this->width, this->height);
+ this->width_back = width;
+ this->height_back = height;
+ this->ratio = (double)width/(double)height;
+ free_yuv_planes(&this->yuv);
+ init_yuv_planes(&this->yuv, this->width, this->height);
+ }
}
- } while( this->sample_counter >= this->samples_per_frame );
+ }
+ }
}
diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c
index 21a8b6a39..4cb57156d 100644
--- a/src/video_out/video_out_xcbxv.c
+++ b/src/video_out/video_out_xcbxv.c
@@ -1245,7 +1245,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis
if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_HUE")) {
if (!strncmp(xcb_xv_adaptor_info_name(adaptor_it.data), "NV", 2)) {
- xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards");
+ xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n");
} else {
xv_check_capability (this, VO_PROP_HUE, attribute_it.data,
adaptor_it.data->base_id,
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index 894192c6b..aca59e8d1 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.c
@@ -1298,7 +1298,7 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *
if(!strcmp(attr[k].name, "XV_HUE")) {
if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) {
- xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards");
+ xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n");
} else {
xv_check_capability (this, VO_PROP_HUE, attr[k],
adaptor_info[adaptor_num].base_id,
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 75cef4ce6..376ceee0b 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -253,6 +253,7 @@ typedef struct {
* sure nobody will change speed without going through xine.c:set_speed_internal */
int slow_fast_audio; /* play audio even on slow/fast speeds */
+ int16_t last_sample[RESAMPLE_MAX_CHANNELS];
audio_buffer_t *frame_buf[2]; /* two buffers for "stackable" conversions */
int16_t *zero_space;
@@ -746,19 +747,19 @@ static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) {
switch (this->input.mode) {
case AO_CAP_MODE_MONO:
ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3), num_output_frames);
- _x_audio_out_resample_mono (buf->mem, buf->num_frames,
+ _x_audio_out_resample_mono (this->last_sample, buf->mem, buf->num_frames,
this->frame_buf[1]->mem, num_output_frames);
buf = swap_frame_buffers(this);
break;
case AO_CAP_MODE_STEREO:
ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*2, num_output_frames);
- _x_audio_out_resample_stereo (buf->mem, buf->num_frames,
+ _x_audio_out_resample_stereo (this->last_sample, buf->mem, buf->num_frames,
this->frame_buf[1]->mem, num_output_frames);
buf = swap_frame_buffers(this);
break;
case AO_CAP_MODE_4CHANNEL:
ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*4, num_output_frames);
- _x_audio_out_resample_4channel (buf->mem, buf->num_frames,
+ _x_audio_out_resample_4channel (this->last_sample, buf->mem, buf->num_frames,
this->frame_buf[1]->mem, num_output_frames);
buf = swap_frame_buffers(this);
break;
@@ -766,7 +767,7 @@ static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) {
case AO_CAP_MODE_5CHANNEL:
case AO_CAP_MODE_5_1CHANNEL:
ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*6, num_output_frames);
- _x_audio_out_resample_6channel (buf->mem, buf->num_frames,
+ _x_audio_out_resample_6channel (this->last_sample, buf->mem, buf->num_frames,
this->frame_buf[1]->mem, num_output_frames);
buf = swap_frame_buffers(this);
break;
@@ -775,6 +776,25 @@ static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) {
/* pass-through modes: no resampling */
break;
}
+ } else {
+ /* maintain last_sample in case we need it */
+ switch (this->input.mode) {
+ case AO_CAP_MODE_MONO:
+ memcpy (this->last_sample, &buf->mem[buf->num_frames - 1], sizeof (this->last_sample[0]));
+ break;
+ case AO_CAP_MODE_STEREO:
+ memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 2], 2 * sizeof (this->last_sample[0]));
+ break;
+ case AO_CAP_MODE_4CHANNEL:
+ memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 4], 4 * sizeof (this->last_sample[0]));
+ break;
+ case AO_CAP_MODE_4_1CHANNEL:
+ case AO_CAP_MODE_5CHANNEL:
+ case AO_CAP_MODE_5_1CHANNEL:
+ memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 6], 6 * sizeof (this->last_sample[0]));
+ break;
+ default:;
+ }
}
/* mode conversion */
@@ -2160,6 +2180,8 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver,
fifo_append (this->free_fifo, buf);
}
+
+ memset (this->last_sample, 0, sizeof (this->last_sample));
/* buffers used for audio conversions */
for (i=0; i<2; i++) {
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c
index ec5f5c856..67c8ef909 100644
--- a/src/xine-engine/configfile.c
+++ b/src/xine-engine/configfile.c
@@ -45,13 +45,8 @@
#include "xineutils.h"
#include "xine_internal.h"
-
-typedef struct {
- const char *old;
- const char *new;
-} config_entry_translation_t;
-
-static const config_entry_translation_t config_entry_translation[] = {
+static const xine_config_entry_translation_t *config_entry_translation_user = NULL;
+static const xine_config_entry_translation_t config_entry_translation[] = {
{ "audio.a52_pass_through", "" },
{ "audio.alsa_a52_device", "audio.device.alsa_passthrough_device" },
{ "audio.alsa_default_device", "audio.device.alsa_default_device" },
@@ -209,7 +204,8 @@ static const config_entry_translation_t config_entry_translation[] = {
{ "video.xv_colorkey", "video.device.xv_colorkey" },
{ "video.xv_pitch_alignment", "video.device.xv_pitch_alignment" },
{ "video.xvmc_more_frames", "video.device.xvmc_more_frames" },
- { "video.xvmc_nvidia_color_fix", "video.device.xvmc_nvidia_color_fix" }
+ { "video.xvmc_nvidia_color_fix", "video.device.xvmc_nvidia_color_fix" },
+ {}
};
@@ -354,6 +350,15 @@ static void config_remove(config_values_t *this, cfg_entry_t *entry, cfg_entry_t
prev->next = entry->next;
}
+static const char *config_xlate_internal (const char *key, const xine_config_entry_translation_t *trans)
+{
+ --trans;
+ while ((++trans)->old)
+ if (trans->new[0] && strcmp(key, trans->old) == 0)
+ return trans->new;
+ return NULL;
+}
+
static const char *config_translate_key (const char *key) {
/* Returns translated key or, if no translation found, NULL.
* Translated key may be in a static buffer allocated within this function.
@@ -373,13 +378,11 @@ static const char *config_translate_key (const char *key) {
}
/* search the translation table... */
- for (trans = 0;
- trans < sizeof(config_entry_translation) / sizeof(config_entry_translation[0]);
- trans++)
- if (config_entry_translation[trans].new[0] && strcmp(key, config_entry_translation[trans].old) == 0)
- return config_entry_translation[trans].new;
+ newkey = config_xlate_internal (key, config_entry_translation);
+ if (!newkey && config_entry_translation_user)
+ newkey = config_xlate_internal (key, config_entry_translation_user);
- return NULL;
+ return newkey;
}
static void config_lookup_entry_int (config_values_t *this, const char *key,
@@ -895,6 +898,14 @@ static void config_update_string (config_values_t *this,
}
/*
+ * front end config translation handling
+ */
+void xine_config_set_translation_user (const xine_config_entry_translation_t *xlate)
+{
+ config_entry_translation_user = xlate;
+}
+
+/*
* load/save config data from/to afile (e.g. $HOME/.xine/config)
*/
void xine_config_load (xine_t *xine, const char *filename) {
diff --git a/src/xine-engine/resample.c b/src/xine-engine/resample.c
index a7b16917c..1bc9dfaf9 100644
--- a/src/xine-engine/resample.c
+++ b/src/xine-engine/resample.c
@@ -24,26 +24,34 @@
#include "config.h"
#endif
+#include <string.h>
#include <inttypes.h>
#include "attributes.h"
#include "resample.h"
/* contributed by paul flinders */
-void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples,
+void _x_audio_out_resample_mono(int16_t *last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples)
{
unsigned int osample;
/* 16+16 fixed point math */
- uint32_t isample = 0;
- uint32_t istep = ((in_samples-2) << 16)/(out_samples-2);
+ uint32_t isample = 0xFFFF0000U;
+ uint32_t istep = (in_samples << 16) / out_samples + 1;
#ifdef VERBOSE
printf ("Audio : resample %d samples to %d\n",
in_samples, out_samples);
#endif
- for (osample = 0; osample < out_samples - 1; osample++) {
+ for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) {
+ uint32_t t = isample&0xffff;
+ output_samples[osample] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16;
+ isample += istep;
+ }
+
+ for (; osample < out_samples; osample++) {
int s1;
int s2;
int16_t os;
@@ -58,23 +66,31 @@ void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples,
isample += istep;
}
- output_samples[out_samples-1] = input_samples[in_samples-1];
+ last_sample[0] = input_samples[in_samples - 1];
}
-void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples,
+void _x_audio_out_resample_stereo(int16_t *last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples)
{
unsigned int osample;
/* 16+16 fixed point math */
- uint32_t isample = 0;
- uint32_t istep = ((in_samples-2) << 16)/(out_samples-2);
+ uint32_t isample = 0xFFFF0000U;
+ uint32_t istep = (in_samples << 16) / out_samples + 1;
#ifdef VERBOSE
printf ("Audio : resample %d samples to %d\n",
in_samples, out_samples);
#endif
- for (osample = 0; osample < out_samples - 1; osample++) {
+ for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) {
+ uint32_t t = isample&0xffff;
+ output_samples[osample*2 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16;
+ output_samples[osample*2+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16;
+ isample += istep;
+ }
+
+ for (; osample < out_samples; osample++) {
int s1;
int s2;
int16_t os;
@@ -94,25 +110,34 @@ void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples,
output_samples[(osample * 2 )+1] = os;
isample += istep;
}
- output_samples[out_samples*2-2] = input_samples[in_samples*2-2];
- output_samples[out_samples*2-1] = input_samples[in_samples*2-1];
+ memcpy (last_sample, &input_samples[in_samples*2-2], 2 * sizeof (last_sample[0]));
}
-void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples,
+void _x_audio_out_resample_4channel(int16_t *last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples)
{
unsigned int osample;
/* 16+16 fixed point math */
- uint32_t isample = 0;
- uint32_t istep = ((in_samples-2) << 16)/(out_samples-2);
+ uint32_t isample = 0xFFFF0000U;
+ uint32_t istep = (in_samples << 16) / out_samples + 1;
#ifdef VERBOSE
printf ("Audio : resample %d samples to %d\n",
in_samples, out_samples);
#endif
- for (osample = 0; osample < out_samples - 1; osample++) {
+ for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) {
+ uint32_t t = isample&0xffff;
+ output_samples[osample*4 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16;
+ output_samples[osample*4+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16;
+ output_samples[osample*4+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16;
+ output_samples[osample*4+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16;
+ isample += istep;
+ }
+
+ for (; osample < out_samples; osample++) {
int s1;
int s2;
int16_t os;
@@ -145,28 +170,35 @@ void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples,
isample += istep;
}
- output_samples[out_samples*4-4] = input_samples[in_samples*4-4];
- output_samples[out_samples*4-3] = input_samples[in_samples*4-3];
- output_samples[out_samples*4-2] = input_samples[in_samples*4-2];
- output_samples[out_samples*4-1] = input_samples[in_samples*4-1];
-
+ memcpy (last_sample, &input_samples[in_samples*4-4], 4 * sizeof (last_sample[0]));
}
-void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples,
+void _x_audio_out_resample_5channel(int16_t *last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples)
{
unsigned int osample;
/* 16+16 fixed point math */
- uint32_t isample = 0;
- uint32_t istep = ((in_samples-2) << 16)/(out_samples-2);
+ uint32_t isample = 0xFFFF0000U;
+ uint32_t istep = (in_samples << 16) / out_samples + 1;
#ifdef VERBOSE
printf ("Audio : resample %d samples to %d\n",
in_samples, out_samples);
#endif
- for (osample = 0; osample < out_samples - 1; osample++) {
+ for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) {
+ uint32_t t = isample&0xffff;
+ output_samples[osample*5 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16;
+ output_samples[osample*5+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16;
+ output_samples[osample*5+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16;
+ output_samples[osample*5+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16;
+ output_samples[osample*5+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16;
+ isample += istep;
+ }
+
+ for (; osample < out_samples; osample++) {
int s1;
int s2;
int16_t os;
@@ -205,29 +237,36 @@ void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples,
isample += istep;
}
-
- output_samples[out_samples*5-5] = input_samples[in_samples*5-5];
- output_samples[out_samples*5-4] = input_samples[in_samples*5-4];
- output_samples[out_samples*5-3] = input_samples[in_samples*5-3];
- output_samples[out_samples*5-2] = input_samples[in_samples*5-2];
- output_samples[out_samples*5-1] = input_samples[in_samples*5-1];
+ memcpy (last_sample, &input_samples[in_samples*5-5], 5 * sizeof (last_sample[0]));
}
-void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples,
+void _x_audio_out_resample_6channel(int16_t *last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples)
{
unsigned int osample;
/* 16+16 fixed point math */
- uint32_t isample = 0;
- uint32_t istep = ((in_samples-2) << 16)/(out_samples-2);
+ uint32_t isample = 0xFFFF0000U;
+ uint32_t istep = (in_samples << 16) / out_samples + 1;
#ifdef VERBOSE
printf ("Audio : resample %d samples to %d\n",
in_samples, out_samples);
#endif
- for (osample = 0; osample < out_samples - 1; osample++) {
+ for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) {
+ uint32_t t = isample&0xffff;
+ output_samples[osample*6 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16;
+ output_samples[osample*6+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16;
+ output_samples[osample*6+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16;
+ output_samples[osample*6+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16;
+ output_samples[osample*6+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16;
+ output_samples[osample*6+5] = (last_sample[5] * (0x10000-t) + input_samples[5] * t) >> 16;
+ isample += istep;
+ }
+
+ for (; osample < out_samples; osample++) {
int s1;
int s2;
int16_t os;
@@ -272,13 +311,7 @@ void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples,
isample += istep;
}
-
- output_samples[out_samples*6-6] = input_samples[in_samples*6-6];
- output_samples[out_samples*6-5] = input_samples[in_samples*6-5];
- output_samples[out_samples*6-4] = input_samples[in_samples*6-4];
- output_samples[out_samples*6-3] = input_samples[in_samples*6-3];
- output_samples[out_samples*6-2] = input_samples[in_samples*6-2];
- output_samples[out_samples*6-1] = input_samples[in_samples*6-1];
+ memcpy (last_sample, &input_samples[in_samples*6-6], 6 * sizeof (last_sample[0]));
}
void _x_audio_out_resample_8to16(int8_t* input_samples,
diff --git a/src/xine-engine/resample.h b/src/xine-engine/resample.h
index e5aad1afa..1fd478d06 100644
--- a/src/xine-engine/resample.h
+++ b/src/xine-engine/resample.h
@@ -27,19 +27,26 @@
#ifndef HAVE_RESAMPLE_H
#define HAVE_RESAMPLE_H
-void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples,
+#define RESAMPLE_MAX_CHANNELS 6
+
+void _x_audio_out_resample_stereo(int16_t* last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED;
-void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples,
+void _x_audio_out_resample_mono(int16_t* last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED;
-void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples,
+void _x_audio_out_resample_4channel(int16_t* last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED;
-void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples,
+void _x_audio_out_resample_5channel(int16_t* last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED;
-void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples,
+void _x_audio_out_resample_6channel(int16_t* last_sample,
+ int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED;
void _x_audio_out_resample_8to16(int8_t* input_samples,