サウンドサンプルについて

                                         1998年9月17日
                                         (株)セガ・エンタープライゼス
                                             テクニカルサポートセンター

※注意
  サウンドドライバおよび(ツールで吐き出した)データが古い場合、
  今回提供したライブラリでは音が鳴らない可能性があります。
  このライブラリセットを利用する場合、最低でも、ドライバの1.00以降
  ツールは、
    Sound Project Manager 1.1.0
    MIDI Program Editor   1.1.0
    Sound Data Converter  1.1.1
    FX Program Editor     1.0.5
  で作成されたデータを使う必要があります。
  また、ドライバは、
    Manatee.drv Ver. 1.1.F
  です。ドライバのバージョンを知るには、Macintosh用のツール、
  サウンドプロジェクトマネージャでサウンドドライバブロックをダブルクリック
  したときの情報ダイアログ、右上に表示されます。(通常はクリエイタに確認して
  おいてください。)

１）提供したサンプル
・BLKCHG
  任意のタイミングでMIDIデータを差し替えるサンプルプログラムです。
・DEMO
  MIDI、One Shot、PCM、GDDAの同時再生サンプルです。FXもかけられます。
・FX
  FXプログラムによるエフェクトをかけるプログラムです。
・GDDA
  GD-DAの再生サンプルです。
・MEMPLAY1
  オンメモリPCMの応用サンプルです。
・MEMPLAY2
  オンメモリPCMの応用サンプルです。
・MIDI
  ダイレクトMIDIを使ったMIDIメッセージを直接送信するサンプルです。
・ONESHOT
  One Shot再生のサンプルです
・ONESHOT2
  One Shotの同時再生サンプルです
・SEQUENCE
  MIDIのシーケンスデータを再生するためのサンプルです。
・STEREO
  BOOT ROMのステレオ・モノラル設定を反映して再生するサンプルです。
・STREAM
  PCMストリームを使用した簡単なサンプルです。

それ以外に「DISKROOT」ディレクトリが存在しますが、このディレクトリには
各サンプルで使用する、サウンドデータ、ドライバなどが含まれています。
これらのデータは、GD-WorkShopでGD-ROMのプロジェクトを作成し、そのルート
ディレクトリにおいてください。
すべてのサンプルはGDを使用します。
また、「DISKROOT」ディレクトリ内のファイルはすべて、上記のツールおよび
ドライバで作成されたものです。
また、SHAREディレクトリには、サウンドブロックのイニシアライズ等の定型処理を
まとめたユーティリティ関数群のソースファイルがあります。

２）サンプルの実行方法
・コンパイル
  コンパイルには、Microsoft NAMAKEが必要です。
  NMAKEはVisual Studio、Visual C++などのパッケージに含まれています。
  ex)Visual Studioの場合、
    DevStudio\Vc\bin\nmake.exe
  nmakeを実行すると、各サンプルのディレクトリにはsample.elfというファイルが
  できあがります。
  ※Make時の注意
    現在サウンドのサンプルはすべてNTSCモードで動作するようになっています。

