1 /*
2  * ZaMultiComp multiband compressor
3  * Copyright (C) 2014  Damien Zammit <damien@zamaudio.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  */
15 
16 #ifndef ZAMULTICOMPX2PLUGIN_HPP_INCLUDED
17 #define ZAMULTICOMPX2PLUGIN_HPP_INCLUDED
18 
19 #include "DistrhoPlugin.hpp"
20 #include <algorithm>
21 
22 START_NAMESPACE_DISTRHO
23 
24 #define MAX_FILT 2
25 #define MAX_COMP 3
26 #define MAX_SAMPLES 480
27 #define DANGER 100000.f
28 #define EPS 1e-20f
29 
30 // -----------------------------------------------------------------------
31 
32 class ZaMultiCompPlugin : public Plugin
33 {
34 public:
35     enum Parameters
36     {
37         paramAttack1 = 0,
38         paramAttack2,
39         paramAttack3,
40         paramRelease1,
41         paramRelease2,
42         paramRelease3,
43         paramKnee1,
44         paramKnee2,
45         paramKnee3,
46         paramRatio1,
47         paramRatio2,
48         paramRatio3,
49         paramThresh1,
50         paramThresh2,
51         paramThresh3,
52 
53         paramMakeup1,
54         paramMakeup2,
55         paramMakeup3,
56 
57         paramXover1,
58         paramXover2,
59 
60         paramToggle1,
61         paramToggle2,
62         paramToggle3,
63 
64         paramListen1,
65         paramListen2,
66         paramListen3,
67 
68         paramGlobalGain,
69         paramOutputLevel,
70         paramOutputLevelLow,
71         paramOutputLevelMed,
72         paramOutputLevelHigh,
73         paramGainR1,
74         paramGainR2,
75         paramGainR3,
76 
77         paramCount
78     };
79 
80     enum States
81     {
82         stateReadMeter,
83 	stateCount
84     };
85 
86     ZaMultiCompPlugin();
87 
88 protected:
89     // -------------------------------------------------------------------
90     // Information
91 
getLabel() const92     const char* getLabel() const noexcept override
93     {
94         return "ZaMultiComp";
95     }
96 
getDescription() const97     const char* getDescription() const noexcept override
98     {
99         return "Mono multiband compressor, with 3 adjustable bands.";
100     }
101 
getMaker() const102     const char* getMaker() const noexcept override
103     {
104         return "Damien Zammit";
105     }
106 
getHomePage() const107     const char* getHomePage() const noexcept override
108     {
109         return "http://www.zamaudio.com";
110     }
111 
getLicense() const112     const char* getLicense() const noexcept override
113     {
114         return "GPL v2+";
115     }
116 
getVersion() const117     uint32_t getVersion() const noexcept override
118     {
119         return d_version(3, 14, 0);
120     }
121 
getUniqueId() const122     int64_t getUniqueId() const noexcept override
123     {
124         return d_cconst('Z', 'M', 'M', 'C');
125     }
126 
127     // -------------------------------------------------------------------
128     // Init
129 
130     void initParameter(uint32_t index, Parameter& parameter) ;
131     void initProgramName(uint32_t index, String& programName) ;
132     void initState(uint32_t, String&, String&) override;
133 
134     // -------------------------------------------------------------------
135     // Internal data
136 
137     float getParameterValue(uint32_t index) const override;
138     void setParameterValue(uint32_t index, float value) override;
139     void loadProgram(uint32_t index) override;
140     String getState(const char* key) const override;
141     void setState(const char* key, const char* value) override;
142 
143     // -------------------------------------------------------------------
144     // Process
145 
146 	static inline float
sanitize_denormal(float v)147 	sanitize_denormal(float v) {
148 	        if(!std::isnormal(v))
149 	                return 0.f;
150 	        return v;
151 	}
152 
153 	static inline float
from_dB(float gdb)154 	from_dB(float gdb) {
155 	        return (expf(0.05f*gdb*logf(10.f)));
156 	}
157 
158 	static inline float
to_dB(float g)159 	to_dB(float g) {
160 	        return (20.f*log10f(g));
161 	}
162 
163     void run_comp(int k, float in, float *out);
164     void run_limit(float in, float *out);
165     void run_lr4(int i, float in, float *outlo, float *outhi);
166     void calc_lr4(float f, int i);
167 
168     void activate() override;
169     void run(const float** inputs, float** outputs, uint32_t frames) override;
170 
171 	struct linear_svf {
172 		double k;
173 		double g;
174 
175 		double s[2];
176 	};
177 
178 	struct linear_svf simper[2][MAX_FILT];
179     void linear_svf_set_xover(struct linear_svf *self, float sample_rate, float cutoff, float resonance);
180     void linear_svf_reset(struct linear_svf *self);
181     float run_linear_svf_xover(struct linear_svf *self, float in, float mixlow, float mixhigh);
182 
183 	void pushsample(float sample, int k);
184     // -------------------------------------------------------------------
185 
186 private:
187     float attack[MAX_COMP],release[MAX_COMP],knee[MAX_COMP],ratio[MAX_COMP],thresdb[MAX_COMP],makeup[MAX_COMP],globalgain;
188     float gainr[MAX_COMP],toggle[MAX_COMP],listen[MAX_COMP],max,out,xover1,xover2;
189     float old_yl[MAX_COMP], old_y1[MAX_COMP], old_yg[MAX_COMP];
190     float old_ll, old_l1;
191     float limit, outlevel[3];
192     int pos[3];
193     float average[3];
194     float oldxover1, oldxover2;
195     bool reset;
196 
197 };
198 
199 // -----------------------------------------------------------------------
200 
201 END_NAMESPACE_DISTRHO
202 
203 #endif
204