Java Понимание ByteArrayOutputStream и ByteArrayInputStream

Я читал эту статью: http://www.java-tips.org/java-se-tips-100019/120-javax-sound/917-capturing-audio-with-java-sound-api.html Я не знаю не хочу писать весь код до статьи...

Мне нужно уточнить мое понимание, и мне нужно объяснение об использовании ByteArrayInputStream и ByteArrayOutputStream...

На основании полного кода:

В методе captureAudio(), фокусирующемся на цикле

while (running) {
  int count = line.read(buffer, 0, buffer.length);
    if (count > 0) {
      out.write(buffer, 0, count);
    }
}
out.close();

По определению (проверьте строки 64 и 65):

final TargetDataLine line = (TargetDataLine)
    AudioSystem.getLine(info);

в строке 79: строка является микрофоном и // считывает аудиоданные из входного буфера строки данных. Другими словами, байты, поступающие с микрофона, находятся или хранятся в байтах. buffer,

По строке 81:

      out.write(buffer, 0, count);

out является объектом ByteArrayOutputStream..

Класс ByteArrayOutputStream API Java IO позволяет вам захватывать данные, записанные в поток в массиве. Вы записываете свои данные в ByteArrayOutputStream, а когда закончите, вызываете метод ByteArrayOutputStream для toByteArray(), чтобы получить все записанные данные в байтовом массиве. Буфер автоматически увеличивается при записи данных в него.

По моим словам: ByteArrayOutputStream будет расти, принимая байты из буфера, определенного в количестве count

На другой стороне:

В методе playAudio().

Я вижу, что в первой строке (строка 101 полного кода) взяты все байты!!!

byte audio[] = out.toByteArray();

https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html

Создает вновь выделенный байтовый массив. Его размер является текущим размером этого выходного потока, и в него было скопировано допустимое содержимое буфера.

Теперь в строках (102 и 103)

InputStream input = 
    new ByteArrayInputStream(audio);

В строках (105 до 107) байты передаются через:

  final AudioInputStream ais = 
    new AudioInputStream(input, format, 
    audio.length / format.getFrameSize());

фокусировка во время цикла и вблизи линий

int count;
while ((count = ais.read(
  buffer, 0, buffer.length)) != -1) {
    if (count > 0) {
      line.write(buffer, 0, count);
    }
  }
line.drain();
line.close();

Байты взяты из ais

И линия (линии 110 и 111) представляет ораторов

  final SourceDataLine line = (SourceDataLine)
    AudioSystem.getLine(info);

Вопрос 1:

outиз метода captureAudio будет принимать байты бесконечно, но как input, из метода playAudio, берет именно байты, необходимые для их последовательного звучания?

Помните: out.toByteArray(); взять все байты, но динамики не звучат многократно одинаковые байты...

Вопрос 2:

Могу ли я обработать эту ситуацию для чтения из микрофона (TargetDataLine) и записи в динамик (SourceDataLine), не используя эти два объекта (ByteArrayOutputStream и ByteArrayInputStream), как связанную статью?

Как следующий код:

while (running) {
  int count = microphone.read(buffer, 0, buffer.length);
    if (count > 0) {
      speaker.write(buffer, 0, count);
    }
}
speaker.drain();
speaker.close();

Вопрос 3:

Как я могу реализовать Repeater (захватывать звук с микрофона и проигрывать его на динамиках, бесконечно, 1 или 2 часа)?

Примечание: не беспокоясь о проблемах хранения байтов в памяти (без сохранения в файле) без задержек воспроизведения.

1 ответ

Я не знаком с Sound API.

Но нет особой причины, по которой ваш последний фрагмент кода не должен работать, если предположить, что ввод можно бесконечно читать, а вывод - бесконечно. Единственная проблема заключается в том, останавливается ли один конец или другой (здесь мой недостаток в знании Sound API вступает в игру).

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

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

Другие вопросы по тегам