サイトのトップへ戻る

libGDX ドキュメント 日本語訳

サイト内検索

Audio

率直に言って、LibGDX を使うとaudio は非常に簡単に扱えるので、この項目はこれまでのものより短いです。 前回のチュートリアルと違い、今回は複数のコード例を使って説明をします。 LibGDX は3つのaudio 形式: oggと mp3 と wavをサポートしています。 MP3 は法律上の問題がある形式で、一方WAV は(ファイルサイズが)大きくなる形式で、大抵はOGG が最良の選択肢として残ります。 とは言うものの、幅広いプラットフォーム(特にブラウザ環境)をサポートする場合は、Ogg だと問題が発生します。 もちろん、各形式に得手不得手があるからこそ複数の形式が存在して、それぞれが使われ続けているのです!



効果音を再生する

音声ファイルの読み込みは簡単です 。以前フォント形式や画像形式を読み込んだ時のように、 android プロジェクトフォルダーのassets フォルダーにファイルを追加する必要があります。 以前と同じ様に慣習に倣って、以下のようにdata サブフォルダへ全てのファイルを配置します:

wyabq5gw

ご覧の通り、mp3.mp3, ogg.ogg , wav.wavと各形式のファイルを追加しました。

これらファイルの読み込みは非常に簡単です:

Sound wavSound = Gdx.audio.newSound(Gdx.files.internal("data/wav.wav"));
Sound oggSound = Gdx.audio.newSound(Gdx.files.internal("data/ogg.ogg"));
Sound mp3Sound = Gdx.audio.newSound(Gdx.files.internal("data/mp3.mp3"));

これは指定されたファイル名を使って、 Sound オブジェクトを戻り値として返します。Soundオブジェクトが取得できれば、再生するのは簡単です:

wavSound.play();

また以下のように、playを実行する時に再生音量を設定するオプションもあります。:

oggSound.play(0.5f);

例えば、上記では oggSound オブジェクトを 50% の音量で再生します。

play()に加えて、Soundオブジェクトを連続してループ再生する loop() もあります。 loop()で音声を再生すると、音声を操作するのに使用できるIDが戻り値として返ります。 以下を見てください:

long id = mp3Sound.loop();
Timer.schedule(new Task(){
   @Override
   public void run(){
      mp3Sound.stop(id);
      }
   }, 5.0f);

上記ではmp3のループ再生を開始し、id値が戻り値として返っています。 その後、5秒後に音声の再生を停止するタスクをスケジュール設定しています。 stop()の呼び出し時に、idをどのように渡しているか分かりましたか? このやり方で、特定のsoundインスタンスの音声再生を制御することができます。 同じSound オブジェクトを同時に複数回再生できるため、このような仕様になっています。 注意すべき重要な点は、Sound オブジェクトはマネージドリソースのため、使い終わったらdispose()をするということです。

wavSound.dispose();
oggSound.dispose();
mp3Sound.dispose();

soundを取得したら、それを操作する方法はいくつかあります。ピッチを変更することもできます:

long id = wavSound.play();
wavSound.setPitch(id,0.5f);

一つ目の引数はピッチを変更するsound のIDで、二つ目の値は新たに設定するピッチ(速度)です。 この値には 0.5から 2.0までの値を設定できます。 1以下だと遅くなり、1より大きいと速くなります。

音量の変更もできます:

long id = wavSound.play();
wavSound.setVolume(id,1.0f);

ここでも、soundのIDだけでなく再生時の音量も渡します。 0の値で音が消え、一方で1だとフル音量となります。 同様に、以下のようにしてPan ( ステレオ位置 )を設定できます:

long id = wavSound.play();
wavSound.setPan(id, 1f, 1f);

この場合の引数は、音声ファイルID、pan値(1だと左側出力、0だと中央出力、-1だと右側出力)、音量となります。 また、play()やloop()を呼び出すときにピッチとパンと音量を設定することもできます。 注意すべき重要なことは、これらのメソッドはWebGL/HTML5バックエンドでの動作が保証されていないということです。 さらにブラウザによってサポートされているファイル形式が変わります。 ( これは非常に面倒くさいです! ) .



音楽をストリーミング再生する

