SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

少ないディレイタップ数で厚みのある残響音を作るテクニック

リバーブサウンド(残響音)生成アルゴリズム一考

確率密度は蜜の味

 さて、ディレイエフェクトのカタマリとしてリバーブエフェクトを実現する時に、肝中の肝となるのが、「ランダムに変化するディレイタイムの確率密度のデザイン」といっても過言ではありません。

 確率密度というと随分堅苦しく聞こえるかもしれませんが、要するに、ディレイタイムが任意の値にセットされる確率をグラフにしたものです。これは言葉とグラフを対にして説明すると、分かりやすいかと思います。

例1

 ディレイタイムは、100ミリ秒~300ミリ秒の区間で同じ確率で分布(一様分布)し、それ以外のディレイタイムは絶対に有り得ない。

例2

 ディレイタイムは、50ミリ秒~100ミリ秒の区間で50%の確率で一様に分布し、200ミリ秒~300ミリ秒の区間で50%の確率で一様に分布する。それ以外のディレイタイムは絶対に有り得ない。

 例2で注意すべき点は50ミリ秒~100ミリ秒の区間にディレイタイムが現れる確率と、200ミリ秒~300ミリ秒の区間に現れる確率は、それぞれ50%づつなのに、グラフでは50ミリ秒~100ミリ秒の区間が2倍の高さになっていることです。これは、「複数の区間があり、各々の区間の出現率が同じだとすると、区間が狭い方が、その区間内に存在する、ある1つのディレイタイムが選ばれる確率が高くなる」という意味で考えてしまえば良いでしょう(厳密に言うと若干異なりますが)。

 この場合、同じ高さにするには50ミリ秒~100ミリ秒の区間の出現率を33.3%、200ミリ秒~300ミリ秒の区間を66.7%とすれば大体よいです。

 これらの確率密度を持つディレイタイムの値をプログラムで生成するには、一定区間(例えば0.0~1.0)で一様分布する乱数を作る関数を用意しておいて、この関数の戻り値を適当にスケーリングすれば良いです。実際にコード例を示すと、次のようになります。

例1
double noise;
    
noise = Noise(); //0.0~1.0で一様分布する乱数
    
//100~300へ移動
noise = 100.0 + noise * 200.0;
例2
double noise;
    
noise = Noise(); //0.0~1.0で一様分布する乱数
if (noise < 0.5) {
//50%分の区間
    noise = noise * 2.0; //先ずは0.0~1.0の範囲に戻して。。
    //50~100へ移動
    noise = 50.0 + noise * 50.0; 
} else {
//残りの50%分の区間
    noise = (noise - 0.5) * 2.0; //こちらも0.0~1.0の範囲に戻して。。
    //200~300へ移動
    noise = 200.0 + noise * 100.0; 
}

/****(同じ高さにする場合) ***************************************/
double noise;
    
noise = Noise(); //0.0~1.0で一様分布する乱数
if (noise < 0.3333) {
//33.33%分の区間
    noise = noise / 0.3333; //先ずは0.0~1.0の範囲に戻して。。
    //50~100へ移動
    noise = 50.0 + noise * 50.0; 
} else {
//残りの66.67%分の区間
    noise = (noise - 0.3333) / 0.6667; //こちらも0.0~1.0の範囲に戻して。。
    //200~300へ移動
    noise = 200.0 + noise * 100.0; 
}

 本当を言うと、この辺は色々な奥義が目白押しなのですが、リバーブ用のディレイタイムを設計するには、コレくらいで何とかなると思います。興味のあるお方は、ネットで「確率変数の和」、「確率分布」とかを検索して、色々調べてみて下さい。

ディレイタイムの設計で注意すること

 さてディレイタイムの確率的な割り振り方を解説したので、あとは実際に割り振る時のコツなり注意点なりを書いてみたいと思います。単刀直入にいうと、「近すぎず、遠すぎず、濃すぎず、薄すぎず」という感じです。

 「近すぎる」、つまりディレイタイムが短すぎると、同じ残響時間を作り出すのに必要なフィードバック量が大きくなってしまいます。つまり、一定間隔のヤマビコがたくさん作られてしまい周波数特性のクセが付きやすい、それどころか音程感さえ生んでしまう結果となってしまいます。

 このクセは一兆一夕に解消できるものではありませんので、短すぎるディレイタイムが生まれないような設計をする必要があるかと思います。大体の目安として「20ミリ秒よりも短いものはまずい」という気がします。

 「遠すぎる」場合ですが、これは逆にフィードバック量が小さくなってしまって、ディレイタップの残響生成能力を生かしきれないという問題が生じます。つまりリバーブタイムが3秒のところ、ディレイタイムが3秒だったら、最初のヤマビコは-60dB、次のヤマビコは-120dBとなってしまって、ほどんど聴こえないわけです。なので、これも、「大体リバーブタイムの3分の1程度までにしておいた方がよい」と思います。

 「濃すぎる」というのは、確率密度が高すぎることです。先ほどの図で言うと、一部のディレイタイムの区間(たとえば100ミリ秒~101ミリ秒の区間)が異様に高くて、大半のディレイタップが密集してしまっている状態です。こうした場合は、1つの問題として「単一のディレイのように聞こえてしまう」という問題が発生します。

 しかしもっと深刻なのは、「結果としてフィードバック量が不安定になる」問題です。非常に短い時間区間にディレイタップが集中してしまうと、同一サンプルに複数のディレイタップが重なる状態が高頻度に発生します。「フィードバック量の概算」のところでも述べましたが、ディレイタップのフィードバック値の位相はプラスとマイナスが半々ずつですので、同一サンプルに重なっているディレイタップのフィードバック量の「平均値」は0です。

 しかし分散というのか、不安定さは非常に大きくなります。4つのディレイタップのフィードバック量が全てプラスで、しかも最大値で重なっていたとしたら、想定されるフィードバック量の4倍の値となってしまい、その結果ハウリングのような状態が発生してしまいます。つまり、普段はあまり響かないけど突然ハウリングを起こして、また響かなくなる、というようにリバーブの概念を通り越したキワモノ系エフェクトと化してしまうのです。

 「薄すぎる」を説明しましょう。この薄すぎるは、「濃すぎる」や「遠すぎる」の影響で死んでしまうディレイタップが生まれる反動として発生することが多いのですが、つまり「あるディレイタイムの区間に割り当てられるディレイタップの出現率が低すぎる状態」です。

 これが問題なのは明らかでしょう。ヤマビコっぽさが解消されず、「リバーブというより、複数のディレイがランダムに変化しているように聴こえる」という状態が発生してしまいます。

 以上の注意点を考慮に入れておけば、「自然なリバーブ感がイマイチ得られないけど、どうしていいか分からない」という問題は少なくなるものと思います。ただし、これらは自然なリバーブ感を得るためにどうしたらいいかなぁ、という僕なりの工夫に基づくものですので、逆に極端な設定で面白い音響を作り出したい筋には、もっと色んなディレイタイムの分布を試していただくのも一興かなと思います。

次のページ
高域ダンピング

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

鼻クローン(ハナクローン)

アルゴリズムオタクです。今は信号処理、統計処理などを頑張って勉強してます。勉強!自分の仕事とあまり関係していないことが玉に傷ですが。。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/315 2006/02/21 19:15

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー