了解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

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行上:Line是麦克风和//从数据线的输入缓冲区读取音频数据。 换句话说,来自麦克风的字节被定位或存储在字节buffer

在第81行上:

      out.write(buffer, 0, count);

out是一个ByteArrayOutputStream对象..

Java IO API的ByteArrayOutputStream类允许您捕获写入数组流中的数据。 将数据写入ByteArrayOutputStream,完成后,调用ByteArrayOutputStream的方法toByteArray()获取字节数组中的所有写入数据。 数据写入时缓冲区会自动增长。

用我的话来说: ByteArrayOutputStream将会从数量上定义的缓冲区中获取字节count

另一方面:

playAudio()方法中。

我可以看到第一行(完整代码的第101行)所有字节都被占用了!

byte audio[] = out.toByteArray();

https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html#toByteArray()

创建一个新分配的字节数组。 其大小是此输出流的当前大小,并且缓冲区的有效内容已被复制到其中。

现在在线(102和103)

InputStream input = 
    new ByteArrayInputStream(audio);

在行(105到107)上,字节通过:

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

专注于while循环和近线

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是:

我如何实现中继器(从麦克风捕捉声音并在扬声器上播放,无限次,1或2小时)?

注意:不用担心存储器中存储的问题字节(不存储在文件中),而无需播放延迟。


我不熟悉Sound API。

但是,没有什么特别的理由说明为什么你的最后一段代码片段不能工作,假设输入可以被无限地读取,而输出可以无限地馈送。 唯一的问题是一端还是另一端“失速”(这里我缺乏关于Sound API的知识)。

如果输出端由于某种原因而停顿,那么输入端可能会溢出一些内部缓冲区,从而丢失信息。 如果输入停止,这不是一个问题。 我不知道这是否是Sound API的实际问题。 相比之下,如果有两个线程在发生(或使用Async I / O),一个管理输入和一个管理输出,输入端将为您的程序提供使用语义缓存传入数据的机会,而不是API语义,而输出通道停滞。

ByteArrayStreams的问题仅仅是填充机制和每个扩展的字节数组,而不需要自己管理它,并且类似地,将流语义添加到底层字节数组(具有各种有用功能)。

链接地址: http://www.djcxy.com/p/72777.html

上一篇: Java Understanding ByteArrayOutputStream and ByteArrayInputStream

下一篇: Using a byte array to create an AudioInputStream