linux – 从ALSA录制 – 了解内存映射
发布时间:2020-12-13 18:50:47 所属栏目:Linux 来源:网络整理
导读:我试图使用ALSA从USB音频设备获取输入,并将其作为一系列签名的短值写入磁盘.我最终得到的是看似有效数据的块,其中散布着大块的零.我猜我的缓冲区设置不正确,并没有正确使用内存映射. 我在尝试什么: sample rate: 8K (this is forced by the device) buffer
我试图使用ALSA从USB音频设备获取输入,并将其作为一系列签名的短值写入磁盘.我最终得到的是看似有效数据的块,其中散布着大块的零.我猜我的缓冲区设置不正确,并没有正确使用内存映射.
我在尝试什么:
该设备似乎正确打开并接受各种参数.经过一些设置后,循环运行如下: 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 Hz之间变化的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; } (为清楚起见,删除了错误检查 解决方法
在ARM上有一个带有USB音频驱动程序的
known bug,其中内核和相同缓冲区的应用程序映射可能不是缓存一致的.
仅当代码可以直接处理样本而不将其复制到另一个缓冲区时,使用ALSA内存映射函数才有意义. 捕获时,缓冲区大小对延迟没有影响,因此您应该尽可能大,以避免可能的溢出. 较小的周期大小可以降低延迟,但是您的程序不会做任何与实时相关的事情,因此您可以使用更大的周期大小来节省一点功率. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |