Вопрос

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

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

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 и HTC Magic идеально без каких-либо предупреждений / ошибок входа, но вызывает проблемы на эмуляторах и устройстве Nexus One.

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

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

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

РЕДАКТИРОВАТЬ

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

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 и все эмуляторы теперь работают (даже если некоторые более отстают, чем другие).

Я делаю что-то ужасно не так?

Это было полезно?

Решение

Я решил это!

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

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

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

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

Если честно, код Splmeter даже не должен работать на устройствах HTC. Я думаю, именно поэтому мое устройство Dev названо HTC Magic = P

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top