summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine')
-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
4 files changed, 137 insertions, 64 deletions
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,