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: 14 сент. 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_SIDECHAIN_H_
23 #define CORE_UTIL_SIDECHAIN_H_
24 
25 #include <core/types.h>
26 #include <core/IStateDumper.h>
27 #include <core/util/ShiftBuffer.h>
28 #include <core/filters/Equalizer.h>
29 
30 namespace lsp
31 {
32     // Sidechain signal source
33     enum sidechain_source_t
34     {
35         SCS_MIDDLE,
36         SCS_SIDE,
37         SCS_LEFT,
38         SCS_RIGHT
39     };
40 
41     enum sidechain_mode_t
42     {
43         SCM_PEAK,
44         SCM_RMS,
45         SCM_LPF,
46         SCM_UNIFORM
47     };
48 
49     enum sidechain_stereo_mode_t
50     {
51         SCSM_STEREO,
52         SCSM_MIDSIDE
53     };
54 
55     class Sidechain
56     {
57         private:
58             Sidechain & operator = (const Sidechain &);
59 
60         protected:
61             ShiftBuffer     sBuffer;                // Shift buffer for history
62             size_t          nReactivity;            // Reactivity (in samples)
63             float           fReactivity;            // Reactivity (in time)
64             float           fTau;                   // Tau for RMS
65             float           fRmsValue;              // RMS value
66             size_t          nSource;                // Sidechain source
67             size_t          nMode;                  // Sidechain mode
68             size_t          nSampleRate;            // Sample rate
69             size_t          nRefresh;               // Sidechain refresh
70             size_t          nChannels;              // Number of channels
71             float           fMaxReactivity;         // Maximum reactivity
72             float           fGain;                  // Sidechain gain
73             bool            bUpdate;                // Update sidechain parameters flag
74             bool            bMidSide;               // Mid-side mode
75             Equalizer      *pPreEq;                 // Pre-equalizer
76 
77         protected:
78             void            update_settings();
79             void            refresh_processing();
80             bool            preprocess(float *out, const float **in, size_t samples);
81             bool            preprocess(float *out, const float *in);
82 
83         public:
84             explicit Sidechain();
85             ~Sidechain();
86 
87         public:
88             /** Initialize sidechain
89              *
90              * @param channels number of input channels, possible 1 or 2
91              * @param max_reactivity maximum reactivity
92              */
93             bool init(size_t channels, float max_reactivity);
94 
95             /** Destroy sidechain
96              *
97              */
98             void destroy();
99 
100             /** Set pre-processing equalizer
101              *
102              * @param eq equalizer
103              */
set_pre_equalizer(Equalizer * eq)104             inline void set_pre_equalizer(Equalizer *eq)            { pPreEq = eq; }
105 
106             /** Set sample rate
107              *
108              * @param sr sample rate
109              */
110             void set_sample_rate(size_t sr);
111 
112             /** Set sidechain reactivity
113              *
114              * @param reactivity sidechain reactivity
115              */
set_reactivity(float reactivity)116             inline void set_reactivity(float reactivity)
117             {
118                 if ((fReactivity == reactivity) ||
119                     (reactivity <= 0.0) ||
120                     (reactivity >= fMaxReactivity))
121                     return;
122                 fReactivity     = reactivity;
123                 bUpdate         = true;
124             }
125 
set_stereo_mode(sidechain_stereo_mode_t mode)126             inline void set_stereo_mode(sidechain_stereo_mode_t mode)
127             {
128                 bMidSide        = mode == SCSM_MIDSIDE;
129             }
130 
131             /** Set sidechain source
132              *
133              * @param source sidechain source
134              */
set_source(size_t source)135             inline void set_source(size_t source)
136             {
137                 nSource         = source;
138             }
139 
140             /** Set sidechain mode
141              *
142              * @param mode sidechain mode
143              */
set_mode(size_t mode)144             inline void set_mode(size_t mode)
145             {
146                 if (nMode == mode)
147                     return;
148                 fRmsValue       = 0.0f;
149                 nMode           = mode;
150             }
151 
152             /** Set-up pre-amplification gain
153              *
154              * @param gain sidechain pre-amplification gain
155              */
set_gain(float gain)156             inline void set_gain(float gain)
157             {
158                 fGain           = gain;
159             }
160 
161             /** Get pre-amplification gain
162              *
163              * @return pre-amplification gain
164              */
get_gain()165             inline float get_gain() const
166             {
167                 return fGain;
168             }
169 
170             /** Process sidechain signal
171              *
172              * @param out output buffer
173              * @param in input buffers
174              * @param samples number of samples to process
175              */
176             void process(float *out, const float **in, size_t samples);
177 
178             /** Process sidechain signal (single sample)
179              *
180              * @param in input data (one sample per channel)
181              */
182             float process(const float *in);
183 
184             /**
185              * Dump the state
186              * @param dumper dumper
187              */
188             void dump(IStateDumper *v) const;
189     };
190 
191 } /* namespace lsp */
192 
193 #endif /* CORE_UTIL_SIDECHAIN_H_ */
194