DirectXプログラミング講座 〜Vol14. レーシングカーのエンジン音をリアルに再現〜

ステップ11でやった3Dサウンドを活用し、前回のプログラムに手を加えてみましょう。


作成方法



真中のクルクルがリスナーとなる

サンプルプロジェクトをダウンロード

前回の "driving" プロジェクトを改良する形で作業を進めます。別途、"listener.x" 及び "EngineNoise.wav" が必要になりますので、プロジェクトのディレクトリに保存しておいてください。
→listener.xをダウンロード
→EngineNoise.wavをダウンロード

●driving.abpの先頭部分のコーディング

音源オブジェクト(CAudio3Dクラス)を定義します。dwDefaultFrequencyはエンジン音WAVEファイルの初期周波数を格納するための変数です。

リスナーオブジェクト(CListenerクラス)を定義します。pLisModelはリスナーを視覚的に表示するためのXファイルを管理するためのオブジェクトです。ListenerPositionにはリスナーの初期位置を指定します。

#include "driving.idx"


Dim ScreenX=640 As Long    'ディスプレイの幅  (ピクセル単位)
Dim ScreenY=480 As Long    'ディスプレイの高さ(ピクセル単位)

' TODO: この位置にグローバル変数を定義してください。

Const MAX_SPEED = 25    '最高速(メートル/秒)
Const FPS = 60          'FPSの基準値

'FPSを計算するための変数
Dim dwNowFPS=FPS As DWord
Dim temp_FPS=FPS As DWord
Dim temp_Count As DWord

'自動車
Dim pModel As *CMeshModel                   'メッシュモデル
Dim VectorPosition=[0,0,-5] As D3DVECTOR    '位置
Dim direction_xz=D3DX_PI As Single          'XZ平面上の方向
Dim velocity As Single                      '速度

'エンジンノイズの音源
Dim pEngineNoise As *CAudio3D
Dim dwDefaultFrequency As DWord

'リスナー
Dim pListener As *CListener
Dim pLisModel As *CMeshModel
Dim ListenerPosition=[0,1,0] As D3DVECTOR	'位置

●InitProc関数のコーディング

リスナー及び音源(エンジン音)のオブジェクトを生成し、初期化を行います。

Function InitProc()
    'DirectXを初期化
    If dx_Init(hMainWnd,ScreenX,ScreenY,FALSE)=0 Then
        InitProc=0
        Exit Function
    End If

    'マウスカーソルを非表示にする
    ShowCursor(FALSE)

    ' TODO: この位置にアプリケーションの初期化コードを記述してください。

    'ライト
    dx_SetDefaultLight()


    '------------------------
    ' メッシュモデルの初期化
    '------------------------

    '自動車
    pModel=New CMeshModel("model.x")

    'リスナー
    pLisModel=New CMeshModel("listener.x")


    '----------------------------
    ' リスナーの初期化
    '----------------------------

    'CListenerオブジェクトを生成
    pListener=New CListener

    'リスナーの位置を設定
    pListener->SetPosition(ListenerPosition.x,ListenerPosition.y,ListenerPosition.z)


    '----------------------------
    ' 音源(エンジン音)の初期化
    '----------------------------

    'CAudio3Dオブジェクトを生成
    pEngineNoise=New CAudio3D

    'セカンダリモードに設定
    pEngineNoise->SetSecondary()

    '読み込み
    pEngineNoise->Load("EngineNoise.wav")

    'デフォルト時の周波数を取得
    pEngineNoise->GetFrequency(VarPtr(dwDefaultFrequency))

    '最短距離、最長距離を設定
    pEngineNoise->SetMinDistance(0)
    pEngineNoise->SetMaxDistance(50)        '50メートルの距離まで音が届く

    'リピート回数を無限に設定
    pEngineNoise->SetRepeats(DMUS_SEG_REPEAT_INFINITE)

    '再生
    pEngineNoise->Play()


    InitProc=1
End Function

●QuitProc関数のコーディング

リスナー及び音源(エンジン音)で使ったオブジェクトを破棄します。

Sub QuitProc()
    ' TODO: この位置にアプリケーションの終了処理を記述してください。

    'メッシュモデルを破棄
    Delete pModel

    'リスナーのメッシュモデルを破棄
    Delete pLisModel

    'エンジン音を停止し、破棄
    pEngineNoise->Stop()
    Delete pEngineNoise

    'リスナーを破棄
    Delete pListener

    'DirectXの終了処理
    dx_Quit()
End Sub

●InputActionProc関数のコーディング

dwPowerFrequency変数に現在の速度に対するエンジン音の周波数を格納します。こうすることで、エンジンの吹け上がりサウンドをリアルに表現できます。アイドリング時は通常の1/4の周波数を設定して低音サウンドを響かせ、逆に最高速付近ではdwDefaultFrequencyと同等の値を設定することで高音のエキゾーストサウンドを響かせます。音源の周波数はCAudio3D::SetFrequency関数で設定します。

