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 软件层面的"水管"被完全排空。

相关推荐
longforus14 天前
linux上播放音乐的终极解决方案
linux·音频·折腾
开发笔记-阿牛16 天前
CK6159A 性能测评:多外设并发交互下的运行表现与方案参考
stm32·单片机·音频
MegaSig美格信17 天前
非处方气导助听器音频测试解决方案
音视频·音频·健康医疗
qq_3665665018 天前
视频配音自动化Pipeline:TTS选型+音色克隆+批量处理(附完整代码)
自动化·新媒体运营·音视频·音频
DogDaoDao18 天前
【GitHub】VoxCPM2 实战全解析:原理、部署与效果对比
深度学习·大模型·github·音频·语音模型·tss·文本生成语音
shandianchengzi21 天前
【记录】Claude Code|Windows11给Claude Code新增任务消息提示音
windows·ai·音频·claude·claude code
X54先生(人文科技)24 天前
《终章-镜中深爱之星》上架成果简报
人工智能·音频·ai写作·开源协议
眸生1 个月前
基于NeteaseCloudMusicApi的音乐app 支持 DeepSeek 自然语言找歌、批量导入歌单、下载音乐转换成MP3,下载歌词
android·python·kotlin·android studio·音频·fastapi·android jetpack
shandianchengzi1 个月前
【记录】Claude Code|Ubuntu26给Claude Code新增任务消息提示音
运维·服务器·ubuntu·ai·大模型·音频·claude
VOOHU-沃虎1 个月前
音频变压器选型指南:阻抗匹配、隔离耐压与低失真设计的工程实践
网络·音频