嵌入式音频框架alsa学习之pcm状态

cpp 复制代码
/** PCM state */
typedef enum _snd_pcm_state {
	/** Open */
	SND_PCM_STATE_OPEN = 0,
	/** Setup installed */ 
	SND_PCM_STATE_SETUP,
	/** Ready to start */
	SND_PCM_STATE_PREPARED,
	/** Running */
	SND_PCM_STATE_RUNNING,
	/** Stopped: underrun (playback) or overrun (capture) detected */
	SND_PCM_STATE_XRUN,
	/** Draining: running (playback) or stopped (capture) */
	SND_PCM_STATE_DRAINING,
	/** Paused */
	SND_PCM_STATE_PAUSED,
	/** Hardware is suspended */
	SND_PCM_STATE_SUSPENDED,
	/** Hardware is disconnected */
	SND_PCM_STATE_DISCONNECTED,
	SND_PCM_STATE_LAST = SND_PCM_STATE_DISCONNECTED,
	/** Private - used internally in the library - do not use*/
	SND_PCM_STATE_PRIVATE1 = 1024
} snd_pcm_state_t;

1. SND_PCM_STATE_OPEN

  • 含义:PCM 设备已打开,但尚未配置任何硬件参数(如采样率、格式等)。
  • 触发场景 :调用 snd_pcm_open() 打开设备后的初始状态。

2. SND_PCM_STATE_SETUP

  • 含义 :硬件参数已安装(通过 snd_pcm_hw_params() 设置),但尚未准备好传输数据。
  • 触发场景 :调用 snd_pcm_hw_params() 成功配置参数后进入此状态。

3. SND_PCM_STATE_PREPARED

  • 含义:设备已准备好开始传输数据(如播放或录制),但尚未开始运行。
  • 触发场景 :调用 snd_pcm_prepare() 后进入此状态,此时可以安全地启动数据传输。

4. SND_PCM_STATE_RUNNING

  • 含义:设备正在活跃地处理数据(例如正在播放音频或录制输入)。
  • 触发场景 :调用 snd_pcm_start() 后,设备开始运行。

5. SND_PCM_STATE_XRUN

  • 含义 :发生了 underrun(播放时缓冲区数据不足)overrun(录制时缓冲区已满),导致设备停止。
  • 触发场景
    • 播放场景:应用程序未及时填充数据,导致缓冲区耗尽。
    • 录制场景:应用程序未及时读取数据,导致缓冲区溢出。
  • 处理方式 :需调用 snd_pcm_prepare()snd_pcm_recover() 恢复设备。

6. SND_PCM_STATE_DRAINING

  • 含义:设备正在排空缓冲区中剩余的数据(仅适用于播放模式)。
  • 触发场景 :调用 snd_pcm_drain() 后,设备停止新数据写入,但会继续播放缓冲区中的剩余数据。

7. SND_PCM_STATE_PAUSED

  • 含义:设备被显式暂停(例如用户手动暂停播放)。
  • 触发场景 :调用 snd_pcm_pause() 并设置暂停标志为 1

8. SND_PCM_STATE_SUSPENDED

  • 含义:硬件因系统事件(如进入省电模式)被挂起。
  • 触发场景:系统电源管理事件(如休眠)导致设备暂停。

9. SND_PCM_STATE_DISCONNECTED

  • 含义:物理设备已断开连接(例如 USB 音频设备被拔出)。
  • 触发场景:硬件被物理移除或断开。

10. SND_PCM_STATE_PRIVATE1

  • 含义:ALSA 库内部使用的私有状态,开发者无需关注。
  • 用途:用于 ALSA 内部实现,用户代码中不应依赖此状态。

状态转换示意图

复制代码
OPEN → SETUP → PREPARED → RUNNING → (XRUN/DRAINING/PAUSED/SUSPENDED) → ... → DISCONNECTED

常见问题

Q1: 如何检测并处理 XRUN 状态?
  • 调用 snd_pcm_state() 检查状态,若为 XRUN,需恢复设备:

    复制代码
    if (snd_pcm_state(pcm_handle) == SND_PCM_STATE_XRUN) {
        snd_pcm_prepare(pcm_handle);  // 或 snd_pcm_recover()
    }
Q2: DRAININGPAUSED 的区别?
  • DRAINING:设备正在播放剩余数据(仅播放模式)。
  • PAUSED:设备完全停止,不会继续处理数据,需显式恢复。
Q3: 如何强制停止设备?
  • 调用 snd_pcm_drop() 立即停止设备并丢弃缓冲区数据,状态回到 SETUP
相关推荐
lingggggaaaa15 小时前
小迪安全v2023学习笔记(七十七讲)—— 业务设计篇&隐私合规检测&重定向漏洞&资源拒绝服务
笔记·学习·安全·web安全·网络安全
呵呵哒( ̄▽ ̄)"15 小时前
专项智能练习(音频基础)
音视频
百度森森15 小时前
【nuscenes数据集有关】
c++·数码相机·学习·ubuntu
OEC小胖胖17 小时前
React学习之路永无止境:下一步,去向何方?
前端·javascript·学习·react.js·前端框架·react·web
我命由我1234517 小时前
Photoshop - Photoshop 触摸功能
运维·笔记·学习·ui·课程设计·设计·美工
蓑衣客VS索尼克19 小时前
第三章:生活重构:当程序员不再只是“码农“
学习·程序人生·重构·生活
耳总是一颗苹果21 小时前
数据结构---选择排序
c语言·数据结构·学习·算法·排序算法
ai产品老杨21 小时前
以技术共享点燃全球能源变革新引擎的智慧能源开源了
javascript·人工智能·开源·音视频·能源
ホロHoro1 天前
学习笔记:MYSQL(3)(常用函数和约束)
笔记·学习·mysql
TSINGSEE1 天前
数据库选择有讲究?SQLite、PostgreSQL还是MySQL?
mysql·音视频·实时音视频·数据库架构·视频编解码