Using the spectrogram function to analyse harmonic content
29 ビュー (過去 30 日間)
古いコメントを表示
What I'm trying to achieve;
I would like to use MATLAB to perform FFT on an audio file. The audio file is a recording of a single note of a musical instrument. I am trying to find the amplitude over time of each harmonic of the note.
Im first using the function
[y,fs]=audioread('sample.wav');
which creates a variable from the sample rate, and an array of each sample.
I then use
s=spectrogram(y,1024,512,fs);
which produces a matrix of 22051x580. Which is where I get a little lost. In fact I'm not certain, that is the best use of the function for my purpose.
So I believe that I'm right in thinking that the 22051 rows each correspond to a frequency, and that the file length (in seconds) divided by 580 would equal the time between each column. Is this correct?
Also, despite taking only the real parts of each result, many of them are negative. Is this due to negative phase?
Finally I'd greatly appreciate an idea of how I can process the results to extract the amplitude variation over time of just the harmonics of the note.
0 件のコメント
回答 (2 件)
Star Strider
2016 年 4 月 19 日
I don’t have your sound file so I can’t reply specifically to the data you get from it. The spectrogram function uses the surf function, so you can use that (or the mesh function as I did here) to see your signal in both frequency and time.
Run this code to get an idea how to approach your data:
fs = 4.41E+4;
t = linspace(0,2*fs,2*fs); % Time Vector
y = sin(2*pi*t*1000/fs).*exp(-2/fs*t); % Signal Vector
sound(y,fs) % Listen
figure(1)
plot(t, y)
grid
[s,f,t]=spectrogram(y,1024,512,fs);
[pks,idx] = findpeaks(abs(s(:,10)), 'MinPeakHeight',10); % Amplitude(s) & Index (Indices) Of Harmonics
figure(2)
mesh(t, f, abs(s))
grid on
xlabel('Time')
ylabel('Frequency')
So you would need to determine the columns that have your frequencies, then model each as an appropriate decaying exponential across rows.
Greg Dionne
2016 年 5 月 11 日
This plots the first 20 or so harmonics:
[y,fs] = audioread('Trumpet_C4.wav');
fund = 262;
spectrogram(y(1:20000),kaiser(2048,12),2048-441,(1:20)*fund,fs,'yaxis');
Or, if you like, you can show the voids in the middle too:
spectrogram(y,kaiser(2048,12),2048-441,(1:0.5:20)*fund,fs,'yaxis');
To get the power and frequencies out you can do:
[~,F,T,P] = spectrogram(y,kaiser(2048,12),2048-441,(1:0.5:20)*fund,fs);
That should give you the power output every 100ms or so (inspect the F and T vectors to get a sense of where the power is).
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Spectral Measurements についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!