Проблемы AudioRecord с устройствами не HTC - PullRequest
0 голосов
/ 10 июня 2010

У меня проблемы с использованием AudioRecord.

Пример использования некоторого кода, полученного из проекта splmeter :

private static final int FREQUENCY = 8000;
private static final int CHANNEL = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private int BUFFSIZE = 50;
private AudioRecord recordInstance = null;

...

android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
recordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC, FREQUENCY, CHANNEL, ENCODING, 8000);
recordInstance.startRecording();
short[] tempBuffer = new short[BUFFSIZE];
int retval = 0;

while (this.isRunning) {
   for (int i = 0; i < BUFFSIZE - 1; i++) {
      tempBuffer[i] = 0;
   }

   retval = recordInstance.read(tempBuffer, 0, BUFFSIZE);
   ... // process the data
}

Это работает на HTCDream и HTC Magic совершенно без каких-либо предупреждений / ошибок журнала, но вызывают проблемы на эмуляторах и устройстве Nexus One.

На Nexus one он просто никогда не возвращает полезные данные.Я не могу предоставить другую полезную информацию, так как у меня есть удаленный друг, который проводит тестирование.

На эмуляторах (Android 1.5, 2.1 и 2.2) я получаю странные ошибки от переполнений AudioFlinger и Buffer с AudioRecordThread,У меня также наблюдается значительное замедление отклика пользовательского интерфейса (хотя запись происходит в отдельном потоке, нежели пользовательский интерфейс).

Есть ли что-то очевидное, что я делаю неправильно?Нужно ли делать что-то особенное для оборудования Nexus One?

EDIT

Я частично решил проблему ... Документация для AudioRecord говорит:

public static int getMinBufferSize (int sampleRateInHz, int channelConfig, int audioFormat)

Возвращает минимальный размер буфера, необходимый для успешного создания объекта AudioRecord.Обратите внимание, что этот размер не гарантирует плавную запись под нагрузкой, и следует выбирать более высокие значения в соответствии с ожидаемой частотой, с которой экземпляр AudioRecord будет опрашиваться для новых данных. Для новых данных.

Поэтому я изменил длину буфера на

private static final int BUFFSIZE = AudioRecord.getMinBufferSize(FREQUENCY, CHANNEL, ENCODING);

И теперь эмуляторы работают хорошо.

Но

Оборудование не работает.Хотя эмуляторы возвращают значение 640 из этого вызова (что дает 12,5 опросов в секунду) на основе 8 кГц, аппаратное обеспечение HTC возвращает 4096!Это означает примерно 2 опроса в секунду и задержку звука в полсекунды!Кроме того, тот же самый вызов на Nexus One возвращает 8192!Итак, полная секундная задержка!

Я бы хотел, чтобы на этом все закончилось, но Nexus One все еще не возвращает никакого звука (по-прежнему у меня его нет, поэтому я не могуполучить правильную информацию об отладке от одного), даже если устройства HTC и все эмуляторы теперь работают (даже если некоторые из них более медленные, чем другие).

Я что-то здесь делаю ужасно неправильно?

1 Ответ

2 голосов
/ 16 июня 2010

Я решил это!

Я (ошибочно) предположил, что магическое число 8000, использованное в конструкторе класса AudioRecord, было дубликатом переменной частоты.На самом деле это должен быть размер буфера, который вы будете использовать.

К сожалению, это не только отличается от длины буфера splmeter (по умолчанию 320 - которую я изменил до 50 в моем первом кодовом блоке), но иминимальный размер буфера, приемлемый для Nexus One, составляет 8192, поэтому экземпляр AudioRecord не должен был быть создан должным образом.

Поэтому, когда у меня была измененная длина буфера (из getMinBufferSize), заменил магический 8000 на него, иувеличил мою переменную Frequency до рекомендованного 44100, все отлично работает на всех платформах / эмуляторах.

Так что, если вы планируете использовать кодовую базу splmeter до того, как она будет исправлена, примите во внимание эти три вещи.

Если честно, код сплитметра не должен работать даже на устройствах HTC.Наверное, поэтому мое девайс-устройство называется HTC Magic = P

.
...