summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2001-08-23 21:40:05 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2001-08-23 21:40:05 +0000
commit9af0f9b8e5cf19ac23ddf3e1ff62629b0109d253 (patch)
treef675c9458bb600f1b0c7843e882b1263f84083c9
parentd08d8d6d67096518a67a3cd4467d3c0b1186d3e8 (diff)
downloadxine-lib-9af0f9b8e5cf19ac23ddf3e1ff62629b0109d253.tar.gz
xine-lib-9af0f9b8e5cf19ac23ddf3e1ff62629b0109d253.tar.bz2
re-enabled audio resampling, correct a/v sync, corrected code style/indentation. corrected delay() behaviour according to what's specified in the header file comment: return delay(offset) instead of absolute time
CVS patchset: 473 CVS date: 2001/08/23 21:40:05
-rw-r--r--src/audio_out/audio_oss_out.c255
-rw-r--r--src/xine-engine/audio_out.c353
-rw-r--r--src/xine-engine/audio_out.h55
-rw-r--r--src/xine-engine/xine.c4
-rw-r--r--src/xine-engine/xine_internal.h4
5 files changed, 345 insertions, 326 deletions
diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c
index 82227e5b2..76abc62e8 100644
--- a/src/audio_out/audio_oss_out.c
+++ b/src/audio_out/audio_oss_out.c
@@ -17,7 +17,7 @@
* 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_oss_out.c,v 1.31 2001/08/22 10:51:05 jcdutton Exp $
+ * $Id: audio_oss_out.c,v 1.32 2001/08/23 21:40:05 guenter Exp $
*
* 20-8-2001 First implementation of Audio sync and Audio driver separation.
* Copyright (C) 2001 James Courtier-Dutton James@superbug.demon.co.uk
@@ -32,7 +32,7 @@
* when dealing with audio_bytes instead of audio_frames.
*
* The number of samples passed to/from the audio driver is also sent in units of audio_frames.
- * `
+ *
*/
/* required for swab() */
@@ -110,7 +110,6 @@ typedef struct oss_driver_s {
int mode;
int32_t output_sample_rate, input_sample_rate;
- double sample_rate_factor;
uint32_t num_channels;
uint32_t bits_per_sample;
uint32_t bytes_per_frame;
@@ -118,52 +117,53 @@ typedef struct oss_driver_s {
int audio_started;
int audio_has_realtime; /* OSS driver supports real-time */
+ int static_delay; /* estimated delay for non-realtime drivers */
} oss_driver_t;
/*
* open the audio device for writing to
*/
-static int ao_oss_open(ao_driver_t *self_gen,
- uint32_t bits, uint32_t rate, int mode)
+static int ao_oss_open(ao_driver_t *this_gen,
+ uint32_t bits, uint32_t rate, int mode)
{
- oss_driver_t *self = (oss_driver_t *) self_gen;
+ oss_driver_t *this = (oss_driver_t *) this_gen;
int tmp;
printf ("audio_oss_out: ao_open rate=%d, mode=%d\n", rate, mode);
- if ( (mode & self->capabilities) == 0 ) {
+ if ( (mode & this->capabilities) == 0 ) {
printf ("audio_oss_out: unsupported mode %08x\n", mode);
- return -1;
+ return 0;
}
- if (self->audio_fd > -1) {
+ if (this->audio_fd > -1) {
- if ( (mode == self->mode) && (rate == self->input_sample_rate) ) {
- return 1;
+ if ( (mode == this->mode) && (rate == this->input_sample_rate) ) {
+ return this->output_sample_rate;
}
- close (self->audio_fd);
+ close (this->audio_fd);
}
- self->mode = mode;
- self->input_sample_rate = rate;
- self->bits_per_sample = bits;
- self->bytes_in_buffer = 0;
- self->audio_started = 0;
+ this->mode = mode;
+ this->input_sample_rate = rate;
+ this->bits_per_sample = bits;
+ this->bytes_in_buffer = 0;
+ this->audio_started = 0;
/*
* open audio device
*/
- self->audio_fd=open(self->audio_dev,O_WRONLY|O_NDELAY);
- if(self->audio_fd < 0) {
+ this->audio_fd=open(this->audio_dev,O_WRONLY|O_NDELAY);
+ if(this->audio_fd < 0) {
printf("audio_oss_out: Opening audio device %s: %s\n",
- self->audio_dev, strerror(errno));
- return -1;
+ this->audio_dev, strerror(errno));
+ return 0;
}
/* We wanted non blocking open but now put it back to normal */
- fcntl(self->audio_fd, F_SETFL, fcntl(self->audio_fd, F_GETFL)&~FNDELAY);
+ fcntl(this->audio_fd, F_SETFL, fcntl(this->audio_fd, F_GETFL)&~FNDELAY);
/*
* configure audio device
@@ -171,29 +171,29 @@ static int ao_oss_open(ao_driver_t *self_gen,
*/
if(!(mode & AO_CAP_MODE_AC3)) {
tmp = (mode & AO_CAP_MODE_STEREO) ? 1 : 0;
- ioctl(self->audio_fd,SNDCTL_DSP_STEREO,&tmp);
+ ioctl(this->audio_fd,SNDCTL_DSP_STEREO,&tmp);
tmp = bits;
- ioctl(self->audio_fd,SNDCTL_DSP_SAMPLESIZE,&tmp);
+ ioctl(this->audio_fd,SNDCTL_DSP_SAMPLESIZE,&tmp);
- tmp = self->input_sample_rate;
+ tmp = this->input_sample_rate;
#ifdef FORCE_44K_MAX
if(tmp > 44100)
tmp = 44100;
#endif
- if (ioctl(self->audio_fd,SNDCTL_DSP_SPEED, &tmp) == -1) {
+ if (ioctl(this->audio_fd,SNDCTL_DSP_SPEED, &tmp) == -1) {
- printf ("audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n", self->input_sample_rate);
+ printf ("audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n", this->input_sample_rate);
tmp = 44100;
- if (ioctl(self->audio_fd,SNDCTL_DSP_SPEED, &tmp) == -1) {
+ if (ioctl(this->audio_fd,SNDCTL_DSP_SPEED, &tmp) == -1) {
printf ("audio_oss_out: error: 44100 Hz sampling rate not supported\n");
- return -1;
+ return 0;
}
}
- self->output_sample_rate = tmp;
+ this->output_sample_rate = tmp;
xprintf (VERBOSE|AUDIO, "audio_oss_out: audio rate : %d requested, %d provided by device/sec\n",
- self->input_sample_rate, self->output_sample_rate);
+ this->input_sample_rate, this->output_sample_rate);
}
/*
* set number of channels / ac3 throughput
@@ -202,43 +202,43 @@ static int ao_oss_open(ao_driver_t *self_gen,
switch (mode) {
case AO_CAP_MODE_MONO:
tmp = 1;
- ioctl(self->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
- self->num_channels = tmp;
+ ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
+ this->num_channels = tmp;
break;
case AO_CAP_MODE_STEREO:
tmp = 2;
- ioctl(self->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
- self->num_channels = tmp;
+ ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
+ this->num_channels = tmp;
break;
case AO_CAP_MODE_4CHANNEL:
tmp = 4;
- ioctl(self->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
- self->num_channels = tmp;
+ ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
+ this->num_channels = tmp;
break;
case AO_CAP_MODE_5CHANNEL:
tmp = 5;
- ioctl(self->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
- self->num_channels = tmp;
+ ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
+ this->num_channels = tmp;
break;
case AO_CAP_MODE_5_1CHANNEL:
tmp = 6;
- ioctl(self->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
- self->num_channels = tmp;
+ ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
+ this->num_channels = tmp;
break;
case AO_CAP_MODE_AC3:
tmp = AFMT_AC3;
- if (ioctl(self->audio_fd, SNDCTL_DSP_SETFMT, &tmp) < 0 || tmp != AFMT_AC3) {
+ if (ioctl(this->audio_fd, SNDCTL_DSP_SETFMT, &tmp) < 0 || tmp != AFMT_AC3) {
printf("audio_oss_out: AC3 SNDCTL_DSP_SETFMT failed. %d\n",tmp);
- return -1;
+ return 0;
}
- self->num_channels = 2; /* FIXME: is this correct ? */
- self->output_sample_rate = self->input_sample_rate;
+ this->num_channels = 2; /* FIXME: is this correct ? */
+ this->output_sample_rate = this->input_sample_rate;
printf ("audio_oss_out : AO_CAP_MODE_AC3\n");
break;
}
- printf ("audio_oss_out : %d channels output\n",self->num_channels);
- self->bytes_per_frame=(self->bits_per_sample*self->num_channels)/8;
+ printf ("audio_oss_out : %d channels output\n",this->num_channels);
+ this->bytes_per_frame=(this->bits_per_sample*this->num_channels)/8;
/*
* audio buffer size handling
@@ -257,18 +257,18 @@ static int ao_oss_open(ao_driver_t *self_gen,
xprintf (VERBOSE|AUDIO, "Audio buffer fragment info : %x\n",tmp);
- ioctl(self->audio_fd,SNDCTL_DSP_SETFRAGMENT,&tmp);
+ ioctl(this->audio_fd,SNDCTL_DSP_SETFRAGMENT,&tmp);
*/
/*
* Final check of realtime capability, make sure GETOPTR
* doesn't return an error.
*/
- if ( self->audio_has_realtime && !checked_getoptr ) {
+ if ( this->audio_has_realtime && !checked_getoptr ) {
count_info info;
- int ret = ioctl(self->audio_fd, SNDCTL_DSP_GETOPTR, &info);
+ int ret = ioctl(this->audio_fd, SNDCTL_DSP_GETOPTR, &info);
if ( ret == -1 && errno == EINVAL ) {
- self->audio_has_realtime = 0;
+ this->audio_has_realtime = 0;
printf("audio_oss_out: Audio driver SNDCTL_DSP_GETOPTR reports %s,"
" disabling realtime sync...\n", strerror(errno) );
printf("audio_oss_out: ...Will use video master clock for soft-sync instead\n");
@@ -277,27 +277,42 @@ static int ao_oss_open(ao_driver_t *self_gen,
checked_getoptr = 1;
}
- return 1;
+ return this->output_sample_rate;
}
-static int ao_oss_num_channels(ao_driver_t *self_gen)
+static int ao_oss_num_channels(ao_driver_t *this_gen)
{
- oss_driver_t *self = (oss_driver_t *) self_gen;
- return self->num_channels;
+ oss_driver_t *this = (oss_driver_t *) this_gen;
+ return this->num_channels;
}
-static int ao_oss_bytes_per_frame(ao_driver_t *self_gen)
+static int ao_oss_bytes_per_frame(ao_driver_t *this_gen)
{
- oss_driver_t *self = (oss_driver_t *) self_gen;
- return self->bytes_per_frame;
+ oss_driver_t *this = (oss_driver_t *) this_gen;
+ return this->bytes_per_frame;
}
-static int ao_oss_delay(ao_driver_t *self_gen)
+static int ao_oss_delay(ao_driver_t *this_gen)
{
- count_info info;
- oss_driver_t *self = (oss_driver_t *) self_gen;
- ioctl (self->audio_fd, SNDCTL_DSP_GETOPTR, &info);
- return info.bytes / self->bytes_per_frame;
+ count_info info;
+ oss_driver_t *this = (oss_driver_t *) this_gen;
+ int bytes_left;
+
+ if (this->audio_has_realtime) {
+ ioctl (this->audio_fd, SNDCTL_DSP_GETOPTR, &info);
+
+ /* calc delay */
+
+ bytes_left = this->bytes_in_buffer - info.bytes;
+
+ if (bytes_left<=0) /* buffer ran dry */
+ bytes_left = 0;
+ } else {
+ bytes_left = this->static_delay;
+ }
+
+
+ return bytes_left / this->bytes_per_frame;
}
/* Write audio samples
@@ -305,41 +320,43 @@ static int ao_oss_delay(ao_driver_t *self_gen)
* audio frames are equivalent one sample on each channel.
* I.E. Stereo 16 bits audio frames are 4 bytes.
*/
-static int ao_oss_write(ao_driver_t *self_gen,
- int16_t* frame_buffer, uint32_t num_frames)
+static int ao_oss_write(ao_driver_t *this_gen,
+ int16_t* frame_buffer, uint32_t num_frames)
{
- oss_driver_t *self = (oss_driver_t *) self_gen;
- return write(self->audio_fd, frame_buffer, num_frames * self->bytes_per_frame);
+ oss_driver_t *this = (oss_driver_t *) this_gen;
+
+ this->bytes_in_buffer += num_frames * this->bytes_per_frame;
+ return write(this->audio_fd, frame_buffer, num_frames * this->bytes_per_frame);
}
-static void ao_oss_close(ao_driver_t *self_gen)
+static void ao_oss_close(ao_driver_t *this_gen)
{
- oss_driver_t *self = (oss_driver_t *) self_gen;
- close(self->audio_fd);
- self->audio_fd = -1;
+ oss_driver_t *this = (oss_driver_t *) this_gen;
+ close(this->audio_fd);
+ this->audio_fd = -1;
}
-static uint32_t ao_oss_get_capabilities (ao_driver_t *self_gen) {
- oss_driver_t *self = (oss_driver_t *) self_gen;
- return self->capabilities;
+static uint32_t ao_oss_get_capabilities (ao_driver_t *this_gen) {
+ oss_driver_t *this = (oss_driver_t *) this_gen;
+ return this->capabilities;
}
-static void ao_oss_exit(ao_driver_t *self_gen)
+static void ao_oss_exit(ao_driver_t *this_gen)
{
- oss_driver_t *self = (oss_driver_t *) self_gen;
+ oss_driver_t *this = (oss_driver_t *) this_gen;
- if (self->audio_fd != -1)
- close(self->audio_fd);
+ if (this->audio_fd != -1)
+ close(this->audio_fd);
- free (self);
+ free (this);
}
/*
*
*/
-static int ao_oss_get_property (ao_driver_t *self_gen, int property) {
- oss_driver_t *self = (oss_driver_t *) self;
+static int ao_oss_get_property (ao_driver_t *this_gen, int property) {
+ oss_driver_t *this = (oss_driver_t *) this;
/* FIXME: implement some properties
switch(property) {
@@ -357,8 +374,8 @@ static int ao_oss_get_property (ao_driver_t *self_gen, int property) {
/*
*
*/
-static int ao_oss_set_property (ao_driver_t *self_gen, int property, int value) {
- oss_driver_t *self = (oss_driver_t *) self;
+static int ao_oss_set_property (ao_driver_t *this_gen, int property, int value) {
+ oss_driver_t *this = (oss_driver_t *) this;
/* FIXME: Implement property support.
switch(property) {
@@ -376,7 +393,7 @@ static int ao_oss_set_property (ao_driver_t *self_gen, int property, int value)
ao_driver_t *init_audio_out_plugin (config_values_t *config) {
- oss_driver_t *self;
+ oss_driver_t *this;
int caps;
#ifdef CONFIG_DEVFS_FS
char devname[] = "/dev/sound/dsp\0\0\0";
@@ -389,7 +406,7 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
int audio_fd;
int num_channels, status, arg;
- self = (oss_driver_t *) malloc (sizeof (oss_driver_t));
+ this = (oss_driver_t *) malloc (sizeof (oss_driver_t));
/*
* find best device driver/channel
@@ -402,11 +419,11 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
devnum = config->lookup_int (config, "oss_device_num", -1);
if (devnum >= 0) {
- sprintf (self->audio_dev, DSP_TEMPLATE, devnum);
+ sprintf (this->audio_dev, DSP_TEMPLATE, devnum);
devnum = 30; /* skip while loop */
} else {
devnum = 0;
- sprintf (self->audio_dev, "/dev/dsp");
+ sprintf (this->audio_dev, "/dev/dsp");
}
while (devnum<16) {
@@ -420,14 +437,14 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
rate = 48000;
ioctl(audio_fd,SNDCTL_DSP_SPEED, &rate);
if (rate>best_rate) {
- strncpy (self->audio_dev, devname, 19);
+ strncpy (this->audio_dev, devname, 19);
best_rate = rate;
}
close (audio_fd);
} /*else
printf("audio_oss_out: opening audio device %s failed:\n%s\n",
- self->audio_dev, strerror(errno));
+ this->audio_dev, strerror(errno));
*/
sprintf(devname, DSP_TEMPLATE, devnum);
@@ -438,18 +455,18 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
* open that device
*/
- audio_fd=open(self->audio_dev, O_WRONLY|O_NDELAY);
+ audio_fd=open(this->audio_dev, O_WRONLY|O_NDELAY);
if(audio_fd < 0)
{
printf("audio_oss_out: opening audio device %s failed:\n%s\n",
- self->audio_dev, strerror(errno));
+ this->audio_dev, strerror(errno));
- free (self);
+ free (this);
return NULL;
} else
- xprintf (VERBOSE|AUDIO, " %s\n", self->audio_dev);
+ xprintf (VERBOSE|AUDIO, " %s\n", this->audio_dev);
/*
* set up driver to reasonable values for capabilities tests
@@ -468,38 +485,38 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
if ((caps & DSP_CAP_REALTIME) > 0) {
xprintf (VERBOSE|AUDIO, "audio_oss_out : realtime check: passed :-)\n");
- self->audio_has_realtime = 1;
+ this->audio_has_realtime = 1;
} else {
printf ("audio_oss_out : realtime check: *FAILED* :-(((((\n");
- self->audio_has_realtime = 0;
+ this->audio_has_realtime = 0;
}
- if( !self->audio_has_realtime ) {
+ if( !this->audio_has_realtime ) {
printf("audio_oss_out: Audio driver realtime sync disabled...\n");
printf("audio_oss_out: ...Will use video master clock for soft-sync instead\n");
printf("audio_oss_out: ...There may be audio/video synchronization issues\n");
}
- self->capabilities = 0;
+ this->capabilities = 0;
printf ("audio_oss_out : supported modes are ");
num_channels = 1;
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==1) ) {
- self->capabilities |= AO_CAP_MODE_MONO;
+ this->capabilities |= AO_CAP_MODE_MONO;
printf ("mono ");
}
num_channels = 2;
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==2) ) {
- self->capabilities |= AO_CAP_MODE_STEREO;
+ this->capabilities |= AO_CAP_MODE_STEREO;
printf ("stereo ");
}
num_channels = 4;
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==4) ) {
if (config->lookup_int (config, "four_channel", 0)) {
- self->capabilities |= AO_CAP_MODE_4CHANNEL;
+ this->capabilities |= AO_CAP_MODE_4CHANNEL;
printf ("4-channel ");
} else
printf ("(4-channel not enabled in .xinerc) " );
@@ -508,7 +525,7 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==5) ) {
if (config->lookup_int (config, "five_channel", 0)) {
- self->capabilities |= AO_CAP_MODE_5CHANNEL;
+ this->capabilities |= AO_CAP_MODE_5CHANNEL;
printf ("5-channel ");
} else
printf ("(5-channel not enabled in .xinerc) " );
@@ -517,7 +534,7 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
if ( (status != -1) && (num_channels==6) ) {
if (config->lookup_int (config, "five_lfe_channel", 0)) {
- self->capabilities |= AO_CAP_MODE_5_1CHANNEL;
+ this->capabilities |= AO_CAP_MODE_5_1CHANNEL;
printf ("5.1-channel ");
} else
printf ("(5.1-channel not enabled in .xinerc) " );
@@ -526,7 +543,7 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
ioctl(audio_fd,SNDCTL_DSP_GETFMTS,&caps);
if (caps & AFMT_AC3) {
if (config->lookup_int (config, "ac3_pass_through", 0)) {
- self->capabilities |= AO_CAP_MODE_AC3;
+ this->capabilities |= AO_CAP_MODE_AC3;
printf ("ac3-pass-through ");
} else
printf ("(ac3-pass-through not enabled in .xinerc)");
@@ -536,21 +553,23 @@ ao_driver_t *init_audio_out_plugin (config_values_t *config) {
close (audio_fd);
- self->output_sample_rate = 0;
- self->audio_fd = -1;
-
- self->ao_driver.get_capabilities = ao_oss_get_capabilities;
- self->ao_driver.get_property = ao_oss_get_property;
- self->ao_driver.set_property = ao_oss_set_property;
- self->ao_driver.open = ao_oss_open;
- self->ao_driver.num_channels = ao_oss_num_channels;
- self->ao_driver.bytes_per_frame = ao_oss_bytes_per_frame;
- self->ao_driver.delay = ao_oss_delay;
- self->ao_driver.write = ao_oss_write;
- self->ao_driver.close = ao_oss_close;
- self->ao_driver.exit = ao_oss_exit;
-
- return &self->ao_driver;
+ this->output_sample_rate = 0;
+ this->audio_fd = -1;
+
+ this->static_delay = config->lookup_int (config, "oss_static_delay", 1000);
+
+ this->ao_driver.get_capabilities = ao_oss_get_capabilities;
+ this->ao_driver.get_property = ao_oss_get_property;
+ this->ao_driver.set_property = ao_oss_set_property;
+ this->ao_driver.open = ao_oss_open;
+ this->ao_driver.num_channels = ao_oss_num_channels;
+ this->ao_driver.bytes_per_frame = ao_oss_bytes_per_frame;
+ this->ao_driver.delay = ao_oss_delay;
+ this->ao_driver.write = ao_oss_write;
+ this->ao_driver.close = ao_oss_close;
+ this->ao_driver.exit = ao_oss_exit;
+
+ return &this->ao_driver;
}
static ao_info_t ao_info_oss = {
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 462890ffc..1547ea8a7 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.6 2001/08/22 16:20:13 guenter Exp $
+ * $Id: audio_out.c,v 1.7 2001/08/23 21:40:05 guenter Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -66,118 +66,128 @@
#include "metronom.h"
#include "utils.h"
-/* bufsize must be a multiple of 3 and 5 for 5.0 and 5.1 channel playback! */
-#define ZERO_BUF_SIZE 15360
+#define ZERO_BUF_SIZE 5000
#define GAP_TOLERANCE 5000
#define MAX_GAP 90000
struct frmsize_s
{
- uint16_t bit_rate;
- uint16_t frm_size[3];
+ uint16_t bit_rate;
+ uint16_t frm_size[3];
};
static const struct frmsize_s frmsizecod_tbl[64] =
{
- { 32 ,{64 ,69 ,96 } },
- { 32 ,{64 ,70 ,96 } },
- { 40 ,{80 ,87 ,120 } },
- { 40 ,{80 ,88 ,120 } },
- { 48 ,{96 ,104 ,144 } },
- { 48 ,{96 ,105 ,144 } },
- { 56 ,{112 ,121 ,168 } },
- { 56 ,{112 ,122 ,168 } },
- { 64 ,{128 ,139 ,192 } },
- { 64 ,{128 ,140 ,192 } },
- { 80 ,{160 ,174 ,240 } },
- { 80 ,{160 ,175 ,240 } },
- { 96 ,{192 ,208 ,288 } },
- { 96 ,{192 ,209 ,288 } },
- { 112 ,{224 ,243 ,336 } },
- { 112 ,{224 ,244 ,336 } },
- { 128 ,{256 ,278 ,384 } },
- { 128 ,{256 ,279 ,384 } },
- { 160 ,{320 ,348 ,480 } },
- { 160 ,{320 ,349 ,480 } },
- { 192 ,{384 ,417 ,576 } },
- { 192 ,{384 ,418 ,576 } },
- { 224 ,{448 ,487 ,672 } },
- { 224 ,{448 ,488 ,672 } },
- { 256 ,{512 ,557 ,768 } },
- { 256 ,{512 ,558 ,768 } },
- { 320 ,{640 ,696 ,960 } },
- { 320 ,{640 ,697 ,960 } },
- { 384 ,{768 ,835 ,1152 } },
- { 384 ,{768 ,836 ,1152 } },
- { 448 ,{896 ,975 ,1344 } },
- { 448 ,{896 ,976 ,1344 } },
- { 512 ,{1024 ,1114 ,1536 } },
- { 512 ,{1024 ,1115 ,1536 } },
- { 576 ,{1152 ,1253 ,1728 } },
- { 576 ,{1152 ,1254 ,1728 } },
- { 640 ,{1280 ,1393 ,1920 } },
- { 640 ,{1280 ,1394 ,1920 } }
+ { 32 ,{64 ,69 ,96 } },
+ { 32 ,{64 ,70 ,96 } },
+ { 40 ,{80 ,87 ,120 } },
+ { 40 ,{80 ,88 ,120 } },
+ { 48 ,{96 ,104 ,144 } },
+ { 48 ,{96 ,105 ,144 } },
+ { 56 ,{112 ,121 ,168 } },
+ { 56 ,{112 ,122 ,168 } },
+ { 64 ,{128 ,139 ,192 } },
+ { 64 ,{128 ,140 ,192 } },
+ { 80 ,{160 ,174 ,240 } },
+ { 80 ,{160 ,175 ,240 } },
+ { 96 ,{192 ,208 ,288 } },
+ { 96 ,{192 ,209 ,288 } },
+ { 112 ,{224 ,243 ,336 } },
+ { 112 ,{224 ,244 ,336 } },
+ { 128 ,{256 ,278 ,384 } },
+ { 128 ,{256 ,279 ,384 } },
+ { 160 ,{320 ,348 ,480 } },
+ { 160 ,{320 ,349 ,480 } },
+ { 192 ,{384 ,417 ,576 } },
+ { 192 ,{384 ,418 ,576 } },
+ { 224 ,{448 ,487 ,672 } },
+ { 224 ,{448 ,488 ,672 } },
+ { 256 ,{512 ,557 ,768 } },
+ { 256 ,{512 ,558 ,768 } },
+ { 320 ,{640 ,696 ,960 } },
+ { 320 ,{640 ,697 ,960 } },
+ { 384 ,{768 ,835 ,1152 } },
+ { 384 ,{768 ,836 ,1152 } },
+ { 448 ,{896 ,975 ,1344 } },
+ { 448 ,{896 ,976 ,1344 } },
+ { 512 ,{1024 ,1114 ,1536 } },
+ { 512 ,{1024 ,1115 ,1536 } },
+ { 576 ,{1152 ,1253 ,1728 } },
+ { 576 ,{1152 ,1254 ,1728 } },
+ { 640 ,{1280 ,1393 ,1920 } },
+ { 640 ,{1280 ,1394 ,1920 } }
};
/*
* open the audio device for writing to
*/
-static int ao_open(ao_instance_t *self,
+static int ao_open(ao_instance_t *this,
uint32_t bits, uint32_t rate, int mode)
{
- int result;
- if ((result=self->driver->open(self->driver,bits,rate,mode))<0) {
- printf("open failed!\n");
+ int output_sample_rate;
+ if ((output_sample_rate=this->driver->open(this->driver,bits,rate,mode)) == 0) {
+ printf("audio_out: open failed!\n");
return -1;
};
- self->mode = mode;
- self->input_frame_rate = rate;
- self->frames_in_buffer = 0;
- self->audio_started = 0;
- self->last_audio_vpts = 0;
- self->do_resample = 0; /* Resampling currently not working. */
+ printf("audio_out: output sample rate %d\n", output_sample_rate);
- self->output_frame_rate=rate;
- self->num_channels = self->driver->num_channels(self->driver);
+ this->mode = mode;
+ this->input_frame_rate = rate;
+ this->audio_started = 0;
+ this->last_audio_vpts = 0;
- self->frame_rate_factor = (double) self->output_frame_rate / (double) self->input_frame_rate; /* always produces 1 at the moment */
- self->audio_step = (uint32_t) 90000 * (uint32_t) 32768
- / self->input_frame_rate;
- self->frames_per_kpts = self->output_frame_rate * self->num_channels * 2 * 1024 / 90000;
- xprintf (VERBOSE|AUDIO, "audio_out : audio_step %d pts per 32768 frames\n", self->audio_step);
+ this->output_frame_rate = output_sample_rate;
- self->metronom->set_audio_rate(self->metronom, self->audio_step);
+ switch (this->resample_conf) {
+ case 1: /* force off */
+ this->do_resample = 0;
+ break;
+ case 2: /* force on */
+ this->do_resample = 1;
+ break;
+ default: /* AUTO */
+ this->do_resample = this->output_frame_rate != this->input_frame_rate;
+ }
+ if (this->do_resample)
+ printf("audio_out: will resample audio from %d to %d\n",
+ this->input_frame_rate, this->output_frame_rate);
+
+ this->num_channels = this->driver->num_channels(this->driver);
+ this->frame_rate_factor = (double) this->output_frame_rate / (double) this->input_frame_rate;
+ this->audio_step = (uint32_t) 90000 * (uint32_t) 32768 / this->input_frame_rate;
+ this->frames_per_kpts = this->output_frame_rate * 1024 / 90000;
+ xprintf (VERBOSE|AUDIO, "audio_out : audio_step %d pts per 32768 frames\n", this->audio_step);
+
+ this->metronom->set_audio_rate(this->metronom, this->audio_step);
return 1;
}
-static void ao_fill_gap (ao_instance_t *self, uint32_t pts_len) {
+static void ao_fill_gap (ao_instance_t *this, uint32_t pts_len) {
- int num_bytes ;
+ int num_frames ;
xprintf (VERBOSE|AUDIO, "audio_out : fill_gap\n");
if (pts_len > MAX_GAP)
pts_len = MAX_GAP;
- num_bytes = pts_len * self->frames_per_kpts / 1024;
- num_bytes = (num_bytes / (2*self->num_channels)) * (2*self->num_channels);
- if(self->mode == AO_CAP_MODE_AC3) return; /* FIXME */
+ num_frames = pts_len * this->frames_per_kpts / 1024;
- printf ("audio_out: inserting %d 0-bytes to fill a gap of %d pts\n",num_bytes, pts_len);
+ if (this->mode == AO_CAP_MODE_AC3) return; /* FIXME */
- self->frames_in_buffer += num_bytes;
+ printf ("audio_out: inserting %d 0-frames to fill a gap of %d pts\n",num_frames, pts_len);
- while (num_bytes > 0) {
- if (num_bytes > ZERO_BUF_SIZE) {
- self->driver->write(self->driver, self->zero_space, ZERO_BUF_SIZE);
- num_bytes -= ZERO_BUF_SIZE;
+ while (num_frames > 0) {
+ if (num_frames > ZERO_BUF_SIZE) {
+ this->driver->write(this->driver, this->zero_space, ZERO_BUF_SIZE);
+ num_frames -= ZERO_BUF_SIZE;
} else {
- self->driver->write(self->driver, self->zero_space, num_bytes);
- num_bytes = 0;
+ this->driver->write(this->driver, this->zero_space, num_frames);
+ num_frames = 0;
}
}
}
@@ -189,7 +199,7 @@ static void ao_fill_gap (ao_instance_t *self, uint32_t pts_len) {
* So it has moved to here.
*/
-void write_pause_burst(ao_instance_t *self, int error)
+void write_pause_burst(ao_instance_t *this, int error)
{
unsigned char buf[8192];
unsigned short *sbuf = (unsigned short *)&buf[0];
@@ -209,139 +219,134 @@ void write_pause_burst(ao_instance_t *self, int error)
sbuf[5] = 0x0000;
memset(&sbuf[6], 0, 6144 - 96);
- self->driver->write(self->driver, sbuf, 6144 / 4);
+ this->driver->write(this->driver, sbuf, 6144 / 4);
}
-static int ao_write(ao_instance_t *self,
+static int ao_write(ao_instance_t *this,
int16_t* output_frames, uint32_t num_frames,
- uint32_t pts_)
+ uint32_t pts)
{
- uint32_t vpts, buffer_vpts;
- int32_t gap;
- int bDropPackage;
- int pos;
- int frame_size;
- int fscod;
- int frmsizecod;
- uint8_t *data;
+ uint32_t vpts, buffer_vpts;
+ int32_t gap;
+ int bDropPackage;
+ int delay;
+ int frame_size;
+ int fscod;
+ int frmsizecod;
+ uint8_t *data;
- if (self->driver<0)
+ if (this->driver<0)
return 1;
- vpts = self->metronom->got_audio_samples (self->metronom, pts_, num_frames);
+ vpts = this->metronom->got_audio_samples (this->metronom, pts, num_frames);
xprintf (VERBOSE|AUDIO, "audio_out: got %d frames, vpts=%d pts=%d\n",
- num_frames, vpts,pts_);
+ num_frames, vpts, pts);
- if (vpts<self->last_audio_vpts) {
- /* reject self */
- xprintf (VERBOSE|AUDIO, "audio_out: rejected frame vpts=%d, last_audio_vpts=%d\n", vpts,self->last_audio_vpts)
+ if (vpts<this->last_audio_vpts) {
+ /* reject this */
+ xprintf (VERBOSE|AUDIO, "audio_out: rejected frame vpts=%d, last_audio_vpts=%d\n", vpts,this->last_audio_vpts)
return 1;
}
- self->last_audio_vpts = vpts;
+ this->last_audio_vpts = vpts;
bDropPackage = 0;
- if ( self->audio_has_realtime || !self->audio_started ) {
-
- /*
- * where, in the timeline is the "end" of the audio buffer at the moment?
- */
-
- buffer_vpts = self->metronom->get_current_time (self->metronom);
-
- if (self->audio_started) {
- pos = self->driver->delay(self->driver);
- } else
- pos = 0;
- if ( (self->mode==AO_CAP_MODE_AC3) && (pos>10) ) pos-=10; /* External AC3 decoder delay correction */
-
- if (pos>self->frames_in_buffer) /* buffer ran dry */
- self->frames_in_buffer = pos;
-
- buffer_vpts += (self->frames_in_buffer - pos) * 1024 / self->frames_per_kpts;
+ /*
+ * where, in the timeline is the "end" of the audio buffer at the moment?
+ */
+
+ buffer_vpts = this->metronom->get_current_time (this->metronom);
- /*
- * calculate gap:
- */
+ if (this->audio_started)
+ delay = this->driver->delay(this->driver);
+ else
+ delay = 0;
+
+ /* External AC3 decoder delay correction */
+ if (this->mode==AO_CAP_MODE_AC3)
+ delay+=10;
+
+ buffer_vpts += delay * 1024 / this->frames_per_kpts;
- gap = vpts - buffer_vpts;
- xprintf (VERBOSE|AUDIO, "audio_out: buff=%d pos=%d buf_vpts=%d gap=%d\n",
- self->frames_in_buffer, pos,buffer_vpts,gap);
+ /*
+ * calculate gap:
+ */
+
+ gap = vpts - buffer_vpts;
+
+ if (gap>GAP_TOLERANCE) {
+ ao_fill_gap (this, gap);
- if (gap>GAP_TOLERANCE) {
- ao_fill_gap (self, gap);
-
- /* keep xine responsive */
+ /* keep xine responsive */
- if (gap>MAX_GAP)
- return 0;
+ if (gap>MAX_GAP)
+ return 0;
- } else if (gap<-GAP_TOLERANCE) {
- bDropPackage = 1;
- xprintf (VERBOSE|AUDIO, "audio_out: audio package (vpts = %d %d)"
- "dropped\n", vpts, gap);
- }
+ } else if (gap<-GAP_TOLERANCE) {
+ bDropPackage = 1;
+ xprintf (VERBOSE|AUDIO, "audio_out: audio package (vpts = %d %d)"
+ "dropped\n", vpts, gap);
+ }
- } /* has realtime */
-
/*
* resample and output frames
*/
- if(self->mode == AO_CAP_MODE_AC3) bDropPackage=0;
+ if (this->mode == AO_CAP_MODE_AC3)
+ bDropPackage=0;
if (!bDropPackage) {
- int num_output_frames = num_frames * (self->output_frame_rate) / self->input_frame_rate;
+ int num_output_frames = (double) num_frames * this->frame_rate_factor;
- if ((!self->do_resample) && (self->mode != AO_CAP_MODE_AC3)) {
+ if ((!this->do_resample) && (this->mode != AO_CAP_MODE_AC3)) {
xprintf (VERBOSE|AUDIO, "audio_out: writing without resampling\n");
- self->driver->write(self->driver, output_frames,
- num_output_frames );
- } else switch (self->mode) {
+ this->driver->write (this->driver, output_frames,
+ num_output_frames );
+ } else switch (this->mode) {
case AO_CAP_MODE_MONO:
audio_out_resample_mono (output_frames, num_frames,
- self->frame_buffer, num_output_frames);
- self->driver->write(self->driver, self->frame_buffer, num_output_frames);
+ this->frame_buffer, num_output_frames);
+ this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
case AO_CAP_MODE_STEREO:
audio_out_resample_stereo (output_frames, num_frames,
- self->frame_buffer, num_output_frames);
- self->driver->write(self->driver, self->frame_buffer, num_output_frames);
+ this->frame_buffer, num_output_frames);
+ this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
case AO_CAP_MODE_4CHANNEL:
audio_out_resample_4channel (output_frames, num_frames,
- self->frame_buffer, num_output_frames);
- self->driver->write(self->driver, self->frame_buffer, num_output_frames);
+ this->frame_buffer, num_output_frames);
+ this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
case AO_CAP_MODE_5CHANNEL:
audio_out_resample_5channel (output_frames, num_frames,
- self->frame_buffer, num_output_frames);
- self->driver->write(self->driver, self->frame_buffer, num_output_frames);
+ this->frame_buffer, num_output_frames);
+ this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
case AO_CAP_MODE_5_1CHANNEL:
audio_out_resample_6channel (output_frames, num_frames,
- self->frame_buffer, num_output_frames);
- self->driver->write(self->driver, self->frame_buffer, num_output_frames);
+ this->frame_buffer, num_output_frames);
+ this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
case AO_CAP_MODE_AC3:
num_output_frames = (num_frames+8)/4;
- self->frame_buffer[0] = 0xf872; /* spdif syncword */
- self->frame_buffer[1] = 0x4e1f; /* ............. */
- self->frame_buffer[2] = 0x0001; /* AC3 data */
+ this->frame_buffer[0] = 0xf872; /* spdif syncword */
+ this->frame_buffer[1] = 0x4e1f; /* ............. */
+ this->frame_buffer[2] = 0x0001; /* AC3 data */
data = (uint8_t *)&output_frames[1]; /* skip AC3 sync */
fscod = (data[2] >> 6) & 0x3;
frmsizecod = data[2] & 0x3f;
frame_size = frmsizecod_tbl[frmsizecod].frm_size[fscod] << 4;
- self->frame_buffer[3] = frame_size;
+ this->frame_buffer[3] = frame_size;
/* ac3 seems to be swabbed data */
- swab(output_frames,self->frame_buffer+4, num_frames );
- self->driver->write(self->driver, self->zero_space, 2); /* Prevents crackle at start. */
- self->driver->write(self->driver, self->frame_buffer, num_output_frames);
- self->driver->write(self->driver, self->zero_space, 1534-num_output_frames);
+ swab(output_frames,this->frame_buffer+4, num_frames );
+ this->driver->write(this->driver, this->zero_space, 2); /* Prevents crackle at start. */
+ this->driver->write(this->driver, this->frame_buffer, num_output_frames);
+ this->driver->write(this->driver, this->zero_space, 1534-num_output_frames);
num_output_frames=num_output_frames;
break;
}
@@ -352,8 +357,7 @@ static int ao_write(ao_instance_t *self,
* step values
*/
- self->frames_in_buffer += num_output_frames ;
- self->audio_started = 1;
+ this->audio_started = 1;
}
return 1;
@@ -361,34 +365,37 @@ static int ao_write(ao_instance_t *self,
}
-static void ao_close(ao_instance_t *self)
+static void ao_close(ao_instance_t *this)
{
- self->driver->close(self->driver);
+ this->driver->close(this->driver);
}
-static uint32_t ao_get_capabilities (ao_instance_t *self) {
+static uint32_t ao_get_capabilities (ao_instance_t *this) {
uint32_t result;
- result=self->driver->get_capabilities(self->driver);
+ result=this->driver->get_capabilities(this->driver);
return result;
}
-ao_instance_t *ao_new_instance (ao_driver_t *driver, metronom_t *metronom) {
+ao_instance_t *ao_new_instance (ao_driver_t *driver, metronom_t *metronom,
+ config_values_t *config) {
+
+ ao_instance_t *this;
- ao_instance_t *self;
+ this = xmalloc (sizeof (ao_instance_t)) ;
- self = xmalloc (sizeof (ao_instance_t)) ;
+ this->driver = driver;
+ this->metronom = metronom;
- self->driver = driver;
- self->metronom = metronom;
+ this->open = ao_open;
+ this->write = ao_write;
+ this->close = ao_close;
+ this->get_capabilities = ao_get_capabilities;
+ this->audio_loop_running = 0;
+ this->frame_buffer = xmalloc (40000);
+ this->zero_space = xmalloc (ZERO_BUF_SIZE * 2 * 6);
- self->open = ao_open;
- self->write = ao_write;
- self->close = ao_close;
- self->get_capabilities = ao_get_capabilities;
- self->audio_loop_running = 0;
- self->frame_buffer = xmalloc (40000);
- self->zero_space = xmalloc (ZERO_BUF_SIZE);
+ this->resample_conf = config->lookup_int (config, "audio_resample_mode", 0);
- return self;
+ return this;
}
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index 27b4c2f2d..c7ea69b3e 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.h
@@ -17,7 +17,7 @@
* 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_out.h,v 1.9 2001/08/21 19:39:50 jcdutton Exp $
+ * $Id: audio_out.h,v 1.10 2001/08/23 21:40:05 guenter Exp $
*/
#ifndef HAVE_AUDIO_OUT_H
#define HAVE_AUDIO_OUT_H
@@ -58,7 +58,7 @@ struct ao_driver_s {
* open the driver and make it ready to receive audio data
* buffers may be flushed(!)
*
- * return value: <=0 : failure, 1 : ok
+ * return value: 0 : failure, >0 : output sample rate
*/
int (*open)(ao_driver_t *this, uint32_t bits, uint32_t rate, int mode);
@@ -123,7 +123,7 @@ struct ao_instance_s {
/* open display driver for video output */
int (*open) (ao_instance_t *this,
- uint32_t bits, uint32_t rate, int mode);
+ uint32_t bits, uint32_t rate, int mode);
/*
* write audio data to output buffer
@@ -135,8 +135,8 @@ struct ao_instance_s {
*/
int (*write)(ao_driver_t *this,
- int16_t* audio_data, uint32_t num_frames,
- uint32_t pts);
+ int16_t* audio_data, uint32_t num_frames,
+ uint32_t pts);
/* audio driver is no longer used by decoder => close */
void (*close) (ao_instance_t *self);
@@ -146,37 +146,30 @@ struct ao_instance_s {
/* private stuff */
- ao_driver_t *driver;
- metronom_t *metronom;
-
- int audio_loop_running;
- pthread_t audio_thread;
- int audio_step; /* pts per 32 768 samples (sample = #bytes/2) */
- int32_t frames_per_kpts; /* bytes per 1024/90000 sec */
- int32_t output_frame_rate, input_frame_rate;
- double frame_rate_factor;
- uint32_t num_channels;
- uint32_t frames_in_buffer; /* a frame is equivalent to one sample in each channel. */
- int audio_started;
- int audio_has_realtime; /* OSS driver supports real-time */
- uint32_t last_audio_vpts;
- int resample_conf;
- int do_resample;
- int mode;
- uint16_t *frame_buffer;
- int16_t *zero_space;
- int pts_per_half_frame;
- int pts_per_frame;
-
- int num_frames_delivered;
- int num_frames_skipped;
- int num_frames_discarded;
+ ao_driver_t *driver;
+ metronom_t *metronom;
+
+ int audio_loop_running;
+ pthread_t audio_thread;
+
+ int audio_step; /* pts per 32 768 samples (sample = #bytes/2) */
+ int32_t frames_per_kpts; /* frames per 1024/90000 sec */
+ int32_t output_frame_rate, input_frame_rate;
+ double frame_rate_factor;
+ uint32_t num_channels;
+ int audio_started;
+ uint32_t last_audio_vpts;
+ int resample_conf;
+ int do_resample;
+ int mode;
+ uint16_t *frame_buffer;
+ int16_t *zero_space;
};
/* This initiates the audio_out sync routines
* found in ./src/xine-engine/audio_out.c
*/
-ao_instance_t *ao_new_instance (ao_driver_t *driver, metronom_t *metronom) ;
+ao_instance_t *ao_new_instance (ao_driver_t *driver, metronom_t *metronom, config_values_t *config) ;
/*
* to build a dynamic audio output plugin,
* you have to implement these driver:
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 17fd9385b..4d4033934 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine.c,v 1.45 2001/08/21 19:39:50 jcdutton Exp $
+ * $Id: xine.c,v 1.46 2001/08/23 21:40:05 guenter Exp $
*
* top-level xine functions
*
@@ -515,7 +515,7 @@ xine_t *xine_init (vo_driver_t *vo,
video_decoder_init (this);
if(ao) {
- this->audio_out = ao_new_instance (ao, this->metronom);
+ this->audio_out = ao_new_instance (ao, this->metronom, config);
// this->audio_out = ao;
// this->audio_out->connect (this->audio_out, this->metronom);
}
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 8c91426e6..39ede9b61 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_internal.h,v 1.39 2001/08/21 19:39:50 jcdutton Exp $
+ * $Id: xine_internal.h,v 1.40 2001/08/23 21:40:05 guenter Exp $
*
*/
@@ -167,7 +167,7 @@ struct xine_s {
video_decoder_t *cur_video_decoder_plugin;
int video_finished;
- ao_instance_t *audio_out;
+ ao_instance_t *audio_out;
fifo_buffer_t *audio_fifo;
pthread_t audio_thread;
audio_decoder_t *audio_decoder_plugins[DECODER_PLUGIN_MAX];