Sto registrando audio con AudioRecord in formato PCM16LE, 8000Hz, 1canale. Registra bene nelle versioni Android 2.3.3-4.4.4, ma registra strani suoni intermittenti in Android L (5.0) Developer Preview (su nexus 5, nexus 7 ed emulatore).AudioRecord registra audio intermittente in Android L Developer Preview
Ecco il campione del suono registrato (prima metà - la registrazione, la seconda metà - riproduzione): https://www.dropbox.com/s/3wcgufua5pphwtt/android_l_sound_record_error.m4a?dl=0
ho cercato di riprodurre l'audio registrato con tariffa diversa campione (4000, 16000) e come 8bit, ma il suono continua ad essere intermittente. Quale potrebbe essere il problema con questo suono?
Sto usando questo AudioRecordTask per registrare l'audio con getAudioRecord() per l'inizializzazione di ingresso (senza errori restituiti durante il funzionamento; la ricezione di blocchi audio di dimensioni anche per il valore 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);
}
}
}
Questo problema sembra essere risolto nella versione 5.0, tuttavia esiste un problema correlato in cui il parametro di offset viene erroneamente raddoppiato. Vedere https://code.google.com/p/android/issues/detail?id=80866 quando si tenta di per inviare una patch mi è stato detto che è anche fissato internamente, anche se non ha idea di quando verrà visualizzato in una versione. –
Mi sono appena schiantato in questo (credo) in 5.0.2. Questo significa che se il byte [] buffer read è usato tutto funziona bene, incluso il parametro offset, o è ancora doppio? – nmw01223
quando si utilizza il buffer byte [] tutto è ok incluso offset (era così su 5.0 e 5.0.1, non ancora testato su 5.0.2 ancora) –