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