gpt4 book ai didi

linux - 来自 ALSA 的记录——理解内存映射

转载 作者:IT王子 更新时间:2023-10-29 00:31:40 25 4
gpt4 key购买 nike

我正在尝试使用 ALSA 从 USB 音频设备获取输入并将其作为一系列 signed short 值写入磁盘。我最终得到的是似乎是有效数据的 block ,其中散布着大块零。我猜我的缓冲区设置不正确并且没有正确使用内存映射。

我正在尝试:

  • sample rate: 8K (this is forced by the device)
  • buffer size: 2048
  • period size: 512
  • one channel

设备似乎已正确打开并接受各种参数。经过一些设置后,循环运行为:

snd_pcm_avail_update   
snd_pcm_mmap_begin
memcpy data from mmap buffer to array of short
snd_pcm_mmap_commit

memcpy 是指向 short 数组的指针,并按每次传递返回的帧数递增。

记录几秒钟后,我将其关闭并将后续缓冲区作为每行的单个短值写入磁盘。我期待的是一秒或两秒的 PCM 数据在 1200 和 2300 Hz 之间变化。我得到的是一些有很多零的数据。

我想知道的是:我对缓冲区和周期的值(value)观是否合理?有没有人成功使用过 ALSA 的内存映射输出?

编辑:一些代码

const snd_pcm_channel_area_t *areas;  
snd_pcm_uframes_t offset, frames, size;
short* pCID = (short*)malloc( 50000 * sizeof( short ));
short* ppCID = pCID;
while( size > 0 )
{
frames = size;
snd_pcm_mmap_begin (device, &areas, &offset, &frames);
short* pd = (short*)areas[0].addr;
memcpy( ppCID, (pd + (offset*sizeof(short))), frames * sizeof( short ));
ppCID += frames;
snd_pcm_mmap_commit(device, offset, frames);

size -= frames;
}

(为清楚起见删除了错误检查)
说完一切后,我循环遍历 pCID 并写入磁盘。每行一个值。

最佳答案

有一个known bug使用 ARM 上的 USB 音频驱动程序,其中内核和应用程序对同一缓冲区的映射可能不缓存一致。

仅当代码可以直接处理样本而不将它们复制到另一个缓冲区时,使用 ALSA 内存映射函数才有意义。如果您确实复制了它们,那么您所做的snd_pcm_readi 已经做的完全相同。换句话说,就是不要使用内存映射。

捕获时,缓冲区大小对延迟没有影响,因此您应将其设置得尽可能大以避免可能的超限。

较小的周期大小可以降低延迟,但您的程序不会执行任何与实时相关的操作,因此您可以使用较大的周期大小来节省一点电量。

关于linux - 来自 ALSA 的记录——理解内存映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14762103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com