人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

ClipでWAVE再生

Java Sound APIを使ってWAVEファイルを再生する方法です。ここでは、Clipというクラスを使ってみます。ゲームで使う短い効果音なんかはClipで十分です。

wave_engine.jar

WAVEファイルのロード

あらかじめWAVEファイルの内容をすべてClipに読み込んでおく方法です。AudioClipとほぼ同じように使うことができます。ただAudioClipと違って複数の音を同時再生することができます。オーディオファイルのロードは次の手順で行います。

    public void load(String name, String filename) {
        try {
            // オーディオストリームを開く
            AudioInputStream stream = AudioSystem.getAudioInputStream(
                getClass().getResource(filename));

            // ライン情報を取得
            DataLine.Info info = new DataLine.Info(Clip.class, format);

            // 空のクリップを作成
            Clip clip = (Clip) AudioSystem.getLine(info);
            // クリップのイベントを監視
            clip.addLineListener(this);
            // オーディオストリームをクリップとして開く
            clip.open(stream);
            // クリップを登録
            clipMap.put(name, clip);
            // ストリームを閉じる
            stream.close();
        } catch (UnsupportedAudioFileException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (LineUnavailableException e) {
            e.printStackTrace();
        }
    }

ちょっと面倒くさいです。WAVEファイルのストリームからデータを読み込んでClipに格納した後はストリームを閉じてしまって大丈夫です。あとはClipを使って再生できます。

Clipの再生

再生は簡単です。

    clip.start();

Clipの終了検知

Clipは一度再生してしまうともう一度start()しても鳴りません。内部で再生位置を保存しているためです。そのため、再生し終わったら再生位置をClipの最初に戻してやる必要があります。先ほどClipにロードする際にaddLineListener()しました。LineListenerを登録するとClipに関するイベントが起きたときにupdate()が呼び出されます。以下はイベントタイプがLineEvent.Type.STOP(再生停止 or 終了)のときにifブロックが実行されます。Clipを停止して、setFramePosition(0)で再生位置を最初に戻しています。こうしておけば再びstart()で再生したときに最初から再生されます。

    public void update(LineEvent event) {
        // ストップか最後まで再生された場合
        if (event.getType() == LineEvent.Type.STOP) {
            Clip clip = (Clip) event.getSource();
            clip.stop();
            clip.setFramePosition(0); // 再生位置を最初に戻す
        }
    }