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: 30 янв. 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 PLUGINS_MB_COMPRESSOR_H_
23 #define PLUGINS_MB_COMPRESSOR_H_
24 
25 #include <metadata/plugins.h>
26 
27 #include <core/plugin.h>
28 #include <core/util/Bypass.h>
29 #include <core/util/Sidechain.h>
30 #include <core/util/Delay.h>
31 #include <core/util/MeterGraph.h>
32 #include <core/util/Analyzer.h>
33 #include <core/filters/DynamicFilters.h>
34 #include <core/filters/Equalizer.h>
35 #include <core/dynamics/Compressor.h>
36 
37 namespace lsp
38 {
39     class mb_compressor_base: public plugin_t
40     {
41         protected:
42             enum c_mode_t
43             {
44                 MBCM_MONO,
45                 MBCM_STEREO,
46                 MBCM_LR,
47                 MBCM_MS
48             };
49 
50             enum sync_t
51             {
52                 S_COMP_CURVE    = 1 << 0,
53                 S_EQ_CURVE      = 1 << 1,
54 
55                 S_ALL           = S_COMP_CURVE | S_EQ_CURVE
56             };
57 
58             typedef struct comp_band_t
59             {
60                 Sidechain       sSC;                // Sidechain module
61                 Equalizer       sEQ[2];             // Sidechain equalizers
62                 Compressor      sComp;              // Compressor
63                 Filter          sPassFilter;        // Passing filter for 'classic' mode
64                 Filter          sRejFilter;         // Rejection filter for 'classic' mode
65                 Filter          sAllFilter;         // All-pass filter for phase compensation
66                 Delay           sDelay;             // Delay for lookahead purpose
67 
68                 float          *vTr;                // Transfer function
69                 float          *vVCA;               // Voltage-controlled amplification value for each band
70                 float           fScPreamp;          // Sidechain preamp
71 
72                 float           fFreqStart;
73                 float           fFreqEnd;
74 
75                 float           fFreqHCF;           // Cutoff frequency for low-pass filter
76                 float           fFreqLCF;           // Cutoff frequency for high-pass filter
77                 float           fMakeup;            // Makeup gain
78                 float           fGainLevel;         // Gain adjustment level
79                 size_t          nLookahead;         // Lookahead amount
80 
81                 bool            bEnabled;           // Enabled flag
82                 bool            bCustHCF;           // Custom frequency for high-cut filter
83                 bool            bCustLCF;           // Custom frequency for low-cut filter
84                 bool            bMute;              // Mute channel
85                 bool            bSolo;              // Solo channel
86                 bool            bExtSc;             // External sidechain
87                 size_t          nSync;              // Synchronize output data flags
88                 size_t          nFilterID;          // Identifier of the filter
89 
90                 IPort          *pExtSc;             // External sidechain
91                 IPort          *pScSource;          // Sidechain source
92                 IPort          *pScMode;            // Sidechain mode
93                 IPort          *pScLook;            // Sidechain lookahead
94                 IPort          *pScReact;           // Sidechain reactivity
95                 IPort          *pScPreamp;          // Sidechain preamp
96                 IPort          *pScLpfOn;           // Sidechain low-pass on
97                 IPort          *pScHpfOn;           // Sidechain hi-pass on
98                 IPort          *pScLcfFreq;         // Sidechain low-cut frequency
99                 IPort          *pScHcfFreq;         // Sidechain hi-cut frequency
100                 IPort          *pScFreqChart;       // Sidechain band frequency chart
101 
102                 IPort          *pMode;              // Compressor mode
103                 IPort          *pEnable;            // Enable compressor
104                 IPort          *pSolo;              // Soloing
105                 IPort          *pMute;              // Muting
106                 IPort          *pAttLevel;          // Attack level
107                 IPort          *pAttTime;           // Attack time
108                 IPort          *pRelLevel;          // Release level
109                 IPort          *pRelTime;           // Release time
110                 IPort          *pRatio;             // Ratio
111                 IPort          *pKnee;              // Knee
112                 IPort          *pBThresh;           // Boost threshold
113                 IPort          *pBoost;             // Boost signal amount
114                 IPort          *pMakeup;            // Makeup gain
115                 IPort          *pFreqEnd;           // Frequency range end
116                 IPort          *pCurveGraph;        // Compressor curve graph
117                 IPort          *pRelLevelOut;       // Release level out
118                 IPort          *pEnvLvl;            // Envelope level meter
119                 IPort          *pCurveLvl;          // Reduction curve level meter
120                 IPort          *pMeterGain;         // Reduction gain meter
121             } comp_band_t;
122 
123             typedef struct split_t
124             {
125                 bool            bEnabled;           // Split band is enabled
126                 float           fFreq;              // Split band frequency
127 
128                 IPort          *pEnabled;           // Enable port
129                 IPort          *pFreq;              // Split frequency
130             } split_t;
131 
132             typedef struct channel_t
133             {
134                 Bypass          sBypass;            // Bypass
135                 Filter          sEnvBoost[2];       // Envelope boost filter
136                 Delay           sDelay;             // Delay for lookahead purpose
137 
138                 comp_band_t     vBands[mb_compressor_base_metadata::BANDS_MAX];     // Compressor bands
139                 split_t         vSplit[mb_compressor_base_metadata::BANDS_MAX-1];   // Split bands
140                 comp_band_t    *vPlan[mb_compressor_base_metadata::BANDS_MAX];      // Execution plan (band indexes)
141                 size_t          nPlanSize;              // Plan size
142 
143                 float          *vIn;                // Input data buffer
144                 float          *vOut;               // Output data buffer
145                 float          *vScIn;              // Sidechain data buffer (if present)
146 
147                 float          *vInBuffer;          // Input buffer
148                 float          *vBuffer;            // Common data processing buffer
149                 float          *vScBuffer;          // Sidechain buffer
150                 float          *vExtScBuffer;       // External sidechain buffer
151                 float          *vTr;                // Transfer function
152                 float          *vTrMem;             // Transfer buffer (memory)
153                 float          *vInAnalyze;         // Input signal analysis
154                 float          *vOutAnalyze;        // Input signal analysis
155 
156                 size_t          nAnInChannel;       // Analyzer channel used for input signal analysis
157                 size_t          nAnOutChannel;      // Analyzer channel used for output signal analysis
158                 bool            bInFft;             // Input signal FFT enabled
159                 bool            bOutFft;            // Output signal FFT enabled
160 
161                 IPort          *pIn;                // Input
162                 IPort          *pOut;               // Output
163                 IPort          *pScIn;              // Sidechain
164                 IPort          *pFftIn;             // Pre-processing FFT analysis data
165                 IPort          *pFftInSw;           // Pre-processing FFT analysis control port
166                 IPort          *pFftOut;            // Post-processing FFT analysis data
167                 IPort          *pFftOutSw;          // Post-processing FFT analysis controlport
168                 IPort          *pAmpGraph;          // Compressor's amplitude graph
169                 IPort          *pInLvl;             // Input level meter
170                 IPort          *pOutLvl;            // Output level meter
171             } channel_t;
172 
173         protected:
174             Analyzer        sAnalyzer;              // Analyzer
175             DynamicFilters  sFilters;               // Dynamic filters for each band in 'modern' mode
176             size_t          nMode;                  // Compressor mode
177             bool            bSidechain;             // External side chain
178             bool            bEnvUpdate;             // Envelope filter update
179             bool            bModern;                // Modern mode
180             size_t          nEnvBoost;              // Envelope boost
181             channel_t      *vChannels;              // Compressor channels
182             float           fInGain;                // Input gain
183             float           fDryGain;               // Dry gain
184             float           fWetGain;               // Wet gain
185             float           fZoom;                  // Zoom
186             uint8_t        *pData;                  // Aligned data pointer
187             float          *vSc[2];                 // Sidechain signal data
188             float          *vAnalyze[4];            // Analysis buffer
189             float          *vBuffer;                // Temporary buffer
190             float          *vEnv;                   // Compressor envelope buffer
191             float          *vTr;                    // Transfer buffer
192             float          *vPFc;                   // Pass filter characteristics buffer
193             float          *vRFc;                   // Reject filter characteristics buffer
194             float          *vFreqs;                 // Analyzer FFT frequencies
195             float          *vCurve;                 // Curve
196             uint32_t       *vIndexes;               // Analyzer FFT indexes
197             float_buffer_t *pIDisplay;              // Inline display buffer
198 
199             IPort          *pBypass;                // Bypass port
200             IPort          *pMode;                  // Global mode
201             IPort          *pInGain;                // Input gain port
202             IPort          *pOutGain;               // Output gain port
203             IPort          *pDryGain;               // Dry gain port
204             IPort          *pWetGain;               // Wet gain port
205             IPort          *pReactivity;            // Reactivity
206             IPort          *pShiftGain;             // Shift gain port
207             IPort          *pZoom;                  // Zoom port
208             IPort          *pEnvBoost;              // Envelope adjust
209 
210         protected:
211             static bool compare_bands_for_sort(const comp_band_t *b1, const comp_band_t *b2);
212             static compressor_mode_t    decode_mode(int mode);
213 
214         public:
215             explicit mb_compressor_base(const plugin_metadata_t &metadata, bool sc, size_t mode);
216             virtual ~mb_compressor_base();
217 
218         public:
219             virtual void init(IWrapper *wrapper);
220             virtual void destroy();
221 
222             virtual void update_settings();
223             virtual void update_sample_rate(long sr);
224             virtual void ui_activated();
225 
226             virtual void process(size_t samples);
227             virtual bool inline_display(ICanvas *cv, size_t width, size_t height);
228     };
229 
230     //-------------------------------------------------------------------------
231     // Different compressor implementations
232     class mb_compressor_mono: public mb_compressor_base, public mb_compressor_mono_metadata
233     {
234         public:
235             mb_compressor_mono();
236     };
237 
238     class mb_compressor_stereo: public mb_compressor_base, public mb_compressor_stereo_metadata
239     {
240         public:
241             mb_compressor_stereo();
242     };
243 
244     class mb_compressor_lr: public mb_compressor_base, public mb_compressor_lr_metadata
245     {
246         public:
247             mb_compressor_lr();
248     };
249 
250     class mb_compressor_ms: public mb_compressor_base, public mb_compressor_ms_metadata
251     {
252         public:
253             mb_compressor_ms();
254     };
255 
256     class sc_mb_compressor_mono: public mb_compressor_base, public sc_mb_compressor_mono_metadata
257     {
258         public:
259             sc_mb_compressor_mono();
260     };
261 
262     class sc_mb_compressor_stereo: public mb_compressor_base, public sc_mb_compressor_stereo_metadata
263     {
264         public:
265             sc_mb_compressor_stereo();
266     };
267 
268     class sc_mb_compressor_lr: public mb_compressor_base, public sc_mb_compressor_lr_metadata
269     {
270         public:
271             sc_mb_compressor_lr();
272     };
273 
274     class sc_mb_compressor_ms: public mb_compressor_base, public sc_mb_compressor_ms_metadata
275     {
276         public:
277             sc_mb_compressor_ms();
278     };
279 
280 }
281 
282 #endif /* PLUGINS_COMPRESSOR_H_ */
283