TOP

ABOUT

PROGRAM

DIALY







Tutorialのお勉強(4)

 1.はじめに
 今回はXACTを使ってプロジェクトファイルを作成して音を流すやつです。




 2.XACTプロジェクトを作成する
 音関係のファイルを用意するのが色々と面倒なのでXNAのSpace Warスターターキットのファイルを使います。
 最初に,XACT(Microsoft Cross-Platform Audio Creation Tool)を使って音関係のファイルをXNAで使える形にします。
 まずは,スタートメニューからすべてのプログラム→Microsoft XNA Game Studio 2.0→Tool→Microsot Cross-Platform Audio Creation Tool(XACT)を選択してXACTを立ち上げましょう。
 XACTが立ち上がると次のような画面になると思います。



 立ち上がったら画面左上のメニューからFile→New Projectを選択します。するとダイアログボックスが出てくるので,ファイル名を決めて保存ボタンを押します。
 つぎに,画面左側のツリー表示になっているウィンドウの上側に「Wave Banks」というのがあります。このWave Banksの項目を右クリックするとNew Wave Banksというポップアップがでてくるので選択しましょう。
 同じようにSound Banksの項目を右クリックしてNew Sound Banksを選択して新しいサウンドバンクを作成しましょう。
 あと,新しく作成されたウェーブバンクの名前がデフォルトですとWave Bank,サウンドバンクのデフォルト名がSound Bankになっていると思います。この名前はあとでXNAで使用します。デフォルト名でもいいのですが,一応名前を変えておきます。Wave Bank→WBに変更,Sound Bank→SBに変更しておきましょう。
 一応ここまでの作業で下のような画面になります。


 つぎに音を出すための音源をウェーブバンクに登録していきます。ウェーブバンクのウィンドウを右クリックして,Insert Wave File(s)を選択します。
 スターターキットのContentフォルダにあるAudioフォルダの中にあるShipsフォルダからengine_2.wavを選択します。



 同様にして,右クリックしてAudioフォルダ内にあるWeaponsフォルダからhyperspace_activate.wavを選択します。



 いま,選択して追加したファイルは自分で作成するXNAのプロジェクトにあとでコピーしておくのを忘れないでください。WAVEファイルがない場合コンパイルが失敗するので注意してください。
 ふたつのファイルを追加するとウェーブバンクウィンドウが次のようになっているはずです。



次に,上の画面のようにウェーブバンクウィンドウにある二つのファイルを今度はサウンドバンクウィンドウにドラッグアンドドロップします。するとサウンドバンクウィンドウが下のようになるはずです。



 engine_2ファイルはボタンを押している間ずっとエンジン音を流すように後でプログラムを組むので,ループ再生できるようにする必要があります。サウンドバンクウィンドウの中の左上にあるSound Nameの項目にあるengine_2を左クリックして選択されている状態にします。つぎにXACTのウィンドウの左下にあるウィンドウにLoopingというグループがあります。このなかにInfiniteというチェックボックスがあるのでチェックを入れてずっとループ再生されるようにしておきます。



 あとは,XACTで再生できるかどうかのチェックもしておきましょう。XACTを起動した状態のままで,デスクトップのスタートメニュー→すべてのプログラム→XNA Game Studio 2.0→Tool→XACT Auditioning Utilityを選択して起動させます。起動すると下のようなコンソール画面で出るはずです。



 コンソール画面を開いた状態のままXACTの画面にもどります。XACTのサウンドバンクウィンドウの右上にあるウィンドウからTrack 1→Play Wave→engine_2(100%)を選択します。つぎにメニュー画面の下にあるツールバーの中に再生ボタンがあるので押します。するとサウンドが再生されます。



 サウンドを止める場合は上の赤丸で囲った範囲の一番右側にある停止ボタンを押してください。engine_2と同様にhyperspace_activateも確認してみてください。
 確認できたらXACTのプロジェクトを保存します。File→Save Projectで上書き保存しましょう。これでXACTの作業は終了です。


 3.XNAで音を再生する
 前回作成したプロジェクトを元に音関連の処理を追加していきます。
ソリューションエクスプローラーからContenを右クリックして「新しいフォルダの作成」を選択してAudioフォルダを作成します。Audioフォルダを作成したら,Visual Studioのウィンドウを最小化して,先ほど作成したXACTのプロジェクトと,2つのWAVEファイル(engine_2.wav,hyperspace_activate.wav)を自分で作成したXNAのContentフォルダ内にあるのAudioフォルダにコピーペーストします。コピペしたらVisual Sudioに戻って,ソリューションエクスプローラーからContent→AudioにいきAudioを右クリックして「既存の項目の追加」を選択して,いまAudioフォルダにコピペしたXACTプロジェクト(*.xap)を追加します。



 これで,下準備は完了です。あとはコーディングしていきます。
