TOP > プログラミング関連 > SFML非公式翻訳トップ > 【非公式翻訳】SFML2.4チュートリアル > オーディオモジュール > 立体音響:音を3Dっぽくする

[原文(公式)]

◆◆ 立体音響:音を3Dっぽくする ◆◆
SFML2.4 非公式日本語翻訳
立体音響
デフォルトではサウンドも音楽も両サイドのスピーカーからフルボリュームで再生されます。3Dっぽくない。

だけど、ゲーム内で、画面の右側にある物体から効果音が出てるなら、右のスピーカーから音が出て欲しいですよね? プレイヤーの背後のオブジェクトが音を出しているなら、背後のスピーカーから音が出て欲しい(5.1ch のサラウンドシステムはお持ち?)。

さて、どうすればいいのかな?
立体音響にできるのはモノラルサウンドだけ
立体音響効果が有効なのは、モノラルサウンドなどの、単一のチャンネルで再生されるものだけです。 複数のチャンネルで再生されているときには立体音響効果は無効になります。 なぜかというと、左右のスピーカーをどう使うのかが、それぞれのチャンネルで、個別に設定されるからです。 大事なことなので覚えておいてね。
リスナー
ユーザーの音声環境で再生されるサウンドは、まずは、ソフトウェア内の仮想の「リスナー」の耳に届きます。 スピーカーからどんな音が出てくるかは、その「リスナー」の耳にどんなふうに音が届いたのか、で決まります。

リスナーの状態は sf::Listener クラスで定義します。
リスナーはプログラムの実行環境内に1人だけなので、このクラスにはスタティック関数しかありません。 つまり、インスタンス生成はしない想定です。

まず最初に、画面の中でのリスナーの立ち位置を設定です:
sf::Listener::setPosition (10.f, 0.f, 5.f);
2Dのゲームなら、高さの概念がないので Y座標はいつも同じです(多分 0 で固定)。

次は、リスナーの向きです:
sf::Listener::setDirection (1.f, 0.f, 0.f);
このサンプルでは、リスナーは純粋に X軸のプラス方向を向いて立ってます。 つまり、たとえば、効果音が 座標(15, 0, 5) から発せられている場合、右のスピーカーから音が出ます。

デフォルトでは、リスナーの「上方向」は (0, 1, 0) に設定されています。 つまり、リスナーの頭の方向は Y軸のプラス方向を向いているということです。 これを変更しなきゃいけないというのはレアケースだとは思いますが、 次のようにすることで「リスナーの頭の向き」を変更することもできます。
sf::Listener::setUpVector(1.f, 1.f, 0.f);

最後にもう1つ。リスナーは世界全体の音のボリュームを変更することもできます:
sf::Listener::setGlobalVolume (50.f);
ボリューム値の範囲は [0 ~ 100] です。たとえば 50 に設定すると元々の音量の半分になります。

以上で設定した値は、もちろん、それぞれに対応する get関数で参照もできます。
音源を設定
SFML のオーディオ関連のオブジェクト (sf::Sound、sf::Music、sf::SoundStream など) は3D効果用に同じプロパティを持ってます。

まずは音源の位置です。
sound.setPosition (2.f, 0.f, -5.f);
設定する値はデフォルトでは絶対座標です。
必要とあらば、リスナーからの相対座標として設定ようにすることもできます。
sound.setRelativeToListener (true);
相対座標の設定にしておくと、リスナー自身が音を出すような場合にコードがわかりやすくなります (足音とか、ピストルを撃つとか)。
ちなみに、音源の位置を 相対位置(0, 0, 0) にすると3D効果を無効にしたのと同じような結果にできます。 なかなか面白い副作用ですね。え、何の役に立つかって? 結構役に立つのですよ? マウスクリック音などの GUIのサウンドとか、BGM とか。

音源とリスナーとの距離に応じて音が減衰する設定もできます。
sound.setMinDistance (5.f);   // 最短距離
sound.setAttenuation (10.f);  // 減衰しやすさ
「最短距離」の値は、音が最大のボリュームで聴こえる距離です。 なので、たとえば爆発音のような大きな音は、この値を大きく設定しておきましょう。遠くからでも聴こえるように。
注意点。 この値を 0 にするとどうなるのかな? リスナーの頭の中に音源があるというのは、ちょっと奇妙ですね。 立体音響として正しくない結果になったり、音が減衰しなくなってしまったりします。
0 は使ってはイケない値、ということでお願いいたします。

「減衰しやすさ」が大きければ大きいほど、リスナーから離れた音は聴こえにくくなります。 減衰しない設定にするには、この値に 0 をセットします。 一方、100 のような大きな値にすると、減衰しまくる設定になります。 つまり、リスナーのすぐ近くにあるときにだけ聴こえるような設定、ということです。

最終的に「減衰率」が計算されて、ボリュームに掛け算されます。
以下、減衰率の計算式です。正確な値を計算したいときの参考にどうぞ:
MinDistance   :最短距離。setMinDistance() でセット
Attenuation   :減衰しやすさ。setAttenuation() でセット
Distance      :音源とリスナーとの距離
Volume factor :減衰率。範囲は [0~1]です。この値がボリュームに掛け算されます。

Volume factor = 
    MinDistance / 
    ( 
      MinDistance + 
      Attenuation * ( max(Distance, MinDistance) - MinDistance ) 
    )