MATLAB: IIR filter to correspond 5ms attack and 20ms release times

attackdrcframe powerrelease

I have Fs=16kHz audio signals and processing it frame-by-frame using 10ms frames. I am calculating the envelope of a signal by its root mean square value ("Pow") and trying to filter with 1st order IIR filter to correspond attack and release times of 5ms and 20ms respectively. Aim is to select compressor gain based on this filtered frame power value. Any help how to CORRECT values for the filter?
attack = 0.1350: % not equal to 5ms attack, how to get it correct?
release = 0.6050; % not equal to 20ms release, how to get it correct?
diff = PowIIR – Pow;
tmp_coeff = attack;
if(diff > 0) tmp_coeff = release; end
PowIIR = Pow + (diff * tmp_coeff);
Any help available?

Best Answer

hello again
so this is a very simple code that gives you the filter coeficients vs rise / fall constant times and Fs.
you can change the a and b value in the recursive equation on the fly, based on you Pow signal.
enjoy
% Example: Impulse Response Using MATLAB
% first order IIR filter
% recursive equation : y(k) = a*y(k-1) + b*x(k)
% NB : for unitary gain filter : b = 1-a
clc
clear all
Fs = 16e3;
dt = 1/Fs;
samples = 1000;
n = 0:samples-1;
t = n*dt;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



% filters coeffs for attack
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
time_constant = 5e-3; % 5 ms to reach 90% of asymptote amplitude
nn= round(time_constant/dt); % rise time in samples

a1 = (1-0.9)^(1/nn); % here the "0.9" correpond to 90% of asymptote amplitude

b1 = 1-a1;
x = [ones(1,samples)]; % step sequence input

y1 = filter([b1 0],[1 -a1],x);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% filters coeffs for release
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
time_constant = 20e-3; % 20 ms to reach 90% of asymptote amplitude
nn= round(time_constant/dt); % rise time in samples
a2 = (1-0.9)^(1/nn); % here the "0.9" correpond to 90% of asymptote amplitude
b2 = 1-a2;
x = [ones(1,samples)]; % step sequence input
y2 = filter([b2 0],[1 -a2],x);
figure(1),plot(t,y1,'-*b',t,y2,'-*r')
ylabel('Step Response h[n]')
xlabel('Time (s)')
legend('attack','release');