我将保留解释,我的代码如何工作,非常短。我建议你自己尝试一下这个代码,所以也许你会更好地理解它。我有一个音频文件,并在我的代码中读取它。现在我使用函数FFT从时域切换到频域。但唯一的区别是,我正在对我的音频信号执行STFT。我每隔30ms做一次,直到我的信号长度。我知道,matlab中有许多不同的功能,它们也可以轻松地执行此操作,但是没有给我我需要的结果。现在,我每隔30ms绘制许多不同的频谱。但我把我的信号分成了三个频段。它们被称为LOW,MEDIUM和HIGH。基本上,这意味着我每隔30ms有3个不同的光谱图。我要做的下一步是将所有幅度从一个频谱汇总到一起,这意味着每个频谱有一个值,这是平方的。
现在,我拥有各种光谱的力量!所有这些值都在我的代码中绘制。我只是绘制功率值,否则我的代码执行时间会非常慢。
顺便说一句,代码看起来很长,但有两个for循环。在第一个中,我读取低频谱,当它完成时,第二个从中等和高频谱开始。基本上他们是一样的。我知道,我可以用findpeaks或类似的东西做到这一点。但是我该如何写/拉呢呢?或者做了什么必要的步骤。最后,我收录了一个文件,希望你能看到。 我想测量峰值并从红色图中获得它们之间的距离。
修改 好吧,我得到了山峰,但不是我想象的方式。我想显示高于5000线的峰值。很抱歉没有在开头清楚。看我的情节,我的意思。我想说我的代码,只应测量峰值,高于5000线。
[pks, locs] = findpeaks(ValuesOfYc);
p=plot(x,ValuesOfYc,'r-' ,x(locs), pks,'ob');
这就是我在上面的第一个循环中所做的。我该怎么办呢?
clear;
clc;
%% MATLAB
%% read file
%_________________________________________
[y,fs]=audioread('Undertale - Megalovania.wav');
% audioread = read wav -file
% y = contains the audio signal
% fs = 44100
% 'UnchainMyHeart' = name of the wav-file
%_________________________________________
%% PARAMETER FOR STFT
%_________________________________________
t_seg=0.03; % length of segment in ms
fftlen = 4096; %FFT-Points
% Defining size of frequency bands
f_low= 1:200; %lower frequencies
f_medium= 201:600; %medium frequencies
f_high= 601:1000; %higher frequencies
%__________________________________________
%% CODE
segl =floor(t_seg*fs);
windowshift=segl/2;
% defining the size of the window shift
window=hann(segl);
% apply hann function on segment length (30 ms)
window=window.';
% transpose vector
si=1;
% defining start index
ei=segl;
% defining end index
N=floor( length(y)/windowshift - 1);
% Calculates the number, how often the window has to shift
% until to length of the audio signal
f1=figure;
% Generating new window
f=0:1:fftlen-1;
f=f/fftlen*fs;
% defining frequency vector
Ya=zeros(1,fftlen);
ValuesOfYc = NaN(1,N);
ValuesOfYd = NaN(1,N);
ValuesOfYe = NaN(1,N);
x =(1:N)*windowshift/fs;
% defining x-axis
for m= 1:1:N
y_a = y(si:ei);
% a segment is taken out from audio signal length(30ms)
y_a= y_a.*window;
% multiplying segment with window (hanning)
Ya=fft(y_a, fftlen);
% Applying fft on segment
Yb=abs(Ya(1:end/2)).^2;
% Squaring the magnitudes from one-sided spectrum
drawnow; % Updating the graphical values
figure(f1);
% Showing the power values
%% frequency bands
y_low = Yb(f_low); % LOW frequency spectrum
Yc=sum(y_low);
% Summing all the power values from one frequency spectrum together
% so you get one power value from one spectrum
ValuesOfYc(m) = Yc;
%Output values are being saved here, which are generated from the for
%loop
% m = start variable from for loop
[pks, locs] = findpeaks(ValuesOfYc);
subplot(2,1,1)
p=plot(x,ValuesOfYc,'r-', x(locs(pks>=5000)), pks(pks>=5000),'ob');
p(1).LineWidth =0.5;
xlabel('time (Audio length)')
ylabel('Power')
grid on
si=si+windowshift;
% Updating start index
ei=ei+windowshift;
% Updating end index
end
for o= 1:1:N
y_a = y(si:ei);
% a segment is taken out from audio signal length(30ms)
y_a= y_a.*window;
% multiplying segment with window (hanning)
Ya=fft(y_a, fftlen);
% Applying fft on segment
Yb=abs(Ya(1:end/2)).^2;
% Squaring the magnitudes from one-sided spectrum
drawnow; % Updating the graphical values
figure(f1);
% Showing the power values
[![enter image description here][1]][1]
%% frequency bands
y_medium = Yb(f_medium); % MEDIUM frequency spectrum
y_high = Yb(f_high); % HIGH frequency spectrum
Yd=sum(y_medium);
Ye=sum(y_high);
% Summing all the power values from one frequency spectrum together
% so you get one power value from one spectrum
ValuesOfYd(o) = Yd;
ValuesOfYe(o) = Ye;
%Output values are being saved here, which are generated from the for
%loop
% m = start variable from for loop
subplot(2,1,2)
p=plot(x, ValuesOfYd,'g-', x, ValuesOfYe,'b-' );
p(1).LineWidth =0.5;
xlabel('time (Audio length)')
ylabel('Power')
grid on
si=si+windowshift;
% Updating start index
ei=ei+windowshift;
% Updating end index
end