nishimotzのブックマーク http://b.hatena.ne.jp/nishimotz/matlab/
$ cat my_wavplay.m
function my_wavplay(data, fs) % usage: % [data, fs] = wavread('input.wav'); % my_wavplay(data, fs); if ispc wavplay(data,fs); else name = '/tmp/_my_wavplay.wav'; wavwrite(data, fs, name); system(['play ', name]); % for linux end
more on / off doc 関数名 help 関数名 help . help i type 関数名 clf % clear current figure imagesc 二次元配列を濃淡グラフで表示する fft linspace plot specgram hanning(1024) : 窓関数の行列 hamming
カレントディレクトリの hoge.m はコマンド入力画面で hoge で呼び出せる。 コマンドプロンプトのバッチファイルみたいな感じ。
関数 hoge_func はファイル hoge_func.m に定義する。
specgram() を自分で作ってみる感じの例。
ついうっかり組み込み関数や定義済み定数の名前を、変数にしないように注意すること。
特に i とか j とかをループカウンタに使わないように。。
ここでは「カウンタには n とか k とかを使う」「迷ったら hoge_hemo のような長い変数名」でやっている。
代入の = と配列範囲指定の : は前後にスペースを入れるようにしている。
定数っぽい使い方の変数には「すべて大文字」を使っている。でも matlab は大文字と小文字を区別しないかも。
まず for 文をたくさん使ってしまった(かっこわるい)書き方。
前処理としてデータを平均 0 に、値の範囲を -1.0 .. +1.0 に正規化している。 hamming() は Signal Processing Toolkit の関数。
% fft_ana % d = load('data.txt')'; % 10.0,10.1, ... % fft_ana(d); data_length = length(data_org); SHIFT = 256; WINSIZE = 512; frame_count = floor(data_length / SHIFT); max_data_length = (frame_count - 1) * SHIFT + WINSIZE; data = zeros(max_data_length)'; data_mean = mean(data_org); for n=1 : data_length data(n) = data_org(n) - data_mean; end data_max = max(abs(data_org)); data = data ./ data_max; fft_data = zeros(frame_count, WINSIZE); hamming_data = hamming(WINSIZE); for n=1 : frame_count pos = (n-1) * SHIFT + 1; d = data(pos : pos + WINSIZE - 1); for k=1 : WINSIZE d(k) = d(k) * hamming_data(k); end e = fft(d); fft_data(n, :) = e; end imagesc(abs(fft_data)'); figure; plot(data(1:data_length));
fft() が返す複素数の配列は、先頭要素(インデックス1)に直流成分が入る。 2~512の値は折り返されて514~1024に入っている。 (つまり e(2) = e(1024) に、e(512) = e(514) になる)。
サンプリングレート10KHzの音声だとすると、 e(513) が 5KHz に対応する。 e(2) が 5000/512 Hz に対応する。
abs() は振幅。
angle() にすれば位相。unwrap(angle())すると位相を連続的に視覚化できる。