然后停止线程
if (thread!=null){
thread?.join()
thread =null
}
最后释放AudioRecord
if (audioRecord != null) {
audioRecord?.release()
audioRecord = null
}
通过以上一个流程之后,就可以得到一个非压缩编码的PCM数据了。
但是这个数据在音乐播放器上一般是播放不了的,那么怎么验证我是否录制成功呢?当然是使用我们的AudioTrack
进行播放看看是不是刚刚我们录制的声音了。
由于AudioTrack
是由Android SDK提供比较底层的播放API,也只能操作PCM裸数据,通过直接渲染PCM数据进行播放。当然如果想要使用AudioTrack
进行播放,那就需要自行先将压缩编码格式文件解码。
AudioTrack的使用流程大致如下:
-
根据音频参数创建
AudioTrack
-
调用
play
开始播放 -
开启播放线程,循环想
AudioTrack
缓存区写入音频数据 -
释放资源
创建AudioTrack
我们来看看AudioTrack
的构造方法
public AudioTrack (int streamType,
int sampleRateInHz,
int channelConfig,
int audioFormat,
int bufferSizeInBytes,
int mode,
int sessionId)
- streamType,Android手机上提供音频管理策略,按下音量键我们会发现由媒体声音管理,闹铃声音管理,通话声音管理等等,当系统有多个进程需要播放音频的时候,管理策略会决定最终的呈现效果,该参数的可选值将以常量的形式定义在类AudioManager中,主要包括以下内容:
· STREAM_VOCIE_CALL:电话声音
· STREAM_SYSTEM:系统声音
· STREAM_RING:铃声
· STREAM_MUSCI:音乐声
· STREAM_ALARM:警告声
· STREAM_NOTIFICATION:通知声
因为这里是播放音频,所以我们选择STREAM_MUSCI
。
-
sampleRateInHz,采样率,即播放的音频每秒钟会有多少次采样,可选用的采样频率列表为:8000、16000、22050、24000、32000、44100、48000等,一般采用人能听到最大音频的2倍,也就是44100Hz。
-
channelConfig,声道数的配置,可选值以常量的形式配置在类AudioFormat中,常用的是CHANNEL_IN_MONO(单声道)、CHANNEL_IN_STEREO(立体双声道)
-
audioFormat,采样格式,可选值以常量的形式定义在类AudioFormat中,分别为ENCODING_PCM_16BIT(16bit)、ENCODING_PCM_8BIT(8bit),一般采用16bit。
-
bufferSizeInBytes,其配置的是AudioTrack内部的音频缓冲区的大小,可能会因为生产厂家的不同而有所不同,为了方便AudioTrack提供了一个获取该值最小缓冲区大小的方法
getMinBufferSize
。 -
mode,播放模式,AudioTrack提供了两种播放模式,可选的值以常量的形式定义在类AudioTrack中,一个是MODE_STATIC,需要一次性将所有的数据都写入播放缓冲区中,简单高效,通常用于播放铃声、系统提醒的音频片段;另一个是MODE_STREAM,需要按照一定的时间间隔不间断地写入音频数据,理论上它可以应用于任何音频播放的场景。
-
sessionId,AudioTrack都需要关联一个会话Id,在创建AudioTrack时可直接使用
AudioManager.AUDIO_SESSION_ID_GENERATE
,或者在构造之前通过AudioManager.generateAudioSessionId
获取。
上面这种构造方法已经被弃用了,现在基本使用如下构造(最小skd 版本需要>=21),参数内容与上基本一致:
public AudioTrack (AudioAttributes attributes,
AudioFormat format,
int bufferSizeInBytes,
int mode,
int sessionId)
通过AudioAttributes.Builder
设置参数streamType
var audioAttributes = AudioAttributes.Builder()
.setLegacyStreamType(AudioManager.STREAM_MUSIC)
.build()
通过AudioFormat.Builder
设置channelConfig,sampleRateInHz,audioFormat参数
var mAudioFormat = AudioFormat.Builder()
.setChannelMask(channel)
.setEncoding(audioFormat)
.setSampleRate(sampleRate)
.build()
切换播放状态
首先通过调用getState
判断AudioRecord是否初始化成功,然后通过play
切换成录播放状态
if (null!=audioTrack && audioTrack?.state != AudioTrack.STATE_UNINITIALIZED){
audioTrack?.play()
}