AudioRecord采集的是原始音频数据,一般的音频播放器无法直接播放PCM未编码的原始数据
/**
- Audio:采集原始(未编码)的数据(PCM)
- AudioTrack:播放未编码的PCM原始音频数据
- Audio主要是实现边录边播(AudioRecord+AudioTrack)以及对音频的实时处理(如会说话的汤姆猫、语音)
- 优点:语音的实时处理,可以用代码实现各种音频的封装
- 缺点:输出是PCM语音数据,如果保存成音频文件,是不能够被播放器播放的,所以必须先写代码实现数据编码以及压缩
*/
实现:
public class MyAudio {
/**
* 采集音频数据:
* 1:配置参数,初始化音频缓冲区
* 2:采集数据
* 3:从缓冲区读取音频数据
* 4:停止采集,释放资源
*/
//采集缓冲区的大小
private int receiveBufSize;
//播放缓冲区的大小
private int playBufSize;
//采样率
private static final int SAMPLE_RATE_HZ = 44100;
//采集通道数
private static final int CHANNEL_IN_COUNT = AudioFormat.CHANNEL_IN_MONO;
//播放通道数
private static final int CHANNEL_OUT_COUNT = AudioFormat.CHANNEL_OUT_MONO;
//位数
private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord audioRecord;
private AudioTrack audioTrack;
public MyAudio() {
receiveBufSize = AudioRecord.getMinBufferSize(SAMPLE_RATE_HZ, CHANNEL_IN_COUNT, AUDIO_FORMAT);
playBufSize = AudioTrack.getMinBufferSize(SAMPLE_RATE_HZ, CHANNEL_OUT_COUNT, AUDIO_FORMAT);
}
private boolean isRecording = false;
public void startRecord() {
isRecording = true;
if (audioRecord == null)
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
SAMPLE_RATE_HZ, CHANNEL_IN_COUNT, AUDIO_FORMAT, receiveBufSize);
if (audioTrack == null)
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE_HZ,
CHANNEL_OUT_COUNT, AUDIO_FORMAT, playBufSize, AudioTrack.MODE_STREAM);
new RecodeThread().start();
}
public void stopRecord() {
isRecording = false;
//结束播放和采集
audioTrack.stop();
audioRecord.stop();
}
class RecodeThread extends Thread {
@Override
public void run() {
byte[] buffer = new byte[receiveBufSize];
audioRecord.startRecording();
audioTrack.play();
while (isRecording) {
//从音频缓冲区读取音频数据
audioRecord.read(buffer, 0, receiveBufSize);
//播放声音
audioTrack.write(buffer, 0, receiveBufSize);
}
}
}
}
网友评论