上一篇帖子我记录了音频采集的一些内容,既然有采集了,那么肯定是需要播放的,今天这篇帖子就简单说一下录音的播放步骤。
录音的播放需要用到的是Android中的AudioTrack类,其实AudioTrack类和AudioRecord很相似,我们同样从AudioTrack的初始化开始说起。
AudioTrack的初始化和AudioRecord格式几乎一直,只是参数个数不一样,我们还是先看一下AudioTrack初始化的源码,
public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes, int mode)
throws IllegalArgumentException {
this(streamType, sampleRateInHz, channelConfig, audioFormat,
bufferSizeInBytes, mode, AudioManager.AUDIO_SESSION_ID_GENERATE);
}
这里接收了六个参数,分别为streamType(流类型),sampleRateInHz(采样率),channelConfig(声道),audioFormat(采样深度),bufferSizeInBytes(缓冲区大小),mode(模式)
其中采样率,声道,采样深度,缓冲区大小都和AudioRecord对应,去除了输入音频方式,但是增加了音频类型和音频模式。
这个是我初始化配置的参数,一个一个分析一下
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRateInHz, AudioFormat.CHANNEL_OUT_STEREO, audioFormat, playBufsize, AudioTrack.MODE_STREAM);
streamType
第一个参数是steamType我这边传入的值是AudioManager.STREAM_MUSIC,我们先跳入到AudioManager文件中看下,可选的流类型有哪些
当前Android定义了很多的种音频流的类型,抛开已弃用的和现在不再支持的,仅剩下七种类型可以选择使用,从名称和注释我们也可以大概看出来具体有哪些作用,这里就简单说明一下,方便大家理解
STREAM_VOICE_CALL:电话语音
STREAM_SYSTEM:系统声音
STREAM_RING:铃声
STREAM_MUSIC:音乐
STREAM_ALARM:警告
STREAM_NOTIFICATION:通知
STREAM_DTMF:按键
至于Android为什么要设置那么多的音频类型,我这里不展开说明了,后面再AudioFlinger里再详细说。
sampleRateInHz
采样率,这个和录音时的采样率保存一致就好
channelConfig
声道,这里有点小小的区别,录音时是收音状态AudioFormat.CHANNEL_IN_STEREO,播放时就要放音状AudioFormat.CHANNEL_OUT_STEREO
audioFormat
采样深度和采样率一样,和录音时保持一致
trackBufssize
缓冲区大小和录音时获取缓冲区大小是一样的,唯一的区别是Audiorecord时生成缓冲区大小是用AudioRecord.getMinBufferSize()而AudioTrack获取是用的AudioTrack.getMinBufferSize(),同样都是传入采样率,声道(播放时的声道设置)和采样率
mode
这个参数是AudioTrack较AudioRecord增加的一个参数,我们进入到AudioTrack,看到在AudioTrack中定义了两种mode方式,分别是MODE_STATIC和MODE_STREAM
而两种方式也稍有差别
MODE_STATIC:应用将当前音频数据一次性发给AudioTrack
MODE_STREAM:应用将当前音频数据持续write给AudioTrack,可能会遇到阻塞,但基本适用于所有场景
解释完各个参数,我们就可以开始进行播放录音操作了,播放录音也很简单,几乎和录制音频没有差别,避免占用主线程,同样的开启一共子线程进行操作,一边写入一边播放
private void setTrack() {
Log.e(TAG, "setTrack");
File file = new File(savePath);
if (!file.exists()) {
return;
}
mAudioTrack.play();
try {
FileInputStream fileInputStream = new FileInputStream(file);
byte[] tempBuffer = new byte[playBufsize];
while (fileInputStream.available() > 0 && isTrack) {
int readCount = fileInputStream.read(tempBuffer);
mAudioTrack.write(tempBuffer, 0, readCount);
Log.e(TAG, "setTrack1");
}
Looper.prepare();
Toast.makeText(RecordAndTrackActivity.this, "播放结束", Toast.LENGTH_SHORT).show();
Log.e(TAG, "setTrack2");
Looper.loop();
mAudioTrack.stop();
mAudioTrack.release();
mAudioTrack = null;
isTrack = false;
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
到此,简单的录制和播放音频就告一段落了,但是这些都是最最基本的,因为我也是初学者,很多东西都没有涉及到,慢慢涉及吧,坚持出一个系列。