Audio 中的 drain 和 flash

drain

当上层应用(如播放器)检测到音频文件已到达末尾(EOF)时,它会向 AudioTrack 发出停止指令。Framework 会调用 HAL 的 out_drain 接口,要求硬件把缓冲区里剩余的字节"消化"完。

drain 的两种模式

DRAIN_ALL (全部排空):等待当前缓冲区中的**所有**音频数据播放完毕后再返回。这是最常用的模式,用于正常的歌曲切换或结束。

DRAIN_EARLY_NOTIFY (提前通知):在数据即将播放完(例如还剩最后一点)时就发出回调,以便上层应用能提前准备下一首歌的数据,实现"无缝切换"。

为什么需要 drain?

如果不实现 drain 直接调用 stop 或 flush,会发生什么?

音频截断:你会听到歌曲最后几百毫秒或 1-2 秒的内容突然消失(因为这些数据还在硬件 Ring Buffer 里没播出来)。

爆音/咔哒声:直接切断模拟信号可能导致硬件输出电平瞬间归零,产生杂音。

flash

flush(冲洗/清空)操作的主要目的是立即停止播放并丢弃缓冲区中所有待播放的数据。这通常发生在用户切换歌曲、点击停止或在视频播放中执行快进/快退(Seek)操作时。

与 drain(排空)不同,flush 是"暴力"的------它不要求把剩下的音频播完,而是要求硬件立刻"清零"。

|------|--------------------|--------------------|
| 特性 | drain | flush |
| 主要目的 | 优雅地播完最后一点声音 | 立即丢弃所有声音,准备新操作 |
| 触发场景 | 歌曲自然播放结束 | 用户切歌、快进、停止 |
| 数据处理 | 等待硬件 Buffer 播放结束 | 硬件 Buffer 里的数据直接扔掉 |
| 耗时 | 较长(取决于 Buffer 大小) | 极短(几乎瞬间完成) |
| 回调 | 完成后发送 onDrainReady | 完成后不需要特殊 Ready 回调 |

为什么 Non-blocking 模式下 flush 很重要?

在非阻塞模式下,write 调用可能会因为 Buffer 满而返回 0。如果不执行 flush 就进行 Seek 操作,那么当 write 恢复时,它会继续写入旧位置之后的残余数据,导致用户在快进后听到一小段快进前的"声音残影"。执行 flush 可以确保硬件和 HAL 软件层面的"水管"被完全排空。

相关推荐
开发笔记-阿牛10 天前
蓝牙音乐灯拆解,又一次拆到蓝牙音乐灯芯片CK6865L
人工智能·单片机·嵌入式硬件·音视频·音频
坤坤藤椒牛肉面16 天前
RK3576 音频修改:解决HDMI抢占媒体声音
音频
开发笔记-阿牛16 天前
做工业报警器语音提示,CK6159A 为什么更合适?
人工智能·stm32·单片机·嵌入式硬件·音频
熊猫钓鱼>_>16 天前
声临其境:HarmonyOS 空间音频全链路开发实战
音频·harmonyos·arkts·鸿蒙·arkui·空间·hap
zxy284722530117 天前
C# 音频倍速播放
c#·音频·naudio·soundtouch·倍速
林澈在路上17 天前
能做DJ的AI写歌软件推荐:MELO音乐对比Suno v6
大数据·人工智能·github·音视频·音频
提升汽车音响好物20 天前
斯巴鲁森林人音响升级记录:江门汇声的前后声场与低频搭配
汽车·音频
沐禾安信25 天前
抖音的bgm 想保存? 3个音频提取工具,一键分离
音视频·音频·音频转换·视频转换
A13345551 个月前
Apple TV 软件推荐:全平台怎么选
android·音频
林澈在路上1 个月前
AI翻唱软件哪个好 2026国产AI写歌工具对比推荐
大数据·人工智能·深度学习·github·aigc·音视频·音频