33:音を鳴らす(実践編)

◆PROCESSINGで始めるゲーム作りとコンピュータ

Thunder 33:音を鳴らす(実践編)

今日の話題

 

22:音楽ファイルを読み込む

前回はPROCESSINGで利用可能な音楽演奏用のライブラリである minim をアドオンしました。

今回はいよいよ音を鳴らしてみたいと思います。

音を鳴らすためには、まずは用意した音楽ファイルを minim に読み込ませなければなりません。音楽ファイルを読み込ませるには、Minimクラスが持っている loadFile() 命令を利用します。

loadFile():音楽ファイルを読み込む

●種類
minimの命令(Minimクラス)

●代表書式
AudioPlayer   mini  =  loadFile(  String filename  ) ;

●引数
filename  : 音楽ファイルのパス

●戻り値
AudioPlayer型のインスタンス変数

●使用例
AudioPlayer   mini  =  loadFile( “hoge.mp3” ) ;  //hoge.mp3 を読み込む

.

音楽ファイルは、前回の記事で紹介したSHWフリー音楽素材 様提供の wen-kamuy2.mp3 です。

SHW様のサイト以外から音楽ファイルをダウンロードされた方は、上記プログラムの「wen-kamuy2.mp3」の部分をあなたがダウンロードしたファイル名に置き換えてください。

音楽ファイルもリソースファイルの一種となりますので、ダウンロードしたファイルは data フォルダ配下に置いてあることが前提となります。

リソースファイル?、dataフォルダ?と思われた方は「26:画像を表示する」記事を参照して下さい。

音楽ファイルの読み込みに関しては、2つほど注意があります。

1つ目の注意

まず1つ目ですが、音楽ファイルの読み込みに失敗するとコンソール領域に「java.io.FileNotFoundException
エラーが表示されます。

minimloaderror
残念ながらこのエラーメッセージが表示された方は

  • 音楽ファイルの名前が間違えていないか
  • dataフォルダ配下に置いてあるか

を再度確認してみて下さい。

また minim がサポートしていない音楽ファイルを読み込ませると
javax.sound.sampled.UnsupportedAudioFileException
エラーが表示されます。

この場合は、音楽ファイルが mp3、wav、aif  の何れかの形式である事を確認してください。

2つ目の注意

読み込ませる音楽ファイルによっては、ファイルの読み込みに成功した場合でも、コンソール領域に以下のようなメッセージが表示されることがあります※。

minimloaderror3
※「Don’t know the ID3 code  nnnn」の nnnn の部分は上記以外の場合もあります。

これは mp3 形式の音楽ファイルで、minim が扱えないメタ情報が見つかったよという警告メッセージです。

Error と表示されるのでドキっとしますが、この種類のメッセージであればとりあえず無視してもらっても大丈夫です(笑)。

 

23:タグとメタ情報

どうして上記のようなメッセージが表示されるのかを理解するためには、音楽ファイルの構造を知る必要があります。

多くの場合、音楽ファイルは「音」だけの情報を格納しているわけではありません。特に mp3 形式の音楽ファイルではそうです。

え、音以外なにがあるのか・・・ですって?。

みなさんは音楽プレーヤーで、歌手名や曲名、綺麗なアルバムの絵などを表示してくれるものがあるのはご存知ですよね?。アレです(笑)。

musicplayer(画像URL:andronavi  様)

(必ずではありませんが)多くの場合、その音楽は誰が歌っているのか、誰が演奏しているのか、どの会社が提供しているのかなどの情報が、音楽ファイルの中に「音」の情報と一緒に格納されています。

このように、その曲が「どんなものなのかを定義している情報」の事を「メタ情報」と呼びます。そして多くの音楽ファイルでは、メタ情報を「タグ」と呼ばれる部分に格納しています。

musicplayer2(画像URL:illust-AC 様:Designer758さん、kazuki さん)

上記はmp3ファイルの代表的な構造です。

音のデータを挟み込むように、ファイルの先頭と末尾にタグがついています。このタグの中に様々なメタ情報が格納されているのです。

