octave を使う方法.
octave: > sig = wavread('doremi.wav');
Input file 'doremi.wav' is RIFF format:
Total length = 1056676 bytes
Number of channels = 2
Sampling rate = 44100 Hz
Data length = 528320 samples
ステレオなので sig は2チャンネル分ある.
めんどうなのでモノラルにしよう.
octave: > sig = sig(:,1);
octave: > whos # 変数がどうなっているか確認
octave: > fs = 44100; # サンプリング周波数 (CD と同じ)
octave: > a = size(sig)(:,1) -1; # a にはデータの数 -1 が入る.
octave: > t = 0: 1/fs : a/fs; # 横軸の作成.
octave: > plot (t,sig.')
octave: > sound(sig, fs); # 作った信号の音を聞いてみる (3秒間)
octave: > Y = fft(sig, 1024); # 最初の1024個のデータをフーリエ変換
octave: > f = (0:512)/1024*44100; # 周波数軸を作成
octave: > plot(f,20*log10(abs(Y(1:513)))); # フーリエ変換後のデータを表示(絶対値)
octave: > sp = fft(sig(16001:17024).*hamming(1024));
octave: > f = (0:512)/1024*44100;
octave: > plot(f,20*log10(abs(sp(1:513))));
octave: > [x, ix] = max(20*log10(abs(sp(1:513))))
x = 34.457
ix = 7
octave:15> ix/1024*44100
ans = 301.46 # ピークの周波数
octave: あとは for 文で回せばよい.
transcription.m
sig = wavread('doremi.wav');
sig = sig(:,1);
fs = 44100; # サンプリング周波数 (CD と同じ)
# nf = 4096;
nf = 8196;
a = size(sig)(:,1) -1; # a にはデータの数 -1 が入る.
t = 0: 1/fs : a/fs; # 横軸の作成.
f = (0:nf/2)/nf*44100;
for i = 1:4410:(size(sig)-nf/2) # 0.1 sec おきに測定
sp = fft(sig(i:i+nf-1).*hamming(nf));
# sp = fft(sig(i:i+nf-1));
[x, ix] = max(20*log10(abs(sp(1:nf/2+1))));
peak = ix/nf*44100;
# disp(i)
disp(peak)
endfor
C 261
D 293
E 329
F 349
G 391
A 440
B 493
C 523
% octave transcription.m
263.65
263.65
263.65
269.03
269.03
295.94
295.94
295.94
295.94
333.60
333.60
333.60
333.60
333.60
355.12
355.12
355.12
355.12
355.12
355.12
398.17
398.17
398.17
398.17
441.22
441.22
446.60
446.60
441.22
500.40
500.40
500.40
500.40
995.42
532.69
527.31
527.31
527.31
527.31
527.31
495.02
1049.2
527.31
527.31
527.31
500.40
527.31
527.31
495.02
527.31
少しおかしい。
どこがおかしいか考えてみる。