Мое приложение записывает аудио с телефонных микрофонов и выполняет некоторую обработку в реальном времени на нем. Он отлично работает на физических устройствах, но действует "смешно" в эмуляторе. Он записывает что-то, но я не совсем уверен, что он записывает.
Похоже, что на эмуляторе звуковые сэмплы читаются примерно в два раза быстрее, чем на реальных устройствах. В приложении у меня виджет визуального прогресса (горизонтально движущаяся головка записи), которая перемещается примерно в два раза быстрее в эмуляторе.
Вот цикл записи:
int FREQUENCY = 44100;
int BLOCKSIZE = 110;
int bufferSize = AudioRecord.getMinBufferSize(FREQUENCY,
AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT) * 10;
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.CAMCORDER,
FREQUENCY, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
short[] signal = new short[BLOCKSIZE * 2]; // Times two for stereo
audioRecord.startRecording();
while (!isCancelled()) {
int bufferReadResult = audioRecord.read(signal, 0, BLOCKSIZE * 2);
if (bufferReadResult != BLOCKSIZE * 2)
throw new RuntimeException("Recorded less than BLOCKSIZE x 2 samples:"
+ bufferReadResult);
// process the `signal` array here
}
audioRecord.stop();
audioRecord.release();
Источник звука установлен на "CAMCORDER" и записывается в стерео. Идея состоит в том, что если в телефоне есть несколько микрофонов, приложение будет обрабатывать данные от обоих и использовать то, что лучше SNR. Но у меня такие же проблемы, если записывать моно из AudioSource.MIC
. Он считывает аудиоданные в цикле while
, я предполагаю, что audioRecord.read()
является блокирующим вызовом и не позволит мне дважды читать одни и те же данные.
Записанные данные выглядят ОК - буфер записи содержит 16-битные образцы PCM для двух каналов. Кажется, что цикл работает в два раза быстрее, чем на реальных устройствах. Это заставляет меня думать, что, возможно, эмулятор использует более высокую частоту дискретизации, чем указанные 44100 Гц. Если я запрошу частоту дискретизации с audioRecord.getSampleRate()
, он вернет правильное значение.
Также во время записи есть несколько интересных аудиосообщений в logcat:
07-13 12:22:02.282 1187 1531 D AudioFlinger: mixer(0xf44c0000) throttle end: throttle time(154)
(...)
07-13 12:22:02.373 1187 1817 E audio_hw_generic: Error opening input stream format 1, channel_mask 0010, sample_rate 16000
07-13 12:22:02.373 1187 3036 I AudioFlinger: AudioFlinger thread 0xf3bc0000 ready to run
07-13 12:22:02.403 1187 3036 W AudioFlinger: RecordThread: buffer overflow
(...)
07-13 12:22:24.792 1187 3036 W AudioFlinger: RecordThread: buffer overflow
07-13 12:22:30.677 1187 3036 W AudioFlinger: RecordThread: buffer overflow
07-13 12:22:37.722 1187 3036 W AudioFlinger: RecordThread: buffer overflow
Я использую современные Android Studio и Android SDK, и я пробовал изображения эмуляторов с уровнями API 21-24. Моя среда для разработчиков - Ubuntu 16.04
Кто-нибудь испытал нечто подобное? Я что-то делаю неправильно в своем цикле записи?