1 // Copyright 2014 Emilie Gillet.
2 //
3 // Author: Emilie Gillet (emilie.o.gillet@gmail.com)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 //
23 // See http://creativecommons.org/licenses/MIT/ for more information.
24 //
25 // -----------------------------------------------------------------------------
26 //
27 // Filter bank.
28 
29 #ifndef WARPS_DSP_FILTER_BANK_H_
30 #define WARPS_DSP_FILTER_BANK_H_
31 
32 #include "stmlib/stmlib.h"
33 
34 #include "stmlib/dsp/dsp.h"
35 #include "stmlib/dsp/filter.h"
36 
37 #include "warps/dsp/sample_rate_converter.h"
38 #include "warps/resources.h"
39 
40 namespace warps {
41 
42 const int32_t kNumBands = 20;
43 const int32_t kLowFactor = 4;
44 const int32_t kMidFactor = 3;
45 const int32_t kDelayLineSize = 6144;
46 const int32_t kMaxFilterBankBlockSize = 96;
47 const int32_t kSampleMemorySize = kMaxFilterBankBlockSize * kNumBands / 2;
48 
49 class PooledDelayLine {
50  public:
PooledDelayLine()51   PooledDelayLine() { }
~PooledDelayLine()52   ~PooledDelayLine() { }
53 
Init(float * ptr,int32_t delay)54   void Init(float* ptr, int32_t delay) {
55     delay_line_ = ptr;
56     size_ = delay + 1;
57     head_ = 0;
58     std::fill(&ptr[0], &ptr[size_], 0.0f);
59   }
60 
size()61   inline int32_t size() const { return size_; }
62 
ReadWrite(float value)63   float ReadWrite(float value) {
64     delay_line_[head_] = value;
65     head_ = (head_ + 1) % size_;
66     return delay_line_[head_];
67   };
68 
69  private:
70   float* delay_line_;
71   int32_t size_;
72   int32_t head_;
73 
74   DISALLOW_COPY_AND_ASSIGN(PooledDelayLine);
75 };
76 
77 struct Band {
78   int32_t group;
79   float sample_rate;
80   float post_gain;
81   stmlib::CrossoverSvf svf[2];
82   int32_t decimation_factor;
83   float* samples;
84   PooledDelayLine delay_line;
85   int32_t delay;
86 };
87 
88 class FilterBank {
89  public:
FilterBank()90   FilterBank() { }
~FilterBank()91   ~FilterBank() { }
92   void Init(float sample_rate);
93   void Analyze(const float* in, size_t size);
94   void Synthesize(float* out, size_t size);
band(int32_t index)95   const Band& band(int32_t index) {
96     return band_[index];
97   }
98 
99  private:
100   SampleRateConverter<SRC_DOWN, kMidFactor, 36> mid_src_down_;
101   SampleRateConverter<SRC_UP, kMidFactor, 36> mid_src_up_;
102   SampleRateConverter<SRC_DOWN, kLowFactor, 48> low_src_down_;
103   SampleRateConverter<SRC_UP, kLowFactor, 48> low_src_up_;
104 
105   float tmp_[2][kMaxFilterBankBlockSize];
106   float samples_[kSampleMemorySize];
107   float delay_buffer_[kDelayLineSize];
108 
109   Band band_[kNumBands + 1];
110 
111   DISALLOW_COPY_AND_ASSIGN(FilterBank);
112 };
113 
114 }  // namespace warps
115 
116 #endif  // WARPS_DSP_FILTER_BANK_H_
117