Я использую AudioRecord для записи звука в файлы wav. Я выполняю операцию чтения() в цикле во вторичном потоке, и данные передаются в очередь через другую секунду. thread для записи в файл.
Проблема заключается в следующем: Когда я выбираю сохранить аудиоданные на внешней SD-карте, звук содержит несколько миллисекунд пропусков/искажений (только иногда). У других пользователей также возникает эта проблема при сохранении на внутреннюю SD-карту
Вот как я создаю экземпляр объекта AudioRecord:
initBufferSize = assureMinBufferSize();
if (minBufferSize == AudioRecord.ERROR_BAD_VALUE) {
throw new Exception("" + ErrorCodes.ERROR_CODE_0);
}
else if (minBufferSize == AudioRecord.ERROR) {
throw new Exception("" + ErrorCodes.ERROR_CODE_0);
}
buffer = new byte[initBufferSize];
aRecorder = new AudioRecord(mSource, sRate, nChannel, AudioFormat.ENCODING_PCM_16BIT, initBufferSize);
и вот как я объединяю объект AudioRecorder:
private class AudioReaderRunnable implements Runnable {
private volatile boolean stopped;
@Override
public void run() {
while (!stopped) {
while(mState == State.RECORDING){
read();
}
}
Log.i(getClass().getName(), "AudioReade thread stopped!");
}
private void read(){
if(aRecorder == null)
return;
// "dirty" patch for some null crash for some users
if(buffer == null)
buffer = new byte[initBufferSize];
//int x = aRecorder.read(buffer, 0, buffer.length);
int x = readFully(buffer, 0, buffer.length);
if(x <= 0)
return;
payloadSize += x;
mWavData.arrayCopy(buffer);
mWavData.setGain(rGain);
mWavData.setBitsPerSamples(bitsPerSample);
mWavData.setNrChannels(nChannelsNumber);
// send audio to another thread for writing
mAudioWritter.add(audioData);
}
private int readFully(byte[] data, int off, int length) {
int read = 0;
int result = 0;
int requestedSize = length;
if(aRecorder == null){
return read;
}
try {
result = aRecorder.read(data, off, requestedSize);
} catch (Exception e) {
Log.e(getClass().getName(), e.getMessage(), e);
if(aRecorder == null)
return read;
}
read = result;
while (requestedSize != result && !stopped) {
if(aRecorder == null)
return read;
requestedSize -= result;
try {
result = aRecorder.read(data, result - 1, requestedSize);
} catch (Exception e) {
Log.e(getClass().getName(), e.getMessage(), e);
if(aRecorder == null)
return read;
}
read += result;
}
return read;
}
public void stopThread() {
stopped = true;
}
}