2016-02-20 79 views
0

我读这篇文章: http://www.java-tips.org/java-se-tips-100019/120-javax-sound/917-capturing-audio-with-java-sound-api.html 我不想从文章之前写的所有代码...Java的理解ByteArrayOutputStream和ByteArrayInputStream的

我要澄清我的理解,我需要了解的使用说明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:线是麦克风和//读取音频来自数据线输入缓冲区的数据。换句话说,来自麦克风的字节被定位或以字节buffer存储。

在线路81:

 out.write(buffer, 0, count); 

out是一个ByteArrayOutputStream对象..

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

在我的话: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)的字节被传递throught:

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小时)?

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

+1

首先我们需要了解你! - 这是不可理解的 - 也许你最好用西班牙语或其他语言发布它 – gpasch

+0

@gpasch,根据你的文字不清楚? –

回答

0

我不熟悉Sound API。

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

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

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

+0

Thaks我认为ByteArrayOutputStream和ByteArrayInputStream会增长,但两者都需要缩小(一边将引入字节,但另一边将删除它们)。 bytearrayoutputstream将如何减小其大小(或将再次为空)?因为每个'out.write(buffer,0,count);'被调用,bytearrayoutputstream将会增长,并且pass是如何传递的到ByteArrayInputStream?或者'ByteArrayInputStream(audio);'如何精确读取未被使用的最后一个字节? 'out.toByteArray()'这里是所有字节(甚至是最后一个字节的第一个字节) –

相关问题