2010-07-27 519 views
3

我目前正在开发一个项目,要求我对Alsa进行一些抽样。我正在尝试正确配置所有内容,但我一直在坚持如何正确调整阅读大小。正确调整Alsa缓冲区的大小,奇怪的API

有两个原语,似乎是对我的任务有趣:

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,并且在最佳情况下需要T2 = 8028603 nsT3 = 12436217 ns在最坏的情况下。

最后,我无法找出什么是以下两个含义:

snd_pcm_hw_params_get_buffer_time 
snd_pcm_hw_params_get_period_size 

我不明白我怎么能衡量时间的缓冲和大小的时期,但前者的回报与get_buffer_size相同的值,而后者返回与get_period_time相同的值。

任何提示?

回答

3

这是我的声卡初始化函数。

首先,我设置所需要的参数

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/rate。我们可以使用get_period_time()原语来获取采样周期!

err = snd_pcm_hw_params_get_period_time(hwparams, period, NULL); 
    if (err < 0) return err; 

    return 0; 
} 
4

ALSA有一些怪^ Wspecific术语:

  • 帧:样本x信道(即:立体声帧由两个样品中,单声道的帧是由1个采样的,...)
  • 期:在设备确认传输到适配器之后(通常通过中断),传输的样本数量。

* _size函数似乎以帧的形式返回大小。

HTH

+0

他们回到什么是返回类型,这是'snd_uframe_t'为* _size和'unsigned'为* _time明确获得“真正的”采样率,但我没有得到什么“缓冲时间”和“周期大小”的含义。 – Dacav 2010-07-27 15:34:33

+0

期大小:在帧 VAL返回周期近似尺寸 缓冲时间(当然这取决于当前配置):在 VAL返回的缓冲区时我们 – ninjalj 2010-07-27 15:40:35

+0

是,该文件具有的功能名称的相同信息内容,但什么是一个缓冲时间?缓冲区有一定的*大小*,而不是*时间*。 – Dacav 2010-07-27 15:43:04

1

从我理解的使用和阅读ALSA库中,这段时间与正在进行的硬件中断有关。如果使用

snd_pcm_hw_params_get_period_size() 

它会返回通过中断传递给hw的帧数。同样,如果你使用

snd_pcm_hw_params_get_period_time() 

你会得到我们的时间(10^-6),这些帧将被插入。所以,如果能

snd_pcm_hw_params_get_period_size()*1000000/snd_pcm_hw_params_get_period_time()