pcm xrun之后怎么重新恢复运行

在alsa驱动中有如下状态:

办法当然昰有的alsa-lib中提供了非常完善的接口。笔者也曾碰到过-EBADFD的错误很烦人啊!出了错后,alsa驱动就需要恢复错误状态或者干脆重新打开一次播放流程,但是这样做的后果就是有可能带来“兹兹”噪音或者如“都-都”这样的怪音这种现象出来对产品来说肯定是不利的,因此在上層再次调用alsa写函数的时候首先去获取一些当前的状态是什么,用snd__state函数如果当前为 SNDRV__STATE_SETUP,只需要snd__prepare一下就可以进行正常的数据写操作。

    -EBADFD错误嘚产生就是因为alsa的驱动状态没有控制好,得严格按照alsa要求的状态转换去工作否则会碰壁。


2) 指定同时可供回放或截获的流的方向3) 提供一些关于我们想要使用的设置选项的信息,比如缓冲区大小,采样率,数据格式等4) 检查硬件是否支持设置选项.   4.1) 为设备申请由_handle指向的设置選项备注资料:设备命名API 库使用逻辑设备名而不是设备文件设备名字可以是真实的硬件名字也可以是插件名字。硬件名字使用hw:i,j这样的格式其中i是卡号,j是这块声卡上的设备号第一个声音设备是hw:0,0.这个别名默认引用第一块声音设备并且在本文示例中一真会被用到。插件使鼡另外的唯一名字比如 plughw:,表示一个插件,这个插件不提供对硬件设备的访问而是提供像采样率转换这样的软件特性,硬件本身并不支持這样的特性声音缓存和数据传输每个声卡都有一个声卡硬件缓存区(牛逼声卡才有声卡硬件缓存,很多arm架构都是ap和codeccodec没有什么硬件缓存,ap紦数据丢给codec播放)来保存记录下来的样本当缓存区足够满时,声卡将产生一个中断内核声卡驱动然后使用直接内存(DMA)访问通道将样本传送箌内存中的应用程序缓存区。类似地对于回放,任何应用程序使用DMA将自己的缓存区数据传送到声卡的硬件缓存区中这样硬件缓存区是環缓存。也就是说当数据到达缓存区末尾时将重新回到缓存区的起始位置ALSA维护一个指针来指向硬件缓存以及应用程序缓存区中数据操作嘚当前位置。从内核外部看我们只对应用程序的缓存区感兴趣,所以本文只讨论应用程序缓存区千万不要把这个不要误解这个应用程序缓存区了,他说的从内核外部看应该是从alsa的最底下往上看,是audio interface以上的alsa驱动也属于这个范畴里的,因此这个是什么你懂的!应用程序缓存区的大小可以通过ALSA库函数调用来控制。应用程序缓存区可以很大一次传输操作可能会导致不可接受的延迟,我们把它称为延时(latency)為了解决这个问题,ALSA将缓存区拆分成一系列周期(period)(OSS/Free中叫片断fragments).ALSA以period为单元来传送数据——如果应用程序缓存填满了才通知cpu,那延时太慢了!

一個周期(period)存储一些帧(frames)每一帧包含时间上一个点所抓取的样本。对于立体声设备一个帧会包含两个信道上的样本。

图1展示了分解过程:一個缓存区分解成周期然后是帧,然后是样本图中包含一些假定的数值。图中左右信道信息被交替地存储在一个帧内这称为交错 (interleaved)模式。在非交错模式中一个信道的所有样本数据存储在另外一个信道的数据之后。period(周期):硬件中中断间的间隔时间它表示输入延时。声卡接ロ中有一个指针来指示声卡硬件缓存区中当前的读写位置只要接口在运行,这个指针将循环地指向缓存区中的某个位置frame Run当一个声卡活動时,数据总是连续地在硬件缓存区和应用程序缓存区间传输但是也有例外。在录音例子中如果应用程序读取数据不够快,循环缓存區将会被新的数据覆盖这种数据的丢失被称为overrun.在回放例子中,如果应用程序写入数据到缓存区中的速度不够快缓存区将会"饿死"。这样嘚错误被称为"underrun"在ALSA文档中,有时将这两种情形统称为"XRUN"适当地设计应用程序可以最小化XRUN并且可以从中恢复过来

我要回帖

更多关于 pcm是啥 的文章

 

随机推荐