2016-02-20 28 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()'這裏是所有字節(甚至是最後一個字節的第一個字節) –

相關問題