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

简介: 在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要求的状态转换去工作,否则会碰壁。

 

目录
相关文章
|
消息中间件 Cloud Native Java
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
|
存储 边缘计算 数据管理
Docker 存储驱动解析:选择最适合你的存储方案,优化容器化部署性能和数据管理
Docker 存储驱动解析:选择最适合你的存储方案,优化容器化部署性能和数据管理
511 0
|
9月前
|
机器学习/深度学习 传感器 人工智能
穹彻智能-上交大最新Nature子刊速递:解析深度学习驱动的视触觉动态重建方案
上海交大研究团队在Nature子刊发表论文,提出基于深度学习的视触觉动态重建方案,结合高密度可拉伸触觉手套与视觉-触觉联合学习框架,实现手部与物体间力量型交互的实时捕捉和重建。该方案包含1152个触觉感知单元,通过应变干扰抑制方法提高测量准确性,平均重建误差仅1.8厘米。实验结果显示,其在物体重建的准确性和鲁棒性方面优于现有方法,为虚拟现实、远程医疗等领域带来新突破。
202 32
|
8月前
|
数据采集 监控 搜索推荐
深度解析淘宝商品详情API接口:解锁电商数据新维度,驱动业务增长
淘宝商品详情API接口,是淘宝开放平台为第三方开发者提供的一套用于获取淘宝、天猫等电商平台商品详细信息的应用程序接口。该接口涵盖了商品的基本信息(如标题、价格、图片)、属性参数、库存状况、销量评价、物流信息等,是电商企业实现商品管理、市场分析、营销策略制定等功能的得力助手。
|
12月前
|
Java 关系型数据库 MySQL
【编程基础知识】Eclipse连接MySQL 8.0时的JDK版本和驱动问题全解析
本文详细解析了在使用Eclipse连接MySQL 8.0时常见的JDK版本不兼容、驱动类错误和时区设置问题,并提供了清晰的解决方案。通过正确配置JDK版本、选择合适的驱动类和设置时区,确保Java应用能够顺利连接MySQL 8.0。
969 1
|
消息中间件 Java RocketMQ
微服务架构师的福音:深度解析Spring Cloud RocketMQ,打造高可靠消息驱动系统的不二之选!
【8月更文挑战第29天】Spring Cloud RocketMQ结合了Spring Cloud生态与RocketMQ消息中间件的优势,简化了RocketMQ在微服务中的集成,使开发者能更专注业务逻辑。通过配置依赖和连接信息,可轻松搭建消息生产和消费流程,支持消息过滤、转换及分布式事务等功能,确保微服务间解耦的同时,提升了系统的稳定性和效率。掌握其应用,有助于构建复杂分布式系统。
283 0
|
自然语言处理 Java 测试技术
Java中的行为驱动开发(BDD)方法论解析
Java中的行为驱动开发(BDD)方法论解析
|
人工智能 安全 大数据
开源软件全景解析:驱动技术创新与行业革新的力量
开源软件全景解析:驱动技术创新与行业革新的力量
828 0
开源软件全景解析:驱动技术创新与行业革新的力量
|
存储 机器学习/深度学习 数据挖掘
数据仓库与数据湖:解析数据驱动的未来
在数字化时代,数据成为企业决策的核心资源。本文将深入探讨数据仓库和数据湖的概念、特点以及应用场景,分析其在实现数据驱动决策过程中的重要性和优势,并展望数据驱动的未来发展趋势。
297 5
|
存储 Linux Go
Docker 存储驱动解析:选择最适合你的存储方案
Docker 存储驱动解析:选择最适合你的存储方案
320 0

热门文章

最新文章

推荐镜像

更多
  • DNS