1 /*
2  * DISTRHO 3BandSplitter Plugin, based on 3BandSplitter by Michael Gruhn
3  * Copyright (C) 2007 Michael Gruhn <michael-gruhn@web.de>
4  * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation.
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 Lesser General Public License for more details.
14  *
15  * For a full copy of the license see the LICENSE file.
16  */
17 
18 #include "DistrhoPlugin3BandSplitter.hpp"
19 
20 #include <cmath>
21 
22 static const float kAMP_DB = 8.656170245f;
23 static const float kDC_ADD = 1e-30f;
24 static const float kPI     = 3.141592654f;
25 
26 START_NAMESPACE_DISTRHO
27 
28 // -----------------------------------------------------------------------
29 
DistrhoPlugin3BandSplitter()30 DistrhoPlugin3BandSplitter::DistrhoPlugin3BandSplitter()
31     : Plugin(paramCount, 1, 0) // 1 program, 0 states
32 {
33     // set default values
34     loadProgram(0);
35 
36     // reset
37     deactivate();
38 }
39 
40 // -----------------------------------------------------------------------
41 // Init
42 
initParameter(uint32_t index,Parameter & parameter)43 void DistrhoPlugin3BandSplitter::initParameter(uint32_t index, Parameter& parameter)
44 {
45     switch (index)
46     {
47     case paramLow:
48         parameter.hints      = kParameterIsAutomable;
49         parameter.name       = "Low";
50         parameter.symbol     = "low";
51         parameter.unit       = "dB";
52         parameter.ranges.def = 0.0f;
53         parameter.ranges.min = -24.0f;
54         parameter.ranges.max = 24.0f;
55         break;
56 
57     case paramMid:
58         parameter.hints      = kParameterIsAutomable;
59         parameter.name       = "Mid";
60         parameter.symbol     = "mid";
61         parameter.unit       = "dB";
62         parameter.ranges.def = 0.0f;
63         parameter.ranges.min = -24.0f;
64         parameter.ranges.max = 24.0f;
65         break;
66 
67     case paramHigh:
68         parameter.hints      = kParameterIsAutomable;
69         parameter.name       = "High";
70         parameter.symbol     = "high";
71         parameter.unit       = "dB";
72         parameter.ranges.def = 0.0f;
73         parameter.ranges.min = -24.0f;
74         parameter.ranges.max = 24.0f;
75         break;
76 
77     case paramMaster:
78         parameter.hints      = kParameterIsAutomable;
79         parameter.name       = "Master";
80         parameter.symbol     = "master";
81         parameter.unit       = "dB";
82         parameter.ranges.def = 0.0f;
83         parameter.ranges.min = -24.0f;
84         parameter.ranges.max = 24.0f;
85         break;
86 
87     case paramLowMidFreq:
88         parameter.hints      = kParameterIsAutomable;
89         parameter.name       = "Low-Mid Freq";
90         parameter.symbol     = "low_mid";
91         parameter.unit       = "Hz";
92         parameter.ranges.def = 440.0f;
93         parameter.ranges.min = 0.0f;
94         parameter.ranges.max = 1000.0f;
95         break;
96 
97     case paramMidHighFreq:
98         parameter.hints      = kParameterIsAutomable;
99         parameter.name       = "Mid-High Freq";
100         parameter.symbol     = "mid_high";
101         parameter.unit       = "Hz";
102         parameter.ranges.def = 1000.0f;
103         parameter.ranges.min = 1000.0f;
104         parameter.ranges.max = 20000.0f;
105         break;
106     }
107 }
108 
initProgramName(uint32_t index,String & programName)109 void DistrhoPlugin3BandSplitter::initProgramName(uint32_t index, String& programName)
110 {
111     if (index != 0)
112         return;
113 
114     programName = "Default";
115 }
116 
117 // -----------------------------------------------------------------------
118 // Internal data
119 
getParameterValue(uint32_t index) const120 float DistrhoPlugin3BandSplitter::getParameterValue(uint32_t index) const
121 {
122     switch (index)
123     {
124     case paramLow:
125         return fLow;
126     case paramMid:
127         return fMid;
128     case paramHigh:
129         return fHigh;
130     case paramMaster:
131         return fMaster;
132     case paramLowMidFreq:
133         return fLowMidFreq;
134     case paramMidHighFreq:
135         return fMidHighFreq;
136     default:
137         return 0.0f;
138     }
139 }
140 
setParameterValue(uint32_t index,float value)141 void DistrhoPlugin3BandSplitter::setParameterValue(uint32_t index, float value)
142 {
143     if (getSampleRate() <= 0.0)
144         return;
145 
146     switch (index)
147     {
148     case paramLow:
149         fLow   = value;
150         lowVol = std::exp( (fLow/48.0f) * 48.0f / kAMP_DB);
151         break;
152     case paramMid:
153         fMid   = value;
154         midVol = std::exp( (fMid/48.0f) * 48.0f / kAMP_DB);
155         break;
156     case paramHigh:
157         fHigh   = value;
158         highVol = std::exp( (fHigh/48.0f) * 48.0f / kAMP_DB);
159         break;
160     case paramMaster:
161         fMaster = value;
162         outVol  = std::exp( (fMaster/48.0f) * 48.0f / kAMP_DB);
163         break;
164     case paramLowMidFreq:
165         fLowMidFreq = std::fmin(value, fMidHighFreq);
166         freqLP = fLowMidFreq;
167         xLP  = std::exp(-2.0f * kPI * freqLP / (float)getSampleRate());
168         a0LP = 1.0f - xLP;
169         b1LP = -xLP;
170         break;
171     case paramMidHighFreq:
172         fMidHighFreq = std::fmax(value, fLowMidFreq);
173         freqHP = fMidHighFreq;
174         xHP  = std::exp(-2.0f * kPI * freqHP / (float)getSampleRate());
175         a0HP = 1.0f - xHP;
176         b1HP = -xHP;
177         break;
178     }
179 }
180 
loadProgram(uint32_t index)181 void DistrhoPlugin3BandSplitter::loadProgram(uint32_t index)
182 {
183     if (index != 0)
184         return;
185 
186     // Default values
187     fLow = 0.0f;
188     fMid = 0.0f;
189     fHigh = 0.0f;
190     fMaster = 0.0f;
191     fLowMidFreq = 220.0f;
192     fMidHighFreq = 2000.0f;
193 
194     // Internal stuff
195     lowVol = midVol = highVol = outVol = 1.0f;
196     freqLP = 200.0f;
197     freqHP = 2000.0f;
198 
199     // reset filter values
200     activate();
201 }
202 
203 // -----------------------------------------------------------------------
204 // Process
205 
activate()206 void DistrhoPlugin3BandSplitter::activate()
207 {
208     const float sr = (float)getSampleRate();
209 
210     xLP  = std::exp(-2.0f * kPI * freqLP / sr);
211 
212 #ifdef DISTRHO_OS_WINDOWS
213     // don't ask me why, but this fixes a crash/exception below on windows...
214     printf("%f\n", -xLP);
215 #endif
216 
217     a0LP = 1.0f - xLP;
218     b1LP = -xLP;
219 
220     xHP  = std::exp(-2.0f * kPI * freqHP / sr);
221     a0HP = 1.0f - xHP;
222     b1HP = -xHP;
223 }
224 
deactivate()225 void DistrhoPlugin3BandSplitter::deactivate()
226 {
227     out1LP = out2LP = out1HP = out2HP = 0.0f;
228     tmp1LP = tmp2LP = tmp1HP = tmp2HP = 0.0f;
229 }
230 
run(const float ** inputs,float ** outputs,uint32_t frames)231 void DistrhoPlugin3BandSplitter::run(const float** inputs, float** outputs, uint32_t frames)
232 {
233     const float* in1  = inputs[0];
234     const float* in2  = inputs[1];
235     float*       out1 = outputs[0];
236     float*       out2 = outputs[1];
237     float*       out3 = outputs[2];
238     float*       out4 = outputs[3];
239     float*       out5 = outputs[4];
240     float*       out6 = outputs[5];
241 
242     for (uint32_t i=0; i < frames; ++i)
243     {
244         tmp1LP = a0LP * in1[i] - b1LP * tmp1LP + kDC_ADD;
245         tmp2LP = a0LP * in2[i] - b1LP * tmp2LP + kDC_ADD;
246         out1LP = tmp1LP - kDC_ADD;
247         out2LP = tmp2LP - kDC_ADD;
248 
249         tmp1HP = a0HP * in1[i] - b1HP * tmp1HP + kDC_ADD;
250         tmp2HP = a0HP * in2[i] - b1HP * tmp2HP + kDC_ADD;
251         out1HP = in1[i] - tmp1HP - kDC_ADD;
252         out2HP = in2[i] - tmp2HP - kDC_ADD;
253 
254         out6[i] = out2HP*highVol * outVol;
255         out5[i] = out1HP*highVol * outVol;
256         out4[i] = (in2[i] - out2LP - out2HP)*midVol * outVol;
257         out3[i] = (in1[i] - out1LP - out1HP)*midVol * outVol;
258         out2[i] = out2LP*lowVol * outVol;
259         out1[i] = out1LP*lowVol * outVol;
260     }
261 }
262 
263 // -----------------------------------------------------------------------
264 
createPlugin()265 Plugin* createPlugin()
266 {
267     return new DistrhoPlugin3BandSplitter();
268 }
269 
270 // -----------------------------------------------------------------------
271 
272 END_NAMESPACE_DISTRHO
273