Странное искажение при записи с микрофона в Android 2.2 - PullRequest
0 голосов
/ 14 октября 2010

У меня есть приложение, которое записывает звук с микрофона, а затем выполняет некоторую постобработку звука в режиме реального времени, поэтому я должен использовать класс AudioRecord вместо стандартного MediaRecorder.Мой код для записи таков:

DataOutputStream dataOutputStreamInstance = new DataOutputStream(bufferedStreamInstance);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

int bufferSize = AudioRecord.getMinBufferSize((int)sampleRate, channelConfiguration, DEFAULT_AUDIO_ENCODING) * 2;
short[] microphoneBuffer = new short[bufferSize];
float[] processingBuffer = new float[bufferSize];
short[] outputBuffer = new short[bufferSize];

AudioRecord microphoneRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);

microphoneRecorder.startRecording();
while(isRecording) {
  synchronized(mutex) { ... check for pause condition, wait, etc. ... }
  int numSamplesRead = microphoneRecorder.read(microphoneBuffer, 0, bufferSize);

  // Convert 16-bit short data to floating point
  getFloatingPointBufferFromPcmData(microphoneBuffer, processingBuffer, bufferSize);

  doProcessingStuff(processingBuffer, bufferSize);

  if(numSamplesRead == AudioRecord.ERROR_INVALID_OPERATION) {
    throw new IllegalStateException("read() returned AudioRecord.ERROR_INVALID_OPERATION");
  }
  else if(numSamplesRead == AudioRecord.ERROR_BAD_VALUE) {
    throw new IllegalStateException("read() returned AudioRecord.ERROR_BAD_VALUE");
  }

  try {
    // Dump the output to the target file in 16-bit short format
    getShortPcmBufferFromFloatingPointData(processingBuffer, outputBuffer, bufferSize);
    for(int bufferIndex = 0; bufferIndex < numSamplesRead; bufferIndex++) {
      dataOutputStreamInstance.writeShort(outputBuffer[bufferIndex]);
    }
  }
  catch(Exception e) {
    Log.e("MyApp", "Error while writing audio data to file: " + e.getMessage());
    e.getStackTrace();
  }
}

microphoneRecorder.stop();

Приведенный выше код работает нормально, и я действительно могу записывать звук с устройства, и я слышу свой голос и тому подобное.Проблема в том, что через несколько секунд начинает появляться очень странная картина искажения, пока весь сигнал не заглушится.Вот скриншот записи молчания, которую я сделал, наложив на микрофон какую-то ленту и оставив приложение на минуту или около того:

Screenshot of distortion in wave file

Исходный волновой файл может быть скачано здесь .

Проблема определенно , а не из-за моего кода обработки эффектов, так как я пытался закомментировать его и получить одинаковые результаты в обоих случаях.Я искал в Интернете другой код или людей, которые могут испытывать подобные проблемы, но ничего не нашли.

Ответы [ 3 ]

1 голос
/ 14 октября 2010

Я совсем не знаю Android SDK, но getFloatingPointBufferFromPcmData и getShortPcmBufferFromFloatingPointData не похожи на стандартные функции API, несмотря на прекрасное соглашение об именах. :)

Ты сам написал это? Возможно, они используют общее состояние и накапливают результаты по итерациям цикла? Если это ваша реализация, пожалуйста, поделитесь их кодом, чтобы мы могли помочь вам определить действительную проблему.

Существует также вероятность того, что вы записываете данные PCM в неправильном формате (число битов, порядковый номер) и что ваш аудиоредактор интерпретирует данные в другом формате, что приводит к неверно декодированным аудиоданным, которые появляются обманчиво, как будто происходит эффект накопления.

Если ни один из этих запросов не приведет вас к решению вашей проблемы, то моя следующая рекомендация будет заключаться в создании нового экземпляра микрофонаBuffer для каждой итерации цикла вместо использования одного экземпляра в цикле while.

Опять же, я не эксперт по Android SDK, так что это всего лишь общие советы, основанные на многолетнем опыте работы с практически всеми видами API и деталями его реализации.

Надеюсь, это поможет диагностировать вашу проблему!

0 голосов
/ 15 октября 2010

Бах, на самом деле проблема была не в ошибках Android - она ​​была вызвана программным обеспечением, которое я использовал для преобразования необработанных данных PCM в формат WAV.Очевидно, есть некоторая ошибка в преобразовании с прямым порядком байтов, так как чипы ARM имеют большой порядок байтов, а WAV - младший.Когда мы попытались открыть необработанные файлы PCM в Audacity, они выглядели нормально.

0 голосов
/ 14 октября 2010

При тишине может быть автоматическая регулировка усиления, которая увеличивает разумное усиление входного сигнала, пытаясь найти «что-то» для вас, чтобы записать (и, конечно, найти минимальный уровень шума)настроить громкоговорители ПК для воспроизведения хорошей синусоиды звуковой частоты - шум по-прежнему возрастает или вы продолжаете записывать синусоидальную волну?

...