サイン波sine waveは正弦波とも呼ばれますが音の波として一番シンプルなものとされています。以前作った矩形波も複数の波長の異なるサイン波に分解できます。ここからはサイン波を作るプログラムを考えます。その前に必要な知識を集めます。
サイン波の座標の求め方
サイン波について
上のグラフでx座標(横方向)は時間です。左から右へと時間が経過してきます。y座標(縦方向)は音量です。中央が0で+とー音量の幅があります。サイン波のy座標はJavaで以下のように求めます。
double y = Math.sin(x);
このxに何を入れるかが問題になります。xの単位はラジアンです。ラジアンは角度の単位で360度は2πラジアンになります。x方向は時間だと言いましたが角度と時間とどう関係づければ良いのでしょうか?
例えば一つの波が1周、つまりyの値が0から始まって最大と最小を通ってまた元の0に戻るまで、この前と後でy座標は同じ値0になります。これは2周しても3周しても同じです。
sin(x) = sin(x + 2π) = sin(x + 4π) = sin(x + 6π)
サンプリングレートと周波数
あるサンプルと次のサンプルの間の時間、つまり1サンプルに割り当てられる時間をtとします。
double t = 1.0 / 48000.0
実数にわざわざ小数.0をつけるのはdouble値として使うためです。
例えば440Hzの周波数のサイン波は1秒間に440周します。1周は2πラジアンなので1秒間に進む角度は440×2πになります。これがグラフのx方向に相当します。
1サンプルで進む角度を求めるにはこれに1サンプルあたりの時間tをかけます。Javaで書くと以下のようになります。
double omega_t = 440.0 * 2.0 * Math.PI * t;
これは「440Hzの周波数の音が1サンプル間で進む角度をラジアンで表したもの」で角周波数といってωt(オメガティー)と呼びます。
サイン波のy座標は以下のように求めれば良いことになります。Javaで表現しやすいように0ベースで説明しています。
- 0番目のy座標はsin(ωt x 0)
- 1番目のy座標はsin(ωt x 1)
- 2番目のy座標はsin(ωt x 2)
- 3番目のy座標はsin(ωt x 3)
Javaで計算し出力する
ではここまでのまとめの意味でJavaで処理を書いて実行します。
double sample_rate = 48000; double freq = 440; double t = 1d / sample_rate; double omega_t = freq * 2 * Math.PI * t; for(int i = 0;i < 100;i++){ double x = omega_t * i; double y = Math.sin(x); System.out.printf("x=%f, y=%f\n", x, y); }
以下はこの結果です。yが1に近い値まで増加してその後-1に近い値まで減少しまた増加する途中で終わっている様子が読めます。これを前に作成したグラフ表示に応用したものが上の画像になります。
wavファイルの波形を表示させる(1)
wavファイルの波形を表示させる(2)
wavファイルの波形を表示させる(3)
x=0.000000, y=0.000000 x=0.057596, y=0.057564 x=0.115192, y=0.114937 x=0.172788, y=0.171929 x=0.230383, y=0.228351 x=0.287979, y=0.284015 x=0.345575, y=0.338738 x=0.403171, y=0.392337 x=0.460767, y=0.444635 x=0.518363, y=0.495459 x=0.575959, y=0.544639 x=0.633555, y=0.592013 x=0.691150, y=0.637424 x=0.748746, y=0.680721 x=0.806342, y=0.721760 x=0.863938, y=0.760406 x=0.921534, y=0.796530 x=0.979130, y=0.830012 x=1.036726, y=0.860742 x=1.094321, y=0.888617 x=1.151917, y=0.913545 x=1.209513, y=0.935444 x=1.267109, y=0.954240 x=1.324705, y=0.969872 x=1.382301, y=0.982287 x=1.439897, y=0.991445 x=1.497492, y=0.997314 x=1.555088, y=0.999877 x=1.612684, y=0.999123 x=1.670280, y=0.995056 x=1.727876, y=0.987688 x=1.785472, y=0.977046 x=1.843068, y=0.963163 x=1.900664, y=0.946085 x=1.958259, y=0.925871 x=2.015855, y=0.902585 x=2.073451, y=0.876307 x=2.131047, y=0.847122 x=2.188643, y=0.815128 x=2.246239, y=0.780430 x=2.303835, y=0.743145 x=2.361430, y=0.703395 x=2.419026, y=0.661312 x=2.476622, y=0.617036 x=2.534218, y=0.570714 x=2.591814, y=0.522499 x=2.649410, y=0.472551 x=2.707006, y=0.421036 x=2.764602, y=0.368125 x=2.822197, y=0.313992 x=2.879793, y=0.258819 x=2.937389, y=0.202787 x=2.994985, y=0.146083 x=3.052581, y=0.088894 x=3.110177, y=0.031411 x=3.167773, y=-0.026177 x=3.225368, y=-0.083678 x=3.282964, y=-0.140901 x=3.340560, y=-0.197657 x=3.398156, y=-0.253758 x=3.455752, y=-0.309017 x=3.513348, y=-0.363251 x=3.570944, y=-0.416281 x=3.628540, y=-0.467930 x=3.686135, y=-0.518027 x=3.743731, y=-0.566406 x=3.801327, y=-0.612907 x=3.858923, y=-0.657375 x=3.916519, y=-0.699663 x=3.974115, y=-0.739631 x=4.031711, y=-0.777146 x=4.089306, y=-0.812084 x=4.146902, y=-0.844328 x=4.204498, y=-0.873772 x=4.262094, y=-0.900319 x=4.319690, y=-0.923880 x=4.377286, y=-0.944376 x=4.434882, y=-0.961741 x=4.492477, y=-0.975917 x=4.550073, y=-0.986856 x=4.607669, y=-0.994522 x=4.665265, y=-0.998890 x=4.722861, y=-0.999945 x=4.780457, y=-0.997684 x=4.838053, y=-0.992115 x=4.895649, y=-0.983255 x=4.953244, y=-0.971134 x=5.010840, y=-0.955793 x=5.068436, y=-0.937282 x=5.126032, y=-0.915663 x=5.183628, y=-0.891007 x=5.241224, y=-0.863396 x=5.298820, y=-0.832921 x=5.356415, y=-0.799685 x=5.414011, y=-0.763796 x=5.471607, y=-0.725374 x=5.529203, y=-0.684547 x=5.586799, y=-0.641450 x=5.644395, y=-0.596225 x=5.701991, y=-0.549023