Android16音频之写数据AudioTrack.write:用法实例(一百二十七)

简介: 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介绍

  1. 基本概念

    write()将PCM数据推入AudioTrack内部缓冲区,阻塞或非阻塞模式由TransferMode决定;需先play(),系统持续消费数据并输出音频。

  2. 功能

    支持byte[]、short[]、float[]、ByteBuffer;阻塞返回写入长度;与缓冲区大小、采样格式联动;无需权限;线程安全。

  3. 使用限制

    必须在play()后调用;数据长度需为帧整数倍;浮点模式按4字节对齐;阻塞模式下write耗时与缓冲区剩余相关;欠载时产生爆音。

  4. 性能特性

    AudioFlinger共享内存交换;延迟等于缓冲区剩余帧数/采样率;无JNI拷贝(直接内存);内存占用随缓冲区线性增长。

  5. 使用场景

    音乐解码播放、游戏实时音效、VoIP语音发送、回调拉取模式。

🌻3. 代码实例

🌻3.1 阻塞write播放本地音乐
  1. 应用场景

    解码线程循环推送PCM。

  2. 用法实例

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低延迟游戏音
  1. 应用场景

    射击游戏实时生成枪口PCM。

  2. 用法实例

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语音
  1. 应用场景

    通话系统主动拉取语音数据。

  2. 用法实例

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语音
相关推荐
ai产品老杨1 天前
异构计算时代的视频底座:基于 ZLMediaKit 与 Spring Boot 的 X86/ARM 跨平台架构解析
arm开发·spring boot·音视频
Black蜡笔小新1 天前
花屏/蓝屏/黑屏/画面抖动/冻结/模糊检测,聊聊EasyCVR的视频质量诊断插件,解决运维人的实际烦恼
运维·音视频
琪伦的工具库1 天前
批量音频音量调整工具使用说明:固定增减分贝与目标响度两种模式怎么选
音视频
y小花1 天前
安卓音频子系统之USBAlsaManager
android·音视频
AI2512241 天前
2026年9款主流AI视频生成器功能评测
人工智能·音视频
2401_885885041 天前
视频短信二次开发接口怎么做?视频短信API发送教程
音视频
2401_885885041 天前
视频短信第三方接口好开发吗?全国三网覆盖能力的视频短信平台
音视频
hay_lee1 天前
匿名屠榜,阿里认领:HappyHorse 1.0 如何重写AI视频生成规则?
人工智能·音视频
ai产品老杨1 天前
打破品牌孤岛:基于 GB28181 与 ZLMediaKit 的多协议视频统一接入网关架构
架构·音视频
视***间1 天前
智采高清,视界无界——视程空间视频采集卡,定义专业采集新标杆
人工智能·机器人·音视频·边缘计算·采集卡·视程空间·视频采集卡