Проблемы с AudioRecord на устройствах, отличных от HTC

У меня проблемы с использованием 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
}

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

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

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

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

ИЗМЕНИТЬ

Я частично решил проблему... Документация для 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! Итак, задержка на целую секунду!

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

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


person Marc    schedule 10.06.2010    source источник


Ответы (1)


Я решил это!

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

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

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

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

Честно говоря, код splmeter не должен работать даже на устройствах HTC. Я думаю, именно поэтому мое устройство разработчика называется HTC Magic =P

person Marc    schedule 16.06.2010
comment
Как вы узнали об этом номере 8000? Предлагаемые частоты дискретизации 44100 и 22050 не работают, но 8000 работает! - person Shawn Lauzon; 18.12.2010
comment
Я не совсем уверен, что понимаю ваш вопрос? Номер 8000 был в исходном коде, на который я ссылался в проекте splmeter (code.google.com/p /splmeter). И затем 8000 используется дважды в исходном коде; один раз как частота дискретизации и один раз как размер буфера. Для размера буфера я предлагаю использовать вызов функции getMinBufferSize вместо установки магической переменной. Что касается частоты дискретизации, если 44100 не поддерживается, я не знаю, как проверить поддерживаемые частоты. В документации для AudioRecord говорится, что примерами скоростей являются (но не ограничиваются ими) 44100, 22050 и 11025. - person Marc; 30.12.2010