・実行
  実行するときには、まず、GD-Workshopを立ち上げあらかじめ作成しておいた
  ディスクイメージを開きます。
  その後、Codescapeを立ち上げて
    「File/Load Program File」
  から、sb.elfを選択し、
  SET4にデータをダウンロードします。
  数秒待った後、GD-WorkshopのトレイがCloseされているのを確認した後、
  F9キーで実行します。
  各サンプルの操作方法は画面にも出ますが、以下の通りになっています。
  BLKCHG
    サウンドブロックを差し替えるサンプルです。
    このデータは、MIDIプログラムバンクおよび、MIDIシーケンスデータを
    差し替えることが出来るようにあらかじめ少し大き目にブロックサイズを
    確保してあります。
    パッドのXとYでそれぞれのバンクを切り替えます。
    上下で、MIDIまたは、Oneshotを選択し
    スタートで曲の再生を始めます。再生中にスタートボタンを押すと
    再生中の曲が停止します。
    Oneshotバンクには全部で4つのOneshotデータがありますので、
    左右ボタンでその選曲をすることが出来ます。
    ※以前のバージョンにあった、シーケンスが鳴らなくなるバグは、
      データに問題があることが判明しました。
      本バージョンからは、新しいデータを使用しています。もしこのサンプルを
      動作させる場合、データの差し替えも必ず行うようにしてください
  DEMO
    MIDI、One Shot、PCMストリーム、GDDAを一通り再生させるサンプルで、
    FXの変更も可能です。
    用意しているFXモジュールは全部で、4っつあり
      0:MIDI Sequence A用、Qサウンドとリバーブで構成
      1:MIDI Sequence B用、拡張ディレイ
      2:One Shot用、拡張リバーブ
      3:GDDA用 リバーブ
    です。サウンドソースのFX入力チャネルがあっていれば、ほかの再生方法のものにも
    FXがかかります。
    操作方法は
      上下キー：機能の選択
    で、機能によりほかのキーはそれぞれ違います。
    ・MIDI
      Aボタン：シーケンスAの再生・停止
      Bボタン：シーケンスBの再生・停止
    ・One Shot
      左右キー：One Shotの選曲
      Aボタン：選択された曲の再生・停止
    ・PCMストリーム
      Aボタン：PCMストリームの再生・停止
      Bボタン：ループをするかしないかの設定
    ・GDDA
      左右キー：DAドラックの選曲
      Aボタン：DAトラックの再生
      Bボタン：DAトラックの再生停止
    ・FX
      左右キー：FXプログラムの選択
      LRボタン：FX Outデータの選択
      Aボタン：FXプログラムの変更
      Bボタン：FX Outの変更
      スタートボタン：FXプログラムとFXOutの変更
    です。なお、MIDIシーケンス再生時には、それぞれのシーケンスが使用する
    FXプログラムに変更しています。
    又、シーケンスAのQサウンドは、曲の途中で現れるヘリコプターのプロペラ音
    の定位変更に使用しています。
  FX
    FXプログラムを用いたシーケンスデータの再生サンプルです。
    デフォルトのFXプログラムバンクには、
      0:サラウンド
      1:拡張リバーブ
    があります。
    スタートボタンで
    再生中であれば、再生を停止し、再生されていなければ再生します。
    上下ボタンで、FXプログラムを選択、
    XボタンがFXをOn、YボタンがFXをOffです。
  GDDA
    GD-DA(Digital Audio)の再生サンプルです。
    スタートボタンで、再生・停止します。
    GDDAトラックはトラック番号4を想定しています。
    このサンプルデータだけは、DISKROOTディレクトリにはなく、このサンプルの
    ディレクトリにあります。(トラックが異なるため)
    ファイル名は「sample.da」で、これをGD Workshopで第4トラックにCD-DAとして
    おいてください。(2番目のSESSIONの"ISO Level2"を右クリックして出てくる
    ポップアップウィンドウから、「Insert/Track/Digital Audio」でトラックを追加
    そこにファイルをドラッグアンドドロップしてください。)
    さらに、現在はGD Workshopの問題で最終トラックのGDDAを再生する場合、
    曲の最後まで正しく再生させることが出来ません。
    最終トラックが再生できなくなるバグは、解消されました。
    上下キーでボリューム、左右キーでPANの設定を行うことが出来ます。
    ただし、PANは使用しているドライバにバグがあるので、途中で左に振り切れた後
    右側に戻ってしまいます。
    この不具合は次回リリースで修正される予定です。
  MEMPLY1
    オンメモリのPCMストリーム再生の応用サンプルです。
    実行すると、データダウン後すぐ再生を開始します。
    曲の最後までいくと、曲の途中(ループポイント)に戻ってシームレスに再生を
    続けます。
  MEMPLY2
    MEMPLY1と同じユーティリティを用いた応用サンプルで、
    スタートボタンによって、ソフトウェアでLFOをかけます。
  MIDI
    スタートボタンを押すと、
    再生中であれば、再生を停止し、再生されていなければ再生します。
    音としては、ピアノの音になります。
  ONESHOT
    パッドの上下ボタンで選曲し、スタートボタンで再生します。
    再生中にスタートボタンが押されたら、前の曲は再生停止し、次の曲が
    鳴ります。
  ONESHOT2
    OneShotの同時再生サンプルで、8つのOne Shotポートをあらかじめ開き、
    それぞれのポートに、曲番号、ボリウム、パン、ピッチを設定できます。
    上下キーで、ポートを選択し、左右キーで、曲番号、ボリウム、パン、ピッチの
    どれを変更するかを選択し、LRまたはXYでその値を上下させます。スタートボタン
    を押すと選択中のパラメータ初期値に戻します。
    Aボタンでそのポートの再生・停止を行います。
    ドライバのバージョンによっては、パンがかからない場合があります。
  SEQUENCE
    スタートボタンを押すと、
    再生中であれば、再生を停止し、再生されていなければ再生します。
  STEREO
    スタートボタンで再生されます。
    画面上にBOOT ROMでの設定が表示され、サウンドの出力もそれと同じになります。
  STREAM
    スタートボタンを押すと、
    再生中であれば、再生を停止し、再生されていなければ再生します。

