1 /*
2  * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3  *           (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4  *
5  * This file is part of lsp-plugins
6  * Created on: 1 февр. 2018 г.
7  *
8  * lsp-plugins is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * any later version.
12  *
13  * lsp-plugins is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef CORE_FILTERS_DYNAMICFILTERS_H_
23 #define CORE_FILTERS_DYNAMICFILTERS_H_
24 
25 #include <dsp/dsp.h>
26 #include <core/filters/common.h>
27 #include <core/status.h>
28 
29 namespace lsp
30 {
31     /** This class implements set of sequential dynamic filters grouped
32      * into one object for resource economy purpose.
33      *
34      */
35     class DynamicFilters
36     {
37         private:
38             DynamicFilters & operator = (const DynamicFilters &);
39 
40         protected:
41             typedef struct filter_t
42             {
43                 filter_params_t     sParams;                // Filter parameters
44                 bool                bActive;                // Filter activity
45             } filter_t;
46 
47             union biquad_bank_t
48             {
49                 void               *ptr;
50                 biquad_x1_t        *x1;
51                 biquad_x2_t        *x2;
52                 biquad_x4_t        *x4;
53                 biquad_x8_t        *x8;
54             };
55 
56             static const f_cascade_t    sNormal;
57 
58         protected:
59             filter_t           *vFilters;           // Array of filters
60             f_cascade_t        *vCascades;          // Analog filter cascade bank
61             float              *vMemory;            // Filter memory
62             biquad_bank_t       vBiquads;           // Biquad bank
63             size_t              nFilters;           // Number of filters
64             size_t              nSampleRate;        // Sample rate
65             void               *pData;              // Aligned pointer data
66             bool                bClearMem;          // Clear memory
67 
68         protected:
69             size_t              quantify(size_t c, size_t nc);
70             size_t              build_filter_bank(f_cascade_t *dst, const filter_params_t *fp, size_t cj, const float *sfg, size_t samples);
71             size_t              build_lrx_ladder_filter_bank(f_cascade_t *dst, const filter_params_t *fp, size_t cj, const float *sfg, size_t samples, size_t ftype);
72             size_t              build_lrx_shelf_filter_bank(f_cascade_t *dst, const filter_params_t *fp, size_t cj, const float *sfg, size_t samples, size_t ftype);
73 
74             size_t              precalc_lrx_ladder_filter_bank(f_cascade_t *dst, const filter_params_t *fp, size_t cj, const float *sfg, size_t samples);
75             void                calc_lrx_ladder_filter_bank(f_cascade_t *dst, const filter_params_t *fp, size_t cj, size_t samples, size_t ftype, size_t nc);
76 
77             void                vcomplex_transfer_calc(float *re, float *im, const f_cascade_t *fc, const float *freq, size_t cj, size_t nc, size_t nf);
78             void                vcomplex_transfer_calc(float *dst, const f_cascade_t *fc, const float *freq, size_t cj, size_t nc, size_t nf);
79 
80         public:
81             explicit DynamicFilters();
82             ~DynamicFilters();
83 
84             /**
85              * Construct the object as a part of memory chunkk
86              */
87             void                construct();
88 
89             /** Initialize the dynamic filters set
90              *
91              * @param filters
92              * @return
93              */
94             status_t            init(size_t filters);
95 
96             /** Destroy the dynamic filters set
97              *
98              */
99             void                destroy();
100 
101         public:
102             /** Set sample rate
103              *
104              * @param sr sample rate
105              */
106             void                set_sample_rate(size_t sr);
107 
108             /** Check that filter is active
109              *
110              * @param id ID of filter
111              * @return true if filter is active
112              */
filter_active(size_t id)113             inline bool         filter_active(size_t id) const { return (id < nFilters) ? vFilters[id].bActive : false; };
114 
115             /** Check that filter is inactive
116              *
117              * @param id ID of filter
118              * @return true if filter is inactive
119              */
filter_inactive(size_t id)120             inline bool         filter_inactive(size_t id) const { return (id < nFilters) ? !vFilters[id].bActive : true; };
121 
122             /** Set activity of the specific filter
123              *
124              * @param id filter identifier
125              * @param active activity of the specific filter
126              * @return true on success
127              */
set_filter_active(size_t id,bool active)128             inline bool         set_filter_active(size_t id, bool active)
129             {
130                 if (id >= nFilters)
131                     return false;
132                 vFilters[id].bActive        = true;
133                 return true;
134             }
135 
136             /** Update filter parameters
137              * @param id ID of the filter
138              * @param params  filter parameters
139              * @return true on success
140              */
141             bool                set_params(size_t id, const filter_params_t *params);
142 
143             /** Get filter parameters
144              * @param id ID of the filter
145              * @param params  filter parameters
146              * @return true on success
147              */
148             bool                get_params(size_t id, filter_params_t *params);
149 
150             /** Process signal with filter varying by it's gain parameter
151              *
152              * @param id filer identifier
153              * @param out output signal
154              * @param in input signal
155              * @param gain the gain level of the filter
156              * @param samples number of samples to process
157              */
158             void                process(size_t id, float *out, const float *in, const float *gain, size_t samples);
159 
160             /** Get frequency chart of the specific filter
161              *
162              * @param id ID of the filter
163              * @param re real part of the frequency chart
164              * @param im imaginary part of the frequency chart
165              * @param f frequencies to calculate value
166              * @param count number of dots for the chart
167              */
168             bool                freq_chart(size_t id, float *re, float *im, const float *f, float gain, size_t count);
169 
170             /** Get frequency chart of the specific filter
171              *
172              * @param id ID of the filter
173              * @param dst array of complex numbers to store data
174              * @param f frequencies to calculate value
175              * @param count number of dots for the chart
176              */
177             bool                freq_chart(size_t id, float *dst, const float *f, float gain, size_t count);
178     };
179 } /* namespace lsp */
180 
181 #endif /* CORE_FILTERS_DYNAMICFILTERS_H_ */
182