;; 12db/oct low-pass filter based on Korg 35 module
;; (found in MS-10 and MS-20).
;;
;; Based on code by Will Pirkle, presented in:
;;
;; http://www.willpirkle.com/Downloads/AN-5Korg35_V3.pdf
;;
;; [ARGS]
;;
;; ain - audio input
;; acutoff - frequency of cutoff
;; kQ - filter Q [1, 10.0] (k35-lpf will clamp to boundaries)
;; knonlinear - use non-linear processing
;; ksaturation - saturation for tanh distortion
opcode k35_lpf, a, aKKKK
ain, kcutoff, kQ, knonlinear, ksaturation xin
kz1 init 0
kz2 init 0
kz3 init 0
kv1 init 0
kv2 init 0
kv3 init 0
aout init 0
kg init 0
kG init 0
kK init 0
klastcut init -1
klastQ init -1
kS35 init 0
kalpha init -1
klpf2_beta init -1
khpf1_beta init -1
kindx = 0
kQ = limit(kQ, 1.0, 10.0)
kcf = kcutoff
if (klastcut != kcf) then
; pre-warp the cutoff- these are bilinear-transform filters
kwd = 2 * $M_PI * kcf
iT = 1/sr
kwa = (2/iT) * tan(kwd * iT/2)
kg = kwa * iT/2
kG = kg / (1 + kg)
endif
if (klastQ != kQ) then
kK = 0.01 + ((2.0 - 0.01) * (kQ / 10.0))
endif
if ((klastcut != kcf) || (klastQ != kQ)) then
klpf2_beta = (kK - (kK * kG)) / (1.0 + kg)
khpf1_beta = -1.0 / (1.0 + kg)
kalpha = 1.0 / (1.0 - (kK * kG) + (kK * kG * kG))
endif
klastcut = kcf
klastQ = kQ
while (kindx < ksmps) do
ksig = ain[kindx]
;; lpf1
kv1 = (ksig - kz1) * kG
klp1 = kv1 + kz1
kz1 = klp1 + kv1
ku = kalpha * (klp1 + kS35)
if (knonlinear == 1) then
ku = tanh(ku * ksaturation)
endif
;; lpf2
kv2 = (ku - kz2) * kG
klp2 = kv2 + kz2
kz2 = klp2 + kv2
ky = kK * klp2
;; hpf1
kv3 = (ky - kz3) * kG
klp3 = kv3 + kz3
kz3 = klp3 + kv3
khp1 = ky - klp3
kS35 = (klpf2_beta * kz2) + (khpf1_beta * kz3)
kout = (kK > 0) ? (ky / kK) : ky
aout[kindx] = kout
kindx += 1
od
xout aout
endop
opcode k35_lpf, a, aaKKK
ain, acutoff, kQ, knonlinear, ksaturation xin
kz1 init 0
kz2 init 0
kz3 init 0
kv1 init 0
kv2 init 0
kv3 init 0
aout init 0
kg init 0
kG init 0
kK init 0
klastcut init -1
klastQ init -1
kS35 init 0
kalpha init -1
klpf2_beta init -1
khpf1_beta init -1
kindx = 0
kQ = limit(kQ, 1.0, 10.0)
if (klastQ != kQ) then
kK = 0.01 + ((2.0 - 0.01) * (kQ / 10.0))
endif
klastQ = kQ
while (kindx < ksmps) do
kcf = acutoff[kindx]
ksig = ain[kindx]
if (klastcut != kcf) then
; pre-warp the cutoff- these are bilinear-transform filters
kwd = 2 * $M_PI * kcf
iT = 1/sr
kwa = (2/iT) * tan(kwd * iT/2)
kg = kwa * iT/2
kG = kg / (1 + kg)
endif
if ((klastcut != kcf) || (klastQ != kQ)) then
klpf2_beta = (kK - (kK * kG)) / (1.0 + kg)
khpf1_beta = -1.0 / (1.0 + kg)
kalpha = 1.0 / (1.0 - (kK * kG) + (kK * kG * kG))
endif
;; lpf1
kv1 = (ksig - kz1) * kG
klp1 = kv1 + kz1
kz1 = klp1 + kv1
ku = kalpha * (klp1 + kS35)
if (knonlinear == 1) then
ku = tanh(ku * ksaturation)
endif
;; lpf2
kv2 = (ku - kz2) * kG
klp2 = kv2 + kz2
kz2 = klp2 + kv2
ky = kK * klp2
;; hpf1
kv3 = (ky - kz3) * kG
klp3 = kv3 + kz3
kz3 = klp3 + kv3
khp1 = ky - klp3
kS35 = (klpf2_beta * kz2) + (khpf1_beta * kz3)
kout = (kK > 0) ? (ky / kK) : ky
aout[kindx] = kout
klastcut = kcf
kindx += 1
od
xout aout
endop
;; 6db/oct high-pass filter based on Korg 35 module
;; (found in MS-10 and MS-20).
;;
;; Based on code by Will Pirkle, presented in:
;;
;; http://www.willpirkle.com/Downloads/AN-7Korg35HPF_V2.pdf
;;
;; [ARGS]
;;
;; ain - audio input
;; acutoff - frequency of cutoff
;; kQ - filter Q [1, 10.0] (k35_hpf will clamp to boundaries)
;; knonlinear - use non-linear processing
;; ksaturation - saturation for tanh distortion
opcode k35_hpf, a, aKKKK
ain, kcutoff, kQ, knonlinear, ksaturation xin
kz1 init 0
kz2 init 0
kz3 init 0
kv1 init 0
kv2 init 0
kv3 init 0
aout init 0
kg init 0
kG init 0
kK init 0
klastcut init -1
klastQ init -1
kS35 init 0
kalpha init -1
khpf2_beta init -1
klpf1_beta init -1
kindx = 0
kQ = limit(kQ, 1.0, 10.0)
kcf = kcutoff
if (klastcut != kcf) then
; pre-warp the cutoff- these are bilinear-transform filters
kwd = 2 * $M_PI * kcf
iT = 1/sr
kwa = (2/iT) * tan(kwd * iT/2)
kg = kwa * iT/2
kG = kg / (1 + kg)
endif
if (klastQ != kQ) then
kK = 0.01 + ((2.0 - 0.01) * (kQ / 10.0))
endif
if ((klastcut != kcf) || (klastQ != kQ)) then
khpf2_beta = -kG / (1.0 + kg)
klpf1_beta = 1.0 / (1.0 + kg)
kalpha = 1.0 / (1.0 - (kK * kG) + (kK * kG * kG))
endif
klastcut = kcf
klastQ = kQ
while (kindx < ksmps) do
ksig = ain[kindx]
;; hpf1
kv1 = (ksig - kz1) * kG
klp1 = kv1 + kz1
kz1 = klp1 + kv1
ky1 = ksig - klp1
ku = kalpha * (ky1 + kS35)
ky = kK * ku
if (knonlinear == 1) then
ky = tanh(ky * ksaturation)
endif
;; hpf2
kv2 = (ky - kz2) * kG
klp2 = kv2 + kz2
kz2 = klp2 + kv2
khp2 = ky - klp2
;; lpf1
kv3 = (khp2 - kz3) * kG
klp3 = kv3 + kz3
kz3 = klp3 + kv3
kS35 = (khpf2_beta * kz2) + (klpf1_beta * kz3)
kout = (kK > 0) ? (ky / kK) : ky
aout[kindx] = kout
kindx += 1
od
xout aout
endop
opcode k35_hpf, a, aaKKK
ain, acutoff, kQ, knonlinear, ksaturation xin
kz1 init 0
kz2 init 0
kz3 init 0
kv1 init 0
kv2 init 0
kv3 init 0
aout init 0
kg init 0
kG init 0
kK init 0
klastcut init -1
klastQ init -1
kS35 init 0
kalpha init -1
khpf2_beta init -1
klpf1_beta init -1
kindx = 0
kQ = limit(kQ, 1.0, 10.0)
if (klastQ != kQ) then
kK = 0.01 + ((2.0 - 0.01) * (kQ / 10.0))
endif
klastQ = kQ
while (kindx < ksmps) do
kcf = acutoff[kindx]
ksig = ain[kindx]
if (klastcut != kcf) then
; pre-warp the cutoff- these are bilinear-transform filters
kwd = 2 * $M_PI * kcf
iT = 1/sr
kwa = (2/iT) * tan(kwd * iT/2)
kg = kwa * iT/2
kG = kg / (1 + kg)
endif
if ((klastcut != kcf) || (klastQ != kQ)) then
khpf2_beta = -kG / (1.0 + kg)
klpf1_beta = 1.0 / (1.0 + kg)
kalpha = 1.0 / (1.0 - (kK * kG) + (kK * kG * kG))
endif
;; hpf1
kv1 = (ksig - kz1) * kG
klp1 = kv1 + kz1
kz1 = klp1 + kv1
ky1 = ksig - klp1
ku = kalpha * (ky1 + kS35)
ky = kK * ku
if (knonlinear == 1) then
ky = tanh(ky * ksaturation)
endif
;; hpf2
kv2 = (ky - kz2) * kG
klp2 = kv2 + kz2
kz2 = klp2 + kv2
khp2 = ky - klp2
;; lpf1
kv3 = (khp2 - kz3) * kG
klp3 = kv3 + kz3
kz3 = klp3 + kv3
kS35 = (khpf2_beta * kz2) + (klpf1_beta * kz3)
kout = (kK > 0) ? (ky / kK) : ky
aout[kindx] = kout
klastcut = kcf
kindx += 1
od
xout aout
endop