% Plots Fig. 7 shown in 'High-Precision Parallel Graphic Equalizer' by J.
% Rämö, V. Välimäki, and B. Bank

% 20.12.2013, Jussi Rämö

% load impulse responses of the analog, second-order, and fourth-order
% graphic equalizers
load filter_data;

Fs=44100;       % Sample rate
FSTART=20;      % Lowest band
FSTOP=20000;    % Highest band

% EQ center frequencies
eqfr = [20 25 31.5 40 50 63 80 100 125 160 200 250 315 400 500 630 800 1000 1250 1600 2000 2500 3150 ...
    4000 5000 6300 8000 10000 12500 16000 20000];
BANDS=length(eqfr);
eqfr=[0 eqfr Fs/2]; % Add extra frequency points to prevent target interpolation errors

% Set gains, every third up
eqgain = zeros(1,31);
eqgain(3:3:31) = 12;
eqgain = [eqgain(1) eqgain eqgain(end)];

fir = 1; % Parallel direct path b_o is in use


% creating target response via
% piecewise cubic hermite interpolation
targetfr=logspace(log10(10),log10(Fs/2),BANDS*10);
dBtarget=pchip(eqfr,eqgain,targetfr);
wtarget=2*pi*targetfr/Fs;

polefr = [20 22.4 25 28.2 31.5 35.5 40 44.7 50 56.2 63 70.8 80 89.1 100 112 125 141 160 178 200 224 250 282 315 355 400 447 ...
    500 562 630 708 800 891 1000 1120 1250 1410 1600 1780 2000 2240 2500 2820 3150 3550 4000 4470 5000 5620 6300 7080 8000 ...
    8910 10000 11200 12500 14100 16000 17800 20000];    % Pole frequencies
p=freqpoles([10 polefr]); % Compute poles
POLENUM=length(polefr); % Number of poles

% the design is done on double amount of points compared to pole freqs
designfr=logspace(log10(10),log10(Fs/2),POLENUM*2);
wdesign=2*pi*designfr/Fs;

% making the target minimumphase and resample at design points
minphtarget=minphasen(10.^(dBtarget/20),wtarget,2^14,wdesign);

% Frequency-dependent weghting
Wt = 1./abs(minphtarget).^2;

% designs the second-order sections [Bm,Am] and the FIR coefficient b_0
[Bm,Am,FIR]=parfiltdesfr(wdesign,minphtarget,p,fir,Wt);
parfresp=parfiltfresp(Bm,Am,FIR,wtarget);

eqgain_fc = eqgain(2:end-1); % gain slider positions


% Plot figures
figure(1);
yl = [-5 18]; % Ylim

% Calculate analog EQ spectrum
sig = filter_data.analog.everythird; % Analog equalizer
len = length(sig);
siz = floor(len/2);
spectr = abs(fft(sig));
spectr = 20*log10(spectr(1:siz)); 
dfreq = Fs/len;
len = length(spectr);
frq = linspace(0,dfreq*(len-1),len);
% Plot analog EQ
subplot(2,2,1)
semilogx(targetfr,dBtarget,'Color',[0.5 0.5 0.5],'LineWidth',4);
hold on;
semilogx(eqfr(2:end-1),eqgain_fc,'ok','LineWidth',1.5)
semilogx(frq,spectr,'k','LineWidth',2);
hold off;
xlim([20 20000]);
ylim(yl)
grid off;
set(gca,'XTick',[100 1000 10000]);
set(gca,'XTickLabel',{'100','1k','10k'},'Fontname','Times','Fontsize',18)
xlabel('Frequency (Hz)')
ylabel('Magnitude (dB)')
xlabel('Frequency (Hz)')

% Calculate second-order EQ spectrum
sig = filter_data.second.everythird; % second-order equalizer
len = length(sig);
siz = floor(len/2);
spectr = abs(fft(sig));
spectr = 20*log10(spectr(1:siz));
% Plot second-order EQ
subplot(2,2,2)
semilogx(targetfr,dBtarget,'Color',[0.5 0.5 0.5],'LineWidth',4);
hold on;
semilogx(eqfr(2:end-1),eqgain_fc,'ok','LineWidth',1.5)
semilogx(frq,spectr,'k','LineWidth',2);
hold off;
xlim([20 20000]);
ylim(yl)
grid off;
set(gca,'XTick',[100 1000 10000]);
set(gca,'XTickLabel',{'100','1k','10k'},'Fontname','Times','Fontsize',18)
xlabel('Frequency (Hz)')
ylabel('Magnitude (dB)')
xlabel('Frequency (Hz)')

% Calculate fourth-order EQ spectrum
sig = filter_data.fourth.everythird; % fourth-order equalizer
len = length(sig);
siz = floor(len/2);
spectr = abs(fft(sig));
spectr = 20*log10(spectr(1:siz));
% Plot fourth-order EQ
subplot(2,2,3)
semilogx(targetfr,dBtarget,'Color',[0.5 0.5 0.5],'LineWidth',4);
hold on;
semilogx(eqfr(2:end-1),eqgain_fc,'ok','LineWidth',1.5)
semilogx(frq,spectr,'k','LineWidth',2);
hold off;
xlim([20 20000]);
ylim(yl)
grid off;
set(gca,'XTick',[100 1000 10000]);
set(gca,'XTickLabel',{'100','1k','10k'},'Fontname','Times','Fontsize',18)
xlabel('Frequency (Hz)')
ylabel('Magnitude (dB)')
xlabel('Frequency (Hz)')

% Plot parallel EQ
subplot(2,2,4)
semilogx(targetfr,dBtarget,'Color',[0.5 0.5 0.5],'LineWidth',4);
hold on;
semilogx(eqfr(2:end-1),eqgain_fc,'ok','LineWidth',1.5)
semilogx(targetfr,db(parfresp),'k','LineWidth',2);
hold off;
xlim([20 20000]);
ylim(yl)
grid off;
set(gca,'XTick',[100 1000 10000]);
set(gca,'XTickLabel',{'100','1k','10k'},'Fontname','Times','Fontsize',18)
xlabel('Frequency (Hz)')
ylabel('Magnitude (dB)')
xlabel('Frequency (Hz)')


