Java で適切で信頼性の高いデジタル サンプリング サウンドを再生するための良いレシピはありますか?
私のリクエストのリストはかなり短いです:
- デジタル化されたサンプルを .wav ファイルなどからメモリにロードします (たとえば、jar にバンドルされたリソースから)。
- ノンブロッキングでプレイする
- 複数のサンプルを同時に再生し、それらが時間的に交差する場合、適切にミックスされるはずです
次のものがあるといいのですが、実際にはそれがなくても生活できます。
- .ogg または同様の圧縮形式からの再生 (明らかに、Java で CPU を大量に消費するデコーダーを実装する必要はありません)
- 再生中に同じサンプルを再度再生しても、特定のサンプルの前の再生を停止するべきではありませんが、2 番目のコピーが開始され、最初のコピーと適切にミックスされる必要があります。
悪名高いJava Sound APIを試してみましたが、まったく信頼性が低く、最小限の希望リストさえ満たすことができないようです。私が得る問題:
ALSA dmix (OpenJDK 6) を使用する Linux では、Java Sound API の初期化中に他のアプリケーションでオーディオを使用すると、Java アプリからのすべてのサウンドがエラーや警告なしで消えます。
Linux (OpenJDK 6) では、 を一覧表示し、それらのいずれかを使用し
MixerInfo
てオブジェクトを取得しようとすると、wav ファイルをロードしようとすると、次の例外がスローされます。Clip
java.lang.IllegalArgumentException: Line unsupported: interface Clip supporting format PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
したがって、
AudioSystem.getClip(anySortOfMixer)
まったく機能していないようです。のみAudioSystem.getClip()
動作します。を使用してサンプルレート/ビット/フォーマットが異なるファイルをロードすると、 で
Clip
失敗しLineUnavailableException
ます。を最初に呼び出すと、clip.open
サウンド システムが特定のサウンド オプションに設定され、次にわずかに異なるサンプル レートでファイルをロードするように見えます (たとえば、最初は 44100、2 番目は 48000)。Linux (OpenJDK 6) では、いくつか
Clip
の異なる を初期化してそれらを再生しようとすると、最後にロードされたものだけがClip
聞こえるようになります - エラー/警告は表示されませんがplay
、最後にClip
ロードされたものを使用するだけでまったく音が出ません - 他のすべては無音です:Clip loadSound(String name) { URL url = this.getClass().getResource("/" + name + ".wav"); Clip clip = AudioSystem.getClip(); AudioInputStream ais = AudioSystem.getAudioInputStream(url); clip.open(ais); return clip; } void playSound(Clip) { if (clip.isRunning()) clip.stop(); clip.setFramePosition(0); clip.start(); } ... Clip c1 = loadSound("foo"); Clip c2 = loadSound("bar"); ... playSound(c1); // silence ... playSound(c2); // audible
Windows でこのコードを使用すると、すべて問題ありません。すべてのクリップが聞こえ、再生され、適切にミックスされます。Macではテストしていません。
サポートされているファイル形式 (で分析
AudioSystem.getAudioFileTypes
) は、Linux/OpenJDK6 と Windows/Oracle JDK 7 の両方で wav / au / aif を返すため、oggs や mp3 さえありません:(Clip
2 番目のコピーを別々の としてロードせずに、同じサウンドの 2 つのコピーを同時に作成する簡単な方法はないようですClip
。
それで、問題は - このすべてのものを修正して信頼性を高めるための良い解決策/回避策はありますか? 他のサウンド システム ( LWJGL OpenALやpaulscode.com サウンド システムなど) に切り替えると効果がありますか? または、Java Sound API をいくつかのセーフ ガードでラップすることは可能で、適切に動作しますか?
上記のすべてをテストする小さなアプリケーションを作成しましたが、少し長いのでgistとして公開しようと思いましたが、残念ながら、現在 GitHub でいくつかのネットワークの問題が発生しています。ということで、もう少ししたら公開します。