转载请注明转载自http://blog.csdn.net/l646871731/article/details/52160462
最近在弄项目,刚接触碰到了一个声音录制的问题
用了半天的时间写了一个录制demo,简单地写了使用AudioRecord来录制声音,结果却出来了一大堆问题
经过了总结,问题一共有三个:
1.使用不同的方式采集声音源
2.使用不同的录音通道(主要是API的更新)
3.使用不同的保存音源数据的方式
下面我们一一说一下上面的三个问题。
原因及解决:
1. 不同的设备对音源输入的支持不同,部分不支持MediaRecorder.AudioSource.VOICE_RECOGNITION方式采取声音源的,采集到的是杂音,方案是判断次后视镜设备是否支持
MediaRecorder.AudioSource.VOICE_RECOGNITION方式采取声音源,若支持,则使用,不支持则使用MediaRecorder.AudioSource.MIC方式采集。
2. channelConfig通道参数中api在版本5以后有部分修改,
Added in API level5;
修改如下:
3.保存音源信息成ACM流文件,可以用byte型数组取资源或者用short型数组,我一开始用的是short,但是奇怪的是用short[]去保存数据,出来的ACM流信息的音源文件播放出来的是杂音,又有可能是出来的文件,每隔一段没有了一些声音信息,原因还没有找到。如果大家有知道这个问题的原因和解决,欢迎大家提出和讨论。
最后用byte[]来保存就没有问题了。
下面我把main文件贴出来供大家参考。
public class MainActivity extends Activity implements OnClickListener {
private TextView stateView;
private Button btnStart;
private Button btnStop;
private RecordTask recorder;
private boolean isRecording = true;
// ???????ڴ??
private int bufferSizeInBytes = 0;
private AudioRecord audioRecord;
private int audioSource = MediaRecorder.AudioSource.VOICE_RECOGNITION;
private int frequence = 16000;
/**
* ChannelConfig:AudioFormat .CHANNEL_CONFIGURATION_MONO??dioFormat.CHANNEL_CONFIGURATION_STEREO(??ʱ?????
* CHANNEL_OUT_STEREO ???CHANNEL_IN_STEREO???
* **/
private int channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
stateView = (TextView) this.findViewById(R.id.view_state);
btnStart = (Button) this.findViewById(R.id.btn_start);
btnStart.setOnClickListener(this);
btnStop = (Button) this.findViewById(R.id.btn_stop);
btnStop.setOnClickListener(this);
btnStop.setEnabled(false);
}
@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.btn_start:
// ??ʼ¼?
recorder = new RecordTask();
recorder.execute();
stateView.setText("??ʼ¼?");
break;
case R.id.btn_stop:
// ֹͣ¼?,???״̬
this.isRecording = false;
stateView.setText("ֹͣ¼?");
break;
}
}
@Override
public void onDestroy() {
// ¼????
if (isRecording) {
audioRecord.stop();
audioRecord.release();
}
audioRecord = null;
super.onDestroy();
}
class RecordTask extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void...arg0) {
isRecording = true;
try {
// ???ݶ???õļ??????????????ʵĻ???С
if (MediaRecorder.getAudioSourceMax() >= MediaRecorder.AudioSource.VOICE_RECOGNITION) {
audioSource = MediaRecorder.AudioSource.MIC;
}
bufferSizeInBytes = AudioRecord.getMinBufferSize(frequence, channelConfig, audioEncoding);
// ʵ????AudioRecord
audioRecord = new AudioRecord(audioSource, frequence, channelConfig, audioEncoding, bufferSizeInBytes);
// ??ʼ¼?
audioRecord.startRecording();
writeDateTOFile();
} catch (Exception e) {
}
return null;
}
protected void onProgressUpdate(Integer...progress) {
stateView.setText(progress[0].toString());
}
protected void onPostExecute(Void result) {
btnStop.setEnabled(false);
btnStart.setEnabled(true);
}
protected void onPreExecute() {
btnStart.setEnabled(false);
btnStop.setEnabled(true);
}
}
/**
* ??ォ????????
*/
private void writeDateTOFile() {
// newһ??byte????????Щ?????ݣ????Ϊ????????
byte[] audiodata = new byte[bufferSizeInBytes];
FileOutputStream fos = null;
int readsize = 0;
try {
File file;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// ????SD?????
file =
new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/record/" + "record"
+ System.currentTimeMillis() + ".pcm");
file.mkdirs();
if (file.exists()) {
file.delete();
}
} else// ????SD?????
{
file = this.getCacheDir();
}
fos = new FileOutputStream(file);
} catch (Exception e) {
e.printStackTrace();
}
while (isRecording == true) {
readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
if (AudioRecord.ERROR_INVALID_OPERATION != readsize && fos != null) {
try {
fos.write(audiodata);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
if (fos != null)
fos.close();
// ¼????
audioRecord.stop();
audioRecord.release();
} catch (IOException e) {
e.printStackTrace();
}
}
}