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: 19 нояб. 2016 г. 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_UTIL_OVERSAMPLER_H_ 23 #define CORE_UTIL_OVERSAMPLER_H_ 24 25 #include <core/IStateDumper.h> 26 #include <core/filters/Filter.h> 27 28 namespace lsp 29 { 30 /** Callback to perform processing of oversampled signal 31 * 32 */ 33 class IOversamplerCallback 34 { 35 public: 36 /** Virtual destructor 37 * 38 */ 39 virtual ~IOversamplerCallback(); 40 41 /** Processing routine 42 * 43 * @param out output buffer of samples size 44 * @param in input buffer of samples size 45 * @param samples number of samples to process 46 */ 47 virtual void process(float *out, const float *in, size_t samples); 48 }; 49 50 enum over_mode_t 51 { 52 OM_NONE, 53 54 OM_LANCZOS_2X2, 55 OM_LANCZOS_2X3, 56 OM_LANCZOS_2X4, 57 58 OM_LANCZOS_3X2, 59 OM_LANCZOS_3X3, 60 OM_LANCZOS_3X4, 61 62 OM_LANCZOS_4X2, 63 OM_LANCZOS_4X3, 64 OM_LANCZOS_4X4, 65 66 OM_LANCZOS_6X2, 67 OM_LANCZOS_6X3, 68 OM_LANCZOS_6X4, 69 70 OM_LANCZOS_8X2, 71 OM_LANCZOS_8X3, 72 OM_LANCZOS_8X4 73 }; 74 75 /** Oversampler class 76 * 77 */ 78 class Oversampler 79 { 80 private: 81 Oversampler & operator = (const Oversampler &); 82 83 protected: 84 enum update_t 85 { 86 UP_MODE = 1 << 0, 87 UP_SAMPLE_RATE = 1 << 2, 88 UP_OTHER = 1 << 3, 89 90 UP_ALL = UP_MODE | UP_OTHER | UP_SAMPLE_RATE 91 }; 92 93 protected: 94 IOversamplerCallback *pCallback; 95 float *fUpBuffer; 96 float *fDownBuffer; 97 size_t nUpHead; 98 size_t nMode; 99 size_t nSampleRate; 100 size_t nUpdate; 101 Filter sFilter; 102 uint8_t *bData; 103 bool bFilter; 104 105 public: 106 explicit Oversampler(); 107 virtual ~Oversampler(); 108 109 void construct(); 110 111 public: 112 /** Initialize oversampler 113 * 114 */ 115 bool init(); 116 117 /** Destroy oversampler 118 * 119 */ 120 void destroy(); 121 122 /** Set sample rate 123 * 124 * @param sr sample rate 125 */ 126 void set_sample_rate(size_t sr); 127 128 /** Set oversampling callback 129 * 130 * @param callback calback to call on process() 131 */ set_callback(IOversamplerCallback * callback)132 inline void set_callback(IOversamplerCallback *callback) 133 { 134 pCallback = callback; 135 } 136 137 /** Set oversampling ratio 138 * 139 * @param mode oversampling mode 140 */ set_mode(over_mode_t mode)141 inline void set_mode(over_mode_t mode) 142 { 143 if (mode < OM_NONE) 144 mode = OM_NONE; 145 else if (mode > OM_LANCZOS_8X4) 146 mode = OM_LANCZOS_8X4; 147 if (nMode == mode) 148 return; 149 nMode = mode; 150 nUpdate |= UP_MODE; 151 } 152 153 /** Enable/disable low-pass filter when performing downsampling 154 * 155 * @param filter enables/diables low-pass filter 156 */ set_filtering(bool filter)157 inline void set_filtering(bool filter) 158 { 159 if (bFilter == filter) 160 return; 161 bFilter = filter; 162 nUpdate |= UP_MODE; 163 } 164 165 /** Check that module needs re-configuration 166 * 167 * @return true if needs reconfiguration 168 */ modified()169 inline bool modified() const 170 { 171 return nUpdate; 172 } 173 174 /** Get current oversampling multiplier 175 * 176 * @return current oversampling multiplier 177 */ 178 size_t get_oversampling() const; 179 180 /** Update settings 181 * 182 */ 183 void update_settings(); 184 185 /** Perform upsampling of the signal 186 * 187 * @param dst destination buffer of samples*ratio size 188 * @param src source buffer of samples size 189 * @param samples number of samples that should be processed in src buffer 190 */ 191 void upsample(float *dst, const float *src, size_t samples); 192 193 /** Perform downsampling of the signal 194 * 195 * @param dst destination buffer of samples size 196 * @param src source buffer of samples*ratio size 197 * @param samples number of samples that should be produced into the dst buffer 198 */ 199 void downsample(float *dst, const float *src, size_t samples); 200 201 /** Perform processing of the signal 202 * 203 * @param dst destination buffer of samples size 204 * @param src source buffer of samples size 205 * @param samples number of samples to process 206 * @param callback callback to handle buffer 207 */ 208 void process(float *dst, const float *src, size_t samples, IOversamplerCallback *callback); 209 210 /** Perform processing of the signal 211 * 212 * @param dst destination buffer of samples size 213 * @param src source buffer of samples size 214 * @param samples number of samples to process 215 */ process(float * dst,const float * src,size_t samples)216 inline void process(float *dst, const float *src, size_t samples) 217 { 218 process(dst, src, samples, pCallback); 219 } 220 221 /** 222 * Get oversampler latency 223 * @return oversampler latency in normal (non-oversampled) samples 224 */ 225 size_t latency() const; 226 227 /** 228 * Get maximum possible latency 229 * @return maximum possible latency 230 */ max_latency()231 inline size_t max_latency() const { return 8; } 232 233 /** 234 * Dump the state 235 * @param dumper dumper 236 */ 237 void dump(IStateDumper *v) const; 238 }; 239 240 } /* namespace lsp */ 241 242 #endif /* CORE_UTIL_OVERSAMPLER_H_ */ 243