简介: CSDN博客专家、《Android系统多媒体进阶实战》作者
博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏地址:Audio工程师进阶系列【原创干货持续更新中...... 】🚀
Android多媒体专栏地址:多媒体系统工程师系列【原创干货持续更新中...... 】🚀
推荐1:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
推荐2:Android14 Binder之HIDL与AIDL通信实战课 🚀
推荐3:Android15快速自定义与集成音效实战课 🚀
推荐4:Android15音频策略实战课 🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
更多原创,欢迎关注:Android系统攻城狮

🍉🍉🍉文章目录🍉🍉🍉
-
-
- [🌻1. 前言](#🌻1. 前言)
- [🌻2. Android16进阶之写数据AudioTrack.write介绍](#🌻2. Android16进阶之写数据AudioTrack.write介绍)
- [🌻3. 代码实例](#🌻3. 代码实例)
-
- [🌻3.1 阻塞write播放本地音乐](#🌻3.1 阻塞write播放本地音乐)
- [🌻3.2 浮点write低延迟游戏音](#🌻3.2 浮点write低延迟游戏音)
- [🌻3.3 回调拉取write VoIP语音](#🌻3.3 回调拉取write VoIP语音)
- [🌻3.4 用法总结](#🌻3.4 用法总结)
-
🌻1. 前言
本篇目的:Android16进阶之写数据AudioTrack.write:用法实例
🌻2. Android16进阶之写数据AudioTrack.write介绍
-
基本概念
write()将PCM数据推入AudioTrack内部缓冲区,阻塞或非阻塞模式由TransferMode决定;需先play(),系统持续消费数据并输出音频。
-
功能
支持byte[]、short[]、float[]、ByteBuffer;阻塞返回写入长度;与缓冲区大小、采样格式联动;无需权限;线程安全。
-
使用限制
必须在play()后调用;数据长度需为帧整数倍;浮点模式按4字节对齐;阻塞模式下write耗时与缓冲区剩余相关;欠载时产生爆音。
-
性能特性
AudioFlinger共享内存交换;延迟等于缓冲区剩余帧数/采样率;无JNI拷贝(直接内存);内存占用随缓冲区线性增长。
-
使用场景
音乐解码播放、游戏实时音效、VoIP语音发送、回调拉取模式。
🌻3. 代码实例
🌻3.1 阻塞write播放本地音乐
-
应用场景
解码线程循环推送PCM。
-
用法实例
java
AudioTrack track = new AudioTrack.Builder()
.setAudioFormat(new AudioFormat.Builder()
.setSampleRate(44100)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.build())
.setBufferSizeInBytes(65536)
.build();
track.play();
while (decoding) {
int len = decoder.read(pcmBuf, 0, pcmBuf.length);
if (len <= 0) break;
track.write(pcmBuf, 0, len);
}
track.stop();
track.release();
代码功能:循环阻塞write,解码结束自动停止并释放。
🌻3.2 浮点write低延迟游戏音
-
应用场景
射击游戏实时生成枪口PCM。
-
用法实例
java
AudioTrack track = new AudioTrack.Builder()
.setAudioFormat(new AudioFormat.Builder()
.setSampleRate(48000)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.setEncoding(AudioFormat.ENCODING_PCM_FLOAT)
.build())
.setBufferSizeInBytes(4096)
.build();
track.play();
float[] floatBuf = new float[2048];
fillFloatSfx(floatBuf);
track.write(floatBuf, 0, floatBuf.length, AudioTrack.WRITE_NON_BLOCKING);
代码功能:非阻塞浮点写入,降低线程等待时间。
🌻3.3 回调拉取write VoIP语音
-
应用场景
通话系统主动拉取语音数据。
-
用法实例
java
AudioTrack track = new AudioTrack.Builder()
.setAudioFormat(new AudioFormat.Builder()
.setSampleRate(16000)
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.build())
.setTransferMode(AudioTrack.TRANSFER_CALLBACK)
.setAudioTrackCallback(new AudioTrack.AudioTrackCallback() {
public void onDataRequest(AudioTrack track, int size) {
byte[] buf = new byte[size];
rtpDecoder.read(buf, 0, size);
track.write(buf, 0, size);
}
})
.build();
track.play();
代码功能:系统缺数据时回调,应用即时write,端到端延迟最低。
🌻3.4 用法总结
| 代码关键字 | 功能描述 | 典型应用 |
|---|---|---|
| write(byte[]) 阻塞 | 推送PCM | 音乐播放 |
| write(float[]) 非阻塞 | 浮点写入 | 游戏音效 |
| onDataRequest + write | 回调拉取 | VoIP语音 |