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