Spec-Zone .ru
спецификации, руководства, описания, API
|
Получение обращается к процессу получения сигнала снаружи компьютера. Общее применение аудио получения записывает, такие как запись ввода микрофона к звуковому файлу. Однако, получение не синонимично с записью, потому что запись подразумевает, что приложение всегда сохраняет звуковые данные, это входит. Приложение, которое получает аудио, не обязательно хранит аудио. Вместо этого это могло бы сделать что-то с данными, поскольку это входит — те, которые записывают речь в текст — но тогда отбрасывают каждый буфер аудио, как только это заканчивается с тем буфером.
Как обсуждено в Кратком обзоре Выбранного Пакета, типичная система аудиовхода в реализации API Звука Java состоит из:
Обычно, только один входной порт может быть открытым за один раз, но микшер аудиовхода, который смешивает аудио от многократных портов, также возможен. Другой сценарий состоит из микшера, который не имеет никаких портов, но вместо этого получает его аудиовход по сети.
TargetDataLine
интерфейс был представлен кратко под Иерархией Линейного интерфейса. TargetDataLine
непосредственно походит SourceDataLine
интерфейс, который был обсужден экстенсивно в Воспроизведении Аудио. Вспомните что SourceDataLine
интерфейс состоит из:
write
метод, чтобы отправить аудио микшеруavailable
метод, чтобы определить, сколько данных может быть записано буферу без блокирования Точно так же TargetDataLine
состоит из:
read
метод, чтобы получить аудио от микшераavailable
метод, чтобы определить, сколько данных может быть считано из буфера без блокированияПроцесс получения целевой строки данных был описан в Доступе к Ресурсам Аудиосистемы, но мы повторяем это здесь для удобства:
TargetDataLine line; DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); // format is an AudioFormat object if (!AudioSystem.isLineSupported(info)) { // Handle the error ... } // Obtain and open the line. try { line = (TargetDataLine) AudioSystem.getLine(info); line.open(format); } catch (LineUnavailableException ex) { // Handle the error ... }
Вы могли вместо этого вызвать Mixer's
getLine
метод, а не AudioSystem's
.
Как показано в этом примере, как только Вы получили целевую строку данных, Вы резервируете ее для использования своего приложения, вызывая SourceDataLine
метод open
, точно, как был описан в случае строки исходных данных в Воспроизведении Аудио. Версия единственного параметра open
метод заставляет буфер строки иметь размер значения по умолчанию. Можно вместо этого установить размер буфера согласно потребностям своего приложения, вызывая версию с двумя параметрами:
void open(AudioFormat format, int bufferSize)
Как только строка открыта, это готово начать получать данные, но это еще не активно. Чтобы фактически начать аудио получение, используйте DataLine
метод start
. Это начинает поставлять входные аудиоданные буферу строки для Вашего приложения, чтобы читать. Ваше приложение должно вызвать, запускаются только, когда это готово начать читать из строки; иначе большая обработка тратится впустую на заполнение накопительного буфера, только чтобы иметь это переполнение (то есть, данные отбрасывания).
Чтобы начать получать данные от буфера, вызвать TargetDataLine's
метод чтения:
int read(byte[] b, int offset, int length)
Этот метод пытается читать length
байты данных в массив b
, запуск в позиции байта offset
в массиве. Метод возвращает число байтов фактически чтение.
Как с SourceDataLine's write
метод, можно запросить больше данных чем, фактически помещается в буфер, потому что блоки метода до требуемого объема данных были поставлены, даже если Вы запрашиваете ценность многих буферов данных.
Чтобы избежать иметь Ваше приложение зависают во время записи, можно вызвать метод чтения в пределах цикла, пока Вы не получили весь аудиовход, как в этом примере:
// Assume that the TargetDataLine, line, has already // been obtained and opened. ByteArrayOutputStream out = new ByteArrayOutputStream(); int numBytesRead; byte[] data = new byte[line.getBufferSize() / 5]; // Begin audio capture. line.start(); // Here, stopped is a global boolean set by another thread. while (!stopped) { // Read the next chunk of data from the TargetDataLine. numBytesRead = line.read(data, 0, data.length); // Save this chunk of data. out.write(data, 0, numBytesRead); }
Заметьте, что в этом примере, размер байтового массива, в который читаются данные, устанавливается быть одной пятой размер буфера строки. Если Вы вместо этого делаете это столь же большим как буфер строки и попытка считать весь буфер, Вы должны быть очень точными в своей синхронизации, потому что данные будут выведены, если микшер должен поставить данные строке, в то время как Вы читаете из этого. При использовании некоторой части размера буфера строки, как показано здесь, Ваше приложение будет более успешным в совместном использовании доступа к буферу строки с микшером.
read
метод TargetDataLine
берет три параметра: байтовый массив, смещение в массив, и число байтов входных данных, которые требуется считать. В этом примере третьим параметром является просто длина Вашего байтового массива. read
метод возвращает число байтов, которые были фактически считаны в Ваш массив.
Как правило, Вы читаете данные из строки в цикле, как в этом примере. В пределах while
цикл, каждый блок полученных данных обрабатывается любым способом, является подходящим для applicationâ здесь, это пишется a ByteArrayOutputStream
. Не показанный здесь использование отдельного потока, чтобы установить булево stopped
, который завершает цикл. Значение этой булевской переменной могло бы быть установлено в true
когда пользователь щелкает по Кнопке остановки, и также когда слушатель получает a CLOSE
или STOP
событие от строки. Слушатель необходим для CLOSE
события и рекомендуемый для STOP
события. Иначе, если строка останавливается так или иначе без остановленного, устанавливаемого в true
, while
цикл получит нулевые байты на каждой итерации, работая быстро и тратя впустую циклы ЦП. Более полный пример кода показал бы цикл, повторно вводимый, если получение становится активным снова.
Как со строкой исходных данных, возможно истощить или сбросить целевую строку данных. Например, если Вы запишете ввод к файлу, то Вы будете, вероятно, хотеть вызвать drain
метод, когда пользователь щелкает по Кнопке остановки. drain
метод заставит остающиеся данные микшера быть поставленными целевому буферу строки данных. Если Вы не истощаете данные, полученный звук, могло бы казаться, был бы усеченным преждевременно в конце.
Могли бы быть некоторые случаи, где Вы вместо этого хотите сбросить данные. В любом случае, если Вы ни не сбросите, ни истощите данные, то это оставят в микшере. Это означает, что, когда получение возобновляет, будет некоторый оставшийся звук в начале новой записи, которая могла бы быть нежелательным. Может быть полезно, тогда, сбросить целевую строку данных прежде, чем перезапустить получение.
Поскольку TargetDataLine
интерфейс расширяется DataLine
, целевые строки данных генерируют события таким же образом, строки исходных данных делают. Можно зарегистрировать объект получить события всякий раз, когда целевая строка данных открывается, завершения, запускается, или остановки. Для получения дополнительной информации см. предыдущее обсуждение Контроля Состояния Строки.
Как некоторые строки исходных данных, у целевых строк данных некоторых микшеров есть средства управления обработки сигналов, такие как усиление, панорамирование, реверберация, или средства управления демонстрационного уровня. Входные порты могли бы иметь подобные средства управления, особенно получить средства управления. В следующем разделе Вы изучите, как определить, есть ли у строки такие средства управления, и как использовать их, если это делает.