I’ve been playing with signal processing and I would like to apply an “equal loudness filter” to a track, as is done during calculation of Replay Gain values. I’ve been using this Replay Gain documentation as a guide. At this point I have not been able to figure out how to reproduce the “average inverse equal loudness curve” shown. I think it should be possible to use the equations of the yulewalk and butter functions, along with the filter coefficients given here, to generate the curve. So far I’ve just been using the yulewalk equation thinking that:
B(z)/A(z) = Amplitude and,
z = Frequency
But somehow I don’t get the expected curve shape (the one with a good fit on the right side), never mind the units.
Anyone know where I’m fooling up?
Are you referring to this file...
http://replaygain.hydrogenaudio.org//equal_loud_coef.txt
This contains the IIR filter coefficients, not amplitude vs frequency data!
If you want to make an IIR filter, then read a book, use google, or just look at the source code for other ReplayGain implementations (mp3gain, MusePack ReplayGain, VorbisGain etc).
If you want amplitude vs frequency data, see this MATLAB file which I used to generate the filter coefficients...
function [a1,b1,a2,b2]=equalloudfilt(fs)
% Design a filter to match equal loudness curves
% 9/7/2001
% If the user hasn't specified a sampling frequency, use the CD default
if nargin<1,
fs=44100;
end
% Specify the 80 dB Equal Loudness curve
if fs==44100 | fs==48000,
EL80=[0,120;20,113;30,103;40,97;50,93;60,91;70,89;80,87;90,86;100,85;200,78;300,76;400,76;500,76;600,7
6;700,77;800,78;900,79.5;1000,80;1500,79;2000,77;2500,74;3000,71.5;3700,70;4000,70.5;5000,74;6000,79
;
7000,84;8000,86;9000,86;10000,85;12000,95;15000,110;20000,125;fs/2,140];
elseif fs==32000,
EL80=[0,120;20,113;30,103;40,97;50,93;60,91;70,89;80,87;90,86;100,85;200,78;300,76;400,76;500,76;600,7
6;700,77;800,78;900,79.5;1000,80;1500,79;2000,77;2500,74;3000,71.5;3700,70;4000,70.5;5000,74;6000,79
;
7000,84;8000,86;9000,86;10000,85;12000,95;15000,110;fs/2,115];
else
error('Filter not defined for current sample rate');
end
% convert frequency and amplitude of the equal loudness curve into format suitable for yulewalk
f=EL80(:,1)./(fs/2);
m=10.^((70-EL80(:,2))/20);
% Use a MATLAB utility to design a best bit IIR filter
[b1,a1]=yulewalk(10,f,m);
% Add a 2nd order high pass filter at 150Hz to finish the job
[b2,a2]=butter(2,(150/(fs/2)),'high');
EL80=
... defines the 80dB equal loudness curve (IIRC it's slightly modified from the real data to make yulewalk converge better)
f=EL80(:,1)./(fs/2);
normalises the frequency range for the current sample rate
m=10.^((70-EL80(:,2))/20);
takes the 80dB Equal loudness curve, inverts it, and converts it to a linear scale.
There's a longer version (more comments, more sample rates, draws graphs) on the ReplayGain website...
http://replaygain.hydrogenaudio.org//mfiles/equalloud.m
see the the page about the Equal Loudness curve for details.
Hope this helps.
Cheers,
David.
P.S. sorry for the wide post!