Я в настоящее время работаю над проектом, который требует, чтобы я сделал некоторую выборку с Alsa. Я пытаюсь настроить правильно все, но я застреваю о том, как правильно измерить мое чтение.
Существует два примитива, которые, кажется, интересны для моей задачи:
snd_pcm_hw_params_get_period_time
snd_pcm_hw_params_get_buffer_size
Название первого предполагает, что вывод будет продолжительностью периода выборки, однако это странно: если я устанавливаю частоту дискретизации на f = 44100Hz
период выборки (в наносекундах) должен быть T0 = 1e9 / 44100 ~= 22676 ns
в то время как функция ответит T1 = 725 us = 725000 ns
.
Между тем, даже если меня попросили использовать примитивы без блокировки, я пытаюсь представить время, требуемое для блокировки 'readi', и оказывается, что образец требует T2 = 8028603 ns
в лучшее время случая и T3 = 12436217 ns
в худшем случае.
Наконец я не могу выяснить то, что является значением следующих двух:
snd_pcm_hw_params_get_buffer_time
snd_pcm_hw_params_get_period_size
Я не добираюсь, как я мог измерить буфер вовремя и период в размере, Однако первый возвращает то же значение как get_buffer_size
, в то время как последние возвраты то же значение как get_period_time
.
Какая-либо подсказка?
Это моя функция инициализации звуковой карты.
Прежде всего, я установил необходимые параметры
static
int init_soundcard (snd_pcm_t *handle, unsigned *rate, uint8_t channels,
snd_pcm_uframes_t *nframes, unsigned *period)
{
snd_pcm_hw_params_t *hwparams;
int err;
snd_pcm_hw_params_alloca(&hwparams);
err = snd_pcm_hw_params_any(handle, hwparams);
if (err < 0) return err;
err = snd_pcm_hw_params_set_rate_near(handle, hwparams, rate, NULL);
if (err < 0) return err;
err = snd_pcm_hw_params_set_access(handle, hwparams,
SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0) return err;
err = snd_pcm_hw_params_set_format(handle, hwparams,
SND_PCM_FORMAT_S16_LE);
if (err < 0) return err;
err = snd_pcm_hw_params_set_channels(handle, hwparams, channels);
if (err < 0) return err;
После того, как все параметры были установлены правильно, параметры применяются к дескриптору:
err = snd_pcm_hw_params(handle, hwparams);
if (err < 0) return err;
После того, как было применено, смелый программист может получить требуемые данные следующим образом :
get_period_size_min () дает минимальный размер в кадрах буфера, который будет содержать выборку. Буфер такого размера достаточно широк.
err = snd_pcm_hw_params_get_period_size_min(hwparams, nframes, NULL);
if (err < 0) return err;
Это довольно нелогично, но правильный период выборки не определяется соотношением 1 / частота, как можно подумать. Можно получить период выборки, используя примитив get_period_time ()!
err = snd_pcm_hw_params_get_period_time(hwparams, period, NULL);
if (err < 0) return err;
return 0;
}
ALSA имеет некоторую странную^W специфическую терминологию:
Функции *_size, похоже, возвращают размеры в кадрах.
HTH