Tools: Tune: EQ: Normalize IIR and FIR separately

This allows more freedom to scale the equalizers. Common criteria
resulted with safe scaling to unnecessarily silent result or
risk for audible clipping in the equalizer.

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
This commit is contained in:
Seppo Ingalsuo 2024-04-26 16:50:09 +03:00 committed by Kai Vehmanen
parent a2338e5103
commit 03dbc7ba2c
8 changed files with 50 additions and 44 deletions

View File

@ -87,8 +87,8 @@ function eq = test_response(fn, vn, fs)
eq = eq_defaults();
eq.fs = fs;
eq.enable_iir = 1;
eq.norm_type = 'peak';
eq.norm_offs_db = 1;
eq.iir_norm_type = 'peak';
eq.iir_norm_offs_db = 1;
%% Parametric EQ
eq.peq = [ ...

View File

@ -109,7 +109,9 @@ p.fir_compensate_iir = 1;
p.p_fmin = 10;
p.p_fmax = 30e3;
p.name = '';
p.norm_type = 'loudness'; % loudness/peak/1k
p.norm_offs_db = 0;
p.iir_norm_type = 'loudness'; % loudness/peak/1k
p.iir_norm_offs_db = 0;
p.fir_norm_type = 'loudness'; % loudness/peak/1k
p.fir_norm_offs_db = 0;
end

View File

@ -40,34 +40,37 @@ m_max_fir = max(eq.fir_eq_db);
m_max_iir = max(eq.iir_eq_db);
sens_fir = sum(m_lin_fir.*w_lin)/sum(w_lin);
sens_iir = sum(m_lin_iir.*w_lin)/sum(w_lin);
g_offs = 10^(eq.norm_offs_db/20);
g_offs_iir = 10^(eq.iir_norm_offs_db/20);
g_offs_fir = 10^(eq.fir_norm_offs_db/20);
%% Determine scaling gain
switch lower(eq.norm_type)
switch lower(eq.iir_norm_type)
case 'loudness'
g_fir = 1/sens_fir;
g_iir = 1/sens_iir;
case '1k'
g_fir = 1/m_lin_fir(i1k);
g_iir = 1/m_lin_iir(i1k);
case 'peak'
g_fir = 10^(-m_max_fir/20);
g_iir = 10^(-m_max_iir/20);
otherwise
error('Requested normalization is not supported');
error('Requested IIR normalization is not supported');
end
switch lower(eq.fir_norm_type)
case 'loudness'
g_fir = 1/sens_fir;
case '1k'
g_fir = 1/m_lin_fir(i1k);
case 'peak'
g_fir = 10^(-m_max_fir/20);
otherwise
error('Requested FIR normalization is not supported');
end
%% Adjust FIR and IIR gains if enabled
if eq.enable_fir && eq.enable_iir
eq.b_fir = eq.b_fir * g_fir * g_offs;
eq.p_k = eq.p_k * g_iir * g_offs;
if eq.enable_fir
eq.b_fir = eq.b_fir * g_fir * g_offs_fir;
end
if eq.enable_fir && eq.enable_iir == 0
eq.b_fir = eq.b_fir * g_fir * g_offs;
end
if eq.enable_fir == 0 && eq.enable_iir
eq.p_k = eq.p_k * g_iir * g_offs;
if eq.enable_iir
eq.p_k = eq.p_k * g_iir * g_offs_iir;
end
%% Re-compute response after adjusting gain

View File

@ -173,10 +173,10 @@ m = [ 0.00,-0.13,-0.27,-0.39,-0.52,-0.64,-0.77,-0.89,-1.02,-1.16, ...
%% Design EQ
eq = eq_defaults();
eq.fs = fs;
eq.target_f = f; % Set EQ frequency response target: frequencies Hz
eq.target_m_db = m; % Set EQ frequency response target: magnitudues dB
eq.norm_type = 'loudness'; % Normalize criteria can be loudness/peak/1k
eq.norm_offs_db = 0; % Offset in dB to normalize
eq.target_f = f; % Set EQ frequency response target: frequencies Hz
eq.target_m_db = m; % Set EQ frequency response target: magnitudues dB
eq.fir_norm_type = 'loudness'; % Normalize criteria can be loudness/peak/1k
eq.fir_norm_offs_db = 0; % Offset in dB to normalize
eq.enable_fir = 1; % By default both FIR and IIR disabled, enable one
eq.fir_beta = 4.0; % Use with care, low value can corrupt
@ -203,8 +203,8 @@ eq.parametric_target_response = [ ...
%% Design EQ
eq.fs = fs;
eq.norm_type = 'peak'; % Can be loudness/peak/1k to select normalize criteria
eq.norm_offs_db = 0; % E.g. -1 would leave 1 dB headroom if used with peak
eq.fir_norm_type = 'peak'; % Can be loudness/peak/1k to select normalize criteria
eq.fir_norm_offs_db = 0; % E.g. -1 would leave 1 dB headroom if used with peak
eq.enable_fir = 1; % By default both FIR and IIR disabled, enable one
eq.fir_beta = 3.5; % Use with care, low value can corrupt

View File

@ -62,8 +62,8 @@ function eq = lo_band_iir(fs)
eq = eq_defaults();
eq.fs = fs;
eq.enable_iir = 1;
eq.norm_type = 'peak';
eq.norm_offs_db = 0;
eq.iir_norm_type = 'peak';
eq.iir_norm_offs_db = 0;
%% Manually setup low-shelf and high shelf parametric equalizers
%
@ -95,8 +95,8 @@ function eq = hi_band_iir(fs)
eq = eq_defaults();
eq.fs = fs;
eq.enable_iir = 1;
eq.norm_type = 'peak';
eq.norm_offs_db = 0;
eq.iir_norm_type = 'peak';
eq.iir_norm_offs_db = 0;
%% Manually setup low-shelf and high shelf parametric equalizers
%

View File

@ -267,8 +267,8 @@ eq.fs = fs;
eq.target_f = f;
eq.target_m_db = m;
eq.enable_iir = 1;
eq.norm_type = 'loudness';
eq.norm_offs_db = 0;
eq.iir_norm_type = 'loudness';
eq.iir_norm_offs_db = 0;
%% Manually setup low-shelf and high shelf parametric equalizers
%
@ -300,8 +300,8 @@ function eq = hp_iir_eq(fs, fc, gain_db)
eq = eq_defaults();
eq.fs = fs;
eq.enable_iir = 1;
eq.norm_type = '1k';
eq.norm_offs_db = gain_db;
eq.iir_norm_type = '1k';
eq.iir_norm_offs_db = gain_db;
% Design
eq.peq = [ eq.PEQ_HP2 fc NaN NaN ];
@ -316,8 +316,8 @@ function eq = bassboost_iir_eq(fs)
eq = eq_defaults();
eq.fs = fs;
eq.enable_iir = 1;
eq.norm_type = 'loudness';
eq.norm_offs_db = 0;
eq.iir_norm_type = 'loudness';
eq.iir_norm_offs_db = 0;
% Design
eq.peq = [ ...
@ -335,8 +335,8 @@ function eq = bandpass_iir_eq(fs)
eq = eq_defaults();
eq.fs = fs;
eq.enable_iir = 1;
eq.norm_type = 'loudness';
eq.norm_offs_db = 0;
eq.iir_norm_type = 'loudness';
eq.iir_norm_offs_db = 0;
% Design EQ
eq.peq = [ ...

View File

@ -46,8 +46,10 @@ eq = eq_defaults();
eq.fs = fs; % Default sample rate in SOF
eq.enable_fir = 1; % Try enabling and disabling FIR part
eq.enable_iir = 1; % Try enabling and disabling IIR part
eq.norm_type = 'peak'; % Scale filters to have peak at 0 dB
eq.norm_offs_db = 0; % Can be used to control gain
eq.iir_norm_type = 'peak'; % Scale filters to have peak at 0 dB
eq.iir_norm_offs_db = 0; % Can be used to control gain
eq.fir_norm_type = 'peak'; % Scale filters to have peak at 0 dB
eq.fir_norm_offs_db = 0; % Can be used to control gain
eq.p_fmin = 100; % With this data start plots from 100 Hz
eq.p_fmax = 20e3; % and end to 20 kHz.

View File

@ -464,15 +464,15 @@ function push_config(h, evnt)
eq_left = eq_defaults();
eq_left.enable_iir = 1;
eq_left.peq = build_peq(1, EQ);
eq_left.norm_type = 'peak';
eq_left.norm_offs_db = 0;
eq_left.iir_norm_type = 'peak';
eq_left.iir_norm_offs_db = 0;
eq_left.fs = get_config().Fs;
eq_right = eq_defaults();
eq_right.enable_iir = 1;
eq_right.peq = build_peq(2, EQ);
eq_right.norm_type = 'peak';
eq_right.norm_offs_db = 0;
eq_right.iir_norm_type = 'peak';
eq_right.iir_norm_offs_db = 0;
eq_right.fs = get_config().Fs;
eq_left = eq_compute(eq_left);
@ -504,4 +504,3 @@ function update_control_elements(section, EQ)
set_udata_field(section.type.dropdown, "EQ", EQ);
set_udata_field(section.enable_switch, "EQ", EQ);
end