我试图使用 ALSA 从 USB 音频设备获取输入并将其作为一系列signed short
值写入磁盘。我最终得到的是似乎是有效数据的块,其中散布着大块零。我猜我的缓冲区设置不正确,并且没有正确使用内存映射。
我正在尝试什么:
- 采样率:8K(这是设备强制的)
- 缓冲区大小:2048
- 期数:512
- 一个频道
该设备似乎已正确打开并接受各种参数。经过一些设置后,循环运行为:
snd_pcm_avail_update
snd_pcm_mmap_begin
memcpy data from mmap buffer to array of short
snd_pcm_mmap_commit
memcpy 是指向 short 数组的指针,并按每次传递返回的帧数递增。
在此记录几秒钟后,我将其关闭并将后续缓冲区作为每行上的单个短值写入磁盘。我期待的是一两秒在 1200 到 2300 赫兹之间变化的 PCM 数据。我得到的是一些有很多零的数据。
我想知道的是:我的缓冲区和周期值是否合理?有没有人成功使用 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 并写入磁盘。每行一个值。