summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Courtier-Dutton <jcdutton@users.sourceforge.net>2004-05-16 14:44:42 +0000
committerJames Courtier-Dutton <jcdutton@users.sourceforge.net>2004-05-16 14:44:42 +0000
commita3d8d5b4ec8d1b5d01c2079fdfdeb9c6cc41de3c (patch)
tree49648df9bc73d12c4ec3939b877cf72080e91b5b
parenta8edaf6b718b172e668ed1cd375025c5313791f5 (diff)
downloadxine-lib-a3d8d5b4ec8d1b5d01c2079fdfdeb9c6cc41de3c.tar.gz
xine-lib-a3d8d5b4ec8d1b5d01c2079fdfdeb9c6cc41de3c.tar.bz2
Plugin is now a XINE_POST_TYPE_AUDIO_FILTER.
Some updates so that upmixing 8,16,24 and floats works. The output of the upmixer is currently 32bit floats, so it currently only works with alsa. New audio plugins could be added to change it back to 16bit before reaching audio out so that it works with OSS etc. We just need Frontend GUIs to catch up and support AUDIO_FILTER post plugins. CVS patchset: 6548 CVS date: 2004/05/16 14:44:42
-rw-r--r--src/post/audio/upmix.c100
1 files changed, 68 insertions, 32 deletions
diff --git a/src/post/audio/upmix.c b/src/post/audio/upmix.c
index f0e40c83a..168411fd3 100644
--- a/src/post/audio/upmix.c
+++ b/src/post/audio/upmix.c
@@ -23,7 +23,7 @@
* process. It simply paints the screen a solid color and rotates through
* colors on each iteration.
*
- * $Id: upmix.c,v 1.3 2004/05/16 02:56:35 jcdutton Exp $
+ * $Id: upmix.c,v 1.4 2004/05/16 14:44:42 jcdutton Exp $
*
*/
@@ -158,9 +158,10 @@ static int upmix_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream,
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) {
+ if ((capabilities & AO_CAP_MODE_5_1CHANNEL) && (capabilities & AO_CAP_32BITS)) {
this->channels_out=6;
mode = AO_CAP_MODE_5_1CHANNEL;
+ bits = 32; /* Upmix to Floats */
} else {
this->channels_out=2;
}
@@ -204,36 +205,74 @@ static void upmix_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream
_x_post_dec_usage(port);
}
-static int upmix_frames_2to51_16bit(uint8_t *dst8, uint8_t *src8, int num_frames, af_sub_t *sub) {
- int16_t *dst=(int16_t *)dst8;
- int16_t *src=(int16_t *)src8;
-
- int frame;
- int bytes_per_sample=1; /* Actually int16 per sample here */
+static int upmix_frames_2to51_any_to_float(uint8_t *dst8, uint8_t *src8, int num_frames, int step_channel_in, af_sub_t *sub) {
+ float *dst=(float *)dst8;
+ int16_t *src16=(int16_t *)src8;
+ float *src_float=(float *)src8;
int src_num_channels=2;
int dst_num_channels=6;
int src_frame;
int dst_frame;
+ int32_t sample24;
float sample;
- int32_t sum;
+ float left;
+ float right;
+ float sum;
+ int frame;
+ int src_units_per_sample=1;
+ if (step_channel_in == 3) src_units_per_sample=step_channel_in; /* Special handling for 24 bit 3byte input */
for (frame=0;frame < num_frames; frame++) {
- dst_frame=frame*dst_num_channels*bytes_per_sample;
- src_frame=frame*src_num_channels*bytes_per_sample;
- dst[dst_frame] = src[src_frame];
- dst[dst_frame+(1*bytes_per_sample)] = src[src_frame+(1*bytes_per_sample)];
+ dst_frame=frame*dst_num_channels;
+ src_frame=frame*src_num_channels*src_units_per_sample;
+ switch (step_channel_in) {
+ case 1:
+ left = src8[src_frame];
+ left = (left - 128 ) / 128; /* FIXME: Need to verify this is correct */
+ right = src8[src_frame+1];
+ right = (right - 128) / 128;
+ break;
+ case 2:
+ left = (1.0/SHRT_MAX)*((float)src16[src_frame]);
+ right = (1.0/SHRT_MAX)*((float)src16[src_frame+1]);
+ break;
+ case 3:
+#ifdef WORDS_BIGENDIAN
+ sample24 = (src8[src_frame] << 24) | (src8[src_frame+1] << 16) | ( src8[src_frame+2] << 8);
+#else
+ sample24 = (src8[src_frame] << 8) | (src8[src_frame+1] << 16) | ( src8[src_frame+2] << 24);
+#endif
+ left = (1.0/INT32_MAX)*((float)sample24);
+#ifdef WORDS_BIGENDIAN
+ sample24 = (src8[src_frame+3] << 24) | (src8[src_frame+4] << 16) | ( src8[src_frame+5] << 8);
+#else
+ sample24 = (src8[src_frame+3] << 8) | (src8[src_frame+4] << 16) | ( src8[src_frame+5] << 24);
+#endif
+ right = (1.0/INT32_MAX)*((float)sample24);
+ break;
+ case 4:
+ left = src_float[src_frame];
+ right = src_float[src_frame+1];
+ break;
+ default:
+ left = right = 0.0;
+ }
+
+ dst[dst_frame] = left;
+ dst[dst_frame+1] = right;
/* try a bit of dolby */
/* FIXME: Dobly surround is a bit more complicated than this, but this is a start. */
- dst[dst_frame+(2*bytes_per_sample)] = (src[src_frame] - src[src_frame+(1*bytes_per_sample)]) / 2;
- dst[dst_frame+(3*bytes_per_sample)] = (src[src_frame] - src[src_frame+(1*bytes_per_sample)]) / 2;
- sum = ((int32_t)src[src_frame] + (int32_t)src[src_frame+(1*bytes_per_sample)]) / 2;
- dst[dst_frame+(4*bytes_per_sample)] = (int16_t)sum;
+ dst[dst_frame+2] = (left - right) / 2;
+ dst[dst_frame+3] = (left - right) / 2;
+ sum = (left + right) / 2;
+ dst[dst_frame+4] = sum;
/* Create the LFE channel using a low pass filter */
/* filter feature ported from mplayer */
- sample = (1.0/SHRT_MAX)*((float)sum);
+ sample = sum;
IIR(sample * sub->k, sub->w[0], sub->q[0], sample);
IIR(sample , sub->w[1], sub->q[1], sample);
- dst[dst_frame+(5*bytes_per_sample)] = (int16_t)(sample * SHRT_MAX);
+ dst[dst_frame+5] = sample;
+
}
return frame;
}
@@ -243,15 +282,10 @@ static void upmix_port_put_buffer (xine_audio_port_t *port_gen,
post_audio_port_t *port = (post_audio_port_t *)port_gen;
post_plugin_upmix_t *this = (post_plugin_upmix_t *)port->post;
- vo_frame_t *frame;
- int16_t *data;
- int8_t *data8;
- int samples_used = 0;
- int64_t pts = buf->vpts;
- int i, j;
int src_step_frame;
int dst_step_frame;
- int step_channel;
+ int step_channel_in;
+ int step_channel_out;
uint8_t *data8src;
uint8_t *data8dst;
int num_bytes;
@@ -270,13 +304,14 @@ static void upmix_port_put_buffer (xine_audio_port_t *port_gen,
/* FIXME: The audio buffer should contain this info.
* We should not have to get it from the open call.
*/
- this->buf->format.bits = port->bits;
+ this->buf->format.bits = 32; /* Upmix to floats */
this->buf->format.rate = port->rate;
this->buf->format.mode = AO_CAP_MODE_5_1CHANNEL;
_x_extra_info_merge( this->buf->extra_info, buf->extra_info);
- step_channel = this->buf->format.bits>>3;
- dst_step_frame = this->channels_out*step_channel;
- src_step_frame = this->channels*step_channel;
+ step_channel_in = port->bits>>3;
+ step_channel_out = this->buf->format.bits>>3;
+ dst_step_frame = this->channels_out*step_channel_out;
+ src_step_frame = this->channels*step_channel_in;
num_bytes=(buf->num_frames-num_frames_processed)*dst_step_frame;
if (num_bytes > this->buf->mem_size) {
num_bytes = this->buf->mem_size;
@@ -285,7 +320,7 @@ static void upmix_port_put_buffer (xine_audio_port_t *port_gen,
data8src=(int8_t*)buf->mem;
data8src+=num_frames_processed*src_step_frame;
data8dst=(int8_t*)this->buf->mem;
- num_frames_done = upmix_frames_2to51_16bit(data8dst, data8src, num_frames, this->sub);
+ num_frames_done = upmix_frames_2to51_any_to_float(data8dst, data8src, num_frames, step_channel_in, this->sub);
this->buf->num_frames = num_frames_done;
num_frames_processed+= num_frames_done;
/* pass data to original port */
@@ -387,7 +422,8 @@ static void *upmix_init_plugin(xine_t *xine, void *data)
}
/* plugin catalog information */
-post_info_t upmix_special_info = { XINE_POST_TYPE_AUDIO_VISUALIZATION };
+/* 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 */