簡體   English   中英

筆記本電腦退出休眠狀態后,Java MIDI音頻會延遲

[英]Java MIDI audio is delayed after laptop comes out of hibernation

我正在開發一種音樂編程語言 ,並使用JVM(通過Clojure)來播放用這種語言編寫的樂譜。 到目前為止,我們只是使用javax.sound.midi MidiSynthesizer來播放分數。

由於Clojure啟動時間較慢,我們希望能夠從命令行中獲得分數並立即聽到,我們選擇將分數解釋器構建為后台服務器進程,並使用更輕量級的方式與之通信用Java編寫的命令行客戶端。

所有這一切在大多數情況下都很有效,但是,有一個奇怪的問題,我們看到你在哪里啟動服務器,然后關閉你的筆記本電腦*讓它休眠,然后再打開它讓服務器播放一個得分,音頻不會立即發生,但會延遲幾秒鍾。 使用調試日志記錄運行服務器,我實際上可以看到MIDI音符開/關事件立即發生(並且正確定時),但音頻被延遲。

*這可能是也可能不是特定於平台的。 我在運行OS X 10.9.5 Mavericks的2014 Macbook Pro上看到了這個問題。

為了幫助縮小范圍,我將這個簡單的例子(使用Java,而不是Clojure)放在一起,演示了這個問題:

https://github.com/daveyarwood/java-midi-delayed-audio-example

我已經在這一段時間里摸不着頭腦了。 為什么音頻會延遲,我們能做些什么呢?

這看起來像是Sun的Synthesizer實現中的一個錯誤。

我沒有深入研究,但我發現問題顯然是在包含AudioInputStream Jitter Corrector中。 抖動校正器線程依賴於System.nanoTime() 但是,當計算機從待機或休眠模式喚醒時, nanoTime可能會跳轉。

解決方法是禁用抖動校正器。 您可以通過以下方式打開Synthesizer來執行此操作:

    synth = MidiSystem.getSynthesizer();

    if (synth instanceof com.sun.media.sound.SoftSynthesizer) {
        Map<String, Object> params = Collections.singletonMap("jitter correction", false);
        ((com.sun.media.sound.SoftSynthesizer) synth).open(null, params);
    } else {
       synth.open();
    }

除了@ apangin的解決方案,我還找到了另外兩個解決方法:

  • 在每次播放之前,關閉並重新打開相同的Synthesizer實例。

  • 每次播放都使用新的Synthesizer實例。

這些都不是理想的,因為打開合成器實例需要幾秒鍾(即使它是以前打開的現有實例),但這些解決方法可能足以滿足某些用例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM