1 /***************************************************************************
2 * Copyright (C) 2009 by Pere Ràfols Soler *
3 * sapista2@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (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 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 #include <stdlib.h>
22 #include <iostream>
23
24 #include <cstring>
25 #include "dynamicswindow.h"
26 #include "guiconstants.h"
27 #include "setwidgetcolors.h"
28
29 #define KNOB_ICON_FILE "/knobs/knob2_32px.png"
30 #define KNOB_SIZE_X 75
31 #define KNOB_SIZE_Y 72
32 #define WIDGET_BORDER 3
33 #define LOGO_PATH "icons/logodynamics.png"
34
35
DynMainWindow(const char * uri,std::string bundlePath,std::string title,bool isCompressor,bool hasSideChain)36 DynMainWindow::DynMainWindow(const char *uri, std::string bundlePath, std::string title, bool isCompressor, bool hasSideChain)
37 :m_pluginUri(uri),
38 m_bundlePath(bundlePath),
39 m_bIsCompressor(isCompressor)
40 {
41 m_InGainFader = Gtk::manage(new KnobWidget2(-20.0, 20.0, "In Gain", "dB", (m_bundlePath + KNOB_ICON_FILE).c_str(), KNOB_TYPE_LIN, true ));
42 m_InputVu = Gtk::manage(new VUWidget(1, -48.0, 6.0, "In", false, true));
43 m_GainReductionVu = Gtk::manage(new VUWidget(1, 0.0, 20.0, "GR", true));
44 m_Attack = Gtk::manage(new KnobWidget2(0.01, 500.0, "Attack", "ms", (m_bundlePath + KNOB_ICON_FILE).c_str() , KNOB_TYPE_TIME ));
45 m_Release = Gtk::manage(new KnobWidget2(5.0, 4000.0, "Release", "ms", (m_bundlePath + KNOB_ICON_FILE).c_str() , KNOB_TYPE_TIME ));
46 m_Punch = Gtk::manage(new KnobWidget2(0.0, 100.0, "Punch", "%", (m_bundlePath + KNOB_ICON_FILE).c_str(), KNOB_TYPE_LIN ));
47 m_HPF = Gtk::manage(new KnobWidget2(20.0, 20000.0, "Key HPF", "Hz", (m_bundlePath + KNOB_ICON_FILE).c_str() , KNOB_TYPE_FREQ));
48 m_LPF = Gtk::manage(new KnobWidget2(20.0, 20000.0, "Key LPF", "Hz", (m_bundlePath + KNOB_ICON_FILE).c_str() , KNOB_TYPE_FREQ));
49 m_DryWet = Gtk::manage(new KnobWidget2(0.0, 100.0, "Dry/Wet", "%", (m_bundlePath + KNOB_ICON_FILE).c_str(), KNOB_TYPE_LIN ));
50 m_Ratio = Gtk::manage(new KnobWidget2(1.0, 100.0, "Ratio", "dB", (m_bundlePath + KNOB_ICON_FILE).c_str(), KNOB_TYPE_TIME ));
51 m_Knee = Gtk::manage(new KnobWidget2(0.0, 20.0, "Knee", "dB", (m_bundlePath + KNOB_ICON_FILE).c_str() ));
52
53 if(m_bIsCompressor)
54 {
55 //Is Compressor
56 m_Hold_Makeup = Gtk::manage(new KnobWidget2(0.0, 20.0, "Makeup", "dB", (m_bundlePath + KNOB_ICON_FILE).c_str() ));
57 }
58 else
59 {
60 //Is Gate
61 m_Hold_Makeup = Gtk::manage(new KnobWidget2(0.01, 3000.0, "Hold", "ms", (m_bundlePath + KNOB_ICON_FILE).c_str() , KNOB_TYPE_TIME ));
62 m_Range = Gtk::manage(new KnobWidget2(-90.0, -1.0, "Range", "dB", (m_bundlePath + KNOB_ICON_FILE).c_str() ));
63 }
64
65 m_Plot = Gtk::manage(new PlotDynCurve(m_bIsCompressor));
66
67 m_KeyButton.set_label("Key Listen");
68 m_KeyButton.set_size_request(-1,20);
69 m_KeyButtonAlign.add(m_KeyButton);
70 m_KeyButtonAlign.set_padding(0,0, 10, 10);
71
72 if(hasSideChain)
73 {
74 m_FeedBackMode_SideChainActive.set_label("SC Active");
75 }
76 else
77 {
78 m_FeedBackMode_SideChainActive.set_label("Feedback");
79 }
80 m_FeedBackMode_SideChainActive.set_size_request(-1,20);
81 m_FeedBackModeAlign.add(m_FeedBackMode_SideChainActive);
82 m_FeedBackModeAlign.set_padding(0,0, 10, 10);
83
84
85 m_OptoMode.set_label("S-Release");
86 m_OptoMode.set_size_request(-1,20);
87 m_OptoModeAlign.add(m_OptoMode);
88 m_OptoModeAlign.set_padding(0,0, 10, 10);
89
90
91 m_LTitle.set_use_markup(true);
92 m_LTitle.set_markup( "<span font_weight=\"bold\" font=\"12px\" font_family=\"Monospace\">" + title + "</span>");
93 m_LTitle.set_size_request(-1, 25);
94 m_TitleAlign.add(m_LTitle);
95 m_TitleAlign.set_padding(0,0, 60, 0);
96
97 //load image logo
98 image_logo = new Gtk::Image(m_bundlePath + "/" + LOGO_PATH);
99
100 m_VuBox.pack_start(*m_InputVu, Gtk::PACK_SHRINK);
101 m_VuBox.pack_start(*m_GainReductionVu, Gtk::PACK_SHRINK);
102 m_VuBox.set_border_width(4);
103 m_VuBox.show_all_children();
104
105 m_SideChain2Box.set_border_width(WIDGET_BORDER);
106 m_SideChain2Box.set_spacing(WIDGET_BORDER);
107 m_SideChain2Box.pack_start(*m_LPF, Gtk::PACK_EXPAND_WIDGET);
108 m_SideChain2Box.pack_start(*m_HPF, Gtk::PACK_EXPAND_WIDGET);
109
110 m_SideChainBox.set_border_width(WIDGET_BORDER);
111 m_SideChainBox.set_spacing(WIDGET_BORDER);
112 m_SideChainBox.pack_start(m_KeyButtonAlign,Gtk::PACK_SHRINK);
113 if(m_bIsCompressor)
114 {
115 m_SideChainBox.pack_start(m_FeedBackModeAlign,Gtk::PACK_SHRINK);
116 m_SideChainBox.pack_start(m_OptoModeAlign,Gtk::PACK_SHRINK);
117 }
118 m_SideChainBox.pack_start(m_SideChain2Box,Gtk::PACK_SHRINK);
119 m_SideChainBox.show_all_children();
120 m_keyPadding.add(m_SideChainBox);
121 m_keyPadding.set_padding(30,0, 0, 0);
122
123 m_SCBox.add(m_keyPadding);
124 m_sidchianAlign.set_padding(0, 3, 0, 0);
125 m_sidchianAlign.add(m_SCBox);
126
127 m_DynBox.set_border_width(WIDGET_BORDER);
128 m_DynBox.set_spacing(WIDGET_BORDER);
129 m_DynBox.pack_start(*m_InGainFader, Gtk::PACK_SHRINK);
130 m_DynBox.pack_start(*m_Ratio, Gtk::PACK_SHRINK);
131 m_DynBox.pack_start(*m_Knee, Gtk::PACK_SHRINK);
132
133 m_DynBox.pack_start(*m_DryWet, Gtk::PACK_SHRINK);
134 m_DynBox.show_all_children();
135
136 m_BalBox.set_border_width(WIDGET_BORDER);
137 m_BalBox.set_spacing(WIDGET_BORDER);
138 m_BalBox.pack_start(*m_Attack, Gtk::PACK_SHRINK);
139 m_BalBox.pack_start(*m_Release, Gtk::PACK_SHRINK);
140 if(m_bIsCompressor)
141 {
142 m_BalBox.pack_start(*m_Punch, Gtk::PACK_SHRINK);
143 }
144 m_BalBox.pack_start(*m_Hold_Makeup, Gtk::PACK_SHRINK);
145 if(!m_bIsCompressor)
146 {
147 m_BalBox.pack_start(*m_Range, Gtk::PACK_SHRINK);
148 }
149 m_BalBox.show_all_children();
150
151 m_PlotBox.pack_start(m_DynBox, Gtk::PACK_SHRINK);
152 m_PlotBox.pack_start(*m_Plot, Gtk::PACK_SHRINK);
153 m_PlotBox.show_all_children();
154
155 m_PlotLabelBox.pack_start(m_TitleAlign, Gtk::PACK_SHRINK);
156 m_PlotLabelBox.pack_start(m_PlotBox, Gtk::PACK_SHRINK);
157 m_PlotLabelBox.show_all_children();
158
159 m_TitleBox.pack_start(m_BalBox, Gtk::PACK_SHRINK);
160 m_TitleBox.pack_start(*image_logo, Gtk::PACK_SHRINK);
161 m_TitleBox.show_all_children();
162
163 m_BotBox.pack_start(m_TitleBox, Gtk::PACK_SHRINK);
164 m_BotBox.pack_start(m_sidchianAlign, Gtk::PACK_EXPAND_PADDING);
165
166 m_Main2Box.pack_start(m_PlotLabelBox, Gtk::PACK_SHRINK);
167 m_Main2Box.pack_start(m_BotBox, Gtk::PACK_SHRINK);
168
169 m_MainBox.pack_start(m_Main2Box, Gtk::PACK_SHRINK);
170 m_MainBox.pack_start(m_VuBox, Gtk::PACK_SHRINK);
171
172 show_all();
173 add(m_MainBox);
174
175 //Set cutom theme color:
176 Gdk::Color m_WinBgColor;
177 SetWidgetColors m_WidgetColors;
178 m_WidgetColors.setGenericWidgetColors(&m_LTitle);
179
180 //Connect signals
181 m_InGainFader->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onGainChange));
182 m_InputVu->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onThresholdChange));
183 m_Ratio->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onRatioChange));
184 m_Attack->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onAttackChange));
185 m_Hold_Makeup->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onHoldChange));
186 m_Release->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onReleaseChange));
187 m_LPF->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onLPFChange));
188 m_HPF->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onHPFChange));
189 m_DryWet->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onDryWetChange));
190 m_KeyButton.signal_clicked().connect(sigc::mem_fun(*this, &DynMainWindow::onKeyListenChange));
191 m_Knee->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onKneeChange));
192
193 if(m_bIsCompressor)
194 {
195 m_FeedBackMode_SideChainActive.signal_clicked().connect(sigc::mem_fun(*this, &DynMainWindow::onFeedbackModeChange));
196 m_OptoMode.signal_clicked().connect(sigc::mem_fun(*this, &DynMainWindow::onModeCompressorChange));
197 m_Punch->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onPunchChange));
198 }
199 else
200 {
201 m_Range->signal_changed().connect(sigc::mem_fun(*this, &DynMainWindow::onRangeChange));
202 }
203 }
204
~DynMainWindow()205 DynMainWindow::~DynMainWindow()
206 {
207 delete m_InputVu;
208 delete m_GainReductionVu;
209 delete m_InGainFader;
210 delete m_Attack;
211 delete m_Hold_Makeup;
212 delete m_Release;
213 delete m_Ratio;
214 delete m_Knee;
215 delete m_Punch;
216 if(!m_bIsCompressor)
217 {
218 delete m_Range;
219 }
220 delete m_HPF;
221 delete m_LPF;
222 delete m_DryWet;
223 delete image_logo;
224 }
225
onGainChange()226 void DynMainWindow::onGainChange()
227 {
228 //Write to LV2 port
229 float aux;
230 aux = m_InGainFader->get_value();
231 write_function(controller, PORT_GAIN, sizeof(float), 0, &aux);
232 }
233
onThresholdChange()234 void DynMainWindow::onThresholdChange()
235 {
236 //Write to LV2 port
237 float aux;
238 aux = m_InputVu->get_value_th();
239 m_Plot->set_threshold(aux);
240 write_function(controller, PORT_THRESHOLD, sizeof(float), 0, &aux);
241 }
242
onRangeChange()243 void DynMainWindow::onRangeChange()
244 {
245 //Write to LV2 port
246 float aux;
247 aux = m_Range->get_value();
248
249 m_Plot->set_range(aux);
250 write_function(controller, PORT_FEEDBACK_RANGE_SCACTIVE, sizeof(float), 0, &aux);
251 }
252
onRatioChange()253 void DynMainWindow::onRatioChange()
254 {
255 //Write to LV2 port
256 float aux;
257 aux = m_Ratio->get_value();
258 m_Plot->set_ratio(aux);
259
260 write_function(controller, PORT_RATIO, sizeof(float), 0, &aux);
261 }
262
onAttackChange()263 void DynMainWindow::onAttackChange()
264 {
265 //Write to LV2 port
266 float aux;
267 aux = m_Attack->get_value();
268 write_function(controller, PORT_ATACK, sizeof(float), 0, &aux);
269 }
270
onHoldChange()271 void DynMainWindow::onHoldChange()
272 {
273 //Write to LV2 port
274 float aux;
275 aux = m_Hold_Makeup->get_value();
276 if(m_bIsCompressor)
277 {
278 m_Plot->set_makeup(aux);
279 }
280 write_function(controller, PORT_HOLD_MAKEUP, sizeof(float), 0, &aux);
281 }
282
onReleaseChange()283 void DynMainWindow::onReleaseChange()
284 {
285 //Write to LV2 port
286 float aux;
287 aux = m_Release->get_value();
288 write_function(controller, PORT_DECAY, sizeof(float), 0, &aux);
289 }
290
onPunchChange()291 void DynMainWindow::onPunchChange()
292 {
293 //Write to LV2 port
294 float aux;
295 aux = 0.01*m_Punch->get_value(); //Div by 100 to get 0% to 100% in range 0 to 1
296 write_function(controller, PORT_PUNCH, sizeof(float), 0, &aux);
297 }
298
onKneeChange()299 void DynMainWindow::onKneeChange()
300 {
301 //Write to LV2 port
302 float aux;
303 aux = m_Knee->get_value();
304 m_Plot->set_knee(aux);
305 write_function(controller, PORT_KNEE, sizeof(float), 0, &aux);
306 }
307
onHPFChange()308 void DynMainWindow::onHPFChange()
309 {
310 //Write to LV2 port
311 float aux;
312 aux = m_HPF->get_value();
313 write_function(controller, PORT_HPFFREQ, sizeof(float), 0, &aux);
314 }
315
onLPFChange()316 void DynMainWindow::onLPFChange()
317 {
318 //Write to LV2 port
319 float aux;
320 aux = m_LPF->get_value();
321 write_function(controller, PORT_LPFFREQ, sizeof(float), 0, &aux);
322 }
323
onDryWetChange()324 void DynMainWindow::onDryWetChange()
325 {
326 //Write to LV2 port
327 float aux;
328 aux = 0.01*m_DryWet->get_value(); //Div by 100 to get 0% to 100% in range 0 to 1
329 write_function(controller, PORT_DRY_WET, sizeof(float), 0, &aux);
330 }
331
onKeyListenChange()332 void DynMainWindow::onKeyListenChange()
333 {
334 //Write to LV2 port
335 float aux;
336 aux = m_KeyButton.get_active() ? 1.0 : 0.0;
337 write_function(controller, PORT_KEY_LISTEN, sizeof(float), 0, &aux);
338 }
339
onFeedbackModeChange()340 void DynMainWindow::onFeedbackModeChange()
341 {
342 //Write to LV2 port
343 float aux;
344 aux = m_FeedBackMode_SideChainActive.get_active() ? 1.0 : 0.0;
345 write_function(controller, PORT_FEEDBACK_RANGE_SCACTIVE, sizeof(float), 0, &aux);
346 }
347
onModeCompressorChange()348 void DynMainWindow::onModeCompressorChange()
349 {
350 //Write to LV2 port
351 float aux;
352 aux = m_OptoMode.get_active() ? 1.0 : 0.0;
353 write_function(controller, PORT_COMP_MODE, sizeof(float), 0, &aux);
354 }
355
356