Matlab Audio Filter with changing Frequency
6 ビュー (過去 30 日間)
古いコメントを表示
Dear Matlab Community, I am working on project where I need to be able to filter/extract a frequency band which should be „tuneable“ over time. For example: I am interested in the frequency range 220 to 240 for 0.5 seconds, then the range should gradually go up to 320 to 340 in 1 second. Ideal would be a solution similar to an envelope where time and frequency can be inserted. There is modern audio software, where it is possible to draw a selection and then export that as an audio file but I am looking for an automated solution since I need to do that many hundreds time. Any help is much appreciated thanks!
2 件のコメント
Mathieu NOE
2022 年 11 月 30 日
hello Hans and welcome back !
this code is the IIR filtering of a signal with fixed filter coefficients
now we could make the coefficients variable with time , this is my next step for tomorrow..
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load signal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% data
[x,Fs] = audioread('test_voice_mono.wav');
[samples,channels] = size(x);
dt = 1/Fs;
time = (0:samples-1)*dt;
%% IIR filter recursive equation
c1 = 8;
c2 = 2;
c3 = 7;
b0 = 0.05 * c1;
b1 = 0.03 * c2;
b2 = 0.02 * c3;
a1 = 0.5;
a2 = 0.5;
% manual for loop coding IIR filter
y(1) = b0*x(1) + 0 + 0 + 0 + 0; % 1st iteration
y(2) = b0*x(2) + b1*x(1) + 0 + a1*y(1) + 0; % 2nd iteration
for k = 3:samples % for iteration # 3 and after
y(k) = b0*x(k) + b1*x(k-1) + b2*x(k-2) + a1*y(k-1) + a2*y(k-2);
end
figure(1)
plot(time,x,time,y)
採用された回答
Mathieu NOE
2022 年 12 月 1 日
hello again
so this is a variable coefficient IIR implementation
I used a white noise as test signal, the output signal shows that the spectral content follows the time / frequency characteristics of the bandpass filter.
The for loop could be made faster with a custom made digital filter coefficients computation that will be faster than the call to the built in function butter
Fs = 2000;
x = randn(Fs*3,1); % 3 seconds duration signal (white noise)
[samples,channels] = size(x);
dt = 1/Fs;
time = (0:samples-1)*dt;
%% filter time / frequency characteristics
% 1/ fixed frequency range 220 to 240 for first 0.5 seconds,
stop_sample1 = round(0.5*Fs); % at this iteration value we change to variable IIR (for loop)
flow = 220;
fhigh = 240;
N = 4;
[B,A] = butter(N,2/Fs*[flow fhigh]);
nB = length(B);
nA = length(A);
yy = filter(B,A,x); % init output with fixed characteristics filter
% 2/ frequency ramp up 220 / 240 to 320 to 340 in 1 second.
flow2 = 320;
fhigh2 = 340;
freq_slope_low = (flow2-flow)/Fs /1; % the 1 is for 1 second.
freq_slope_high = (fhigh2-fhigh)/Fs /1; % the 1 is for 1 second.
% IIR filter for loop
y = yy; % init y for samples 1 to stop_sample1
for k = stop_sample1:samples % for iteration >= nB sample
flowk = min(flow2,flow + freq_slope_low*(k-stop_sample1)); % current flow at iteration k
fhighk = min(fhigh2,fhigh + freq_slope_high*(k-stop_sample1)); % current fhigh at iteration k
N = 4;
[B,A] = butter(N,2/Fs*[flowk fhighk]);
% main recursion
y(k) = B*x(k:-1:k-nB+1) - A(2:nA)*y(k-1:-1:k-nA+1);
end
figure(1)
NFFT = 512;
specgram(y,NFFT,Fs,hanning(NFFT),round(0.75*NFFT)) ;
2 件のコメント
Mathieu NOE
2022 年 12 月 9 日
ok
I supposed your hear glitches ? that is something I discovered later .... and finally ended up reading some good publications about the issues regarding time varying filters
その他の回答 (1 件)
jibrahim
2022 年 11 月 30 日
Hi Hans,
Take a look at dsp.VariableBandwidthFIRFilter or dsp.VariableBandwidthIIRFIlter. They both support bandpass tunable filters.
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Simulation, Tuning, and Visualization についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!