2013-04-11 105 views
0

我正在做一個Java的DAW,實際上它比它更基本,我用我曾經擁有的舊Tascam 4軌錄音機來模擬它。我試圖在錄音時監視音頻,儘可能減少兩者之間的延遲(延遲)。如果我在同一個線程中寫入音頻字節,我正在讀取它們的延遲時間很長(如果您想查看我擁有的代碼,我會發布它,但由於我認爲它需要重寫,因此似乎無關緊要) 。我一直在想的是使用生產者,消費者線程和隊列來在其間存儲字節塊。所以我的生產者線程將從TargetDataLine中讀取字節並將它們存儲在隊列中,可能使用返回讀取的字節數的方法,以便在while循環中檢查EOF。並創建一個併發線程,它將隊列中存儲的字節塊(當它們是要寫入的字節時)並將它們寫入SourceDataLine。我的想法是同時運行的兩個線程幾乎可以在讀取字節的同時寫入字節,或者至少比現在更好,但我想知道其他人如何解決這個問題。java生產者消費者線程監控音頻

此外,我需要確保我的使用者線程等待隊列中是否有字節,並在添加字節時再通知再次開始寫入字節,如果有人會發布正確方法的示例來同步兩個線程,我將不勝感激。我知道他們必須在同步代碼塊中,我應該使用多個鎖嗎?我不是要求一個特定於音頻的例子,而只是一個通用的例子,它增加了一些東西,然後刪除它,任何幫助表示讚賞。謝謝。

回答

1

你可以(和probbaly應該)爲生產者 - 消費者實現使用單個鎖對象。像

public final static Object LOCK = new Object(); 

然後在農產品()方法,你就會有這樣的代碼:

synchronized(LOCK) { 
    //place stuff in queue 
    LOCK.notifyAll(); //wake up any sleepers 
} 

,並在你的消費()方法,你將有另一面:

synchronized(LOCK) { 
    if (anything in queue) { 
     return something 
    } 
    //queue is empty - wait 
    while (nothing in queue) { //while bit is important - we might wakeup for no reason or someone else might grab everything leaving us with nothing 
     try { 
     Lock.wait(); 
     } catch (InterruptedException ex) { 
     //99% of java code ignores these spurious wakeups, and they also hardly ever really happen 
     } 
    } 
} 

但這是老派。更現代的Java版本有整齊地包裝所有這些低級伏都教的類。例如ArrayBlockingQueue。你可以定義一個「全局」靜態隊列,然後分別爲你生成()和使用()實現使用offer()和take()。

但是,如果您真的關心延遲,我會多花一分錢,並使用精確寫入低延遲線程間通信的庫。這樣的庫的一個很好的例子是the disruptor,它比ArrayBlockingQueue聲稱更好的延遲。

+0

我喜歡干擾鏈接 – 2013-04-11 05:33:18