diff --git a/libao2/ao_null.c b/libao2/ao_null.c index e894c47bfb..3f39a37f0c 100644 --- a/libao2/ao_null.c +++ b/libao2/ao_null.c @@ -1,6 +1,7 @@ #include #include +#include "afmt.h" #include "audio_out.h" #include "audio_out_internal.h" @@ -8,12 +9,35 @@ static ao_info_t info = { "Null audio output", "null", - "A'rpi", + "Tobias Diedrich", "" }; LIBAO_EXTERN(null) +struct timeval last_tv; +int buffer; + +static int drain(){ + + struct timeval now_tv; + int temp, temp2; + + gettimeofday(&now_tv, 0); + temp = now_tv.tv_sec - last_tv.tv_sec; + temp *= ao_data.bps; + + temp2 = now_tv.tv_usec - last_tv.tv_usec; + temp2 /= 1000; + temp2 *= ao_data.bps; + temp2 /= 1000; + temp += temp2; + + buffer-=temp; + if (buffer<0) buffer=0; + + last_tv = now_tv; +} // to set/get/query special features/parameters static int control(int cmd,int arg){ @@ -24,9 +48,18 @@ static int control(int cmd,int arg){ // return: 1=success 0=fail static int init(int rate,int channels,int format,int flags){ - ao_data.outburst=4096; + ao_data.buffersize= 65536; + ao_data.outburst=1024; + ao_data.channels=channels; + ao_data.samplerate=rate; + ao_data.format=format; + ao_data.bps=channels*rate; + if (format != AFMT_U8 && format != AFMT_S8) + ao_data.bps*=2; + buffer=0; + gettimeofday(&last_tv, 0); - return 0; + return 1; } // close audio device @@ -36,7 +69,7 @@ static void uninit(){ // stop playing and empty buffers (for seeking/pause) static void reset(){ - + buffer=0; } // stop playing, keep buffers (for pause) @@ -54,7 +87,8 @@ static void audio_resume() // return: how many bytes can be played without blocking static int get_space(){ - return ao_data.outburst; + drain(); + return ao_data.buffersize - buffer; } // plays 'len' bytes of 'data' @@ -62,13 +96,18 @@ static int get_space(){ // return: number of bytes played static int play(void* data,int len,int flags){ - return len; + int maxbursts = (ao_data.buffersize - buffer) / ao_data.outburst; + int playbursts = len / ao_data.outburst; + int bursts = playbursts > maxbursts ? maxbursts : playbursts; + buffer += bursts * ao_data.outburst; + return bursts * ao_data.outburst; } // return: delay in seconds between first and last sample in buffer static float get_delay(){ - return 0.0; + drain(); + return (float) buffer / (float) ao_data.bps; }