我目前正在开展一个项目,要求我对Alsa进行一些采样.我正在尝试正确配置所有内容,但我仍然坚持如何正确调整我的阅读量.
我的任务似乎有两个基本原则:
snd_pcm_hw_params_get_period_time
snd_pcm_hw_params_get_buffer_size
Run Code Online (Sandbox Code Playgroud)
第一个的名称表明输出将是采样周期的时间长度,但这很奇怪:如果我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
Run Code Online (Sandbox Code Playgroud)
我不知道如何测量缓冲区的时间和周期大小,但前者返回相同的值get_buffer_size,而后者返回相同的值get_period_time.
任何提示?
ALSA有一些奇怪的特定术语:
*_size函数似乎返回帧中的大小.
HTH
这是我的声卡初始化功能。
首先,我设置所需的参数
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;
Run Code Online (Sandbox Code Playgroud)
正确设置每个参数后,这些参数将应用于手柄:
err = snd_pcm_hw_params(handle, hwparams);
if (err < 0) return err;
Run Code Online (Sandbox Code Playgroud)
后已应用于它的勇敢的程序员可以如下获得所需的数据:
get_period_size_min()给出包含采样的缓冲区的最小大小(以帧为单位)。具有此大小的缓冲区足够宽。
err = snd_pcm_hw_params_get_period_size_min(hwparams, nframes, NULL);
if (err < 0) return err;
Run Code Online (Sandbox Code Playgroud)
这是很违反直觉的,但是正确的采样周期并不是人们可能认为的1 /速率。可以使用get_period_time()原语来获取采样周期!
err = snd_pcm_hw_params_get_period_time(hwparams, period, NULL);
if (err < 0) return err;
return 0;
}
Run Code Online (Sandbox Code Playgroud)