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