diff options
Diffstat (limited to 'libao2/ao_alsa.c')
-rw-r--r-- | libao2/ao_alsa.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/libao2/ao_alsa.c b/libao2/ao_alsa.c index f7eeb7ddd9..1ea974f6c1 100644 --- a/libao2/ao_alsa.c +++ b/libao2/ao_alsa.c @@ -70,6 +70,7 @@ static int ao_noblock = 0; static int open_mode; static int alsa_can_pause = 0; +static snd_pcm_sframes_t prepause_frames; #define ALSA_DEVICE_SIZE 256 @@ -334,6 +335,8 @@ static int init(int rate_hz, int channels, int format, int flags) mp_msg(MSGT_AO,MSGL_V,"alsa-init: compiled for ALSA-%s\n", SND_LIB_VERSION_STR); #endif + prepause_frames = 0; + snd_lib_error_set_handler(alsa_error_handler); ao_data.samplerate = rate_hz; @@ -753,6 +756,10 @@ static void audio_pause(void) } mp_msg(MSGT_AO,MSGL_V,"alsa-pause: pause supported by hardware\n"); } else { + if (snd_pcm_delay(alsa_handler, &prepause_frames) < 0 + || prepause_frames < 0) + prepause_frames = 0; + if ((err = snd_pcm_drop(alsa_handler)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmDropError, snd_strerror(err)); @@ -782,6 +789,11 @@ static void audio_resume(void) mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); return; } + if (prepause_frames) { + void *silence = calloc(prepause_frames, bytes_per_sample); + play(silence, prepause_frames * bytes_per_sample, 0); + free(silence); + } } } @@ -790,6 +802,7 @@ static void reset(void) { int err; + prepause_frames = 0; if ((err = snd_pcm_drop(alsa_handler)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_PcmPrepareError, snd_strerror(err)); @@ -865,10 +878,10 @@ static int get_space(void) return 0; } - ret = snd_pcm_status_get_avail(status) * bytes_per_sample; - if (ret > ao_data.buffersize) // Buffer underrun? - ret = ao_data.buffersize; - return ret; + unsigned space = snd_pcm_status_get_avail(status) * bytes_per_sample; + if (space > ao_data.buffersize) // Buffer underrun? + space = ao_data.buffersize; + return space; } /* delay in seconds between first and last sample in buffer */ |