周波数が同じでないものの非常に近い二つの音を同時に鳴らすと「うなり」が発生します。全く同じ周波数の場合音の山と谷がいつも同じなのでずっと単調な音になります。それが少し違うと少しずつずれていき両方が山の時もあれば片方が山の時に片方が谷になる時もあったりと周期的に変動するようになります。
これをうなりと言い。英語ではbeatと言います。
うなり beat
例えば500Hzの音Aと501Hzの音Bが同時になるとします。Aは1秒間に500周期、Bが501周期の波になります。運動場のトラックをイメージしてください。0秒目に両者は同じ位置からスタートしますが0.5秒目にはちょうど反対の位置になってしまいます。Bの方が半周先に行っているのです。1秒目にはまた同じ位置になるのですがこのときBはまるまる一周先に進んでいることになります。
このときこの音を聞いている耳は1秒間に大きくなって小さくなる波を聞き取ることになります。これはAとBの周波数の差分が1Hzだからです。500Hzと505Hzであれば差が5Hzなので1秒間に5回のうなりを聞き取ることになります。
実際に聞いてみましょう。
コードを書く
今まで作ったものを組み合わせてうなりのファイルを作ることができます。以下のようなwavファイルを作ります。
- 6秒の音声ファイル
- 最初の2秒は右と左の両方が500Hz
- 次の2秒は右が500Hz、左が501Hz
- 次の2秒は右が500Hz、左が505Hz
最初の2秒はうなりは聞こえません、次の2秒は1秒間に1回のゆっくりとしたうなり、最後は1秒間に5回のはやいうなりが聞こえるはずです。
タイムラインのインスタンスを作成します
TimeLine tl = new TimeLine();
パンを設定します。pan1は右、pan2は左です。
DoubleMap pan1 = new DoubleMap(0); DoubleMap pan2 = new DoubleMap(1);
基本の周波数を500Hzにします。
double freqC = 500;
右の周波数です。ずっと変わりません。
DoubleMap freq1 = new DoubleMap(freqC);
左の周波数です最初から2秒の少し前まで500Hzですが2秒から4秒の少し前まで501Hz、4秒目からずっと505Hzになります。
DoubleMap freq2 = new DoubleMap(freqC); freq2.putSecondValue(1.999, freqC); freq2.putSecondValue(2, freqC + 1); freq2.putSecondValue(3.999, freqC + 1); freq2.putSecondValue(4, freqC + 5);
タイムラインにサイン波のオシレータを使って設定します。そのごファイルに出力します。
tl.addReadable(0, new Panner(new OscillatorReader(new SineOscillator(), freq1, 6), pan1)); tl.addReadable(0, new Panner(new OscillatorReader(new SineOscillator(), freq2, 6), pan2)); WavFileWriter.create(tl, new File("wav/beat.wav"));
では聞いてみましょう。
うなりが聞こえたでしょうか?