ALSA驱动中-EBADFD错误原因解析及对策

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 在alsa驱动中有如下状态:   #define SNDRV_PCM_STATE_OPEN  ((__force snd_pcm_state_t) 0) /* stream is open */#define SNDRV_PCM_STATE_SE...

在alsa驱动中有如下状态:

 

#define SNDRV_PCM_STATE_OPEN  ((__force snd_pcm_state_t) 0) /* stream is open */
#define SNDRV_PCM_STATE_SETUP  ((__force snd_pcm_state_t) 1) /* stream has a setup */
#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2) /* stream is ready to start */
#define SNDRV_PCM_STATE_RUNNING  ((__force snd_pcm_state_t) 3) /* stream is running */
#define SNDRV_PCM_STATE_XRUN  ((__force snd_pcm_state_t) 4) /* stream reached an xrun */
#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5) /* stream is draining */
#define SNDRV_PCM_STATE_PAUSED  ((__force snd_pcm_state_t) 6) /* stream is paused */
#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7) /* hardware is suspended */
#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8) /* hardware is disconnected */
#define SNDRV_PCM_STATE_LAST  SNDRV_PCM_STATE_DISCONNECTED

 

     在ALSA最底层写函数snd_pcm_lib_write1中,首先检测当前PCM的状态,是 SNDRV_PCM_STATE_PREPARED、SNDRV_PCM_STATE_RUNNING、 SNDRV_PCM_STATE_PAUSED这三种状态下,驱动就开始transfer数据,如果为SNDRV_PCM_STATE_XRUN返回-EPIPE错误,如果为SNDRV_PCM_STATE_SUSPENDED,就返回 -ESTRPIPE;其他状态均返回-EBADFD错误。

    在打开一个PCM流时,PCM的状态为SNDRV_PCM_STATE_OPEN ,给这个流配置参数,如channel数、采样率、采样精度后,PCM的状态配置为SNDRV_PCM_STATE_SETUP,在写数据之前,需要提示驱动去各继各位,准备工作,这时候去prepare一下,就像是考试前的动员大会一样,让你热血沸腾、充满信心,prepare后PCM流的状态为SNDRV_PCM_STATE_PREPARED,开始写数据的过程中,PCM的状态会设置为 SNDRV_PCM_STATE_RUNNING,播放完数据后,通常需要去drain一下来sync,在调snd_pcm_drain过程中,PCM的状态为PCM的状态,drain完以后PCM的状态为会设置为SNDRV_PCM_STATE_SETUP,因此在再次写数据的时候,驱动就会返回-EBADFD的错误,那么如何有效避免呢?

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

    在系统进入省电模式时,驱动会执行suspend,PCM状态变为SNDRV_PCM_STATE_SUSPENDED,在唤醒系统后,笔者在adroid系统中发现,PCM的状态仍然为SNDRV_PCM_STATE_SUSPENDED状态,在这种状态下,直接进行写操作,无疑会带来-EBADFD的错误。如果在写数据的之前,检测到的pcm状态为SNDRV_PCM_STATE_SUSPENDED,就可以先snd_pcm_resume,再snd_pcm_prepare一下,alsa就可以回到正常工作状态,可以正常的写数据。

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

 

目录
相关文章
|
6月前
|
消息中间件 Cloud Native Java
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
|
存储 边缘计算 数据管理
Docker 存储驱动解析:选择最适合你的存储方案,优化容器化部署性能和数据管理
Docker 存储驱动解析:选择最适合你的存储方案,优化容器化部署性能和数据管理
349 0
|
25天前
|
Java 关系型数据库 MySQL
【编程基础知识】Eclipse连接MySQL 8.0时的JDK版本和驱动问题全解析
本文详细解析了在使用Eclipse连接MySQL 8.0时常见的JDK版本不兼容、驱动类错误和时区设置问题,并提供了清晰的解决方案。通过正确配置JDK版本、选择合适的驱动类和设置时区,确保Java应用能够顺利连接MySQL 8.0。
112 1
|
3月前
|
消息中间件 Java RocketMQ
微服务架构师的福音:深度解析Spring Cloud RocketMQ,打造高可靠消息驱动系统的不二之选!
【8月更文挑战第29天】Spring Cloud RocketMQ结合了Spring Cloud生态与RocketMQ消息中间件的优势,简化了RocketMQ在微服务中的集成,使开发者能更专注业务逻辑。通过配置依赖和连接信息,可轻松搭建消息生产和消费流程,支持消息过滤、转换及分布式事务等功能,确保微服务间解耦的同时,提升了系统的稳定性和效率。掌握其应用,有助于构建复杂分布式系统。
63 0
|
4月前
|
自然语言处理 Java 测试技术
Java中的行为驱动开发(BDD)方法论解析
Java中的行为驱动开发(BDD)方法论解析
|
6月前
|
人工智能 安全 大数据
开源软件全景解析:驱动技术创新与行业革新的力量
开源软件全景解析:驱动技术创新与行业革新的力量
521 0
开源软件全景解析:驱动技术创新与行业革新的力量
|
6月前
|
存储 机器学习/深度学习 数据挖掘
数据仓库与数据湖:解析数据驱动的未来
在数字化时代,数据成为企业决策的核心资源。本文将深入探讨数据仓库和数据湖的概念、特点以及应用场景,分析其在实现数据驱动决策过程中的重要性和优势,并展望数据驱动的未来发展趋势。
203 5
|
存储 Linux Go
Docker 存储驱动解析:选择最适合你的存储方案
Docker 存储驱动解析:选择最适合你的存储方案
208 0
|
消息中间件 架构师 搜索推荐
DDD领域驱动设计的概念解析
DDD领域驱动设计的概念解析
234 0
|
Web App开发 机器学习/深度学习 数据可视化
万字长文解析,领域驱动设计(DDD)落地设计
领域驱动设计(简称 ddd)概念来源于2004年著名建模专家Eric Evans 发表的他最具影响力的书籍:《领域驱动设计——软件核心复杂性应对之道》(Domain-Driven Design –Tackling Complexity in the Heart of Software),简称Evans DDD,领域驱动设计思想进入软件开发者的视野。在将近20年的发展中领域模型设计一直占据着非常重要的位置,但其直接面向业务场景的设计思想,更适合在具有特定业务场景的模型构建。

推荐镜像

更多
下一篇
无影云桌面