Linux   发布时间:2022-04-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了linux – 从ALSA录制 – 了解内存映射大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

我试图使用ALSA从USB音频设备获取输入,并将其作为一系列签名的短值写入磁盘.我最终得到的是看似有效数据的块,其中散布着大块的零.我猜我的缓冲区设置不正确,并没有正确使用内存映射. 我在尝试什么: sample rate: 8K (this is forced by the devicE) buffer size: 2048 period size: 512 one chAnnel 该设备似乎正
我试图使用ALSA从USB音频设备获取输入,并将其作为一系列签名的短值写入磁盘.我最终得到的是看似有效数据的块,其中散布着大块的零.我猜我的缓冲区设置不正确,并没有正确使用内存映射.

我在尝试什么:

该设备似乎正确打开并接受各种参数.经过一些设置后,循环运行如下:

snd_pcm_avail_update   
snd_pcm_mmap_begin   
   memcpy data from mmap buffer to array of short   
snd_pcm_mmap_commit
@H_389_16@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;
}

(为清楚起见,删除错误检查
完成所有操作后,我遍历pCID并写入磁盘.每行一个值.

解决方法

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

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

捕获时,缓冲区大小对延迟没有影响,因此您应该尽可能大,以避免可能的溢出.

较小的周期大小可以降低延迟,但是您的程序不会做任何与实时相关的事情,因此您可以使用更大的周期大小来节省一点功率.

大佬总结

以上是大佬教程为你收集整理的linux – 从ALSA录制 – 了解内存映射全部内容,希望文章能够帮你解决linux – 从ALSA录制 – 了解内存映射所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。