mp3ファイルの場合、タグには旧式と新式があって、そのどちらにもメタ情報が格納可能です。しかし新式のタグの方が柔軟性が高いため、旧式のタグはあまり使われなくなってきています。

タグに格納されるメタ情報には、様々な種類があります。残念ながらminimは、その全てに対応しているわけではありません。(ごく一部のメタ情報にのみ対応しています)

そのためminimが知らないメタ情報がタグに含まれていると、先程のような警告メッセージが表示されるのです。

 

24:音を鳴らす・停める

音楽ファイルの読み込みに成功すると、loadFile() 命令はAudioPlayer型(AudioPlayerクラス)のインスタンス変数を戻してくれます。

以降、このAudioPlayer型の変数を使って曲の演奏や停止を行います。

音を鳴らす

曲を演奏するには、AudioPlayerクラスが持っている play() 命令を使います。

play():演奏する

●種類
minimの命令(AudioPlayerクラス)

●代表書式
void  player. play( )  ;
void  player. play(   int  mills  )  ;

player はAudioPlayer型のインスタンス変数です。

●引数
mills : 演奏開始位置(ミリセカンド)

●戻り値
なし

●使用例
player . play( ) ;  //音楽を演奏する

.
引数を与えないでplay() 命令を実行すると、前回演奏した最後の位置から終端までの演奏を行い、自動的に停止します。

最初の1回目の演奏では、前回演奏した最後の位置はありませんから(笑)、必然的に音楽ファイルの先頭から演奏される事になります。

引数にint型の値を与えると、int型で指定したポジションから演奏を行います。例えば6秒間(6000ms)の再生時間がある音楽ファイルに対して5000を指定すると、最後の1秒部分だけが演奏されることになります。

playindex(画像URL:illust-AC 様:mono777 さん)

以下は、読み込んだ曲を演奏するサンプルプログラムです。

押されたキーの内容を判定し、大文字のSか 小文字のs なら演奏を開始します。

PROCESSINGは押されたキーの内容(文字)を key という特別な変数に覚えています。忘れちゃった方は「29:キーボードの入力を処理する」記事を参照してみてくださいね。

上記のプログラムは押されたキーの内容(key)をもとに、どのキーが押されたかを判定して演奏するか否かを決めています。

注意として、play()命令で演奏が最後までいって自動停止すると、もう一度 play() 命令を発行しても「音が鳴らない」事です。

えーーどうして・・・と思いますよね?。

実は、play() 命令は「曲をどこまで演奏したか」という位置情報を覚えているのです。

playindex2(画像URL:illust-AC 様:mono777 さん、わいるどべあさん)

曲が最後まで演奏されて停止すると、この「曲を演奏した位置」は曲の最後になります。だから、そのままの状態で再度 play() 命令を発行しても、音が鳴らない(これ以上うしろに音のデータがない)状態になるのです。

曲の最後(あるいは途中)まで演奏されたデータを、もう一度最初から演奏したい場合は、後述する cue() 命令を使って曲の演奏位置を先頭に戻すか、
play( 0 ) ;
のように指定して 0 秒の位置(つまり曲の最初)から演奏するように指定する必要があります。

先程のサンプルで play() 命令を発行している箇所を上記のように変更すると、Sキーが押される度に曲の先頭から演奏するようになります。

音を停止する

さて、みなさんは無事に曲が演奏されたでしょうか?。

音が鳴ったら、こんどは止めたくなりますよね?(笑)。演奏を停止するには、3種類の方法があります。

一時停止(いわゆるポーズ)

曲の途中で再生を一時的に停止するには、AudioPlayerクラスの pause() 命令を利用します。

ポーズした場所から曲の演奏を再開するには、引数なしの play() 命令を実行すればOKです。

pause():一時停止する

●種類
minimの命令(AudioPlayerクラス)

●代表書式
void  player. pause( )  ;

player はAudioPlayer型のインスタンス変数です。

●引数
なし

●戻り値
なし

●使用例
player . pause() ;  //演奏を一時停止する

.

完全停止

