Matlab Audio Filter with changing Frequency

5 views (last 30 days)
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 Comments
Hans Buchele
Hans Buchele on 1 Dec 2022
Hey Mathieu, thanks! Glad to have you on board!

Sign in to comment.

Accepted Answer

Mathieu NOE
Mathieu NOE on 1 Dec 2022
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 Comments
Mathieu NOE
Mathieu NOE on 9 Dec 2022
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

Sign in to comment.

More Answers (1)

jibrahim
jibrahim on 30 Nov 2022
Hi Hans,
Take a look at dsp.VariableBandwidthFIRFilter or dsp.VariableBandwidthIIRFIlter. They both support bandpass tunable filters.

Categories

Find more on Measurements and Spatial Audio in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by