音源(エンジン音)の位置及び速度を設定し、3D空間におけるサウンドまたはドップラー効果の演出を行います。最後にCListener::CommitSettings関数を呼び出してリスナー及び音源情報を更新します。

Sub InputActionProc()
    ' TODO: この位置に入力に関するコードを記述してください。
    '       (キーボード、マウス、ジョイパッド、ジョイスティックなどによる入力)

    ' メモ - キャラクタの移動など、状況進行(アクション)を意味するコードを
    '        記述することもできます。

    'ESCキーが押されたときは終了する
    If GetKeyState(VK_ESCAPE) and &H8000 Then
        PostQuitMessage(0)
    End If

    'アクセル制御
    If GetKeyState(VK_UP) and &H8000  Then
        '方向キー(上)が押されているとき
        velocity=velocity+0.1
        If velocity>MAX_SPEED Then velocity=MAX_SPEED
    Else
        '方向キー(上)が離されているとき
        velocity=velocity-0.1
        If velocity<0 Then velocity=0
    End If

    If velocity>3 Then
        'ハンドル操作(車が動いているときのみ)
        If GetKeyState(VK_LEFT) and &H8000  Then
            '方向キー(左)
            direction_xz=direction_xz-2/FPS
            If direction_xz<0 Then direction_xz=D3DX_PI*2+direction_xz
        ElseIf GetKeyState(VK_RIGHT) and &H8000  Then
            '方向キー(右)
            direction_xz=direction_xz+2/FPS
            If direction_xz>=D3DX_PI*2 Then direction_xz=0
        End If
    End If

    '移動
    VectorPosition.x=VectorPosition.x-Sin(direction_xz)*velocity/FPS
    VectorPosition.z=VectorPosition.z-Cos(direction_xz)*velocity/FPS

    '速度をもとに周波数を計算(エンジンの吹け上がりサウンドを再現)
    Dim dwPowerFrequency As DWord
    dwPowerFrequency=dwDefaultFrequency/4+dwDefaultFrequency*(3/4)*(velocity/MAX_SPEED)
    pEngineNoise->SetFrequency(dwPowerFrequency)

    'エンジン音の音源情報を設定
    pEngineNoise->SetPosition(VectorPosition.x,VectorPosition.y,VectorPosition.z)
    pEngineNoise->SetVelocity(
        -Sin(direction_xz)*velocity,
        0,
        -Cos(direction_xz)*velocity)

    'リスナー/音源のパフォーマンスを更新
    pListener->CommitSettings()
End Sub

●RednerProc関数のコーディング

リスナーを視覚的に表示するためのXファイルを表示します。

Sub RenderProc()
    ' TODO: この位置に描画に関するコードを記述してください。

    '自動車を描画
    Dim VectorDirection=[0,0,0] As D3DVECTOR
    VectorDirection.y=direction_xz
    pModel->Draw(VarPtr(VectorPosition),VarPtr(VectorDirection))

    'リスナーを描画
    VectorDirection.x=GetTickCount()/800
    VectorDirection.y=GetTickCount()/900
    VectorDirection.z=GetTickCount()/1000
    pLisModel->Draw(VarPtr(ListenerPosition),VarPtr(VectorDirection))

    'カメラを設定
    Dim VectorEye=[0,5,-10] As D3DVECTOR
    Dim VectorAt=[0,0,0] As D3DVECTOR
    Dim VectorUp=[0,1,0] As D3DVECTOR
    dx_SetCamera(VarPtr(VectorEye),VarPtr(VectorAt),VarPtr(VectorUp))

    '視野を設定
    dx_SetProjection(60*D3DX_PI/180,
        1,
        0.01,
        2000.0)

    'FPSを計算
    temp_FPS=temp_FPS+1
    If GetTickCount()-temp_Count>1000 Then
        temp_Count=GetTickCount()

        dwFPS=temp_FPS
        temp_FPS=0
    End If

    'テキスト情報を描画
    Dim buf[255] As Char
    wsprintf(buf,Ex"%dfps  %dm/s  %dkm/h\nESCキーで終了",dwNowFPS,Int(velocity),Int(velocity*3600/1000))
    dx_DrawText(ScreenX*2/3,ScreenY-50,buf,D3DCOLOR_XRGB(200,200,200))
End Sub

スピーカーの音量をいつもよりちょっとだけ上げたら、早速プログラムを実行してみましょう。3D空間の中に響き渡るエンジンの吹け上がり、リスナー付近を高速で通り過ぎるときのドップラー効果、お楽しみいただけたでしょうか☆



講座インデックスへ戻る ©2005 Discoversoft