嵌入式音频框架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
相关推荐
梦幻精灵_cq几秒前
子函数嵌套的意义——以“颜色排序”为例(Python)
学习
jackson凌23 分钟前
【Java学习笔记】运算符
java·笔记·学习
小白教程1 小时前
如何处理Python爬取视频时的反爬机制?
开发语言·python·音视频·python爬虫
Luke Ewin1 小时前
一个基于OpenAI Whisper开发的音视频字幕文件生成工具
人工智能·whisper·音视频·语音识别·asr·语音转写·视频字幕生成
Always_away1 小时前
数据库系统概论|第三章:关系数据库标准语言SQL—课程笔记4
数据库·笔记·sql·学习
在下_诸葛2 小时前
狂神SQL学习笔记六:列的数据类型讲解
笔记·sql·学习
Ⅰㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ2 小时前
03 UV
笔记·学习·3dmax
Nuyoah.3 小时前
《vue3学习手记3》
前端·javascript·vue.js·学习·前端框架
WDeLiang4 小时前
音频基础概念
音视频
楼田莉子4 小时前
C++学习记录:
开发语言·c++·学习