Nagrywam dźwięk z AudioRecord w formacie PCM16LE, 8000Hz, 1 kanał. Nagrywa w systemie Android w wersjach 2.3.3-4.4.4, ale rejestruje dziwne przerywane dźwięki w Androidzie L (5.0) Developer Preview (na nexusie 5, nexusie 7 i emulatorze).AudioRecord nagrywa przerywany dźwięk w Androidzie L Preview Preview
Oto próbka nagrywanego dźwięku (pierwsza połowa - zapisu, druga połowa - odtwarzanie): https://www.dropbox.com/s/3wcgufua5pphwtt/android_l_sound_record_error.m4a?dl=0
Próbowałem grać nagrany dźwięk przy użyciu różnych częstotliwości próbkowania (4000, 16000) oraz jako 8bit ale dźwięk nie jest przerywany. Jakim problemem może być ten dźwięk?
Używam tego AudioRecordTask do nagrywania dźwięku z getAudioRecord() przez inicjowanie wejściowy (bez błędów zwracanych podczas operacji; otrzymaniu fragmentów dźwiękowych sized równie wartości 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);
}
}
}
Wygląda na to, że naprawiono błąd w wersji 5.0, jednak istnieje problem z błędem podwojenia parametru odsunięcia - patrz https://code.google.com/p/android/issues/detail?id=80866 podczas próby aby przesłać łatkę, powiedziano mi, że jest również poprawiona wewnętrznie, ale nie ma pojęcia, kiedy pojawi się w wydaniu. –
Właśnie wpadłem na to (jak sądzę) w 5.0.2. Czy to oznacza, że jeśli używany jest odczyt bufora bajtowego [], wszystko działa poprawnie, łącznie z parametrem przesunięcia, czy jest jeszcze podwojony? – nmw01223
przy korzystaniu z bufora bajtowego [] wszystko jest ok łącznie z offsetem (tak było w 5.0 i 5.0.1, jeszcze nie testowałem w wersji 5.0.2) –