#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #define BUFFER_TIME_MIN (100000) #define BUFFER_TIME_MAX (1000000) #define BUFFER_TIME_STEP (5000) int try_alsa_setup(snd_pcm_t *pcm, unsigned int rate, unsigned int *buffer_time, unsigned int *periods) { int r; snd_pcm_hw_params_t *hwparams; snd_pcm_hw_params_alloca (&hwparams); r = snd_pcm_hw_params_any(pcm, hwparams); if (r < 0) return r; r = snd_pcm_hw_params_set_rate_resample(pcm, hwparams, 0); if (r < 0) return r; r = snd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); if (r < 0) return r; r = snd_pcm_hw_params_set_format(pcm, hwparams,SND_PCM_FORMAT_S16_LE); if (r < 0) return r; r = snd_pcm_hw_params_set_rate_near(pcm, hwparams, &rate, NULL); if (r < 0) return r; r = snd_pcm_hw_params_set_channels(pcm, hwparams, 2); if (r < 0) return r; r = snd_pcm_hw_params_set_buffer_time_near(pcm, hwparams, buffer_time, NULL); if (r < 0) return r; r = snd_pcm_hw_params_set_periods_near(pcm, hwparams, periods, NULL); if (r < 0) return r; r = snd_pcm_hw_params(pcm, hwparams); if (r < 0) return r; r = snd_pcm_hw_params_current(pcm, hwparams); if (r < 0) return r; return 0; } int main(int argc, char *argv[]) { const char *dev; snd_pcm_t *pcm; unsigned int rates[] = {44100, 88200, 48000, 96000, 0 }; unsigned int periods = 10; unsigned int i; int r; dev = argc > 1 ? argv[1] : "hw:0,0"; printf("Opening %s\n\n", dev); for (i = 0; rates[i]; i++) { unsigned int time = BUFFER_TIME_MIN; do { unsigned int buffer_time = time; r = snd_pcm_open(&pcm, dev, SND_PCM_STREAM_PLAYBACK, 0); if (r < 0) { printf("Failed to open %s\n", dev); return -1; } printf("Try of %dHz, %u us buffer: ", rates[i], buffer_time); r = try_alsa_setup(pcm, rates[i], &buffer_time, &periods); if (r < 0) printf("FAILED\n"); else printf("OK (got %u us)\n", buffer_time); r = snd_pcm_close(pcm); if (r < 0) { printf("snd_pcm_close() failed %d\n", r); return r; } time += BUFFER_TIME_STEP; } while (time <= BUFFER_TIME_MAX); } printf("Done with %s\n\n", dev); return 0; }