проблема метода чтения в классе AudioRecord - PullRequest
5 голосов
/ 31 декабря 2010

public int read (byte [] audioData, int offsetInBytes, int sizeInBytes).

Этот метод считывает аудиоданные с аудиооборудования для записи в буфер.

Его параметры: audioData - массив, в который записываются записанные аудиоданные. Индекс offsetInBytes в audioData, из которого записываются данные, выражается в байтах. sizeInBytes - количество запрошенных байтов.

Возвращается число прочитанных байтов или либо ERROR_INVALID_OPERATION, если объект не был должным образом инициализирован, либо ERROR_BAD_VALUE, если параметры не разрешаются в допустимые данные и индексы. Количество байтов не будет превышать sizeInBytes.

Я написал этот метод в своем коде так: int num; byte [] buf = новый байт [160]; num = record.read (buf, 0, 160);

Проблема в том, что он всегда возвращает 160 (т. Е. Запрошенный байт для чтения) не менее 160, даже если данные недоступны. в чем проблема? Помоги мне. Заранее спасибо.

Ответы [ 2 ]

13 голосов
/ 03 апреля 2013

ОБНОВЛЕНИЕ: эта ошибка в Android была исправлена ​​где-то после 4.2.2 и до 5.01. На 5.01 обратные вызовы работают точно так же, как в документах говорится, что они должны.

Похоже, read блокируется из-за некоторой близорукости разработчиков.

По сути, когда инициализируется аудиорегистратор, он выделяет своего рода кольцевой буфер, а когда ему сообщается .start(), он начинает запись в этот буфер.

Затем, когда вызывается .read(), он считывает до половины размера буфера (или запрошенного размера, в зависимости от того, что меньше) и возвращает.

Если он хочет прочитать 1000 образцов, а доступно только 900, он должен подождать еще 100 образцов, прежде чем вернуться. Однако, если имеется более 1000 сэмплов, он считывает их мгновенно, а затем сразу возвращает.

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

Я не думаю, что они поддерживают первое. Похоже, они пытаются поддержать второе с помощью метода обратного вызова set period, но пока я не могу получить этот обратный вызов в нужное время, чтобы выполнить быстрое неблокирующее чтение.

Я клонировал полный исходный код (8,5 Гбайт) исходного исходного кода C ++, и я пытаюсь проследить функциональность на всех уровнях, чтобы увидеть, как он должен работать.

Хитрость для неблокирования .read(0) заключается в том, чтобы читать только тогда, когда готово полное чтение образцов. Но определить, когда это условие истинно, я еще не понял.

Список литературы: Вот код Java для .read (), который вызывает встроенную функцию C ++:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.4_r1/android/media/AudioRecord.java#AudioRecord.read%28java.nio.ByteBuffer%2Cint%29

Приведенный выше метод read () вызывает нативный native_read_in_direct_buffer(), который находится в:

http://pdroid.googlecode.com/svn/android-2.3.4_r1/trunk/frameworks/base/core/jni/android_media_AudioRecord.cpp

, который вызывает или указывает на android_media_AudioRecord_readInByteArray(), который, в свою очередь, вызывает AudioRecord.read() в frameworks/base/media/libmedia/frameworks/base/media/libmedia/AudioRecord.cpp (насколько я могу судить), и похоже, что в этой функции есть цикл do / while, который по существу блокирует до нужного числа считанных байтов (или половина размера буфера, в зависимости от того, что меньше.)

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

Моя следующая цель - попытаться отследить исходный код обратного вызова notify, чтобы я мог точно догадаться, что и когда он должен делать.

8 голосов
/ 01 января 2011

read - это метод блокировки. Он вернется только после того, как прочитал столько байтов, сколько вы сказали ему прочитать, или если поток закрыт или если поток указывает, что больше нет доступных данных (например, при чтении файла).

AudioRecord представляет собой непрерывный поток, случай «больше нет доступных данных» никогда не применяется.

...