function [z, p, k] = eq_define_parametric_eq(peq, fs) %% % Copyright (c) 2016, Intel Corporation % All rights reserved. % % Redistribution and use in source and binary forms, with or without % modification, are permitted provided that the following conditions are met: % * Redistributions of source code must retain the above copyright % notice, this list of conditions and the following disclaimer. % * Redistributions in binary form must reproduce the above copyright % notice, this list of conditions and the following disclaimer in the % documentation and/or other materials provided with the distribution. % * Neither the name of the Intel Corporation nor the % names of its contributors may be used to endorse or promote products % derived from this software without specific prior written permission. % % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE % IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE % ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE % LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE % POSSIBILITY OF SUCH DAMAGE. % % Author: Seppo Ingalsuo % % Parametric types PEQ_HP1 = 1; PEQ_HP2 = 2; PEQ_LP1 = 3; PEQ_LP2 = 4; PEQ_LS1 = 5; PEQ_LS2 = 6; PEQ_HS1 = 7; PEQ_HS2 = 8; PEQ_PN2 = 9; PEQ_LP4 = 10; PEQ_HP4 = 11; sp = size(peq); z = []; p = []; k = 1; for i=1:sp(1) type = peq(i,1); f = peq(i,2); g = peq(i,3); Q = peq(i,4); if f < fs/2 a0 = []; b0 = []; z0 = []; p0 = []; k0 = []; switch peq(i,1) case PEQ_HP1, [z0, p0, k0] = butter(1, 2*f/fs, 'high'); case PEQ_HP2, [z0, p0, k0] = butter(2, 2*f/fs, 'high'); case PEQ_HP4, [z0, p0, k0] = butter(4, 2*f/fs, 'high'); case PEQ_LP1, [z0, p0, k0] = butter(1, 2*f/fs); case PEQ_LP2, [z0, p0, k0] = butter(2, 2*f/fs); case PEQ_LP4, [z0, p0, k0] = butter(4, 2*f/fs); case PEQ_LS1, [b0, a0] = low_shelf_1st(f, g, fs); case PEQ_LS2, [b0, a0] = low_shelf_2nd(f, g, fs); case PEQ_HS1, [b0, a0] = high_shelf_1st(f, g, fs); case PEQ_HS2, [b0, a0] = high_shelf_2nd(f, g, fs); case PEQ_PN2, [b0, a0] = peak_2nd(f, g, Q, fs); otherwise error('Unknown parametric EQ type'); end if length(a0) > 0 [z0, p0, k0] = tf2zp(b0, a0); end if length(k0) > 0 z = [z ; z0(:)]; p = [p ; p0(:)]; k = k * k0; end end end end function [b, a] = low_shelf_1st(fhz, gdb, fs) zw = 2*pi*fhz; w = wmap(zw, fs); glin = 10^(gdb/20); bs = [1 glin*w]; as = [1 w]; [b, a] = my_bilinear(bs, as, fs); end function [b, a] = low_shelf_2nd(fhz, gdb, fs) zw = 2*pi*fhz; w = wmap(zw, fs); glin = 10^(gdb/20); bs = [1 w*sqrt(2*glin) glin*w^2]; as = [1 w*sqrt(2) w^2]; [b, a] = my_bilinear(bs, as, fs); end function [b, a] = high_shelf_1st(fhz, gdb, fs) zw = 2*pi*fhz; w = wmap(zw, fs); glin = 10^(gdb/20); bs = [glin w]; as = [1 w]; [b, a] = my_bilinear(bs, as, fs); end function [b, a] = high_shelf_2nd(fhz, gdb, fs) zw = 2*pi*fhz; w = wmap(zw, fs); glin = 10^(gdb/20); bs = [glin w*sqrt(2*glin) w^2]; as = [1 w*sqrt(2) w^2]; [b, a] = my_bilinear(bs, as, fs); end function [b, a] = peak_2nd(fhz, gdb, Q, fs) % Reference http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt A = 10^(gdb/40); % Square root of linear gain wc = 2*pi*fhz/fs; alpha = sin(wc)/(2*Q); b0 = 1 + alpha * A; b1 = -2 * cos(wc); b2 = 1 - alpha * A; a0 = 1 + alpha / A; a1 = -2 * cos(wc); a2 = 1 - alpha / A; b = [b0 / a0 b1 / a0 b2 / a0]; a = [1 a1 / a0 a2 / a0]; end function [b, a] = my_bilinear(sb, sa, fs) if exist('OCTAVE_VERSION', 'builtin') [b, a] = bilinear(sb, sa, 1/fs); else [b, a] = bilinear(sb, sa, fs); end end function sw = wmap(w, fs) t = 1/fs; sw = 2/t*tan(w*t/2); end