2

次のコードを使用して、Java(1.5)アプレットゲームでサウンドを正常に再生しています。

// get an available clip to play it
Clip clip = null;
for (Clip clipTemp : players) {
    if (!clipTemp.isOpen()) {
    clip = clipTemp;
        break;
    }
}
if (clip == null) {
    // no available player found, don't play
    return;
}

clip.open(audioFormat, audioByteData, 0, audioByteData.length);

clip.start();

(プレーヤーは、レイテンシーを減らす目的で最初に開いたクリップのリストです。ラインリスナーは、停止イベントが取得されたときにラインを閉じます。)

私が直面している問題は、サウンドを再生するときに最大1秒の断続的な遅延です。これはかなり貧弱です。

これを改善する方法はありますか?SourceDataLines検討する価値がありますか?

4

2 に答える 2

2

Javaアプレットは、クリップを再生したいときにいつでもクリップをストリーミングします。そのため、サウンドファイルがまだメモリにロードされていないため、遅延が発生します。

Javaアプレットのプログラミングを行ってからしばらく経ちましたが、以前はすべてのクリップをプリロードしていたので、その後の再生呼び出しでファイルが再度開かれなかったことを覚えています。

これが私の古いプロジェクトの1つからのコードです

Clip shoot;

private loadShootWav()
{
    AudioInputStream sample;
    sample = AudioSystem.getAudioInputStream(this.getClass().getResource("shoot.wav"));
    shoot = AudioSystem.getClip();
    shoot.open(sample);
}

public void playShootSFX()
{
    shoot.stop();
    shoot.setFramePosition(0);
    shoot.start(); 
}
于 2010-02-12T01:47:12.177 に答える
0

私があなたのコードを正しく読んでいるなら、あなたは未開封のクリップを見つけて、それを再生する前にそれを開いています。開いたクリップを取得して再起動する方が速いでしょう。playShootSFX()の例のJSmythに示されているように、最初にそれらの位置を停止してリセットする必要がある場合があります。

SourceDataLinesでかなり良い応答が得られています。良い点は、サウンドのすべてのデータがRAMにロードされる(クリップを「開く」たびに発生する)まで待つのではなく、すぐに開始するため、開いていないクリップよりも速く開始することです。

しかし、はい、頻繁に再生される小さなサウンドがたくさんある場合は、クリッププールが最適です。それらをオーバーラップさせたい場合、または常に最後まで再生したい場合は、複数のコピーが必要です。そうでない場合は、停止し、0にリセットして、再起動します。しかし、再開し続けないでください!その場合は、SourceDataLineを使用することをお勧めします。

于 2011-08-20T05:23:08.450 に答える