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は音符の半音で表した高さとして使われる。