是ALSA hw_params缓冲区大小的物理卡内存大小?

时间:2013-11-25 21:40:56

标签: c linux audio audio-recording alsa

我正在努力加快ALSA API的速度,并对这个广泛的API提出一些问题。我使用的是“hw”界面而不是“plughw”界面。

问题#1:snd_hw_params_any()例程是否检索默认/当前参数? 一些文档/示例代码表明此例程使用某些值填充已分配的snd_pcm_hw_params_t结构。这些是卡的当前配置设置:设备?

我感到困惑的原因是,如果该例程检索hw_params值,那么我应该能够使用任何的snd_hw_params_get例程来实际获取这些值。这适用于snd_hw_params_get_channels()例程。但是对snd_pcm_hw_params_get_format()或snd_pcm_hw_params_get_buffer_size()的调用将失败。如果我首先使用set例程设置格式或缓冲区大小,我可以调用get例程来检索值而不会出错。表达这个问题的另一种方法是:当我使用这一系列的调用时,为什么snd_pcm_hw_params_get_format()和snd_pcm_hw_parmas_get_buffer_size()会失败:

snd_pcm_hw_params_alloca(); snd_pcm_hw_params_any(); snd_pcm_hw_params_get_channels(); snd_pcm_hw_params_get_format(); snd_pcm_hw_params_get_buffer_size();

问题2:如何确定声卡上物理内存的实际大小? 我注意到,无论我在调用snd_pcm_hw_params_set_buffer_size / min / max()时使用的是什么大小,然后调用snd_pcm_hw_params_get_buffer_size(),我得到相同的大小。我再次使用“hw”接口而不是“plughw”接口,所以我不能设置缓冲区大小似乎是合理的,因为它实际上是卡上的物理内存量。

由于snd_pcm_hw_params_get_buffer_size()检索帧大小,因此声卡上可用物理捕获内存的实际大小将是帧大小乘以通道数乘以样本字长度。例如:

int nNumberOfChannels = 2; snd_pcm_format_t tFormat = SND_PCM_FORMAT_S16; //每个样本2个字节 snd_pcm_uframes_t = 16384;

然后卡上的实际物理内存为:2 * 2 * 16384 =卡上可用的物理内存65536字节。

这是正确的还是我在这里感到困惑?

谢谢,

-Andres

1 个答案:

答案 0 :(得分:1)

snd_pcm_hw_params_get_buffer_size()返回的缓冲区大小不是(并且永远不会)驻留在“声卡”上的内存大小。在本地音频接口的情况下(例如,不是诸如USB或Firewire的串行总线连接设备),这是系统主存储器中的缓冲区的大小,音频样本的DMA周期性地发生在该存储器中。

对于USB和Firewire音频,这指的缓冲区完全是软件概念 - 尽管它可能是Firewire的DMAd。不要指望能够将缓冲区大小设置为低于最小等时传输单元大小。

我认为ALSA不能保证您可以实际更改这些参数 - 它取决于服务于音频接口的DMA控制器中硬件的限制 - 以及其设备驱动程序。缓冲区大小为2的幂的安排并不罕见,因为它更容易在硬件中实现。

您应该非常小心地检查调用snd_pcm_hw_* API调用的返回值,而不是假设您已获得所请求的内容。