gpt4 book ai didi

matlab - 谐波的振幅大于基波的振幅

转载 作者:行者123 更新时间:2023-12-03 00:52:47 30 4
gpt4 key购买 nike

我正在编写MATLAB代码以检测钢琴录音中的频率。

我使用了使用键盘录制的C缩放音频文件(C4 D4 E4 F4 G4 A4 B4 C5)

当我简单地执行FFT(不打断窗口)时,基频具有较高的幅度,这是非常好的。

但是,更准确地说,我做了以下步骤
1.用高斯边缘检测滤波器对我的音频信号进行快速卷积以获得包络。
2.实现了峰值检测算法以查找音符发作。
3.每次演奏时,我对每个音符执行FFT,以获得每个音符的FFT。
但是,当我对上面提到的音频文件执行此操作时,我得到错误的结果,有时谐波的幅度比1st高。

clear all;
clear max;
clc;

%% create 5s sample at 10kHz with tone from 1s to 2s
FS = 10000; % 10kHz
N=5*FS;
song = randn(N,2)/10;
song(FS:2*FS,:)=10*repmat(sin(261*pi*2*(0:FS)/FS)',1,2)+song(FS:2*FS,:);

P = 2000;
t=0:1/FS:(N-1)/FS; % define time period


song = sum(song,2);
song=abs(song);


%----------------------Finding the envelope of the signal-----------------%
% Gaussian Filter
x = linspace( -1, 1, P); % create a vector of P values between -1 and 1 inclusive
sigma = 0.335; % standard deviation used in Gaussian formula
myFilter = -x .* exp( -(x.^2)/(2*sigma.^2)); % compute first derivative, but leave constants out
myFilter = myFilter / sum( abs( myFilter ) ); % normalize


% fft convolution
myFilter = myFilter(:); % create a column vector
song(length(song)+length(myFilter)-1) = 0; %zero pad song
myFilter(length(song)) = 0; %zero pad myFilter
edges =ifft(fft(song).*fft(myFilter));

tedges=edges(P:N+P-1); % shift by P/2 so peaks line up w/ edges
tedges=tedges/max(abs(tedges)); % normalize

%---------------------------Onset Detection-------------------------------%
% This section does the peak picking algorithm
max_col = maxtab(:,1);
peaks_det = max_col/FS;
No_of_peaks = length(peaks_det);

%---------------------------Performing FFT--------------------------------

song_seg = song(max_col(1):max_col(2)-1);
L = length(song_seg);
NFFT = 2^nextpow2(L); % Next power of 2 from length of y

seg_fft = fft(song_seg,NFFT);%/L;

f = FS/2*linspace(0,1,NFFT/2+1);
seg_fft2 = 2*abs(seg_fft(1:NFFT/2+1));
L5 = length(song_seg);

fmin = 60;
fmax = 1000;
region_of_interest = fmax>f & f>fmin;
froi = f(region_of_interest);

[p_max,loc] = max(seg_fft2(region_of_interest));

% index into froi to find the frequency of the peaks
p_max;


f_p_max = froi(loc);

[points, locatn] = findpeaks(seg_fft2(region_of_interest));
aboveMax = points > 0.4*p_max;

if any(aboveMax)
peak_points = points(aboveMax)
f_peak = froi(locatn(aboveMax))

end

end

我在这里做错了什么?真的很需要这里的帮助……

可以看出,根本没有检测到D4的f0,而C4和E4的f0的振幅比谐波小。

最佳答案

过滤绝对值(歌曲)可以找到包络,但是要找到峰值时,您需要先计算原始信号(不包括“绝对值”)。

要查看区别,请尝试:

clear;
FS = 10000;
s=sin(261*pi*2*(0:FS)/FS);
NFFT = 2^nextpow2(length(s));
S1=fft(s,NFFT);
S2=fft(abs(s),NFFT);
f = FS/2*linspace(0,1,NFFT/2+1);
plot(f,abs(S1(1:NFFT/2+1))); % peak near 261
plot(f,abs(S2(1:NFFT/2+1))); % peak near 522

关于matlab - 谐波的振幅大于基波的振幅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19157106/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com