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 <iostream>
22 #include <cstring>
23 #include <gtkmm/rc.h>
24 #include <gtkmm/filechooserdialog.h>
25 #include "eqwindow.h"
26 #include "guiconstants.h"
27 #include "setwidgetcolors.h"
28
29 #define KNOB_ICON_FILE "/knobs/knob2_32px.png"
30 #define KNOB_ICON_FILE_MINI "/knobs/knob2_25px.png"
31
32 //Constructor
EqMainWindow(int iAudioChannels,int iNumBands,const char * uri,const char * bundlePath,const LV2_Feature * const * features)33 EqMainWindow::EqMainWindow(int iAudioChannels, int iNumBands, const char *uri, const char *bundlePath, const LV2_Feature *const *features)
34 :m_BypassButton("Eq On"),
35 m_FftRtaActive("RTA"),
36 m_FftSpecActive("Spec"),
37 m_dB10Scale("10 dB"),
38 m_dB25Scale("25 dB"),
39 m_dB50Scale("50 dB"),
40 m_LRStereoMode("L/R"),
41 m_MSStereoMode("M/S"),
42 m_FlatButton("Flat"),
43 m_SaveButton("Save"),
44 m_LoadButton("Load"),
45 m_FftHold("Hold"),
46 m_iNumOfChannels(iAudioChannels),
47 m_iNumOfBands(iNumBands),
48 m_bMutex(false),
49 m_port_event_InGain(false),
50 m_port_event_OutGain(false),
51 m_port_event_Bypass(false),
52 m_port_event_Curve(false),
53 m_pluginUri(uri),
54 m_bundlePath(bundlePath)
55 {
56 //Get LV2_Feature
57 map = NULL;
58 for (int i = 0; features[i]; ++i)
59 {
60 if (!strcmp(features[i]->URI, LV2_URID_URI "#map"))
61 {
62 map = (LV2_URID_Map*)features[i]->data;
63 }
64 }
65
66 if (!map)
67 {
68 std::cout<<"Eq10q UI: Host does not support urid:map"<<std::endl;
69 }
70 else
71 {
72 //Map uris and init forge
73 map_eq10q_uris(map, &uris);
74 lv2_atom_forge_init(&forge, map);
75 }
76
77 //Prepare curve Events vectors
78 m_port_event_Curve_Gain = new bool[m_iNumOfBands];
79 m_port_event_Curve_Freq = new bool[m_iNumOfBands];
80 m_port_event_Curve_Q = new bool[m_iNumOfBands];
81 m_port_event_Curve_Type = new bool[m_iNumOfBands];
82 m_port_event_Curve_Enable = new bool[m_iNumOfBands];
83
84 //load image logo
85 image_logo_center = new Gtk::Image(m_bundlePath + std::string(IMAGE_LOGO_PATH));
86
87 m_MainWidgetAlign.set_padding(3,3,3,3);
88
89 m_AButton.set_active(true);
90 m_ButtonAAlign.add(m_AButton);
91 m_BypassAlign.add(m_BypassButton);
92 m_ButtonAAlign.set(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, 0.0, 0.0);
93 m_BypassAlign.set(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, 0.0, 0.0);
94 m_FlatAlign.add(m_FlatButton);
95 m_FlatAlign.set(Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER,0.0, 0.0);
96 m_LoadAlign.add(m_LoadButton);
97 m_SaveAlign.add(m_SaveButton);
98 m_LoadAlign.set(Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER,0.0, 0.0);
99 m_SaveAlign.set(Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER,0.0, 0.0);
100 m_BypassAlign.set_size_request(80, -1);
101
102 m_GainFaderIn = Gtk::manage(new KnobWidget2(-20.0, 20.0, "In Gain", "dB", (m_bundlePath + KNOB_ICON_FILE).c_str(), KNOB_TYPE_LIN, true ));
103 m_GainFaderOut = Gtk::manage(new KnobWidget2(-20.0, 20.0, "Out Gain", "dB", (m_bundlePath + KNOB_ICON_FILE).c_str(), KNOB_TYPE_LIN, true ));
104 m_VuMeterIn = Gtk::manage(new VUWidget(m_iNumOfChannels, -36.0, 6.0, "In"));
105 m_VuMeterOut = Gtk::manage(new VUWidget(m_iNumOfChannels, -36.0, 6.0, "Out"));
106
107 m_FftRange = Gtk::manage(new KnobWidget2(20.0, 100.0, "Range", "dB", (m_bundlePath + KNOB_ICON_FILE_MINI).c_str(), KNOB_TYPE_LIN ));
108 m_FftGain = Gtk::manage(new KnobWidget2(-20.0, 20.0, "Gain", "dB", (m_bundlePath + KNOB_ICON_FILE_MINI).c_str(), KNOB_TYPE_LIN, true ));
109 m_FftRange->set_value(80.0);
110 m_FftGain->set_value(0.0);
111 m_FftCtlVBox.pack_start(m_FftRtaActive, Gtk::PACK_EXPAND_PADDING);
112 m_FftCtlVBox.pack_start(m_FftSpecActive, Gtk::PACK_EXPAND_PADDING);
113 m_FftAlngGain.add(*m_FftGain);
114 m_FftAlngGain.set_padding(2, 5, 8, 12);
115 m_FftCtlVBox.pack_start(m_FftAlngGain, Gtk::PACK_SHRINK);
116 m_FftAlngRange.add(*m_FftRange);
117 m_FftAlngRange.set_padding(2, 5, 8, 12);
118 m_FftCtlVBox.pack_start(m_FftAlngRange, Gtk::PACK_SHRINK);
119 m_FftCtlVBox.pack_start(m_FftHold, Gtk::PACK_EXPAND_PADDING);
120
121 m_FftAlignInner.add(m_FftCtlVBox);
122 m_FftAlignInner.set_padding(25, 8, 6, 6);
123 m_FftBox = Gtk::manage(new SideChainBox(" FFT ", 10));
124 m_FftBox->add(m_FftAlignInner);
125 m_FftAlign.set_padding(0, 3, 0, 0);
126 m_FftAlign.add(*m_FftBox);
127
128 m_dBScaleBox.pack_start(m_dB10Scale, Gtk::PACK_EXPAND_PADDING);
129 m_dBScaleBox.pack_start(m_dB25Scale, Gtk::PACK_EXPAND_PADDING);
130 m_dBScaleBox.pack_start(m_dB50Scale, Gtk::PACK_EXPAND_PADDING);
131
132 m_dBScaleAlignInner.add(m_dBScaleBox);
133 m_dBScaleAlignInner.set_padding(25, 8, 6, 6);
134 m_dBScaleFrame = Gtk::manage(new SideChainBox(" Range ", 10));
135 m_dBScaleFrame->add(m_dBScaleAlignInner);
136 m_dBScaleAlign.set_padding(0, 3, 0, 0);
137 m_dBScaleAlign.add(*m_dBScaleFrame);
138
139 //Stereo mode pack
140 if(m_iNumOfChannels == 2)
141 {
142 m_LRStereoMode.set_active(true);
143 m_MSStereoMode.set_active(false);
144 m_StereoBox.pack_start(m_LRStereoMode, Gtk::PACK_EXPAND_PADDING);
145 m_StereoBox.pack_start(m_MSStereoMode, Gtk::PACK_EXPAND_PADDING);
146 m_StereoInnerAlng.add(m_StereoBox);
147 m_StereoInnerAlng.set_padding(25, 8, 6, 6);
148 m_MidSideBox = Gtk::manage(new SideChainBox(" Mode ", 10));
149 m_MidSideBox->add(m_StereoInnerAlng);
150 m_StereAlng.set_padding(0, 3, 0, 0);
151 m_StereAlng.add(*m_MidSideBox);
152 }
153
154 //dB Scale & Fft Ctl box packing
155 if(m_iNumOfChannels == 2)
156 {
157 m_FftdBBox.pack_start(m_StereAlng,Gtk::PACK_SHRINK);
158 }
159 m_FftdBBox.pack_start(m_dBScaleAlign,Gtk::PACK_SHRINK);
160 m_FftdBBox.pack_start(m_FftAlign,Gtk::PACK_SHRINK);
161
162 m_Bode = Gtk::manage(new PlotEQCurve(m_iNumOfBands, m_iNumOfChannels));
163
164 m_BandBox.set_spacing(0);
165 m_BandBox.set_homogeneous(true);
166 m_BandCtlArray = new BandCtl*[m_iNumOfBands];
167
168 for (int i = 0; i< m_iNumOfBands; i++)
169 {
170 m_BandCtlArray[i] = Gtk::manage(new BandCtl(i, &m_bMutex, m_bundlePath.c_str(), m_iNumOfChannels == 2));
171 m_BandBox.pack_start(*m_BandCtlArray[i], Gtk::PACK_SHRINK);
172 m_BandCtlArray[i] -> signal_changed().connect( sigc::mem_fun(*this, &EqMainWindow::onBandChange));
173 m_BandCtlArray[i] -> signal_band_selected().connect( sigc::mem_fun(*this, &EqMainWindow::onBandCtlSelectBand));
174 m_BandCtlArray[i] -> signal_band_unselected().connect( sigc::mem_fun(*this, &EqMainWindow::onBandCtlUnselectBand));
175 m_BandCtlArray[i] -> signal_mid_side_changed().connect( sigc::mem_fun(*this, &EqMainWindow::onBandCtlMidSideChanged));
176 }
177
178 //Bode plot layout
179 m_PlotBox.set_spacing(0);
180 m_PlotBox.pack_start(*m_Bode);
181 m_PlotBox.pack_start(m_FftdBBox,Gtk::PACK_SHRINK);
182
183 //Box layout
184 m_ABFlatBox.set_homogeneous(false);
185 m_ABFlatBox.pack_start(m_BypassAlign,Gtk::PACK_SHRINK);
186 m_ABFlatBox.pack_start(m_ButtonAAlign,Gtk::PACK_SHRINK);
187 m_ABFlatBox.pack_start(*image_logo_center);
188 m_ABFlatBox.pack_start(m_FlatAlign,Gtk::PACK_SHRINK);
189 m_ABFlatBox.pack_start(m_LoadAlign,Gtk::PACK_SHRINK);
190 m_ABFlatBox.pack_start(m_SaveAlign,Gtk::PACK_SHRINK);
191 m_LoadButton.show();
192 m_SaveButton.show();
193 m_LoadAlign.show();
194 m_SaveAlign.show();
195
196 m_CurveBypassBandsBox.pack_start(m_PlotBox ,Gtk::PACK_SHRINK);
197 m_CurveBypassBandsBox.pack_start(m_ABFlatBox ,Gtk::PACK_SHRINK);
198 m_CurveBypassBandsBox.pack_start(m_BandBox ,Gtk::PACK_SHRINK);
199
200 m_InGainBox.pack_start(*m_VuMeterIn, Gtk::PACK_EXPAND_WIDGET);
201 m_InGainBox.pack_start(*m_GainFaderIn, Gtk::PACK_SHRINK);
202
203 m_OutGainBox.pack_start(*m_VuMeterOut, Gtk::PACK_EXPAND_WIDGET);
204 m_OutGainBox.pack_start(*m_GainFaderOut, Gtk::PACK_SHRINK);
205
206 m_GainEqBox.pack_start(m_CurveBypassBandsBox, Gtk::PACK_SHRINK);
207 m_GainEqBox.pack_start(m_InGainBox, Gtk::PACK_SHRINK);
208 m_GainEqBox.pack_start(m_OutGainBox, Gtk::PACK_SHRINK);
209
210 m_GainEqBox.set_spacing(2);
211 m_MainBox.pack_start(m_GainEqBox);
212 m_MainBox.set_spacing(0);
213
214 image_logo_center->show();
215
216 m_MainWidgetAlign.add(m_MainBox);
217 add(m_MainWidgetAlign);
218 m_MainWidgetAlign.show();
219
220 //Add some tooltips
221 m_AButton.set_tooltip_text("A/B eq comparation");
222 m_BypassButton.set_tooltip_text("Enable/Disable the equalizer");
223 m_FlatButton.set_tooltip_text("Reset all values to default");
224 m_GainFaderIn->set_tooltip_text("Adjust the input gain");
225 m_GainFaderOut->set_tooltip_text("Adjust the output gain");
226 m_LoadButton.set_tooltip_text("Load curve from file");
227 m_SaveButton.set_tooltip_text("Save curve to file");
228 m_dB10Scale.set_tooltip_text("Change plot range to 10 dB");
229 m_dB25Scale.set_tooltip_text("Change plot range to 25 dB");
230 m_dB50Scale.set_tooltip_text("Change plot range to 50 dB");
231
232 //connect signals
233 m_BypassButton.signal_clicked().connect(sigc::mem_fun(*this, &EqMainWindow::onButtonBypass));
234 m_AButton.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::onButtonA));
235 m_FlatButton.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::onButtonFlat));
236
237 m_GainFaderIn->signal_changed().connect(sigc::mem_fun(*this, &EqMainWindow::onInputGainChange));
238 m_GainFaderOut->signal_changed().connect(sigc::mem_fun(*this, &EqMainWindow::onOutputGainChange));
239
240 m_Bode->signal_changed().connect(sigc::mem_fun(*this, &EqMainWindow::onCurveChange));
241 m_Bode->signal_enabled().connect(sigc::mem_fun(*this, &EqMainWindow::onCurveBandEnable));
242 m_Bode->signal_selected().connect(sigc::mem_fun(*this, &EqMainWindow::onBodeSelectBand));
243 m_Bode->signal_unselected().connect(sigc::mem_fun(*this, &EqMainWindow::onBodeUnselectBand));
244 Glib::signal_timeout().connect( sigc::mem_fun(*this, &EqMainWindow::on_timeout), TIMER_VALUE_MS);
245 m_SaveButton.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::saveToFile));
246 m_LoadButton.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::loadFromFile));
247
248 //FFT Control
249 m_FftRtaActive.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::onButtonFftRta));
250 m_FftSpecActive.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::onButtonFftSpc));
251 m_FftHold.signal_press().connect( sigc::mem_fun(*this, &EqMainWindow::onHoldFft_press));
252 m_FftHold.signal_release().connect( sigc::mem_fun(*this, &EqMainWindow::onHoldFft_release));
253 m_FftGain->signal_changed().connect(sigc::mem_fun(*this, &EqMainWindow::onFftGainScale));
254 m_FftRange->signal_changed().connect(sigc::mem_fun(*this, &EqMainWindow::onFftRangeScale));
255
256 //dB Scale controlrs
257 m_Bode->setPlotdBRange(25.0);
258 m_dB25Scale.set_active(true);
259 m_dB10Scale.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::onDbScale10Changed));
260 m_dB25Scale.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::onDbScale25Changed));
261 m_dB50Scale.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::onDbScale50Changed));
262
263 //MidSide Mode Selector
264 if(m_iNumOfChannels == 2)
265 {
266 m_LRStereoMode.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::onLeftRightModeSelected));
267 m_MSStereoMode.signal_clicked().connect( sigc::mem_fun(*this, &EqMainWindow::onMidSideModeSelected));
268 }
269
270 //Load the EQ Parameters objects, the params for A curve will be loaded by host acording previous session plugin state
271 m_AParams = new EqParams(m_iNumOfBands);
272 m_BParams = new EqParams(m_iNumOfBands);
273 m_AParams->loadFromTtlFile(m_pluginUri.c_str());
274 m_BParams->loadFromTtlFile(m_pluginUri.c_str());
275 m_CurParams = m_AParams;
276
277 //Set cutom theme color:
278 Gdk::Color m_WinBgColor;
279 SetWidgetColors m_WidgetColors;
280
281 }
282
~EqMainWindow()283 EqMainWindow::~EqMainWindow()
284 {
285 //Send FFT_OFF to DSP
286 sendAtomFftOn(false);
287
288 delete image_logo_center;
289 delete m_AParams;
290 delete m_BParams;
291 delete m_GainFaderIn;
292 delete m_GainFaderOut;
293 delete m_VuMeterIn;
294 delete m_VuMeterOut;
295 delete m_Bode;
296 delete[] m_port_event_Curve_Gain;
297 delete[] m_port_event_Curve_Freq;
298 delete[] m_port_event_Curve_Q;
299 delete[] m_port_event_Curve_Type;
300 delete[] m_port_event_Curve_Enable;
301 delete m_FftGain;
302 delete m_FftRange;
303 delete m_FftBox;
304
305 if(m_iNumOfChannels == 2)
306 {
307 delete m_MidSideBox;
308 }
309
310 for(int i = 0; i < m_iNumOfBands; i++)
311 {
312 delete m_BandCtlArray[i];
313 }
314 delete[] m_BandCtlArray;
315 }
316
request_sample_rate()317 void EqMainWindow::request_sample_rate()
318 {
319 //Request Sample rate
320 int AtomPortNumber = PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands + 2*m_iNumOfChannels + 1;
321 uint8_t obj_buf[64];
322 lv2_atom_forge_set_buffer(&forge, obj_buf, sizeof(obj_buf));
323 LV2_Atom_Forge_Frame frame;
324 LV2_Atom* msg = (LV2_Atom*)lv2_atom_forge_object(&forge, &frame, 0, uris.atom_sample_rate_request);
325 lv2_atom_forge_pop(&forge, &frame);
326 write_function(controller, AtomPortNumber, lv2_atom_total_size(msg), uris.atom_eventTransfer, msg);
327 }
328
329
330 //Timer to redraw all widgets in case of host port events
on_timeout()331 bool EqMainWindow::on_timeout()
332 {
333 if(m_port_event_Bypass)
334 {
335 m_port_event_Bypass = false;
336 m_BypassButton.set_active(m_bypassValue > 0.5f ? false : true);
337 m_Bode->setBypass(m_bypassValue > 0.5f ? true : false);
338 }
339
340 if(m_port_event_InGain)
341 {
342 m_port_event_InGain = false;
343 m_GainFaderIn->set_value((double)m_CurParams->getInputGain());
344 }
345
346 if(m_port_event_OutGain)
347 {
348 m_port_event_OutGain = false;
349 m_GainFaderOut->set_value((double)m_CurParams->getOutputGain());
350 }
351
352 if(m_port_event_Curve)
353 {
354 m_port_event_Curve = false;
355 for(int i = 0; i < m_iNumOfBands; i++)
356 {
357 if(m_port_event_Curve_Gain[i])
358 {
359 m_port_event_Curve_Gain[i] = false;
360 m_BandCtlArray[i]->setGain(m_CurParams->getBandGain(i));
361 m_Bode->setBandGain(i, m_CurParams->getBandGain(i));
362 }
363 if(m_port_event_Curve_Freq[i])
364 {
365 m_port_event_Curve_Freq[i] = false;
366 m_BandCtlArray[i]->setFreq(m_CurParams->getBandFreq(i));
367 m_Bode->setBandFreq(i, m_CurParams->getBandFreq(i));
368 }
369 if(m_port_event_Curve_Q[i])
370 {
371 m_port_event_Curve_Q[i] = false;
372 m_BandCtlArray[i]->setQ(m_CurParams->getBandQ(i));
373 m_Bode->setBandQ(i, m_CurParams->getBandQ(i));
374 }
375 if(m_port_event_Curve_Enable[i])
376 {
377 m_port_event_Curve_Enable[i] = false;
378 m_BandCtlArray[i]->setEnabled(m_CurParams->getBandEnabled(i));
379 m_Bode->setBandEnable(i, m_CurParams->getBandEnabled(i));
380 }
381 if(m_port_event_Curve_Type[i])
382 {
383 m_port_event_Curve_Type[i] = false;
384 m_BandCtlArray[i]->setFilterType(m_CurParams->getBandType(i));
385 m_Bode->setBandType(i, m_CurParams->getBandType(i));
386 }
387 }
388 }
389 return true;
390 }
391
changeAB(EqParams * toBeCurrent)392 void EqMainWindow::changeAB(EqParams *toBeCurrent)
393 {
394 m_CurParams = toBeCurrent;
395
396 //Reload All data
397 m_GainFaderIn->set_value((double)m_CurParams->getInputGain());
398 m_GainFaderOut->set_value((double)m_CurParams->getOutputGain());
399
400 //Write to LV2 port
401 float aux;
402 aux =(float) m_GainFaderIn->get_value();
403 write_function(controller, EQ_INGAIN, sizeof(float), 0, &aux);
404 aux =(float) m_GainFaderOut->get_value();
405 write_function(controller, EQ_OUTGAIN, sizeof(float), 0, &aux);
406
407 //Reset the Curve Plot
408 m_Bode->resetCurve();
409
410 //changeAB action will overwrite Q values by defaults to keep the values we use this var
411 float usedQ;
412
413 for(int i = 0; i < m_iNumOfBands; i++)
414 {
415 usedQ = m_CurParams->getBandQ(i);
416 //It's very important to set de values for bandCtl and bode object.
417 //Because if there are some value that does not change between A/B curves this could be not correctly updated
418 m_BandCtlArray[i]->setFreq(m_CurParams->getBandFreq(i));
419 m_BandCtlArray[i]->setGain(m_CurParams->getBandGain(i));
420 m_BandCtlArray[i]->setEnabled(m_CurParams->getBandEnabled(i));
421 m_BandCtlArray[i]->setFilterType(m_CurParams->getBandType(i));
422 m_BandCtlArray[i]->setQ(usedQ);
423 m_CurParams->setBandQ(i, usedQ);
424
425 m_Bode->setBandGain(i, m_CurParams->getBandGain(i));
426 m_Bode->setBandFreq(i, m_CurParams->getBandFreq(i));
427 m_Bode->setBandQ(i, m_CurParams->getBandQ(i));
428 m_Bode->setBandEnable(i, m_CurParams->getBandEnabled(i));
429 m_Bode->setBandType(i, m_CurParams->getBandType(i));
430
431 //Write to LV2 ports
432 aux = m_CurParams->getBandGain(i);
433 write_function(controller, i + PORT_OFFSET + 2*m_iNumOfChannels, sizeof(float), 0, &aux); //Gain
434 aux = m_CurParams->getBandFreq(i);
435 write_function(controller, i + PORT_OFFSET + 2*m_iNumOfChannels + m_iNumOfBands, sizeof(float), 0, &aux); //Freq
436 aux = m_CurParams->getBandQ(i);
437 write_function(controller, i + PORT_OFFSET + 2*m_iNumOfChannels + 2*m_iNumOfBands, sizeof(float), 0, &aux); //Q
438 aux = m_CurParams->getBandEnabled(i);
439 write_function(controller, i + PORT_OFFSET + 2*m_iNumOfChannels + 4*m_iNumOfBands, sizeof(float), 0, &aux); //Enable
440 aux = m_CurParams->getBandType(i);
441 write_function(controller, i + PORT_OFFSET + 2*m_iNumOfChannels + 3*m_iNumOfBands, sizeof(float), 0, &aux); //Filter type
442 }
443 }
444
onButtonA()445 void EqMainWindow::onButtonA()
446 {
447 if(m_AButton.get_active())
448 {
449 changeAB(m_AParams);
450 }
451 else
452 {
453 changeAB(m_BParams);
454 }
455 }
456
onButtonFlat()457 void EqMainWindow::onButtonFlat()
458 {
459 //Popup a waring message
460 Gtk::MessageDialog dialog((Gtk::Window&)(*this->get_toplevel()),"This will flat the current curve, are you sure?",
461 false /* use_markup */, Gtk::MESSAGE_QUESTION,
462 Gtk::BUTTONS_OK_CANCEL);
463
464 if(dialog.run() == Gtk::RESPONSE_OK)loadEqParams();
465 }
466
onButtonBypass()467 void EqMainWindow::onButtonBypass()
468 {
469 #ifdef PRINT_DEBUG_INFO
470 std::cout<<"onButtonBypass... ";
471 #endif
472
473 m_Bode->setBypass(!m_BypassButton.get_active());
474 if (m_BypassButton.get_active())
475 {
476 m_bypassValue = 0.0f;
477 }
478 else
479 {
480 m_bypassValue = 1.0f;
481 }
482
483 write_function(controller, EQ_BYPASS, sizeof(float), 0, &m_bypassValue);
484
485 #ifdef PRINT_DEBUG_INFO
486 std::cout<<" Return"<<std::endl;
487 #endif
488 }
489
onBandChange(int iBand,int iField,float fValue)490 void EqMainWindow::onBandChange(int iBand, int iField, float fValue)
491 {
492
493 #ifdef PRINT_DEBUG_INFO
494 std::cout<<"onBandChange... Band = "<<iBand<<" Field = "<<iField;
495 #endif
496
497 switch(iField)
498 {
499 case GAIN_TYPE:
500 write_function(controller, iBand + PORT_OFFSET + 2*m_iNumOfChannels, sizeof(float), 0, &fValue);
501 m_CurParams->setBandGain(iBand, fValue);
502 m_Bode->setBandGain(iBand, fValue);
503 break;
504
505 case FREQ_TYPE:
506 write_function(controller, iBand + PORT_OFFSET + 2*m_iNumOfChannels + m_iNumOfBands, sizeof(float), 0, &fValue);
507 m_CurParams->setBandFreq(iBand, fValue);
508 m_Bode->setBandFreq(iBand, fValue);
509 break;
510
511 case Q_TYPE:
512 write_function(controller, iBand + PORT_OFFSET + 2*m_iNumOfChannels + 2*m_iNumOfBands, sizeof(float), 0, &fValue);
513 m_CurParams->setBandQ(iBand, fValue);
514 m_Bode->setBandQ(iBand, fValue);
515 break;
516
517 case FILTER_TYPE:
518 write_function(controller, iBand + PORT_OFFSET + 2*m_iNumOfChannels + 3*m_iNumOfBands, sizeof(float), 0, &fValue);
519 m_CurParams->setBandType(iBand, (int) fValue);
520 m_Bode->setBandType(iBand, (int) fValue);
521 break;
522
523 case ONOFF_TYPE:
524 int ival = (int) fValue;
525 if(m_iNumOfChannels == 2)
526 {
527 switch(m_BandCtlArray[iBand]->getStereoState())
528 {
529 case BandCtl::DUAL:
530 ival |= 0x00;
531 break;
532
533 case BandCtl::ML:
534 ival |= 0x02;
535 break;
536
537 case BandCtl::SR:
538 ival |= 0x04;
539 break;
540 }
541 }
542 float fVal = (float)ival;
543 write_function(controller, iBand + PORT_OFFSET + 2*m_iNumOfChannels + 4*m_iNumOfBands, sizeof(float), 0, &fVal);
544 m_CurParams->setBandEnabled(iBand, (fValue > 0.5));
545 m_Bode->setBandEnable(iBand, (fValue > 0.5));
546 break;
547 }
548
549 #ifdef PRINT_DEBUG_INFO
550 std::cout<<"Return"<<std::endl;
551 #endif
552 }
553
onBandCtlMidSideChanged(int band)554 void EqMainWindow::onBandCtlMidSideChanged(int band)
555 {
556 int ival = m_CurParams->getBandEnabled(band) ? 1 : 0;
557 if(m_iNumOfChannels == 2)
558 {
559 switch(m_BandCtlArray[band]->getStereoState())
560 {
561 case BandCtl::DUAL:
562 ival |= 0x00;
563 m_Bode->setStereoState(band, PlotEQCurve::DUAL);
564 break;
565
566 case BandCtl::ML:
567 ival |= 0x02;
568 m_Bode->setStereoState(band, PlotEQCurve::ML);
569 break;
570
571 case BandCtl::SR:
572 ival |= 0x04;
573 m_Bode->setStereoState(band, PlotEQCurve::SR);
574 break;
575 }
576 }
577 float fValue = (float)ival;
578 write_function(controller, band + PORT_OFFSET + 2*m_iNumOfChannels + 4*m_iNumOfBands, sizeof(float), 0, &fValue);
579
580 //TODO maybe I want to use AB comparation with MID-SIDE????
581 //m_CurParams->setBandEnabled(iBand, (fValue > 0.5));
582 }
583
584
onInputGainChange()585 void EqMainWindow::onInputGainChange()
586 {
587
588 #ifdef PRINT_DEBUG_INFO
589 std::cout<<"onInputGainChange... ";
590 #endif
591
592 //Save data Change
593 m_CurParams->setInputGain((float) m_GainFaderIn->get_value());
594
595 //Write to LV2 port
596 float aux;
597 aux = (float) m_GainFaderIn->get_value();
598 write_function(controller, EQ_INGAIN, sizeof(float), 0, &aux);
599
600 #ifdef PRINT_DEBUG_INFO
601 std::cout<<"Return"<<std::cout;
602 #endif
603 }
604
onOutputGainChange()605 void EqMainWindow::onOutputGainChange()
606 {
607 #ifdef PRINT_DEBUG_INFO
608 std::cout<<"onOutputGainChange... ";
609 #endif
610
611 //Save data Change
612 m_CurParams->setOutputGain((float) m_GainFaderOut->get_value());
613
614 //Write to LV2 port
615 float aux;
616 aux = (float) m_GainFaderOut->get_value();
617 write_function(controller, EQ_OUTGAIN, sizeof(float), 0, &aux);
618
619 #ifdef PRINT_DEBUG_INFO
620 std::cout<<"Return"<<std::cout;
621 #endif
622 }
623
onCurveChange(int band_ix,float Gain,float Freq,float Q)624 void EqMainWindow::onCurveChange(int band_ix, float Gain, float Freq, float Q)
625 {
626 m_BandCtlArray[band_ix]->setGain(Gain);
627 m_BandCtlArray[band_ix]->setFreq(Freq);
628 m_BandCtlArray[band_ix]->setQ(Q);
629
630 //Write to LV2 plugin ports
631 //Gain
632 write_function(controller, band_ix + PORT_OFFSET + 2*m_iNumOfChannels, sizeof(float), 0, &Gain);
633 m_CurParams->setBandGain(band_ix, Gain);
634
635 //Freq
636 write_function(controller, band_ix + PORT_OFFSET + 2*m_iNumOfChannels + m_iNumOfBands, sizeof(float), 0, &Freq);
637 m_CurParams->setBandFreq(band_ix, Freq);
638
639 //Q
640 write_function(controller, band_ix + PORT_OFFSET + 2*m_iNumOfChannels + 2*m_iNumOfBands, sizeof(float), 0, &Q);
641 m_CurParams->setBandQ(band_ix, Q);
642
643 }
644
onCurveBandEnable(int band_ix,bool IsEnabled)645 void EqMainWindow::onCurveBandEnable(int band_ix, bool IsEnabled)
646 {
647 m_BandCtlArray[band_ix]->setEnabled(IsEnabled);
648
649 int ival = IsEnabled ? 1 : 0;
650 if(m_iNumOfChannels == 2)
651 {
652 switch(m_BandCtlArray[band_ix]->getStereoState())
653 {
654 case BandCtl::DUAL:
655 ival |= 0x00;
656 break;
657
658 case BandCtl::ML:
659 ival |= 0x02;
660 break;
661
662 case BandCtl::SR:
663 ival |= 0x04;
664 break;
665 }
666 }
667 float fVal = (float)ival;
668 write_function(controller, band_ix + PORT_OFFSET + 2*m_iNumOfChannels + 4*m_iNumOfBands, sizeof(float), 0, &fVal);
669 m_CurParams->setBandEnabled(band_ix, IsEnabled);
670 }
671
onBodeSelectBand(int band)672 void EqMainWindow::onBodeSelectBand(int band)
673 {
674 m_BandCtlArray[band]->glowBand(true);
675 }
676
onBodeUnselectBand()677 void EqMainWindow::onBodeUnselectBand()
678 {
679 for(int i = 0; i < m_iNumOfBands; i++)
680 {
681 m_BandCtlArray[i]->glowBand(false);
682 }
683 }
684
onBandCtlSelectBand(int band)685 void EqMainWindow::onBandCtlSelectBand(int band)
686 {
687 m_Bode->unglowBands();
688 m_Bode->glowBand(band);
689 }
690
onBandCtlUnselectBand()691 void EqMainWindow::onBandCtlUnselectBand()
692 {
693 m_Bode->unglowBands();
694 }
695
loadEqParams()696 void EqMainWindow::loadEqParams()
697 {
698 m_CurParams->loadFromTtlFile(m_pluginUri.c_str());
699 changeAB(m_CurParams);
700 }
701
saveToFile()702 void EqMainWindow::saveToFile()
703 {
704 Gtk::FileChooserDialog *fileChosser = new Gtk::FileChooserDialog("Save curve to file", Gtk::FILE_CHOOSER_ACTION_SAVE);
705 fileChosser->add_button("Save", Gtk::RESPONSE_ACCEPT);
706 fileChosser->add_button("Cancel", Gtk::RESPONSE_CANCEL);
707 fileChosser->set_current_folder( getenv("HOME"));
708 fileChosser->set_select_multiple(false);
709 fileChosser->set_do_overwrite_confirmation(true);
710
711 //File filter
712 Gtk::FileFilter filter;
713 std::stringstream ss;
714 ss << "EQ" << m_iNumOfBands << "Q Curve File";
715 filter.set_name(ss.str());
716 ss.str( std::string() );
717 ss.clear();
718 ss << "*.eq" << m_iNumOfBands << "q";
719 filter.add_pattern(ss.str());
720 fileChosser->add_filter(filter);
721
722 if (fileChosser->run() == Gtk::RESPONSE_ACCEPT)
723 {
724 ss.str( std::string() );
725 ss.clear();
726 ss << fileChosser->get_filename() << ".eq" << m_iNumOfBands << "q";
727 m_CurParams->saveToFile(ss.str().c_str());
728 }
729 delete fileChosser;
730 }
731
loadFromFile()732 void EqMainWindow::loadFromFile()
733 {
734 Gtk::FileChooserDialog *fileChosser = new Gtk::FileChooserDialog("Load curve from file", Gtk::FILE_CHOOSER_ACTION_OPEN);
735 fileChosser->add_button("Load", Gtk::RESPONSE_ACCEPT);
736 fileChosser->add_button("Cancel", Gtk::RESPONSE_CANCEL);
737 fileChosser->set_current_folder( getenv("HOME"));
738 fileChosser->set_select_multiple(false);
739
740 //File filter
741 Gtk::FileFilter filter;
742 std::stringstream ss;
743 ss << "EQ" << m_iNumOfBands << "Q Curve File";
744 filter.set_name(ss.str());
745 ss.str( std::string() );
746 ss.clear();
747 ss << "*.eq" << m_iNumOfBands << "q";
748 filter.add_pattern(ss.str());
749 fileChosser->add_filter(filter);
750
751 if (fileChosser->run() == Gtk::RESPONSE_ACCEPT)
752 {
753 if (m_CurParams->loadFromFile(fileChosser->get_filename().c_str()))
754 {
755 changeAB(m_CurParams);
756 }
757 else //This is the error case
758 {
759 //Popup a error message
760 Gtk::MessageDialog dialog((Gtk::Window&)(*this->get_toplevel()),"Error loading curve file, number of bands does not match or this is not a valid eq10q file.\n\rNothing is loaded.",
761 false /* use_markup */, Gtk::MESSAGE_ERROR,
762 Gtk::BUTTONS_OK);
763 dialog.run();
764 }
765 }
766
767 delete fileChosser;
768 }
769
onButtonFftRta()770 void EqMainWindow::onButtonFftRta()
771 {
772 sendAtomFftOn( m_FftRtaActive.get_active() );
773 m_Bode->setFftActive(m_FftRtaActive.get_active(), false);
774 if(m_FftRtaActive.get_active())
775 {
776 m_FftSpecActive.set_active(false);
777 }
778 }
779
onButtonFftSpc()780 void EqMainWindow::onButtonFftSpc()
781 {
782 sendAtomFftOn( m_FftSpecActive.get_active() );
783 m_Bode->setFftActive(m_FftSpecActive.get_active(), true);
784 if(m_FftSpecActive.get_active())
785 {
786 m_FftRtaActive.set_active(false);
787 }
788 }
789
790
onHoldFft_press()791 void EqMainWindow::onHoldFft_press()
792 {
793 m_Bode->setFftHold(true);
794 }
795
onHoldFft_release()796 void EqMainWindow::onHoldFft_release()
797 {
798 m_Bode->setFftHold(false);
799 }
800
sendAtomFftOn(bool fft_activated)801 void EqMainWindow::sendAtomFftOn(bool fft_activated)
802 {
803 int AtomPortNumber = PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands + 2*m_iNumOfChannels + 1;
804 uint8_t obj_buf[64];
805 lv2_atom_forge_set_buffer(&forge, obj_buf, sizeof(obj_buf));
806 LV2_Atom_Forge_Frame frame;
807 LV2_Atom* msg = (LV2_Atom*)lv2_atom_forge_object(&forge, &frame, 0, fft_activated? uris.atom_fft_on : uris.atom_fft_off);
808 lv2_atom_forge_pop(&forge, &frame);
809 write_function(controller, AtomPortNumber, lv2_atom_total_size(msg), uris.atom_eventTransfer, msg);
810 }
811
onFftGainScale()812 void EqMainWindow::onFftGainScale()
813 {
814 m_Bode->setFftGain(m_FftGain->get_value());
815 }
816
onFftRangeScale()817 void EqMainWindow::onFftRangeScale()
818 {
819 m_Bode->setFftRange(m_FftRange->get_value());
820 }
821
onDbScale10Changed()822 void EqMainWindow::onDbScale10Changed()
823 {
824 m_dB10Scale.set_active(true);
825 m_dB25Scale.set_active(false);
826 m_dB50Scale.set_active(false);
827 m_Bode->setPlotdBRange(10.0);
828 }
829
onDbScale25Changed()830 void EqMainWindow::onDbScale25Changed()
831 {
832 m_dB10Scale.set_active(false);
833 m_dB25Scale.set_active(true);
834 m_dB50Scale.set_active(false);
835 m_Bode->setPlotdBRange(25.0);
836 }
837
onDbScale50Changed()838 void EqMainWindow::onDbScale50Changed()
839 {
840 m_dB10Scale.set_active(false);
841 m_dB25Scale.set_active(false);
842 m_dB50Scale.set_active(true);
843 m_Bode->setPlotdBRange(50.0);
844 }
845
setStereoMode(bool isMidSide)846 void EqMainWindow::setStereoMode(bool isMidSide)
847 {
848 m_MSStereoMode.set_active(isMidSide);
849 m_LRStereoMode.set_active(!isMidSide);
850 for(int i = 0; i < m_iNumOfBands; i++)
851 {
852 m_BandCtlArray[i]->setStereoMode(isMidSide);
853 }
854 int PortNumber = PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands + 2*m_iNumOfChannels + 2;
855 float fValue = isMidSide ? 1.0f : 0.0f;
856 write_function(controller, PortNumber, sizeof(float), 0, &fValue);
857 }
858
859
onLeftRightModeSelected()860 void EqMainWindow::onLeftRightModeSelected()
861 {
862 setStereoMode(false);
863 }
864
onMidSideModeSelected()865 void EqMainWindow::onMidSideModeSelected()
866 {
867 setStereoMode(true);
868 }
869