11#include " dsplib/subband.h"
2- #include " dsplib/throw .h"
2+ #include " dsplib/assert .h"
33#include " dsplib/resample.h"
44#include " dsplib/fft.h"
55#include " dsplib/ifft.h"
@@ -124,7 +124,6 @@ class DFTFilterBank
124124public:
125125 virtual ~DFTFilterBank () = default ;
126126
127- protected:
128127 explicit DFTFilterBank (int num_bands, int decim_factor, int num_taps, bool synthesis = false )
129128 : nbands_{num_bands}
130129 , ntaps_{num_taps}
@@ -139,19 +138,21 @@ class DFTFilterBank
139138 const int decim_;
140139 const int d_;
141140
141+ // TODO: size optimization
142142 CircBuffer buf_;
143143 CircBuffer gsi_;
144144};
145145
146146arr_real _design_filter (int num_bands, int num_taps) {
147147 // TODO: cache last coeffs
148- return design_multirate_fir (1 , num_bands, std::ceil (num_taps / 2.0 ));
148+ assert (num_taps % 2 == 0 );
149+ return design_multirate_fir (1 , num_bands, num_taps / 2 , 80 );
149150}
150151
151152} // namespace
152153
153154// --------------------------------------------------------------------------------------------------------
154- class ChannelizerImpl : protected DFTFilterBank
155+ class ChannelizerImpl : public DFTFilterBank
155156{
156157public:
157158 explicit ChannelizerImpl (std::shared_ptr<const arr_real> filter, int num_bands, int decim_factor, int num_taps)
@@ -173,8 +174,6 @@ class ChannelizerImpl : protected DFTFilterBank
173174 convert[k + i * d_] = gsi[k];
174175 }
175176 }
176-
177- // TODO: move or use `convert` array
178177 buf_.push (convert, true );
179178
180179 // calculate outputs of polyphase filters
@@ -198,7 +197,7 @@ class ChannelizerImpl : protected DFTFilterBank
198197};
199198
200199// --------------------------------------------------------------------------------------------------------------
201- class ChannelSynthesizerImpl : private DFTFilterBank
200+ class ChannelSynthesizerImpl : public DFTFilterBank
202201{
203202public:
204203 explicit ChannelSynthesizerImpl (std::shared_ptr<const arr_real> filter, int num_bands, int decim_factor,
@@ -212,7 +211,7 @@ class ChannelSynthesizerImpl : private DFTFilterBank
212211 arr_real process (const dsplib::arr_cmplx& x) {
213212 DSPLIB_ASSERT (x.size () == nbands_, " input vector size error" );
214213
215- const auto xx = ifft_ (x * nbands_) ;
214+ const auto xx = ifft_ (x) * nbands_;
216215 buf_.push (xx, true );
217216
218217 // calculate outputs of polyphase filters
@@ -237,7 +236,10 @@ class ChannelSynthesizerImpl : private DFTFilterBank
237236 out[d_ - k - 1 ] += gsi[k + i * d_];
238237 }
239238 }
240- return out;
239+
240+ // normalize ouput
241+ // TODO: more precision, gain error ~ 1 dB
242+ return out * (nbands_ / decim_);
241243 }
242244
243245private:
@@ -247,40 +249,53 @@ class ChannelSynthesizerImpl : private DFTFilterBank
247249};
248250
249251// --------------------------------------------------------------------------------------------------------------
250- Channelizer::Channelizer (const arr_real& filter, int num_bands, int decim_factor, int num_taps) {
251- const auto fptr = std::make_shared<dsplib::arr_real>(filter);
252- d_ = std::make_unique<ChannelizerImpl>(fptr, num_bands, decim_factor, num_taps);
252+ Channelizer::Channelizer (const arr_real& filter, int num_bands, int decim_factor)
253+ : Channelizer(std::make_shared<dsplib::arr_real>(filter), num_bands, decim_factor) {
253254}
254255
255- Channelizer::Channelizer (std::shared_ptr<const arr_real> filter, int num_bands, int decim_factor, int num_taps) {
256+ Channelizer::Channelizer (std::shared_ptr<const arr_real> filter, int num_bands, int decim_factor) {
257+ const int num_taps = filter->size () / num_bands;
258+ DSPLIB_ASSERT (num_taps % 2 == 0 , " `num_taps` expected to be even" );
259+ DSPLIB_ASSERT (num_bands % decim_factor == 0 , " only integer ratio M/D supported" );
260+ DSPLIB_ASSERT (filter->size () == num_bands * num_taps, " filter size must be equal `num_bands * num_taps`" );
256261 d_ = std::make_unique<ChannelizerImpl>(std::move (filter), num_bands, decim_factor, num_taps);
257262}
258263
259264Channelizer::Channelizer (int num_bands, int decim_factor, int num_taps)
260- : Channelizer(_design_filter(num_bands, num_taps), num_bands, decim_factor, num_taps ) {
265+ : Channelizer(_design_filter(num_bands, num_taps), num_bands, decim_factor) {
261266}
262267
263268arr_cmplx Channelizer::process (const arr_real& x) {
264269 return d_->process (x);
265270}
266271
272+ int Channelizer::frame_len () const noexcept {
273+ return (d_->nbands_ / d_->decim_ );
274+ }
275+
267276// --------------------------------------------------------------------------------------------------------------
268- ChannelSynthesizer::ChannelSynthesizer (const arr_real& filter, int num_bands, int decim_factor, int num_taps) {
269- const auto fptr = std::make_shared<dsplib::arr_real>(filter);
270- d_ = std::make_unique<ChannelSynthesizerImpl>(fptr, num_bands, decim_factor, num_taps);
277+ ChannelSynthesizer::ChannelSynthesizer (const arr_real& filter, int num_bands, int decim_factor)
278+ : ChannelSynthesizer(std::make_shared<dsplib::arr_real>(filter), num_bands, decim_factor) {
271279}
272280
273- ChannelSynthesizer::ChannelSynthesizer (std::shared_ptr<const arr_real> filter, int num_bands, int decim_factor,
274- int num_taps) {
281+ ChannelSynthesizer::ChannelSynthesizer (std::shared_ptr<const arr_real> filter, int num_bands, int decim_factor) {
282+ const int num_taps = filter->size () / num_bands;
283+ DSPLIB_ASSERT (num_taps % 2 == 0 , " `num_taps` expected to be even" );
284+ DSPLIB_ASSERT (num_bands % decim_factor == 0 , " only integer ratio M/D supported" );
285+ DSPLIB_ASSERT (filter->size () == num_bands * num_taps, " filter size must be equal `num_bands * num_taps`" );
275286 d_ = std::make_unique<ChannelSynthesizerImpl>(std::move (filter), num_bands, decim_factor, num_taps);
276287}
277288
278289ChannelSynthesizer::ChannelSynthesizer (int num_bands, int decim_factor, int num_taps)
279- : ChannelSynthesizer(_design_filter(num_bands, num_taps), num_bands, decim_factor, num_taps ) {
290+ : ChannelSynthesizer(_design_filter(num_bands, num_taps), num_bands, decim_factor) {
280291}
281292
282293arr_real ChannelSynthesizer::process (const arr_cmplx& x) {
283294 return d_->process (x);
284295}
285296
297+ int ChannelSynthesizer::frame_len () const noexcept {
298+ return (d_->nbands_ / d_->decim_ );
299+ }
300+
286301} // namespace dsplib
0 commit comments