コードのほうではまず,音再生に必要な変数を用意しておきます。
00022:          // 音関連
00023:          AudioEngine audioEngine = null;
00024:          WaveBank waveBank = null;
00025:          SoundBank soundBank = null;
00026:          Cue engineSound = null;

 つぎにIntializeメソッドでファイルの読み込みなどを行います。
00046:          /// <summary>
00047:          /// Allows the game to perform any initialization it needs to before starting to run.
00048:          /// This is where it can query for any required services and load any non-graphic
00049:          /// related content.  Calling base.Initialize will enumerate through any components
00050:          /// and initialize them as well.
00051:          /// </summary>
00052:          protected override void Initialize()
00053:          {
00054:              // TODO: Add your initialization logic here
00055:  
00056:              // オーディオエンジンの作成
00057:              audioEngine = new AudioEngine("Content/Audio/sample.xgs");
00058:  
00059:              // ウェーブバンクの作成
00060:              waveBank = new WaveBank(audioEngine, "Content/Audio/WB.xwb");
00061:  
00062:              // サウンドバンクの作成
00063:              soundBank = new SoundBank(audioEngine, "Content/Audio/SB.xsb");
00064:  
00065:              base.Initialize();
00066:          }
 サウンド関連のファイルはContent.Loadメソッドを使わないようです。またファイル名を指定する場合も拡張子を付ける必要があるので注意してください。
 今回はゲームパッドのボタンが押されたときに音を再生するようにしたいので,音を再生する処理はUpdateInputメソッドで行います。
00120:          /// <summary>
00121:          /// 入力の更新
00122:          /// </summary>
00123:          protected void UpdateInput()
00124:          {
00125:              // ゲームパッドの状態を取得
00126:              GamePadState currentState = GamePad.GetState(PlayerIndex.One);
00127:  
00128:              // ゲームパッドがつながっている場合
00129:              if (currentState.IsConnected)
00130:              {
00131:                  // モデルの速度と回転角
00132:                  modelRotation -= currentState.ThumbSticks.Left.X * 0.1f;
00133:                  Vector3 modelVelocityAdd = Vector3.Zero;
00134:                  modelVelocityAdd.X = -(float)Math.Sin(modelRotation);
00135:                  modelVelocityAdd.Z = -(float)Math.Cos(modelRotation);
00136:                  modelVelocityAdd *= currentState.Triggers.Right;
00137:                  modelVelocity += modelVelocityAdd;
00138:  
00139:                  // 振動させる
00140:                  GamePad.SetVibration(PlayerIndex.One, currentState.Triggers.Right, currentState.Triggers.Right);
00141:  
00142:                  // 右トリガーが押されている場合
00143:                  if (currentState.Triggers.Right > 0)
00144:                  {
00145:                      // キューがセットされていない場合
00146:                      if (engineSound == null)
00147:                      {
00148:                          // キューをセット
00149:                          engineSound = soundBank.GetCue("engine_2");
00150:  
00151:                          // キューを再生
00152:                          engineSound.Play();
00153:                      }
00154:                      // キューが停止している場合
00155:                      else if (engineSound.IsPaused)
00156:                      {
00157:                          // キューを再生
00158:                          engineSound.Resume();
00159:                      }
00160:                  }
00161:                  // 右トリガーが押されてない場合
00162:                  else
00163:                  {
00164:                      // キューがセットされていて,再生されている場合
00165:                      if (engineSound != null && engineSound.IsPlaying)
00166:                      {
00167:                          // キューを停止
00168:                          engineSound.Pause();
00169:                      }
00170:                  }
00171:  
00172:                  // Aボタンが押された場合
00173:                  if (currentState.Buttons.A == ButtonState.Pressed)
00174:                  {
00175:                      // モデルの位置・速度・回転角をリセット
00176:                      modelPosition = Vector3.Zero;
00177:                      modelVelocity = Vector3.Zero;
00178:                      modelRotation = 0.0f;
00179:  
00180:                      // キューを再生
00181:                      soundBank.PlayCue("hyperspace_activate");
00182:                  }
00183:              }
00184:          }
00185:  
engine_2はボタンが押されている間ループ再生するようにするので,すこし処理が変わっています。右トリガーが押されている場合,まず最初にサウンドバンクからengine_2が入ったキューを取り出して,engineSoundに格納します。これでengineSoundはnullではなくなります。つぎにengineSound.Play()メソッドで取り出したキューを再生を開始します。キューが停止されている場合は,eingineSound.Resume()メソッドでキューを再生するようです。
 つぎに,右トリガーが押されていない場合は,キューを停止させます。もちろんキューが停止されているのにわざわざ停止する処理を送る必要ないので,if文でチェックしましょう。
 とりあえず,このようにすれば音が再生できるようですね。これで,なんとか音再生もできるようになりました。


 Download
本ソースコードおよびプログラムを使用したことによる如何なる損害も製作者は責任を負いません。
本ソースコードおよびプログラムは自己責任でご使用ください。
プログラムの作成にはMicrosoft Visual Studio 2005 SP1 Professional, XNA Game Studio 2.0を用いています。