上篇文章写了使用AudioRecord采集音频,为了测试采集音频是否正确,可以通过AudioTrack播放音频试下。
AudioTrack只能播放PCM格式的文件。PCM全称是Pulse Code Modulation,即通常所说的音频的裸数据格式。描述一段PCM数据需要量化格式,采样率以及声道数。因此,播放PCM文件时需要匹配前文AudioRecord采集音频时的参数,否则会出现播放错乱的问题。
1. 初始化AudioTrack
- streamType
设置音频类型。Android提供多重音频管理策略,包括
public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL;
public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM;
public static final int STREAM_RING = AudioSystem.STREAM_RING;
public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC;
public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM;
public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION;
在音量按钮控制时,会提示具体修改哪类音频流的音量大小。注意设置StreamType是通过AudioAttributes设置,其中setLegacyStreamType与setUsgae/setContentType冲突,后两者控制粒度更细,前者是老旧版本设置方式与后两者冲突。
- channel 与AudioRecord录制时参数一致
- sampleRate 与AudioRecord录制时参数一致
- encoding 与AudioRecord录制时参数一致
- mode 播放模式,包括两种: MODE_STATIC , MODE_STREAM;前者一次性将所有数据写入到播放缓冲区,适合小音频;后者不断读取,适合所有音频。在播放时,如果使用STATIC则需要在播放play前将数据写入,否则在AudioTrack的状态为STATE_NO_STATIC_DATA,即无数据无法播放。
- bufferSize 根据mode参数配置,如果是STATIC,则为音频的大小,一次性全部读入;如果是STREAM,则通过AudioTrack计算得到的bufferSize,分批次读取。
- audioSessionId 与其他MediaPlayer或AudioTrack共享AudioEffect的,暂时没用到不了解~
2. 播放音频
以MODE_STATIC模式:
mAudioTrack.play();
以MODE_STREAM模式:
在子线程中读取文件内容到内存,逐份读取
mAudioTrack.play();
while ((length = inputStream.read(buf, 0,
mBufferSize)) >= 0) {
mAudioTrack.write(buf, 0, length);
}
3. 停止播放
AudioTrack#release,如果播放模式是MODE_STREAM,可通过AtomicBoolean方式添加标志位。