2017-12-30 28 views
0

私は曲の特定の時間にどの周波数(ノート)が再生されているかを示すコードを書いていますそれは曲の最初の2分音符だけを掴んでテストしている)。これを行うには、オーディオファイルの最初の1秒を8つの異なるチャンクに分割します。それから私は、各チャンクにFFTを実行し、次のコードでそれをプロットします。私はあまりにもプロットしていますように enter image description here enter image description hereFFT:fs/2サンプル未満のときに片側スペクトルを見つける方法

に見えます:私はこれらのように見えるのグラフを得ることを行うと

% Taking a second of an audio file and breaking it into n many chunks and 
% figuring out what frequencies make up each of those chunks 
clear all; 

% Read Audio 
fs = 44100;   % sample frequency (Hz) 
full = audioread('song.wav'); 

% Perform fft and get frequencies 
chunks = 8;   % How many chunks to break wave into 
for i = 1:chunks 
    beginningChunk = (i-1)*fs/chunks+1 
    endChunk = i*fs/chunks 
    x = full(beginningChunk:endChunk); 
    y = fft(x); 
    n = length(x);  % number of samples in chunk 
    amp = abs(y)/n; % amplitude of the DFT 
    %%%amp = amp(1:fs/2/chunks); % note this is my attempt that I think is wrong 
    f = (0:n-1)*(fs/n);  % frequency range 
    %%%f = f(1:fs/2/chunks); % note this is my attempt that I think is wrong 

    figure(i); 
    plot(f,amp) 
    xlabel('Frequency') 
    ylabel('amplitude') 
end 

グラフの右端に周波数が上がるので、私は両面スペクトルを使用していると考えています。私は1:fs/2のサンプルしか使用しないといけないと思うが、問題は多くのポイントをつかむのに十分な行列がないということだ。私は1:fs/2/chunkから行ってみましたが、それらが正しい値であると私は確信していますので、それらをコメントしました。 fs/2サンプル未満の場合、どのように片側スペクトルを見つけることができますか?

私がすべてのグラフをプロットするとき、私は与えられた周波数がほぼ同じであることに気付きます。これは私にとって驚くべきことです。私は、ちょうどその時に起こっている周波数だけが掴まれるべきであるように、チャンクを小さくしたと思っていました。それゆえ、私は現在のノートを演奏しています。誰かがどのようにノートが毎回再生されているかを分かりやすくすることが分かっていれば、その情報は非常に高く評価されます。

+0

[この質問](https://stackoverflow.com/q/4364823/253056)(可能な重複?)を参照してください。 –

答えて

1

片面FTについては、FFTアルゴリズムの出力の最初の半分を取るだけです。残りの半分(ネイティブ周波数)は入力が実数であることを考えると冗長です。

1/8秒はかなり長いです。私が正しく覚えていれば、関連する周波数は約160-1600Hzです(音楽は私の専門ではありません)。それらはあなたのFTの一番左側にあります。あなたが計算する最も高い周波数(FFTの右半分を落とした後)は、サンプリング周波数の半分、44.1/2kHzです。最も低い周波数とサンプル間の距離は、変換の長さ(44.1 kHz /サンプル数)によって与えられます。

+0

問題を修正しました。私はチャンクを3200に変更しました。私はすべてのグラフが、グラフの左側が高く、グラフの右側が低く(1/xのグラフのように)、[https://imgur.com/a/ u2K9M](このような)。グラフが常にこのように見える理由があったら、私は興味がありました。それは、どの周波数が演奏されているかを引き出すのを難しくします。 –

+0

最初のビンは、f = 0の場合、通常は最高ですが、信号の平均をエンコードします。図のリンクでは、3000Hzを超える周波数ステップがあります。つまり、関連する頻度で値を読み取ることはできません。ミドルCと次のハーフ・ノート(https://en.m.wikipedia.org/wiki/)を区別したい場合は、周波数ステップ・サイズが最大16 Hzになるようにチャンクのサイズを設定する必要があります。 Piano_key_frequencies)。周波数スペクトルを補間することはできませんので、各周波数を読み取るのに十分な密度でサンプリングする必要があります。 –

+0

16hZは速すぎて一度に個々のノートを選びませんか?チャンクサイズ/ Hzのような変数を調整するだけで個々の音符を分離することができますか、別のアルゴリズムを使用する必要がありますか。私は発症の検出に目を向け、それが有用かもしれないと思うが、私はそれを使う必要があるのか​​、それともより良いアルゴリズムがあるのか​​分からない。 –

関連する問題