プログラム講座 初級編7

- AIFFサウンドを再生しよう -

 初級編7です(前回から初級編はだいぶ間隔が開いてしまいました)。今回は今までと異なり「サウンド」を扱います。サウンドと一口に言ってもサンプリングされた声や音楽などを鳴らす、周波数を指定して鳴らす、QuickTIme のオーディオトラックを鳴らす、Quick Time MIDIを鳴らすなど様々です。
 初級編なのでリソースを利用したサウンドを解説しようと思いましたが、リソースを使用したサウンドは後の講座で解説し、今回は(リクエストがあったので)AIFFサウンドを演奏する事にします。


注意:
AIFFには圧縮無しのAIFF、圧縮指定も可能であるAIFCがありますが、ここではどちらも区別なく演奏させる事ができます。ただし、ファイル選択ダイアログに表示されるファイルはAIFFのみになっています。もし両方とも選択できるようにする場合は、ファイルタイプをAIFFAIFCと指定してください。




◆AIFFについて
 サウンドを扱おうとすると一度は耳にするのが、このAIFFです。このAIFFは「Audio Interchange File Format」の略称で、その名のごとくオーディオデータを異機種間でやりとりするものです。元々はIFFの派生(IFFの元はAMIGA。実際はさらに、その元があるのだが)だと思うのですが、まあ規格が決まっていて異機種間でサウンドデータのやりとりが可能だという事です。
 異機種間の音楽データで共通規格化されているものに「MIDI」があります。AIFFはサンプリングサウンドを扱うのに対しMIDIは譜面データを扱います。AIFFは人の声などを簡単に扱えますが、MIDIでは音として定義されていないと(ハードにインプリメントされていないと)鳴らすことが出来ません。MIDIで作成した曲データは数十Kbytesですみますが、AIFFでは数MBytesに及ぶことがあります。




◆Macのサウンド
 MacintoshはX68000, FM TOWNS, PC-9801などと異なりFM音源やPSG音源は搭載していません。基本的に全てサンプリングデータで演奏処理を行っています。ソフトウェアで頑張っているという事になるのですが、そのおかげで多くのサウンドチャンネルを使用する事が出来ます(多分メモリが許す限り、そしてCPUパワーが許す限り)。
 メモリさえあれば複数のサウンドを並行して演奏する事もできます。今回はサウンドを「同期」で演奏させる事にします。というのは「非同期」の場合と比べて楽だからです。単純にファイルのファイル参照番号を指定すれば演奏してくれるからです。それでは、次の項で説明しましょう。



◆AIFFサウンドを再生する
 ファイルのオープンやファイル選択ダイアログの表示や設定については別の講座を参考にしてください。
 ToolBoxにはAIFFサウンドを解析して自動演奏してくれる命令が用意されています。ですから、この命令を呼び出すだけで終わりです。その命令は

FN SNDSTARTFILEPLAY(サウンドチャンネルポインタ, ファイル参照番号, リソース番号,サウンドバッファ, 演奏開始ポインタ, 演奏可能選択範囲, 再生完了ルーチンアドレス, 同期/非同期スイッチ)

 です。順番にパラメーターについて説明します。
サウンドチャンネルポインタですが、これはサウンド再生用のポインタです。非同期の場合は、ちゃんとサウンドチャンネルポインタを確保しなければなりませんが、同期の場合0を指定しておく事によりシステムが自動的に確保し演奏し終わったら破棄してくれます。
 ファイル参照番号はファイルの参照番号です。ファイル参照番号であってボリューム参照番号ではない事に注意してください。これを間違えると頭を抱えてしまう事になります。ファイル参照番号を求める方法は後ほど説明します。
 リソース番号は再生するリソース番号です。この指定からもわかるように従来のサウンドも再生する事はできます。ここで注意しなければいけないのは、リソースとファイル参照番号を同時に指定してはならない、という事です。つまりどちらか指定した場合、残りは0にしなければなりません。
 サウンドバッファはファイルから一回に読み込むバイト数です。これが少ないと演奏に対してファイルの読み込みが追いつかなくなります。マシンパワーが低いと思ったら30Kbytesくらいにしておけば十分です。通常20Kbytesあれば問題なく再生できます。サウンドバッファの容量指定が少ない場合、エラー-205が返ってきてしまい再生されません。再生されなかったら、ここの値を増やしてみて下さい。
 演奏開始ポインタはサウンドデータをどこから再生するかを指定します。実際にやった事がないので不明です。0を指定すれば先頭から再生されます。
 演奏可能選択範囲は再生する範囲を指定します。全て再生させるには0を指定します。
 再生完了ルーチンアドレスは非同期の場合演奏終了時に実行されるルーチンのアドレスを指定します。今回は同期再生の場合、0を指定しておきます。
 同期/非同期スイッチは、同期再生か非同期再生かを指定します。_false(ゼロ)で同期再生、_zTrue(-1)で非同期再生になります。ここで_Trueと指定すると非同期にならずに、同期で演奏されてしまいます。普通は_false, _trueなのに_false, _zTrueというのは、あまり好きではないのですが(-.-b
 まあ、それはさておき実際指定するのはファイル参照番号と同期スイッチだけです。それと演奏されるファイルは「あらかじめオープン」されていなければ駄目です。

 ファイル参照番号を求めるには、ファイルの「パラメーターブロック」から読み出す必要があります。ファイルのパラメーターブロックを読み込むにはいくつか方法がありますが、すでにファイルがオープンされている場合、USR関数で簡単に取得する事ができます。ファイル参照番号はioRefNum%に格納されていますのでパラメーターブロックにioRefNum%を指定すれば求める事ができます。
 これで、できあがりです。何か手頃なAIFFサウンドを演奏させてみてください。なお、演奏中は全くイベントを受け付けませんので再生が終わるまで待っているしかありません。



◆終わりに
 Future BASICのマニュアルと、そのサンプルプログラムは非常によい手本となります。が、_true, _zTrueなど整合性の問題がいくつかあります。今回のプログラムは先にC言語(Code Warrior)で作成したものがあったので、それを元にしたのですが、まさか_true, _zTrueでひっかかたりするとは思いませんでした。同期の場合は良いのですが、実験的に非同期再生もやっていたので、どうして同期再生されてしまうのか悩みました。
 次回は演奏中に他のアプリケーションに移行したり、他の処理ができる非同期演奏について説明します。



◆今回のプログラムリスト
' ' "AIFF サウンドファイルを読み込んで演奏する(同期)" ' DIM soundFilePBPtr& filename$ = FILES$ (_fOpen, "AIFF", , vol%) LONG IF filename$ <> "" OPEN "I", #1, filename$, , vol% soundFilePBPtr& = USR _fileAddr (1) LONG IF soundFilePBPtr& <> 0 osErr% = FN SNDSTARTFILEPLAY (0, soundFilePBPtr&.ioRefNum%, 0, 20000, 0, 0, 0, 0) END IF CLOSE #1 END IF