forとend
forとendを使って音階を演奏する方法を説明する。
ここからは、再びSciNotesを使う。(SciNotesの使い方は->こちら)
myprogram1.sceをダブルクリックしよう。
このプログラムでは15個の音が半音階的にあがっていく。
まずプログラムの基本的な仕組みを理解しよう。
// myprogram1 - 音階の演奏 exec("initialize.sce"); for i=0:14 s=i*fs/4; n=i; f=440*2^(n/12); x(w+s+1)=x(w+s+1)+a.*r.*sin(2*%pi*f*t)*0.1; end play(x);for i=0:14
...繰り返される部分...
end
「for i=0:14」と書くと、forとendの間の命令が i=0に対して1回、, i=1に対して1回、という具合に15回実行される。
forの中身は
forの中では i の値によって以下のように計算が進む。
s=i*fs/4;
n=i;
とあるので、i=3であれば、
s=3*fs/4;
n=3;
となる。sは後で再生するときのサンプル数として使われる。
毎秒 fs = 44100 個のデータからできているので、
s=3*fs/4
とすると sは 3/4秒に相当するサンプル数になる。
音を重ねる
次に音符を一つx重ねる計算を見てみる
f=440*2^(n/12);
x(w+s+1)=x(w+s+1)+sin(2*%pi*f*t)*0.1;で音を一つ重ねることができる。
nを半音階毎の音階番号として周波数を計算し、その周波数の波形を再生される波形に重ねる。
(-->図解)
この計算を行うには、一般的には、
x(w+s+1)=x(w+s+1)+<tを使った式>
という形の式でなければならない。
x(w+s+1) は sサンプル目から始まる信号の一部であり、
x(w+s+1)=x(w+s+1) + <tを使った式>
という計算でその部分に<tを使った式>あらわされる波形を加算する。
音が加算されるタイミングは、s で指定されることになる。
(-->図解)
この部分はやや難しいから、よくわからなければ、変更しなければよい。
forが実行されると
そこで for が実行されると i の値が増えながら以下のように計算が進む。
i s (秒) n f xの音 0 0 0 0 440*2^(0/12) 440Hz=Aの音 1 11025 1/4 1 440*2^(1/12) A,A# 2 22050 2/4 2 440*2^(2/12) A,A#,B 3 33075 3/4 3 440*2^(3/12) A,A#,B,C 4 44100 4/4 4 440*2^(4/12) A,A#,B,C,C# 5 55125 5/4 5 440*2^(5/12) A,A#,B,C,C#,D 6 66150 6/4 6 440*2^(6/12) A,A#,B,C,C#,D,D# 7 77125 7/4 7 440*2^(7/12) A,A#,B,C,C#,D,D#,E ... このときこのプログラムではsは音符がスタートするタイミングのサンプル数として使われ、nは音符の半音で表した高さとして使われる。