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: 13 фев. 2017 г. 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 PLUGINS_IMPULSE_REVERB_H_ 23 #define PLUGINS_IMPULSE_REVERB_H_ 24 25 #include <core/plugin.h> 26 #include <core/ipc/IExecutor.h> 27 #include <core/util/Convolver.h> 28 #include <core/util/Bypass.h> 29 #include <core/util/Delay.h> 30 #include <core/util/Toggle.h> 31 #include <core/filters/Equalizer.h> 32 #include <core/sampling/SamplePlayer.h> 33 #include <core/files/AudioFile.h> 34 35 #include <metadata/plugins.h> 36 37 namespace lsp 38 { 39 40 class impulse_reverb_base: public plugin_t 41 { 42 protected: 43 struct af_descriptor_t; 44 45 class IRLoader: public ipc::ITask 46 { 47 private: 48 impulse_reverb_base *pCore; 49 af_descriptor_t *pDescr; 50 51 public: IRLoader()52 inline IRLoader() 53 { 54 pCore = NULL; 55 pDescr = NULL; 56 } 57 58 void init(impulse_reverb_base *base, af_descriptor_t *descr); 59 virtual ~IRLoader(); 60 61 public: 62 virtual status_t run(); 63 }; 64 65 typedef struct reconfig_t 66 { 67 bool bRender[impulse_reverb_base_metadata::FILES]; 68 size_t nFile[impulse_reverb_base_metadata::CONVOLVERS]; 69 size_t nTrack[impulse_reverb_base_metadata::CONVOLVERS]; 70 size_t nRank[impulse_reverb_base_metadata::CONVOLVERS]; 71 } reconfig_t; 72 73 class IRConfigurator: public ipc::ITask 74 { 75 private: 76 reconfig_t sReconfig; 77 impulse_reverb_base *pCore; 78 79 public: 80 IRConfigurator(impulse_reverb_base *base); 81 virtual ~IRConfigurator(); 82 83 public: 84 virtual status_t run(); 85 set_render(size_t idx,bool render)86 inline void set_render(size_t idx, bool render) { sReconfig.bRender[idx] = render; } set_file(size_t idx,size_t file)87 inline void set_file(size_t idx, size_t file) { sReconfig.nFile[idx] = file; } set_track(size_t idx,size_t track)88 inline void set_track(size_t idx, size_t track) { sReconfig.nTrack[idx] = track; } set_rank(size_t idx,size_t rank)89 inline void set_rank(size_t idx, size_t rank) { sReconfig.nRank[idx] = rank; } 90 }; 91 92 typedef struct af_descriptor_t 93 { 94 AudioFile *pCurr; // Current audio file 95 AudioFile *pSwap; // Pointer to audio file for swapping between RT and non-RT code 96 97 Toggle sListen; // Listen toggle 98 Sample *pSwapSample; 99 Sample *pCurrSample; // Rendered file sample 100 float *vThumbs[impulse_reverb_base_metadata::TRACKS_MAX]; // Thumbnails 101 float fNorm; // Norming factor 102 bool bRender; // Flag that indicates that file needs rendering 103 status_t nStatus; 104 bool bSync; // Synchronize file 105 bool bSwap; // Swap samples 106 107 float fHeadCut; 108 float fTailCut; 109 float fFadeIn; 110 float fFadeOut; 111 bool bReverse; 112 113 IRLoader sLoader; // Audio file loader task 114 115 IPort *pFile; // Port that contains file name 116 IPort *pHeadCut; 117 IPort *pTailCut; 118 IPort *pFadeIn; 119 IPort *pFadeOut; 120 IPort *pListen; 121 IPort *pReverse; // Reverse 122 IPort *pStatus; // Status of file loading 123 IPort *pLength; // Length of file 124 IPort *pThumbs; // Thumbnails of file 125 } af_descriptor_t; 126 127 typedef struct convolver_t 128 { 129 Delay sDelay; // Delay line 130 131 Convolver *pCurr; // Currently used convolver 132 Convolver *pSwap; // Swap 133 // bool bSwap; // Swapping flag 134 size_t nRank; // Last applied rank 135 size_t nRankReq; // Rank request 136 size_t nSource; // Source 137 size_t nFileReq; // File request 138 size_t nTrackReq; // Track request 139 140 float *vBuffer; // Buffer for convolution 141 float fPanIn[2]; // Input panning of convolver 142 float fPanOut[2]; // Output panning of convolver 143 144 IPort *pMakeup; // Makeup gain of convolver 145 IPort *pPanIn; // Input panning of convolver 146 IPort *pPanOut; // Output panning of convolver 147 IPort *pFile; // Convolver source file 148 IPort *pTrack; // Convolver source file track 149 IPort *pPredelay; // Pre-delay 150 IPort *pMute; // Mute button 151 IPort *pActivity; // Activity indicator 152 } convolver_t; 153 154 typedef struct channel_t 155 { 156 Bypass sBypass; 157 SamplePlayer sPlayer; 158 Equalizer sEqualizer; // Wet signal equalizer 159 160 float *vOut; 161 float *vBuffer; // Rendering buffer 162 float fDryPan[2]; // Dry panorama 163 164 IPort *pOut; 165 166 IPort *pWetEq; // Wet equalization flag 167 IPort *pLowCut; // Low-cut flag 168 IPort *pLowFreq; // Low-cut frequency 169 IPort *pHighCut; // High-cut flag 170 IPort *pHighFreq; // Low-cut frequency 171 IPort *pFreqGain[impulse_reverb_base_metadata::EQ_BANDS]; // Gain for each band of the Equalizer 172 } channel_t; 173 174 typedef struct input_t 175 { 176 float *vIn; // Input data 177 IPort *pIn; // Input port 178 IPort *pPan; // Panning 179 } input_t; 180 181 protected: 182 status_t load(af_descriptor_t *descr); 183 status_t reconfigure(const reconfig_t *cfg); 184 static void destroy_file(af_descriptor_t *af); 185 static void destroy_channel(channel_t *c); 186 static void destroy_convolver(convolver_t *cv); 187 static size_t get_fft_rank(size_t rank); 188 void sync_offline_tasks(); 189 190 protected: 191 size_t nInputs; 192 size_t nReconfigReq; 193 size_t nReconfigResp; 194 195 input_t vInputs[2]; 196 channel_t vChannels[2]; 197 convolver_t vConvolvers[impulse_reverb_base_metadata::CONVOLVERS]; 198 af_descriptor_t vFiles[impulse_reverb_base_metadata::FILES]; 199 200 IRConfigurator sConfigurator; 201 202 IPort *pBypass; 203 IPort *pRank; 204 IPort *pDry; 205 IPort *pWet; 206 IPort *pOutGain; 207 IPort *pPredelay; 208 209 uint8_t *pData; 210 ipc::IExecutor *pExecutor; 211 212 public: 213 impulse_reverb_base(const plugin_metadata_t &metadata, size_t inputs); 214 virtual ~impulse_reverb_base(); 215 216 public: 217 virtual void init(IWrapper *wrapper); 218 virtual void destroy(); 219 220 virtual void ui_activated(); 221 virtual void update_settings(); 222 virtual void update_sample_rate(long sr); 223 224 virtual void process(size_t samples); 225 226 }; 227 228 class impulse_reverb_mono: public impulse_reverb_base, public impulse_reverb_mono_metadata 229 { 230 public: 231 impulse_reverb_mono(); 232 virtual ~impulse_reverb_mono(); 233 }; 234 235 class impulse_reverb_stereo: public impulse_reverb_base, public impulse_reverb_stereo_metadata 236 { 237 public: 238 impulse_reverb_stereo(); 239 virtual ~impulse_reverb_stereo(); 240 241 }; 242 243 } /* namespace ddb */ 244 245 #endif /* PLUGINS_IMPULSE_REVERB_H_ */ 246