summaryrefslogtreecommitdiff
path: root/src/xine-engine/audio_out.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine/audio_out.c')
-rw-r--r--src/xine-engine/audio_out.c140
1 files changed, 103 insertions, 37 deletions
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 42f78f335..7cb88d5e3 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.93 2002/12/24 14:00:55 miguelfreitas Exp $
+ * $Id: audio_out.c,v 1.94 2002/12/26 21:53:42 miguelfreitas Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -106,6 +106,50 @@
#define SYNC_BUF_INTERVAL NUM_AUDIO_BUFFERS / 2
#define SYNC_GAP_RATE 4
+
+typedef struct {
+
+ xine_audio_port_t ao; /* public part */
+
+ /* private stuff */
+ ao_driver_t *driver;
+ pthread_mutex_t driver_lock;
+ metronom_clock_t *clock;
+ xine_t *xine;
+ xine_list_t *streams;
+ pthread_mutex_t streams_lock;
+
+ int audio_loop_running;
+ int audio_paused;
+ 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 */
+
+ ao_format_t input, output; /* format conversion done at audio_out.c */
+ double frame_rate_factor;
+
+ int resample_conf;
+ int force_rate; /* force audio output rate to this value if non-zero */
+ int do_resample;
+ int gap_tolerance;
+ audio_fifo_t *free_fifo;
+ audio_fifo_t *out_fifo;
+ int64_t last_audio_vpts;
+
+ audio_buffer_t *frame_buf[2]; /* two buffers for "stackable" conversions */
+ int16_t *zero_space;
+
+ int64_t passthrough_offset;
+ int flush_audio_driver;
+ int discard_buffers;
+
+ int do_compress;
+ double compression_factor; /* current compression */
+ double compression_factor_max; /* user limit on compression */
+
+} aos_t;
+
struct audio_fifo_s {
audio_buffer_t *first;
audio_buffer_t *last;
@@ -206,8 +250,8 @@ static audio_buffer_t *fifo_remove (audio_fifo_t *fifo) {
}
-static void write_pause_burst(xine_audio_port_t *this, uint32_t num_frames) {
-
+static void write_pause_burst(aos_t *this, uint32_t num_frames) {
+
int error = 0;
unsigned char buf[8192];
unsigned short *sbuf = (unsigned short *)&buf[0];
@@ -244,7 +288,7 @@ static void write_pause_burst(xine_audio_port_t *this, uint32_t num_frames) {
}
-static void ao_fill_gap (xine_audio_port_t *this, int64_t pts_len) {
+static void ao_fill_gap (aos_t *this, int64_t pts_len) {
int num_frames ;
@@ -285,7 +329,7 @@ static void ensure_buffer_size (audio_buffer_t *buf, int bytes_per_frame,
buf->num_frames = frames;
}
-static audio_buffer_t * swap_frame_buffers ( xine_audio_port_t *this ) {
+static audio_buffer_t * swap_frame_buffers ( aos_t *this ) {
audio_buffer_t *tmp;
tmp = this->frame_buf[1];
@@ -310,7 +354,7 @@ static int mode_channels( int mode ) {
return 0;
}
-static void audio_filter_compress (xine_audio_port_t *this, int16_t *mem, int num_frames) {
+static void audio_filter_compress (aos_t *this, int16_t *mem, int num_frames) {
int i, maxs;
double f_max;
@@ -358,7 +402,7 @@ static void audio_filter_compress (xine_audio_port_t *this, int16_t *mem, int nu
}
}
-static audio_buffer_t* prepare_samples( xine_audio_port_t *this, audio_buffer_t *buf) {
+static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) {
double acc_output_frames, output_frame_excess = 0;
int num_output_frames ;
@@ -492,7 +536,7 @@ static audio_buffer_t* prepare_samples( xine_audio_port_t *this, audio_buffer_t
*/
static void *ao_loop (void *this_gen) {
- xine_audio_port_t *this = (xine_audio_port_t *) this_gen;
+ aos_t *this = (aos_t *) this_gen;
int64_t hw_vpts;
audio_buffer_t *in_buf, *out_buf;
int64_t gap;
@@ -532,7 +576,7 @@ static void *ao_loop (void *this_gen) {
}
if (this->flush_audio_driver) {
- this->control(this, AO_CTRL_FLUSH_BUFFERS);
+ this->ao.control(&this->ao, AO_CTRL_FLUSH_BUFFERS);
this->flush_audio_driver = 0;
continue;
}
@@ -701,9 +745,10 @@ static void *ao_loop (void *this_gen) {
* open the audio device for writing to, start audio output thread
*/
-static int ao_open(xine_audio_port_t *this, xine_stream_t *stream,
+static int ao_open(xine_audio_port_t *this_gen, xine_stream_t *stream,
uint32_t bits, uint32_t rate, int mode) {
+ aos_t *this = (aos_t *) this_gen;
int output_sample_rate, err;
pthread_attr_t pth_attrs;
@@ -837,7 +882,9 @@ static int ao_open(xine_audio_port_t *this, xine_stream_t *stream,
return this->output.rate;
}
-static audio_buffer_t *ao_get_buffer (xine_audio_port_t *this) {
+static audio_buffer_t *ao_get_buffer (xine_audio_port_t *this_gen) {
+
+ aos_t *this = (aos_t *) this_gen;
audio_buffer_t *buf;
buf = fifo_remove (this->free_fifo);
@@ -846,8 +893,10 @@ static audio_buffer_t *ao_get_buffer (xine_audio_port_t *this) {
return buf;
}
-static void ao_put_buffer (xine_audio_port_t *this, audio_buffer_t *buf, xine_stream_t *stream) {
+static void ao_put_buffer (xine_audio_port_t *this_gen,
+ audio_buffer_t *buf, xine_stream_t *stream) {
+ aos_t *this = (aos_t *) this_gen;
int64_t pts;
if (buf->num_frames == 0) {
@@ -876,8 +925,9 @@ static void ao_put_buffer (xine_audio_port_t *this, audio_buffer_t *buf, xine_st
#endif
}
-static void ao_close(xine_audio_port_t *this, xine_stream_t *stream) {
+static void ao_close(xine_audio_port_t *this_gen, xine_stream_t *stream) {
+ aos_t *this = (aos_t *) this_gen;
audio_buffer_t *audio_buffer;
xine_stream_t *cur;
@@ -910,7 +960,8 @@ static void ao_close(xine_audio_port_t *this, xine_stream_t *stream) {
pthread_mutex_unlock( &this->driver_lock );
}
-static void ao_exit(xine_audio_port_t *this) {
+static void ao_exit(xine_audio_port_t *this_gen) {
+ aos_t *this = (aos_t *) this_gen;
int vol;
int prop = 0;
@@ -971,7 +1022,8 @@ static void ao_exit(xine_audio_port_t *this) {
free (this);
}
-static uint32_t ao_get_capabilities (xine_audio_port_t *this) {
+static uint32_t ao_get_capabilities (xine_audio_port_t *this_gen) {
+ aos_t *this = (aos_t *) this_gen;
uint32_t result;
pthread_mutex_lock( &this->driver_lock );
@@ -981,7 +1033,8 @@ static uint32_t ao_get_capabilities (xine_audio_port_t *this) {
return result;
}
-static int ao_get_property (xine_audio_port_t *this, int property) {
+static int ao_get_property (xine_audio_port_t *this_gen, int property) {
+ aos_t *this = (aos_t *) this_gen;
int ret;
switch (property) {
@@ -993,6 +1046,10 @@ static int ao_get_property (xine_audio_port_t *this, int property) {
ret = this->discard_buffers;
break;
+ case AO_PROP_PAUSED:
+ ret = this->audio_paused;
+ break;
+
default:
pthread_mutex_lock( &this->driver_lock );
ret = this->driver->get_property(this->driver, property);
@@ -1001,7 +1058,8 @@ static int ao_get_property (xine_audio_port_t *this, int property) {
return ret;
}
-static int ao_set_property (xine_audio_port_t *this, int property, int value) {
+static int ao_set_property (xine_audio_port_t *this_gen, int property, int value) {
+ aos_t *this = (aos_t *) this_gen;
int ret;
switch (property) {
@@ -1018,6 +1076,11 @@ static int ao_set_property (xine_audio_port_t *this, int property, int value) {
ret = this->discard_buffers;
break;
+ case AO_PROP_PAUSED:
+ this->audio_paused = value;
+ ret = this->audio_paused;
+ break;
+
default:
pthread_mutex_lock( &this->driver_lock );
ret = this->driver->set_property(this->driver, property, value);
@@ -1027,23 +1090,25 @@ static int ao_set_property (xine_audio_port_t *this, int property, int value) {
return ret;
}
-static int ao_control (xine_audio_port_t *this, int cmd, ...) {
+static int ao_control (xine_audio_port_t *this_gen, int cmd, ...) {
+ aos_t *this = (aos_t *) this_gen;
va_list args;
void *arg;
int rval;
+ pthread_mutex_lock( &this->driver_lock );
va_start(args, cmd);
arg = va_arg(args, void*);
- pthread_mutex_lock( &this->driver_lock );
rval = this->driver->control(this->driver, cmd, arg);
- pthread_mutex_unlock( &this->driver_lock );
va_end(args);
+ pthread_mutex_unlock( &this->driver_lock );
return rval;
}
-static void ao_flush (xine_audio_port_t *this) {
+static void ao_flush (xine_audio_port_t *this_gen) {
+ aos_t *this = (aos_t *) this_gen;
audio_buffer_t *buf;
if( this->audio_loop_running ) {
@@ -1064,11 +1129,11 @@ static void ao_flush (xine_audio_port_t *this) {
xine_audio_port_t *ao_new_port (xine_t *xine, ao_driver_t *driver) {
config_values_t *config = xine->config;
- xine_audio_port_t *this;
+ aos_t *this;
int i;
static char *resample_modes[] = {"auto", "off", "on", NULL};
- this = xine_xmalloc (sizeof (xine_audio_port_t)) ;
+ this = xine_xmalloc (sizeof (aos_t)) ;
this->driver = driver;
this->xine = xine;
@@ -1078,16 +1143,17 @@ xine_audio_port_t *ao_new_port (xine_t *xine, ao_driver_t *driver) {
pthread_mutex_init( &this->streams_lock, NULL );
pthread_mutex_init( &this->driver_lock, NULL );
- this->open = ao_open;
- this->get_buffer = ao_get_buffer;
- this->put_buffer = ao_put_buffer;
- this->close = ao_close;
- this->exit = ao_exit;
- this->get_capabilities = ao_get_capabilities;
- this->get_property = ao_get_property;
- this->set_property = ao_set_property;
- this->control = ao_control;
- this->flush = ao_flush;
+ this->ao.open = ao_open;
+ this->ao.get_buffer = ao_get_buffer;
+ this->ao.put_buffer = ao_put_buffer;
+ this->ao.close = ao_close;
+ this->ao.exit = ao_exit;
+ this->ao.get_capabilities = ao_get_capabilities;
+ this->ao.get_property = ao_get_property;
+ this->ao.set_property = ao_set_property;
+ this->ao.control = ao_control;
+ this->ao.flush = ao_flush;
+
this->audio_loop_running = 0;
this->audio_paused = 0;
this->flush_audio_driver = 0;
@@ -1161,14 +1227,14 @@ xine_audio_port_t *ao_new_port (xine_t *xine, ao_driver_t *driver) {
0, NULL, NULL)) {
int prop = 0;
- if((ao_get_capabilities(this)) & AO_CAP_MIXER_VOL)
+ if((ao_get_capabilities(&this->ao)) & AO_CAP_MIXER_VOL)
prop = AO_PROP_MIXER_VOL;
- else if((ao_get_capabilities(this)) & AO_CAP_PCM_VOL)
+ else if((ao_get_capabilities(&this->ao)) & AO_CAP_PCM_VOL)
prop = AO_PROP_PCM_VOL;
- ao_set_property(this, prop, vol);
+ ao_set_property(&this->ao, prop, vol);
}
}
- return this;
+ return &this->ao;
}