AudioRecord在Android L Developer Preview中记录间歇性声音
我正在以PCM16LE格式,8000Hz,1声道录制AudioRecord声音。 它可以在Android 2.3.3-4.4.4版本中记录,但在Android L(5.0)开发人员预览版(在nexus 5,nexus 7和仿真器上)中记录奇怪的间歇性声音。
这里是录制的声音样本(前半部分 - 录音,后半部分 - 回放):https://www.dropbox.com/s/3wcgufua5pphwtt/android_l_sound_record_error.m4a?dl=0
我试图播放使用不同采样率(4000,16000)和8bit录制的声音,但声音保持间歇性。 这个声音会出现什么问题?
我正在使用此AudioRecordTask以用于初始化输入的getAudioRecord()录制音频(在操作期间未返回错误;接收与internalBufferSize值同等大小的音频块):
public final int SAMPLING_RATE = 8000;
private AudioRecord getAudioRecord() {
int internalBufferSize = AudioRecord.getMinBufferSize(SAMPLING_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT); //returns 640
internalBufferSize = 8000; //also tried returned value (640) and values 2560, 30000 - no changes
final int SOURCE;
if (Build.VERSION.SDK_INT < 11) {
SOURCE = MediaRecorder.AudioSource.MIC;
} else {
SOURCE = MediaRecorder.AudioSource.VOICE_COMMUNICATION;
}
AudioRecord record = new AudioRecord(SOURCE,
SAMPLING_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
internalBufferSize);
int state = record.getState();
if (state != AudioRecord.STATE_INITIALIZED) {
try {
record.release();
} catch (Exception e) {
}
return null;
}
if (record.getState() == android.media.AudioRecord.STATE_INITIALIZED) {
record.startRecording();
} else {
record.release();
return null;
}
return record;
}
private class AudioRecordTask extends AsyncTask<Void, Void, Void> {
final int PARTIAL_BUFFER_SIZE = SAMPLING_RATE;
final int NECESSARY_BUFFER_SIZE = 15 * PARTIAL_BUFFER_SIZE * Short.SIZE / 8;
final int FULL_BUFFER_SIZE = NECESSARY_BUFFER_SIZE * 2; //XXX: * 2 for the case when system returns more data than needed
short[] mBuffer;
int mTotalSize;
int mTotalSizeInBytes;
boolean mResult;
private Object mLock = new Object();
@Override
protected void onPreExecute()
{
mIsRecording = true;
mBuffer = new short[FULL_BUFFER_SIZE];
mTotalSize = 0;
mTotalSizeInBytes = 0;
mResult = false;
}
@Override
protected Void doInBackground(Void... arg0) {
synchronized (mLock) {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
AudioRecord record = getAudioRecord();
if (record == null) {
mResult = false;
return null;
}
for (int i = 0; i < 15 * 100; i++) { //XXX: * 100 to record enough data (system can return lesser than needed)
int datalen = record.read(mBuffer, mTotalSize, PARTIAL_BUFFER_SIZE);
if (datalen > 0) {
mTotalSize += datalen;
mTotalSizeInBytes = mTotalSize*2;
} else {
Log.w("", "error " + datalen + " in AudioRecord.read");
}
if (isCancelled() || mTotalSizeInBytes > NECESSARY_BUFFER_SIZE) {
break;
}
}
if (record.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
record.stop();
}
record.release();
mResult = true;
return null;
}
}
@Override
protected void onPostExecute(Void r) {
synchronized (mLock) {
mIsRecording = false;
fin();
}
}
@Override
protected void onCancelled() {
//XXX: on old Androids (e.g. 2.3.3) onCancelled being called while doInBackground is still running
synchronized (mLock) {
mIsRecording = false;
if (mAbort) {
return;
}
fin();
}
}
private void fin() {
if (mResult && mTotalSizeInBytes > 0) {
sendRecordedAudioToServer(mBuffer, mTotalSize, mTotalSizeInBytes);
} else {
showError(null);
}
}
}
这是Android L Developer Preview中的一个错误:https://code.google.com/p/android-developer-preview/issues/detail?id=1492
AudioRecord.read for short []缓冲区参数以字节为单位返回值,而不是短裤中的值。
作为解决方法,使用带有byte []缓冲区的AudioRecord.read。
链接地址: http://www.djcxy.com/p/81967.html上一篇: AudioRecord records intermittent sound in Android L Developer Preview