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 #ifndef EQ_MAIN_WIN_H 22 #define EQ_MAIN_WIN_H 23 24 #include <iostream> 25 #include <string> 26 27 28 #include <gtkmm/alignment.h> 29 #include <gtkmm/box.h> 30 #include <gtkmm/messagedialog.h> 31 #include <gtkmm/image.h> 32 33 #include <cmath> 34 35 //LV2 UI header 36 #include <lv2/lv2plug.in/ns/extensions/ui/ui.h> 37 #include <lv2/lv2plug.in/ns/ext/atom/forge.h> 38 #include <lv2/lv2plug.in/ns/ext/atom/util.h> 39 #include <lv2/lv2plug.in/ns/ext/urid/urid.h> 40 #include "../../uris.h" 41 42 #include "mainwidget.h" 43 #include "bandctl.h" 44 #include "vuwidget.h" 45 #include "knob2.h" 46 #include "eqparams.h" 47 #include "bodeplot.h" 48 #include "button.h" 49 #include "toggle_button.h" 50 #include "abbutton.h" 51 #include "sidechainbox.h" 52 53 //Include eq definition 54 #include "../eq_defines.h" 55 56 #define IMAGE_LOGO_PATH "icons/logoeq10q.png" 57 #define TIMER_VALUE_MS 100 58 59 //Test print information, comment out for the final release 60 //#define PRINT_DEBUG_INFO 61 62 using namespace sigc; 63 64 class EqMainWindow : public MainWidget 65 { 66 public: 67 EqMainWindow(int iAudioChannels, int iNumBands, const char *uri, const char *bundlePath, const LV2_Feature *const *features); 68 virtual ~EqMainWindow(); 69 void request_sample_rate(); 70 71 // Informing GUI about changes in the control ports gui_port_event(LV2UI_Handle ui,uint32_t port,uint32_t buffer_size,uint32_t format,const void * buffer)72 void gui_port_event(LV2UI_Handle ui, uint32_t port, uint32_t buffer_size, uint32_t format, const void * buffer) 73 { 74 //Atom event from DSP 75 if((int)port == (PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands + 2*m_iNumOfChannels)) 76 { 77 78 const LV2_Atom* atom = (const LV2_Atom*)buffer; 79 80 if (format == uris.atom_eventTransfer && atom->type == uris.atom_Object) 81 { 82 const LV2_Atom_Object* obj = (const LV2_Atom_Object*)atom; 83 84 if(obj->body.otype == uris.atom_sample_rate_response) 85 { 86 const LV2_Atom* samplerate_val = NULL; 87 const int n_props = lv2_atom_object_get(obj, uris.atom_sample_rate_key, &samplerate_val, NULL); 88 89 if (n_props != 1 || samplerate_val->type != uris.atom_Double) 90 { 91 std::cout<<"Atom Object does not have the required properties (sample-rate) with correct types"<<std::endl; 92 } 93 else 94 { 95 SampleRate = ((const LV2_Atom_Double*)samplerate_val)->body; 96 m_Bode->setSampleRate(SampleRate); 97 } 98 } 99 100 else if(obj->body.otype == uris.atom_fft_data_event) 101 { 102 const LV2_Atom* fftdata_val = NULL; 103 const int n_props = lv2_atom_object_get(obj, uris.atom_fft_data_key, &fftdata_val, NULL); 104 105 if (n_props != 1 || fftdata_val->type != uris.atom_Vector) 106 { 107 std::cout<<"Atom Object does not have the required properties (fft-data) with correct types"<<std::endl; 108 } 109 else 110 { 111 const LV2_Atom_Vector* vec = (const LV2_Atom_Vector*)fftdata_val; 112 if (vec->body.child_type != uris.atom_Double) 113 { 114 std::cout<<"Atom fft Vector has incorrect element type"<<std::endl; 115 } 116 else 117 { 118 // Number of elements = (total size - header size) / element size 119 const size_t n_elem = ((fftdata_val->size - sizeof(LV2_Atom_Vector_Body))/ sizeof(double)); 120 121 //std::cout<<"N Elem "<<n_elem << std::endl; 122 123 //Copy data to bodeplot 124 if(n_elem == ((FFT_N/2) + 1)) 125 { 126 // Double elements immediately follow the vector body header 127 m_Bode->setFftData((double*)(&vec->body + 1)); 128 } 129 } 130 } 131 } 132 } 133 }//End of Atom ports reading 134 135 136 //Standard LV2 ports handling 137 float data = * static_cast<const float*>(buffer); 138 139 #ifdef PRINT_DEBUG_INFO 140 std::cout<<"gui_port_event Entring....... "<<std::endl; 141 #endif 142 143 // Checking if params are the same as specified in the LV2 documentation for no-atom ports 144 if (format != 0) { 145 #ifdef PRINT_DEBUG_INFO 146 std::cout<<"\t-- Return Format != 0"<<std::endl; 147 #endif 148 return; 149 } 150 if (buffer_size != 4) { 151 #ifdef PRINT_DEBUG_INFO 152 std::cout<<"\t-- Return buffer_size != 4"<<std::endl; 153 #endif 154 return; 155 } 156 157 // Updating values in GUI ======================================================== 158 switch (port) 159 { 160 case EQ_BYPASS: 161 m_bypassValue = data > 0.5 ? 1 : 0; 162 m_port_event_Bypass = true; //Marck port even boolean 163 ///m_BypassButton.set_active(data > 0.5); 164 #ifdef PRINT_DEBUG_INFO 165 std::cout<<"\t-- BYPASS"<<std::endl; 166 #endif 167 break; 168 169 case EQ_INGAIN: 170 //m_InGainValue = data; 171 m_CurParams->setInputGain(data); 172 m_port_event_InGain = true; //Marck port even boolean 173 ///m_InGain->setGain(data); 174 175 #ifdef PRINT_DEBUG_INFO 176 std::cout<<"\t-- Input Gain"<<std::endl; 177 #endif 178 break; 179 180 case EQ_OUTGAIN: 181 //m_OutGainValue = data; 182 m_CurParams->setOutputGain(data); 183 m_port_event_OutGain = true; //Marck port even boolean 184 ///m_OutGain->setGain(data); 185 #ifdef PRINT_DEBUG_INFO 186 std::cout<<"\t-- Out Gain"<<std::endl; 187 #endif 188 break; 189 190 default: 191 //Connect BandGain ports 192 if((int)port >= (PORT_OFFSET + 2*m_iNumOfChannels) && (int)port < (PORT_OFFSET + 2*m_iNumOfChannels + m_iNumOfBands)) 193 { 194 ///m_BandCtlArray[(int)port - PORT_OFFSET - 2*m_iNumOfChannels]->setGain(data); 195 ///m_Bode->setBandGain((int)port - PORT_OFFSET - 2*m_iNumOfChannels, data); 196 m_CurParams->setBandGain((int)port - PORT_OFFSET - 2*m_iNumOfChannels, data); 197 m_port_event_Curve = true; //Marck port even boolean 198 m_port_event_Curve_Gain[(int)port - PORT_OFFSET - 2*m_iNumOfChannels] = true; 199 #ifdef PRINT_DEBUG_INFO 200 std::cout<<"\t-- Band Gain"<<std::endl; 201 #endif 202 } 203 204 //Connect BandFreq ports 205 else if((int)port >= (PORT_OFFSET + 2*m_iNumOfChannels + m_iNumOfBands) && (int)port < (PORT_OFFSET + 2*m_iNumOfChannels + 2*m_iNumOfBands)) 206 { 207 ///m_BandCtlArray[(int)port - PORT_OFFSET - 2*m_iNumOfChannels - m_iNumOfBands]->setFreq(data); 208 ///m_Bode->setBandFreq((int)port - PORT_OFFSET - 2*m_iNumOfChannels - m_iNumOfBands, data); 209 m_CurParams->setBandFreq((int)port - PORT_OFFSET - 2*m_iNumOfChannels - m_iNumOfBands, data); 210 m_port_event_Curve = true; //Marck port even boolean 211 m_port_event_Curve_Freq[(int)port - PORT_OFFSET - 2*m_iNumOfChannels - m_iNumOfBands] = true; 212 #ifdef PRINT_DEBUG_INFO 213 std::cout<<"\t-- Band Freq"<<std::endl; 214 #endif 215 } 216 217 //Connect BandParam ports 218 else if((int)port >= (PORT_OFFSET + 2*m_iNumOfChannels + 2*m_iNumOfBands) && (int)port < (PORT_OFFSET + 2*m_iNumOfChannels + 3*m_iNumOfBands)) 219 { 220 ///m_BandCtlArray[(int)port - PORT_OFFSET - 2*m_iNumOfChannels - 2*m_iNumOfBands]->setQ(data); 221 ///m_Bode->setBandQ((int)port - PORT_OFFSET - 2*m_iNumOfChannels - 2*m_iNumOfBands, data); 222 m_CurParams->setBandQ((int)port - PORT_OFFSET - 2*m_iNumOfChannels - 2*m_iNumOfBands, data); 223 m_port_event_Curve = true; //Marck port even boolean 224 m_port_event_Curve_Q[(int)port - PORT_OFFSET - 2*m_iNumOfChannels - 2*m_iNumOfBands] = true; 225 #ifdef PRINT_DEBUG_INFO 226 std::cout<<"\t-- Band Q"<<std::endl; 227 #endif 228 } 229 230 //Connect BandType ports 231 else if((int)port >= (PORT_OFFSET + 2*m_iNumOfChannels + 3*m_iNumOfBands) && (int)port < (PORT_OFFSET + 2*m_iNumOfChannels + 4*m_iNumOfBands)) 232 { 233 ///m_BandCtlArray[(int)port - PORT_OFFSET - 2*m_iNumOfChannels - 3*m_iNumOfBands]->setFilterType(data); 234 ///m_Bode->setBandType((int)port - PORT_OFFSET - 2*m_iNumOfChannels - 3*m_iNumOfBands, data); 235 m_CurParams->setBandType((int)port - PORT_OFFSET - 2*m_iNumOfChannels - 3*m_iNumOfBands, ((int)data) & 0xFF); 236 m_port_event_Curve = true; //Marck port even boolean 237 m_port_event_Curve_Type[(int)port - PORT_OFFSET - 2*m_iNumOfChannels - 3*m_iNumOfBands] = true; 238 #ifdef PRINT_DEBUG_INFO 239 std::cout<<"\t-- Band Type"<<std::endl; 240 #endif 241 } 242 243 //Connect BandEnabled ports 244 else if((int)port >= (PORT_OFFSET + 2*m_iNumOfChannels + 4*m_iNumOfBands) && (int)port < (PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands)) 245 { 246 ///m_BandCtlArray[(int)port - PORT_OFFSET - 2*m_iNumOfChannels - 4*m_iNumOfBands]->setEnabled(data > 0.5); 247 ///m_Bode->setBandEnable((int)port - PORT_OFFSET - 2*m_iNumOfChannels - 4*m_iNumOfBands, data > 0.5); 248 249 int iMidSide = (int)data >> 1; 250 const int sel_band = (int)port - PORT_OFFSET - 2*m_iNumOfChannels - 4*m_iNumOfBands; 251 switch(iMidSide) 252 { 253 case 0: 254 m_BandCtlArray[sel_band]->setStereoState(BandCtl::DUAL); 255 if(m_iNumOfChannels == 1) 256 { 257 m_Bode->setStereoState(sel_band, PlotEQCurve::MONO); 258 } 259 else 260 { 261 m_Bode->setStereoState(sel_band, PlotEQCurve::DUAL); 262 } 263 break; 264 265 case 1: 266 m_BandCtlArray[sel_band]->setStereoState(BandCtl::ML); 267 m_Bode->setStereoState(sel_band, PlotEQCurve::ML); 268 break; 269 270 case 2: 271 m_BandCtlArray[sel_band]->setStereoState(BandCtl::SR); 272 m_Bode->setStereoState(sel_band, PlotEQCurve::SR); 273 break; 274 } 275 276 int iEnable = (int)data & 0x01; 277 m_CurParams->setBandEnabled(sel_band, iEnable > 0); 278 m_port_event_Curve = true; //Marck port even boolean 279 m_port_event_Curve_Enable[sel_band] = true; 280 #ifdef PRINT_DEBUG_INFO 281 std::cout<<"\t-- Band Enabled"<<std::endl; 282 #endif 283 } 284 285 //Connect VuInput ports 286 else if((int)port >= (PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands) && (int)port < (PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands + m_iNumOfChannels)) 287 { 288 m_VuMeterIn->setValue((int)port - PORT_OFFSET - 2*m_iNumOfChannels - 5*m_iNumOfBands,data); 289 #ifdef PRINT_DEBUG_INFO 290 std::cout<<"\t-- Vu input"<<std::endl; 291 #endif 292 } 293 294 //Connect VuOutput ports 295 else if((int)port >= (PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands + m_iNumOfChannels) && (int)port < (PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands + 2*m_iNumOfChannels)) 296 { 297 m_VuMeterOut->setValue((int)port - PORT_OFFSET - 2*m_iNumOfChannels - 5*m_iNumOfBands - m_iNumOfChannels, data); 298 #ifdef PRINT_DEBUG_INFO 299 std::cout<<"\t-- Vu output"<<std::endl; 300 #endif 301 } 302 303 //Connect Stereo Mode port 304 else if((int)port == (PORT_OFFSET + 2*m_iNumOfChannels + 5*m_iNumOfBands + 2*m_iNumOfChannels + 2)) 305 { 306 setStereoMode( data > 0.5); 307 #ifdef PRINT_DEBUG_INFO 308 std::cout<<"\t-- Mid Side"<<std::endl; 309 #endif 310 } 311 312 //No more ports here 313 else 314 { 315 #ifdef PRINT_DEBUG_INFO 316 std::cout<<"\t-- Return port index is out of range"<<std::endl; 317 #endif 318 return; 319 } 320 break; 321 } 322 323 #ifdef PRINT_DEBUG_INFO 324 std::cout<<"\t-- Return OK"<<std::endl; 325 #endif 326 327 } 328 329 LV2UI_Controller controller; 330 LV2UI_Write_Function write_function; 331 Eq10qURIs uris; 332 LV2_URID_Map* map; 333 LV2_Atom_Forge forge; 334 335 protected: 336 EqParams *m_AParams, *m_BParams, *m_CurParams; 337 BandCtl **m_BandCtlArray; 338 Gtk::HBox m_BandBox, m_ABFlatBox, m_GainEqBox, m_PlotBox; 339 Gtk::VBox m_CurveBypassBandsBox, m_MainBox, m_InGainBox, m_OutGainBox, m_FftCtlVBox, m_dBScaleBox, m_FftdBBox, m_StereoBox; 340 ToggleButton m_BypassButton, m_FftRtaActive, m_FftSpecActive, m_dB10Scale, m_dB25Scale, m_dB50Scale, m_LRStereoMode, m_MSStereoMode; 341 AbButton m_AButton; 342 Gtk::Alignment m_FlatAlign, m_ABAlign, m_ButtonAAlign, m_BypassAlign, m_LoadAlign, m_SaveAlign, m_FftAlign, m_FftAlignInner, m_FftAlngGain, m_FftAlngRange, m_dBScaleAlign, m_dBScaleAlignInner, m_StereoInnerAlng, m_StereAlng; 343 Button m_FlatButton, m_SaveButton, m_LoadButton, m_FftHold; 344 Gtk::Alignment m_MainWidgetAlign; 345 PlotEQCurve *m_Bode; 346 Gtk::Image *image_logo_center; 347 KnobWidget2 *m_GainFaderIn, *m_GainFaderOut, *m_FftGain, *m_FftRange; 348 VUWidget *m_VuMeterIn, *m_VuMeterOut; 349 SideChainBox *m_FftBox, *m_dBScaleFrame, *m_MidSideBox; 350 351 void loadEqParams(); 352 void changeAB(EqParams *toBeCurrent); 353 void saveToFile(); 354 void loadFromFile(); 355 void sendAtomFftOn(bool fft_activated); 356 void setStereoMode(bool isMidSide); 357 358 //Signal Handlers 359 void onButtonA(); 360 void onButtonFlat(); 361 void onButtonBypass(); 362 void onBandChange(int iBand, int iField, float fValue); 363 void onInputGainChange(); 364 void onOutputGainChange(); 365 void onCurveChange(int band_ix, float Gain, float Freq, float Q); 366 void onCurveBandEnable(int band_ix, bool IsEnabled); 367 bool on_timeout(); 368 void onButtonFftRta(); 369 void onButtonFftSpc(); 370 void onHoldFft_press(); 371 void onHoldFft_release(); 372 void onFftGainScale(); 373 void onFftRangeScale(); 374 void onBodeSelectBand(int band); 375 void onBodeUnselectBand(); 376 void onBandCtlSelectBand(int band); 377 void onBandCtlUnselectBand(); 378 void onBandCtlMidSideChanged(int band); 379 380 void onDbScale10Changed(); 381 void onDbScale25Changed(); 382 void onDbScale50Changed(); 383 384 void onLeftRightModeSelected(); 385 void onMidSideModeSelected(); 386 387 388 private: 389 double SampleRate; 390 float m_bypassValue; 391 const int m_iNumOfChannels; 392 const int m_iNumOfBands; 393 bool m_bMutex, m_port_event_InGain, m_port_event_OutGain, m_port_event_Bypass, m_port_event_Curve; 394 bool *m_port_event_Curve_Gain, *m_port_event_Curve_Freq, *m_port_event_Curve_Q, *m_port_event_Curve_Type, *m_port_event_Curve_Enable; 395 std::string m_pluginUri; 396 std::string m_bundlePath; 397 }; 398 399 #endif 400