我读过这篇文章: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对象。
Java的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());在时间环和近线中聚焦
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是:
来自captureAudio方法的out将无限地占用字节,但是来自playAudio方法的input是如何准确地获得一致发音所需的字节的呢?
记住: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个小时)?
注意:不用担心存储问题,内存中的字节(不存储在文件中),没有回放延迟。
发布于 2016-02-20 22:11:50
我不熟悉声音API。
但是,假设输入可以无休止地读取,而输出可以无休止地提供,您的最后一个代码段不应该工作,这没有什么特别的原因。唯一的问题是,到底是一端还是另一端“停滞”(这里,我对声音API缺乏了解来玩)。
如果输出端因某种原因中断,则输入端可能会溢出一些内部缓冲区,从而丢失信息。如果输入停止,那就不是什么问题了。我不知道这是否是声音API的一个实际问题。相反,如果出现两个线程(或使用异步I/O),一个线程管理输入,另一个线程管理输出,则输入端将使程序有机会使用您的语义而不是API语义来缓存传入的数据,而输出通道则处于停滞状态。
ByteArrayStreams的问题仅仅是填充和每个扩展字节数组的机制,而不是自己管理它,并且,类似地,将流语义添加到底层字节数组(它具有各种有用的功能)。
https://stackoverflow.com/questions/35518494
复制相似问题