10 #include "alnumbers.h"
11 #include "opthelpers.h"
14 template<typename Real>
15 void BandSplitterR<Real>::init(Real f0norm)
17 const Real w{f0norm * (al::numbers::pi_v<Real>*2)};
18 const Real cw{std::cos(w)};
19 if(cw > std::numeric_limits<float>::epsilon())
20 mCoeff = (std::sin(w) - 1.0f) / cw;
29 template<typename Real>
30 void BandSplitterR<Real>::process(const al::span<const Real> input, Real *hpout, Real *lpout)
32 const Real ap_coeff{mCoeff};
33 const Real lp_coeff{mCoeff*0.5f + 0.5f};
37 auto proc_sample = [ap_coeff,lp_coeff,&lp_z1,&lp_z2,&ap_z1,&lpout](const Real in) noexcept -> Real
39 /* Low-pass sample processing. */
40 Real d{(in - lp_z1) * lp_coeff};
44 d = (lp_y - lp_z2) * lp_coeff;
50 /* All-pass sample processing. */
51 Real ap_y{in*ap_coeff + ap_z1};
52 ap_z1 = in - ap_y*ap_coeff;
54 /* High-pass generated from removing low-passed output. */
57 std::transform(input.cbegin(), input.cend(), hpout, proc_sample);
63 template<typename Real>
64 void BandSplitterR<Real>::processHfScale(const al::span<const Real> input, Real *RESTRICT output,
67 const Real ap_coeff{mCoeff};
68 const Real lp_coeff{mCoeff*0.5f + 0.5f};
72 auto proc_sample = [hfscale,ap_coeff,lp_coeff,&lp_z1,&lp_z2,&ap_z1](const Real in) noexcept -> Real
74 /* Low-pass sample processing. */
75 Real d{(in - lp_z1) * lp_coeff};
79 d = (lp_y - lp_z2) * lp_coeff;
83 /* All-pass sample processing. */
84 Real ap_y{in*ap_coeff + ap_z1};
85 ap_z1 = in - ap_y*ap_coeff;
87 /* High-pass generated by removing the low-passed signal, which is then
88 * scaled and added back to the low-passed signal.
90 return (ap_y-lp_y)*hfscale + lp_y;
92 std::transform(input.begin(), input.end(), output, proc_sample);
98 template<typename Real>
99 void BandSplitterR<Real>::processHfScale(const al::span<Real> samples, const Real hfscale)
101 const Real ap_coeff{mCoeff};
102 const Real lp_coeff{mCoeff*0.5f + 0.5f};
106 auto proc_sample = [hfscale,ap_coeff,lp_coeff,&lp_z1,&lp_z2,&ap_z1](const Real in) noexcept -> Real
108 /* Low-pass sample processing. */
109 Real d{(in - lp_z1) * lp_coeff};
110 Real lp_y{lp_z1 + d};
113 d = (lp_y - lp_z2) * lp_coeff;
117 /* All-pass sample processing. */
118 Real ap_y{in*ap_coeff + ap_z1};
119 ap_z1 = in - ap_y*ap_coeff;
121 /* High-pass generated by removing the low-passed signal, which is then
122 * scaled and added back to the low-passed signal.
124 return (ap_y-lp_y)*hfscale + lp_y;
126 std::transform(samples.begin(), samples.end(), samples.begin(), proc_sample);
132 template<typename Real>
133 void BandSplitterR<Real>::processScale(const al::span<Real> samples, const Real hfscale, const Real lfscale)
135 const Real ap_coeff{mCoeff};
136 const Real lp_coeff{mCoeff*0.5f + 0.5f};
140 auto proc_sample = [hfscale,lfscale,ap_coeff,lp_coeff,&lp_z1,&lp_z2,&ap_z1](const Real in) noexcept -> Real
142 Real d{(in - lp_z1) * lp_coeff};
143 Real lp_y{lp_z1 + d};
146 d = (lp_y - lp_z2) * lp_coeff;
150 Real ap_y{in*ap_coeff + ap_z1};
151 ap_z1 = in - ap_y*ap_coeff;
153 /* Apply separate factors to the high and low frequencies. */
154 return (ap_y-lp_y)*hfscale + lp_y*lfscale;
156 std::transform(samples.begin(), samples.end(), samples.begin(), proc_sample);
162 template<typename Real>
163 void BandSplitterR<Real>::processAllPass(const al::span<Real> samples)
165 const Real coeff{mCoeff};
167 auto proc_sample = [coeff,&z1](const Real in) noexcept -> Real
169 const Real out{in*coeff + z1};
173 std::transform(samples.cbegin(), samples.cend(), samples.begin(), proc_sample);
178 template class BandSplitterR<float>;
179 template class BandSplitterR<double>;