--- libao2/ao_alsa.c 2009-09-25 00:40:38.000000000 +0200 +++ libao2/ao_alsa.c 2009-09-25 00:39:50.000000000 +0200 @@ -72,8 +72,11 @@ static snd_pcm_hw_params_t *alsa_hwparams; static snd_pcm_sw_params_t *alsa_swparams; -static unsigned int alsa_buffer_time = 500000; /* 0.5 s */ -static unsigned int alsa_fragcount = 16; +/* 16 sets buffersize to 16 * chunksize is as default 1024 + * which seems to be good avarge for most situations + * so buffersize is 16384 frames by default */ +static int alsa_fragcount = 16; +static snd_pcm_uframes_t chunk_size = 1024; static size_t bytes_per_sample; @@ -84,6 +87,9 @@ #define ALSA_DEVICE_SIZE 256 +#undef BUFFERTIME +#define SET_CHUNKSIZE + static void alsa_error_handler(const char *file, int line, const char *function, int err, const char *format, ...) { @@ -323,7 +329,6 @@ int err; int block; strarg_t device; - snd_pcm_uframes_t chunk_size; snd_pcm_uframes_t bufsize; snd_pcm_uframes_t boundary; opt_t subopts[] = { @@ -479,6 +484,41 @@ open_mode = 0; } + //sets buff/chunksize if its set manually + if (ao_data.buffersize) { + switch (ao_data.buffersize) + { + case 1: + alsa_fragcount = 16; + chunk_size = 512; + mp_msg(MSGT_AO,MSGL_V,"alsa-init: buffersize set manually to 8192\n"); + mp_msg(MSGT_AO,MSGL_V,"alsa-init: chunksize set manually to 512\n"); + break; + case 2: + alsa_fragcount = 8; + chunk_size = 1024; + mp_msg(MSGT_AO,MSGL_V,"alsa-init: buffersize set manually to 8192\n"); + mp_msg(MSGT_AO,MSGL_V,"alsa-init: chunksize set manually to 1024\n"); + break; + case 3: + alsa_fragcount = 32; + chunk_size = 512; + mp_msg(MSGT_AO,MSGL_V,"alsa-init: buffersize set manually to 16384\n"); + mp_msg(MSGT_AO,MSGL_V,"alsa-init: chunksize set manually to 512\n"); + break; + case 4: + alsa_fragcount = 16; + chunk_size = 1024; + mp_msg(MSGT_AO,MSGL_V,"alsa-init: buffersize set manually to 16384\n"); + mp_msg(MSGT_AO,MSGL_V,"alsa-init: chunksize set manually to 1024\n"); + break; + default: + alsa_fragcount = 16; + chunk_size = 1024; + break; + } + } + if (!alsa_handler) { //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC if ((err = try_open_device(alsa_device, open_mode, format == AF_FORMAT_AC3)) < 0) @@ -571,20 +611,57 @@ bytes_per_sample *= ao_data.channels; ao_data.bps = ao_data.samplerate * bytes_per_sample; +#ifdef BUFFERTIME + { + int alsa_buffer_time = 500000; /* original 60 */ + int alsa_period_time; + alsa_period_time = alsa_buffer_time/4; if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_handler, alsa_hwparams, &alsa_buffer_time, NULL)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetBufferTimeNear, snd_strerror(err)); return 0; + } else + alsa_buffer_time = err; + + if ((err = snd_pcm_hw_params_set_period_time_near(alsa_handler, alsa_hwparams, + &alsa_period_time, NULL)) < 0) + /* original: alsa_buffer_time/ao_data.bps */ + { + mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetPeriodTime, + snd_strerror(err)); + return 0; } + mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_ALSA_BufferTimePeriodTime, + alsa_buffer_time, err); + } +#endif//end SET_BUFFERTIME +#ifdef SET_CHUNKSIZE + { + //set chunksize + if ((err = snd_pcm_hw_params_set_period_size_near(alsa_handler, alsa_hwparams, + &chunk_size, NULL)) < 0) + { + /*mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetPeriodSize, + chunk_size, snd_strerror(err));*/ + return 0; + } + else { + mp_msg(MSGT_AO,MSGL_V,"alsa-init: chunksize set to %li\n", chunk_size); + } if ((err = snd_pcm_hw_params_set_periods_near(alsa_handler, alsa_hwparams, &alsa_fragcount, NULL)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToSetPeriods, snd_strerror(err)); return 0; } + else { + mp_msg(MSGT_AO,MSGL_V,"alsa-init: fragcount=%i\n", alsa_fragcount); + } + } +#endif//end SET_CHUNKSIZE /* finally install hardware parameters */ if ((err = snd_pcm_hw_params(alsa_handler, alsa_hwparams)) < 0)