AudioTrack 说明

AudioTrack 允许 PCM 音频缓冲器流到音频接收器进行回访。通过“推”的数据对象的信号使用 write(byte[], int, int), write(short[], int, int) 和 write(float[], int, int, int) 方法。

AudioTrack 实例可以在两种模式下运行:静态或流传输。

在播放音频数据块是,流模式非常有用:

  • 在优先排队的音频正在播放时接收或生成
  • 由于声音播放的持续时间太长而不适合记忆
  • 由于音频数据具有的高采样率,位数等特性

流模式通过 write 方式将数据一次一次的写到 AudioTrack 中,效率低。而静态模式则将数据翻到一个固定的 buffer 中,然后传给 AudioTrack ,只读取一次,适合处理短声音等内存开销较小,延时要求较高的场景。

AudioTrack 创建

构造函数

AudioTrack)(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode) 在 api 26 时弃用,改成 AudioTrack.Builder 或 AudioTrack)(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes, int mode, int sessionId)

AudioTrack)(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode, int sessionId) 在 api 26 时弃用…

AudioTrack)(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes, int mode, int sessionId)

// builder 模式

AudioTrack.Builder

参数含义

  • streamType 音频流类型:与 AudioManager 有关,设计手机音频管理策略。参数类型 AudioManager.STREAM_MUSIC、STREAM_RING、STREAM_SYSTEM、STREAM_VOICE_CALL、STREAM_ALARM、STREAM_NOTIFICATION 等
  • sampleRateInHz 采样频率:越高音质越好,文件体积越大,一般有 8000、20100、44100等
  • channelConfig 声道: 双声道(AudioFormat.CHANNEL_IN_MONO)、单声道(AudioFormat.CHANNEL_IN_STEREO)
  • audioFormat 采样制式:AudioFormat.ENCODING_PCM_16BIT、AudioFormat.ENCODING_PCM_8BIT、AudioFormat.ENCODING_PCM_FLOAT 等。
  • bufferSizeInBytes 缓冲区大小。可以从 AudioRecord.getMinBufferSize (int sampleRateInHz,nt channelConfig,int audioFormat) 获取。
  • mode 模式:静态和流模式两种,AudioTrack.MODE_STATIC、AudioTrack.MODE_STREAM
  • attributes 音频流信息的属性集合:通过 AudioAttributes.Builder() 进行构建,可以设置 usage (音频使用类型)、content(音频内容类型)、flags(特定播放行为)
  • format 音频编制格式:可以设置编码方式、采样频率、声道

AudioTrack 主要方法

  • play() 开始播放
  • pause() 暂停播放
  • write(…) 写入 AudioTrack
  • stop() 停止播放
  • release() 资源释放

AudioTrack 示例代码

Builder 构建

1
2
3
4
5
6
7
8
9
10
11
12
AudioTrack player = new AudioTrack.Builder()
.setAudioAttributes(new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build())
.setAudioFormat(new AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(44100)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.build())
.setBufferSizeInBytes(minBuffSize)
.build();

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
private int mFrequence = 44100; // 采样频率
private int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;//录制 声道
private int mPlayChannelConfig = AudioFormat.CHANNEL_IN_STEREO;//播放 声道
private int mAudioEncoding = AudioFormat.ENCODING_PCM_16BIT;//编码格式
//获取缓存大小
int bufferSize = AudioTrack.getMinBufferSize(mFrequence,
mPlayChannelConfig, mAudioEncoding);
// 实例AudioTrack
AudioTrack player = new AudioTrack(AudioManager.STREAM_MUSIC,mFrequence,
mPlayChannelConfig, mAudioEncoding, bufferSize,
AudioTrack.MODE_STREAM);

读取音频数据(子线程执行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
short[] buffer = new short[bufferSize];
try {
//从本地音频文件中获取 mAudioFile 文件路径
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(mAudioFile)));
//播放
track.play();
while (dis.available() > 0) {
int i = 0;
while (dis.available() > 0 && i < buffer.length) {
buffer[i] = dis.readShort();
i++;
}
//写入
track.write(buffer,0,buffer.length);
}
//停止
track.stop();
dis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

参考文件

AudioTrack)

Android 音视频深入