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