2010-09-20 139 views
13

我正在研究一個java項目,它使用javax.sound.midi庫從midi硬件接收MIDI事件。在文檔中,它說MidiSystem.getMidiDeviceInfo()返回所有連接的MIDI硬件的列表。它適用於我,但問題是,它只能使用一次。第一次真正掃描設備需要一些時間,但每次之後都會立即返回相同的列表,即使新設備已連接。有沒有辦法強制它重新掃描?它會重新掃描,如果應用程序重新啓動,但我不希望我的用戶必須重新啓動,如果他們連接一個新的MIDI設備。Java聲音API - 掃描MIDI設備

順便說一句,我正在使用Mac OS X ...有人指出,不同的操作系統的行爲可能會有所不同。

+1

我不想問這個問題,但這個問題是在Mac OSX,Linux還是Windows上發生的?我知道Java是一次寫入,隨處運行的,但事實是這些操作系統有完全不同的MIDI系統,並且Java運行時本身可能無法正確地與它接口。 – 2010-09-21 18:52:37

+0

感謝您以Google發現它的方式提問。 – 2015-05-04 18:09:42

回答

7

MidiSystem.getMidiDeviceInfo()獲取完整的提供程序列表,並從每個提供程序中提取設備的信息。

的MIDIS提供商列表是從JDK墊層類com.sun.media.sound.JDK13Services回收,通過靜態方法getProviders()

公共靜態同步列表getProviders(類服務類) 獲得包含所述提供者安裝 實例列表爲 請求的服務。 提供者列表被高速緩存在由cachingPeriod給出的 時間段內。在此期間 期間,同一列表實例爲 返回給同一類型的 提供程序。在這段時間之後,構建並返回一個新的 實例。 返回的列表是不可變的。

所以,這個類似乎把你提供者列表保存在一個緩存中,這將在一段時間後重新加載。您可以使用方法setCachingPeriod(int seconds)將此期間設置爲自定義值。只要我知道,默認的緩存週期設置爲60秒。

舉個例子,刷新該緩存每一秒,你coud此行添加到您的代碼:

com.sun.media.sound.JDK13Services.setCachingPeriod(1); 

請注意,該解決方案利用了太陽propietary類的,所以它不可能是100%便攜。

+1

com.sun.media.sound.JDK13Services.setCachingPeriod(..)似乎已經在1.7_51之間和1.7_67。如果有人發現另一種加速緩存期的方法,我會很有興趣聽到它。 – crig 2014-09-16 21:39:34

+0

1)該代碼仍然編譯並運行'com.sun.media.sound.JDK13Services.setCachingPeriod(1);' 2)在OSX上我很確定它根本沒有幫助 – 2015-05-04 18:19:22

+0

我可以證實這一點* DOES不工作*在OS X 10.5.5上。沒有嘗試過別的。另外,緩存期似乎是不確定的?我等了一整分鐘,但它仍然沒有拿起新設備。 – phreakhead 2015-11-09 01:40:57

-1

這聽起來像是可能是一個OS專用的bug,但我可以想到一個解決。

在java中,你可以運行外部命令到操作系統。 (一個快速谷歌,給了我這個例子http://www.javafaq.nu/java-example-code-186.html它看起來不錯,並給你這個想法)。

在檢查新設備時,您可以發送一個外部命令來運行一個簡單的java程序,該程序可以使用MidiSystem.getMidiDeviceInfo()快速查詢MIDI設備並將結果輸出到文本文件,或者可以從BufferedReader中獲取輸出目的。

另外請記住,用於查詢MIDI設備的外部程序不一定要用Java編寫,因爲Java會導致更多的問題。或者,您可以查詢連接設備的操作系統,並使用grep來過濾結果。

希望這會有所幫助。

+0

我需要java來實際上​​能夠連接到設備。我只能從MidiSystem.getMidiDeviceInfo()的結果連接到它們。 – tybro0103 2010-09-24 18:56:38

+1

如果您使返回的對象可串行化,這仍然是可能的。如果你想繼續調用並使用更多的低級操作系統信息,我會建議你使用別的東西而不是Java,它不是最好的語言。特別是考慮到Mac和Java並不總是相處的。你有沒有在不同的操作系統上試過這個? – binarycreations 2010-09-25 23:12:09

+0

我還沒有嘗試過另一個操作系統。我需要它在OS X和Java上工作。 – tybro0103 2010-09-27 15:28:36

3

缺少我的工作電腦上的任何MIDI設備,或任何種類的Mac,我懷疑我能正確地測試它,但是......

的MidiSystem類似乎用com.sun.media.sound.JDK13Services.getProviders(Class providerClass)找到系統上的設備列表。 API docs for this class表示該列表是在cachingPeriod之外的連續呼叫中重新創建的,可通過調用setCachingPeriod(int seconds)來方便地進行設置。

如果運氣好的話,你可以在應用程序的開始時調用一次,並將其設置爲5秒鐘或者什麼的,它會神奇地工作。但是,文檔還聲明「此方法僅用於測試」,所以我不確定這種方法的效果如何。

希望這足以讓你開始,並在此期間繼續探索,看看我是否能找到一種更乾淨的方式來做到這一點。

+0

+1:我們已經得出非常類似的結論 – 2010-09-29 10:05:46

+0

所以我們在幾乎同一時間:) – Zetten 2010-09-29 10:07:33