効果音の再生に加えて、LibGDX では音楽(もしくは再生時間の長い効果音!)の再生もサポートしています。 大きな違いは、これを使うとLibGDX はエフェクトをストリーミング再生し、必要なメモリがかなり減るということです。 これはMusic クラスを使って行います。幸い、やり方は非常に簡単です:

Music mp3Music = Gdx.audio.newMusic(Gdx.files.internal("data/RideOfTheValkyries.mp3"));
mp3Music.play();

必要なのは音声ファイルをストリーミング再生することだけです。 音楽ファイルの操作方法は少し違ってきます。 第一に、IDがないので一つのMusic ファイルの複数のインスタンスを一度に再生することができます。 第二に、VCR スタイルの制御オプションシリーズがあります。 以下は、実用的なものではありませんがMusic ファイルを再生する例になります:

Music mp3Music = Gdx.audio.newMusic(Gdx.files.internal("data/RideOfTheValkyries.mp3"));
mp3Music.play();
mp3Music.setVolume(1.0f);
mp3Music.pause();
mp3Music.stop();
mp3Music.play();
Gdx.app.log("SONG",Float.toString(mp3Music.getPosition()));

音楽ファイルが読み込まれた後、それを再生してそれから音量を 100%に設定しています。 次に一時停止をして、それから停止し、再び音楽ファイルを再生します。 log()の呼び出しを見ると分かるように、getPosition()を呼び出すことでMusic オブジェクトの現在の再生位置を取得できます。 このメソッドでは、曲が始まってから現在までの経過時間を秒単位で返します。 pause()とstop()は一体何が違うのか分かりますか? pause()を呼び出した後に play()を呼び出すと、現在の再生位置から曲の再生を継続します。 stop()を呼び出した後にplay()を呼び出すと、曲は始めから再生されます。

Soundオブジェクトと同じくMusic オブジェクトもマネージドリソースのため、使い終わったらdispose()をしないとメモリリークが発生します。



PCM 音源の録音と再生

LibGDX にはPCMデータを直に使ってローレベルで動作する機能も持っています。 基本的にこれはshort型(16bit) もしくは float型(32bit)の、再生する波形を構成する値の配列です。 これを使ってプラグラム上で効果音を作成できます。 また、音声をPCM形式で記録することもできます。 以下の例を見てみましょう:

AudioDevice playbackDevice = Gdx.audio.newAudioDevice(44100, true);
AudioRecorder recordingDevice = Gdx.audio.newAudioRecorder(44100, true);
short[] samples = new short[44100 * 10]; // 10 seconds mono audio
recordingDevice.read(samples, 0, samples.length);
playbackDevice.writeSamples(samples, 0, samples.length);
recordingDevice.dispose();
playbackDevice.dispose();

上記の例では AudioDevice と AudioRecorderを作成しています。 それらの作成時には、希望するサンプリングレート( 44.1khz は CD 音源品質 )だけでなくモノラル音声( シングルチャンネル )とステレオ音声 ( 左/右 )のどちらを使うかを表すboolean型の値を引数として渡します。次に音声を録音するための配列を作成します。 今回の例では、44.1khzのサンプリングレートで10秒の音声が必要です。 その後、AudioRecorderオブジェクトのread()メソッドを呼び出して音声を録音します。 書き込むための配列、配列の開始点を表すオフセット値、最後に全体のサンプルの長さを引数として渡します。 それからwriteSamplesを呼び出し、録音した音声を再生します。writeSamplesにはread()メソッドと全く同じ引数を使用します。 AudioDevice と AudioRecorder は両方ともマネージドリソースのため、 disposeを使って破棄する必要があります。

注意すべき非常に重要な点がいくつかあります。 一つ目に、PCM 音源はHTML5では使用できません。二つ目に、ステレオで録音している場合は配列のサイズを2倍にする必要があります。 ステレオ波形の場合、配列内のデータは左チャンネルのデータと右チャンネルのデータが交互に入っているのです。 例えば、配列内にある最初のbyteは左の音声チャンネルの最初のfloat 値、その次のfloat 値は右の音声チャンネルの最初の値、その次のfloat値は左の音声チャンネルの二つ目のfloat値、など。