３）解説
  全体的な話
    ・データの受け渡し
      サウンドデザイナからプログラマに渡されるファイルには次のようなものが
      あります。
      サウンドドライバ：サウンドコントロール用のCPU ARM7のコードで書かれた、
                        ドライバです。通常MANATEE.DRVというファイル名です。
      マルチユニットファイル：サウンドのメモリイメージまたはマップ情報が
                              含まれます。このファイルとサウンドドライバ
                              だけでサウンドの再生ができる場合と後で述べる、
                              バンクデータファイルが必要な場合の二通りが
                              あります。「.mlt」という拡張子がつきます。
      MIDIシーケンスバンクファイル：MIDIのシーケンスデータ(音符情報)です。
                                    一つのファイルに複数の曲が登録されて
                                    いることもあります。拡張子が「.msb」
                                    です。
      MIDIプログラムバンクファイル：MIDIの楽器(内蔵音源)情報ファイルです。
                                    通常、MIDIシーケンスデータとMIDI
                                    プログラムは対になります。
                                    拡張子が「.mpb」になっています。
      One Shotバンクファイル：一発再生の内蔵音源データです。
                              いくつかの音色が含まれています。
                              何番がどの音色かはサウンドデータを制作した
                              人に聞いてください。拡張子は「.osb」です。
      FXプログラムバンクファイル：サウンドLSI内蔵のDSPモジュールの
                                  プログラム(FXプログラム)のデータです。
                                  これも何番がどのエフェクトかを
                                  デザイナから聞いておく必要があります。
      FXアウトバンクデータ：FXの出力段にあるミキサの設定だと考えてください。
                            いくつかのFXアウトデータをまとめておくことが
                            出来、エフェクトの種類によってはFXアウトを
                            切り替えたりすることもあります。拡張子は
                            「.fob」です。
      MAP情報ファイル：サウンドメモリのマップ情報をテキストにしたもので、
                       サウンドメモリからのオフセットでどのデータが何処に
                       配置されているか知ることが出来ます。
                       拡張子は「.txt」です。
      GD-DAデータ：GD-DAデータは、RawPCMファイルのリトルエンディアンデータです。
                   一番簡単な作り方は、サウンドクリエイターから、
                   44.1kHz、16ビット、ステレオのWAVファイルをもらい、
                   先頭の、44バイトを削ります。
    ・サウンドブロックのイニシアライズ
      サウンドブロックの初期化には次の3つのステップを踏みます。
      1)ライブラリ内部変数の初期化
        ライブラリ内部変数はsdDrvInit()関数によって行います。
        この関数を実行することで、後で述べるメモリブロックを作成し、
        ドライバなどのデータを転送することが出来ます。
      2)ドライバの転送
        つぎにサウンドRAMにサウンドドライバを転送し、サウンドLSI内にある
        CPUを起動し、サウンドコントロールの可能な状態にします。
        まず、サウンドドライバをメインメモリ上に展開し、
        そのメモリイメージに対してメモリブロックを作成します。
        メモリブロックを作成した後に、
        sdDrvInit関数を呼び、サウンドドライバをサウンドRAM上に
        展開します。
      3)マップの構築
        マップは一般にはマルチユニットファイルの形でサウンドデザイナから
        提供されます。
        マルチユニットファイルには、どのデータが何処から始まり、
        どれくらいのサイズなのかという骨組みの情報と、
        そのデータの実体に別れます。
        実体についてはデータによってはない場合もあります。
        その場合は、マルチユニットデータをダウンロードした後、各モジュール
        データを後で転送することになります。
    ・メモリブロックについて
      サウンドデータは必ず、いったんメインメモリ上に置かれ、そこから
      サウンドRAMへと転送されます。Dreamcastには、GDROMからサウンドRAMへ
      直接転送する手段を持ちませんので、必ずこのような形態になります。
      データを転送する際、そのデータのソースアドレス、データサイズ、
      転送終了コールバック関数などの情報をハンドル化し、ここの転送関数は
      そのハンドルの内容を見て転送アドレスなどを確定します。
      このハンドルをメモリブロックといい、サウンド関連の転送の際に、必ず
      使用します。
      ただし、転送サイズについては、マルチユニットデータ、ユニットデータ、
      サウンドドライバの転送時には必要ありません。
      これらのファイルにはファイル内部に転送サイズに関する情報が含まれて
      いるからです。

  サンプルについて
  BLKCHG
    サウンドのブロック交換サンプルです。
    サウンドRAMは全部で2MBありますが、そのメモリイメージ(マルチユニット
    ファイル)をすべて転送すると非常に時間がかかってしまします。
    そこで、あらかじめ骨組みだけ用意しておき各ブロックを後で個別に
    転送することで時間を効率よく利用することが出来ます。
    このサンプルでは、たとえば、Oneshotデータを再生している間に、
    シーケンスデータの変更が可能であることを示しています。
    ただし、GDROMからのファイルアクセスには完了復帰型のAPIを使用して
    いるので、実際にはメインの処理は落ちてしまいます。
    そこで、即時復帰関数を利用し、高速化する必要があると思われます。

  DEMO
    MIDI2本、One Shot1本、ステレオPCM1本(2チャンネル)、GDDA一本を同時に
    再生できる総合サンプルです。それぞれに専用のFXプログラムが割り当てられて
    おり、再生開始時にそれぞれの使用するFXプログラムが割り当てられます。

  FX
    FXとは、サウンドLSI上にのっているDSPを利用し、音にエフェクトをかける
    効果の事です。
    FXをかけるためにはあらかじめサウンドデータ作成時にFXがかかるように
    設定しておく必要があります。
    プログラム上では、
    sdSndSetFxPrg関数で、PXプログラム番号および、FXアウト番号を指定します。
    FXプログラム番号は、各エフェクトモジュールのことで、サウンドデザイナ
    から、何番にどのエフェクトを使っているのかという情報をもらいます。
    FXアウトは、最終段のミキサに相当するもので、FXアウトによって
    エフェクトのかかった音の出力レベルと、再生定位を決めます。
    これも、サウンドデザイナから、どのFXプログラムはどのFXアウトを
    使用するのかを聞いておいてください。
    一般に曲の再生中にFXを切り替えると、ノイズが発生することがあります。
    これは、残響用などに使用するリングバッファ(FX Work)に前のFXプログラム
    のものが残っているためで、通常、このノイズを回避するには、
    予めデザイナにFX出力レベルが0のFX Outを作ってもらい、FXを切り替える
    際には、最初にその、FX Outに切り替えてからFXを切り替え、しばらく
    時間を置いてからFXOutをFXの出力レベルが高いものと切り替えます。
    このサンプルプログラムはFX Offを選択した時には、上記のような
    FX出力レベルが0のFX OutにsdSndSetFxOut関数で切り替えています。
    ただし、FX On時にノイズを回避する策は講じていません。

  GDDA
    このサンプルは高密トラックにあるデジタルオーディオファイル(GD-DA)
    を再生するサンプルです。
    GDの再生はファイルシステム関数によって行われますが、そのまえに
    サウンドブロックの初期化(sdSysInit)とドライバの転送を行う必要が
    あります。また、音量や再生定位はサウンド関数(sdGdda...)を使います。
    GD-DAを再生させるには、gdFsGddaPlayの前に、必ず、
    sdGddaSetPan関数とsdGddaSetVol関数で再生定位および再生音量の設定を
    行っておいてください。(ドライバのデフォルトでは音が出なくなります。)
    GD-DAの再生ステータスについて、GD-DAの再生ステータスはサウンドのAPIとしての
    実装ではなく、GDドライブのステータスを取得するという方法によって行います。
    GDドライブのステータス取得をするためには、GDブロックに対してドライブ
    ステータスの取得要求(gdFsReqDrvStat)を行い、ドライブのステータスが更新
    されてから、ステータスを取得しに行きます(gdFsGetDrvStat)。
    この時のステータス要求のリクエストは、処理時間が大変に重いため、毎フレーム
    リクエストを要求しかつ、それが終了するのを待つのは、アプリケーションに
    多くの負荷をかけることになります。
    このサンプルでは、実際毎フレームこのような事を行っているため非常に
    パフォーマンスが落ちることが実感して頂けると思います。
    通常GD-DAのステータスは数フレームに一回程度にし、かつ、リクエストと、
    取得は別のフレーム内で行うようにするのが、望ましいと思います。

  MEMPLAY1
    オンメモリPCMストリームのサンプルで、ONMEMPCM.Cはライブラリ的な作り方を
    しているので、MAIN.Cはいたってシンプルに構成できます。
    ステレオ・モノラル、ループ再生などの再生方法に対応しています。ステレオの
    場合、L/Rを分離して二つのファイルに分け別々にロードします。

  MEMPLAY2
    MEMPLAY1と同じONMEMPCM.Cを使用したサンプルで、時間変化に合わせて音量が
    変化するLFO的な効果をねらったものです。
    AICAチップにはハードウェアでLFOを持っていますが、時間とともに深さや、
    周波数が変ることはありませんので、SH側でソフト的な処理を施すことで、
    ちょっと風合いの変った効果を引き出すことが出来ます。
    このONMEMPCM.Cで用意されているコールバック関数は、mpTask関数内の
    定期転送処理の前に呼ばれるので、転送が遅れないように呼び出すタイミングを
    注意する必要があります。このサンプルで行っている処理は、コールバックを
    使用しないでも実現することは出来ます。

  MIDI
    このサンプルはダイレクトMIDIと呼ばれるMIDI再生方法を使用した
    サンプルです。
    普通MIDIシーケンスデータはサウンドクリエイターが作成したものを
    使いますが、MIDIをプログラムから直接制御したい場合に、このような
    再生方法を使用します。
    ダイレクトMIDIを使用する場合に注意しなければいけないのは、
    使用するMIDIチャネルに対して、
      バンクチェンジ(コントロールチェンジ32番)
      プログラムチェンジ
    の二つを必ず行わなければいけないという点です。
    もし、ダイレクトMIDIを利用する前に、普通のMIDIシーケンスの再生が
    されていた場合は必要な意かもしれません。そのシーケンスデータの
    中にこの二つが含まれているかもしれないからです。

  ONESHOT
    One Shotとは、一発再生(SE)を目的とした専用の音源のことですが、
    ループや、エンベロープの機能を持っているため、SE的なBGMに使用される
    事も考えられます。
    基本的な処理プロセスは、MIDIと同じです。

  ONESHOT2
    現在のサウンドドライバはOne Shot用に8つの音源を予約しています。
    つまり、One Shot SEは同時に8本まで再生することが出来ます。
    このサンプルでは、最初に8本すべてのハンドルを開いておき後は、
    アプリケーション側で、ハンドルの管理を行っています
    サンプル中、パン、音量、ピッチをリアルタイムに変更できるほか、
    再生ステータスを表示しています。再生ステータスは、sdShotGetStat関数
    で取得するSDS_SHOT_STAT構造体のm_flgメンバを参考にします。
    なお、このサンプルで使用しているOne Shotデータのうち2番目の銃の音は
    減衰する無間ループSEですので再生終了ステータスにはなりません。

  SEQUENCE
    MIDIを再生するためには、音符情報にあたるMIDIシーケンスバンクデータと、
    楽器情報にあたるMIDIプログラムバンクデータが必要になります。
    このサンプルでは、それらが一つになったマルチユニットデータという
    ファイルを使用していますが、それぞれを別扱いにすることも可能です。
    詳細についてはBLKCHGのサンプルの解説をご覧ください。
    MIDIを再生するためには、
    sdMidiOpenPort関数でポートを確保し、
    その確保したポートに対して、Play、Pause、Stopなどの関数を実行します。
    使わなくなったポートは、
    sdMidiClosePort関数で開放してください。MIDIのポートは8個しか
    ありませんので、Closeしないと音声がならなくなるなどの症状が起こる
    可能性があります。

  STEREO
    作成基準では、
      「ユーザがBOOT ROMで設定したステレオ・モノラル情報をアプリケーションでも
        反映するのが望ましい」
    とされています。
    BOOT ROMで設定されているステレオ・モノラルの情報を取得する関数がありますが
    その関数のみでは、サウンドの出力自体を変更はしません。アプリケーションが
    独自にサウンドブロックを変更をしてあげる必要があります。
    サウンドブロックのステレオ・モノラル変更はsdSndSetSpace関数を使用します。

  STREAM
    現状でサウンド関数を使ったPCM再生は非常に困難です。
    サウンドRAMへのデータ転送はすべてアプリケーションの責任になるため、
    メインRAMのバッファ管理や、定期転送処理などを自前で行う必要が
    あるためです。
    このサンプルでは、1Vに一回呼ばれる定期転送関数で逐次サウンドRAMに
    サウンドデータを転送します。
    サウンドデータを転送する際には、sdPstmIsTransferWaveData関数によって
    サウンドRAMに転送サイズが確保できるか調べた後、メモリブロックを
    作成し、sdPstmTransferWaveDataで転送します。
    sdPstmIsTransferWaveDataは、自分でサウンドRAMの管理が出来るのであれば
    行う必要はありません。
    また、再生の終了判定もアプリケーションの責任において行わなければ
    なりません。(ここが実は一番難しいのですが)