読み込んだ曲の演奏を完全に停止するには、AudioPlayerクラスの close() 命令を利用します。close() すると直ちに曲の演奏が停止します。

ただし、一度 close() した音楽データは再度 play() 命令を発行しても2度と演奏する事ができません。もう一度演奏するには、Minimクラスの loadFile() 命令を使って音楽ファイルを読み直す必要があります。

close() 命令はAudioPlayerクラスのインスタンス変数(例では player変数)の利用を停止するものだと考えてください。

close():演奏を完全に停止する

●種類
minimの命令(AudioPlayerクラス)

●代表書式
void  player. close( )  ;

player はAudioPlayer型のインスタンス変数です。

●引数
なし

●戻り値
なし

●使用例
player . close() ;  //演奏を完全に停止する

.

曲の演奏位置を最後にする

どこを演奏しているのかという位置を、強制的に曲の最後にしてしまいます。こうすると否が応でも音の演奏は停止します(笑)。

AudioPlayerクラスの cue() 命令を利用すると、曲の演奏位置を変更できます。

cue() 命令には、曲の演奏位置をミリセカンド単位で与えます。演奏時間が全部で6秒間(6000ミリセカンド)ある曲の最後に位置づけたいなら
player . cue ( 6000 ) ;
のようにします。

playindex3(画像URL:illust-AC 様:mono777 さん、わいるどべあさん)

cue():演奏位置を変更する

●種類
minimの命令(AudioPlayerクラス)

●代表書式
void  player. cue( int mills )  ;

player はAudioPlayer型のインスタンス変数です。

●引数
mills : 演奏位置(ミリセカンド)

●戻り値
なし

●使用例
player . mills ( 0 ) ;  //演奏位置を先頭にする

.

曲の最後に位置づけるためには、その曲の長さ(総演奏時間)を知る必要がありますよね。

曲の総演奏時間は、AudioPlayerクラスの length() 命令で知ることができます。

playindex4(画像URL:illust-AC 様:mono777 さん、まつけんお母さんさん)

length():曲の総演奏時間を知る

●種類
minimの命令(AudioPlayerクラス)

●代表書式
int len = player. length( )  ;

player はAudioPlayer型のインスタンス変数です。

●引数
なし

●戻り値
len : 曲のトータル演奏時間(ミリセカンド)

●使用例
int len = player . length( ) ;  //総演奏時間を知る

.

上記のプログラムでは、これまで解説した様々な命令を使って曲のコントロールを行っています。

ここで紹介した機能以外にも、minim には様々な命令や機能があります。より具体的な利用方法については、今後ゲームを作りながら解説していきたいと思います。

 

Forest今日の言葉

・メタ情報

定義情報の事です。音楽ファイルなら曲名やアルバム名など、その曲がどんなものなのかを説明するための情報になります。

・タグ

mp3形式の音楽ファイルには、メタ情報を格納するためのタグが付いています。mp3形式ではない音楽ファイルでも、様々なタグを用いてメタ情報を管理しています。音楽ファイルのタグを編集する専門のエディタ(タグ・エディタ)と呼ばれるアプリケーションもあります。

 

scroll今日の文法

・loadFile() 命令

音楽ファイルを読み込みます。

・play() 命令

演奏を開始(あるいは再開)します。

・pause() 命令

演奏を一時停止します。停止した場所から再度演奏するには play() 命令を利用します。

・cue() 命令

演奏位置を変更します。

・close() 命令

演奏を完全に停止します。close() した音楽ファイルは再度 loadFile()するまで演奏することができません。

・length() 命令

演奏時間を取得します。

 

 今日のまとめ

  • 音楽ファイルにはメタ情報を管理するタグが付いている
  • loadFile()命令で音楽ファイルを読み込む
  • ファイルを読み込むと、曲の制御につかえる AudioPlayerクラスの変数が得られる
  • play() 命令は曲の再生位置を覚えている

34:さぁ、ゲームを作ろう!へ進む
32:音を鳴らす(準備編) に戻る
目次へ戻る


本ページで利用している特に参照元記載のないアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。