Ich nehme Sound mit AudioRecord im PCM16LE-Format, 8000Hz, 1Kanal auf. Es nimmt in den Android-Versionen 2.3.3-4.4.4 gut auf, zeichnet aber in Android L (5.0) Developer Preview seltsames intermittierendes Geräusch auf (auf Nexus 5, Nexus 7 und Emulator).AudioRecord zeichnet intermittierenden Sound in Android L auf Entwicklervorschau
Hier ist die Probe des aufgenommenen Tons (die erste Hälfte - Aufnahme, die zweite Hälfte - Wiedergabe): https://www.dropbox.com/s/3wcgufua5pphwtt/android_l_sound_record_error.m4a?dl=0
Ich versuchte aufgenommenen Ton mit verschiedener Sample-Rate (4000, 16000) und als 8bit zu spielen, aber der Ton bleibt intermittierend. Was könnte das Problem an diesem Sound sein?
Ich verwende dieses AudioRecordTask mit getAudioRecord Audio aufnehmen() zur Eingabe der Initialisierung (keine Fehler während des Betriebs zurück; Audio-Stücke empfangen zu internalBufferSize Wert sized gleich):
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);
}
}
}
Dies scheint in Release 5.0 behoben zu sein, es gibt jedoch ein ähnliches Problem, bei dem der Offset-Parameter fälschlicherweise verdoppelt wird - siehe https://code.google.com/p/android/issues/detail?id=80866 beim Versuch um einen Patch zu senden wurde mir gesagt, dass das auch intern behoben wird, allerdings keine Ahnung wann es in einer Veröffentlichung erscheinen wird. –
Ich bin gerade in diese (glaube ich) in 5.0.2 abgestürzt. Bedeutet dies, dass, wenn das Byte [] buffer read verwendet wird, alles richtig funktioniert, einschließlich des Offset-Parameters, oder ist das immer noch verdoppelt? – nmw01223
bei der Verwendung von Byte [] Puffer ist alles ok einschließlich Offset (es war so auf 5.0 und 5.0.1, noch nicht auf 5.0.2 getestet) –