diff options
author | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-05-21 20:39:03 +0000 |
---|---|---|
committer | Miguel Freitas <miguelfreitas@users.sourceforge.net> | 2002-05-21 20:39:03 +0000 |
commit | 55b3044b0866913d8a08717c5c35ba5a3a5c0428 (patch) | |
tree | a15f1ffa741a44dd2c5296bfcb571734ff085479 | |
parent | 8851e1a66d79d6a88f4dbd053ed1545335ca5422 (diff) | |
download | xine-lib-55b3044b0866913d8a08717c5c35ba5a3a5c0428.tar.gz xine-lib-55b3044b0866913d8a08717c5c35ba5a3a5c0428.tar.bz2 |
better output buffer calculations (when resampling) by Ian Goldberg
<ian@cypherpunks.ca>
CVS patchset: 1926
CVS date: 2002/05/21 20:39:03
-rw-r--r-- | src/xine-engine/audio_out.c | 31 | ||||
-rw-r--r-- | src/xine-engine/audio_out.h | 3 |
2 files changed, 29 insertions, 5 deletions
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index 12f2bbf9c..d63e2443d 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.53 2002/04/29 23:32:00 jcdutton Exp $ + * $Id: audio_out.c,v 1.54 2002/05/21 20:39:03 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> @@ -255,6 +255,14 @@ static void ao_fill_gap (ao_instance_t *this, int64_t pts_len) { } } +static void ensure_buffer_size (ao_instance_t *this, int size) +{ + if (this->frame_buffer_size < size) { + free (this->frame_buffer); + this->frame_buffer = xine_xmalloc (size); + this->frame_buffer_size = size; + } +} static void *ao_loop (void *this_gen) { @@ -268,6 +276,7 @@ static void *ao_loop (void *this_gen) { int paused_wait; int64_t last_sync_time; int bufs_since_sync; + double acc_output_frames, output_frame_excess = 0; last_sync_time = bufs_since_sync = 0; @@ -363,13 +372,22 @@ static void *ao_loop (void *this_gen) { * resample and output audio data */ - num_output_frames = (double) buf->num_frames * this->frame_rate_factor; + /* calculate number of output frames (after resampling) */ + acc_output_frames = (double) buf->num_frames * this->frame_rate_factor + + output_frame_excess; + + /* Truncate to an integer */ + num_output_frames = acc_output_frames; + + /* Keep track of the amount truncated */ + output_frame_excess = acc_output_frames - (double) num_output_frames; #ifdef LOG printf ("audio_out: outputting %d frames\n", num_output_frames); #endif - if ((!this->do_resample) + /* check if resample is needed */ + if (((!this->do_resample) || (buf->num_frames == num_output_frames)) && (this->mode != AO_CAP_MODE_A52) && (this->mode != AO_CAP_MODE_AC5)) { @@ -377,26 +395,31 @@ static void *ao_loop (void *this_gen) { buf->num_frames ); } else switch (this->mode) { case AO_CAP_MODE_MONO: + ensure_buffer_size(this, 2*num_output_frames); audio_out_resample_mono (buf->mem, buf->num_frames, this->frame_buffer, num_output_frames); this->driver->write(this->driver, this->frame_buffer, num_output_frames); break; case AO_CAP_MODE_STEREO: + ensure_buffer_size(this, 4*num_output_frames); audio_out_resample_stereo (buf->mem, buf->num_frames, this->frame_buffer, num_output_frames); this->driver->write(this->driver, this->frame_buffer, num_output_frames); break; case AO_CAP_MODE_4CHANNEL: + ensure_buffer_size(this, 8*num_output_frames); audio_out_resample_4channel (buf->mem, buf->num_frames, this->frame_buffer, num_output_frames); this->driver->write(this->driver, this->frame_buffer, num_output_frames); break; case AO_CAP_MODE_5CHANNEL: + ensure_buffer_size(this, 10*num_output_frames); audio_out_resample_5channel (buf->mem, buf->num_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: + ensure_buffer_size(this, 12*num_output_frames); audio_out_resample_6channel (buf->mem, buf->num_frames, this->frame_buffer, num_output_frames); this->driver->write(this->driver, this->frame_buffer, num_output_frames); @@ -654,8 +677,8 @@ ao_instance_t *ao_new_instance (ao_driver_t *driver, xine_t *xine) { this->control = ao_control; this->audio_loop_running = 0; this->audio_paused = 0; - /* FIXME: is 4* good enough for all resample cases?? */ this->frame_buffer = xine_xmalloc (4 * AUDIO_BUF_SIZE); + this->frame_buffer_size = 4 * AUDIO_BUF_SIZE; this->zero_space = xine_xmalloc (ZERO_BUF_SIZE * 2 * 6); this->gap_tolerance = driver->get_gap_tolerance (this->driver); diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h index fb73dc483..5784c6b39 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.28 2002/03/26 01:47:17 miguelfreitas Exp $ + * $Id: audio_out.h,v 1.29 2002/05/21 20:39:03 miguelfreitas Exp $ */ #ifndef HAVE_AUDIO_OUT_H #define HAVE_AUDIO_OUT_H @@ -219,6 +219,7 @@ struct ao_instance_s { audio_fifo_t *free_fifo; audio_fifo_t *out_fifo; uint16_t *frame_buffer; + uint32_t frame_buffer_size; int16_t *zero_space; }; |