1 /*!
2  * @file lfowidget.cpp
3  * @brief Implements the LfoWidget GUI class.
4  *
5  *
6  *      Copyright 2009 - 2017 <qmidiarp-devel@lists.sourceforge.net>
7  *
8  *      This program is free software; you can redistribute it and/or modify
9  *      it under the terms of the GNU General Public License as published by
10  *      the Free Software Foundation; either version 2 of the License, or
11  *      (at your option) any later version.
12  *
13  *      This program is distributed in the hope that it will be useful,
14  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *      GNU General Public License for more details.
17  *
18  *      You should have received a copy of the GNU General Public License
19  *      along with this program; if not, write to the Free Software
20  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  *      MA 02110-1301, USA.
22  */
23 #include <cstdio>
24 #include <vector>
25 
26 #include "lfowidget.h"
27 
28 #include "pixmaps/lfowsine.xpm"
29 #include "pixmaps/lfowsawup.xpm"
30 #include "pixmaps/lfowsawdn.xpm"
31 #include "pixmaps/lfowtri.xpm"
32 #include "pixmaps/lfowsquare.xpm"
33 #include "pixmaps/lfowcustm.xpm"
34 #include "pixmaps/lfowflip.xpm"
35 #include "pixmaps/seqrecord.xpm"
36 #include "config.h"
37 
38 
39 #ifdef APPBUILD
40 LfoWidget::LfoWidget(MidiLfo *p_midiLfo, GlobStore *p_globStore,
41     int portCount, bool compactStyle,
42     bool mutedAdd, bool inOutVisible, const QString& p_name):
43     InOutBox(p_midiLfo, p_globStore, portCount, compactStyle, inOutVisible, p_name),
44     midiLfo(p_midiLfo)
45 {
46 #else
47 LfoWidget::LfoWidget(
48     bool compactStyle,
49     bool mutedAdd, bool inOutVisible):
50     InOutBox(compactStyle, inOutVisible, "LFO:"),
51     midiLfo(NULL)
52 {
53 #endif
54 
55     // group box for wave setup
56     QGroupBox *waveBox = new QGroupBox(tr("Wave"));
57 
58     screen = new LfoScreen(this);
59     screen->setToolTip(
60         tr("Right button to mute points\nLeft button to draw custom wave\nWheel to change offset"));
61     screen->setMinimumHeight(80);
62 
63     connect(screen, SIGNAL(mouseEvent(double, double, int, int)), this,
64             SLOT(mouseEvent(double, double, int, int)));
65     connect(screen, SIGNAL(mouseWheel(int)), this,
66             SLOT(mouseWheel(int)));
67 
68     cursor = new Cursor('L');
69 
70     QLabel *waveFormBoxLabel = new QLabel(tr("&Waveform"));
71     waveFormBox = new QComboBox;
72     waveFormBoxLabel->setBuddy(waveFormBox);
73     //loadWaveForms();
74     waveFormBox->addItem(QPixmap(lfowsine_xpm),"");
75     waveFormBox->addItem(QPixmap(lfowsawup_xpm),"");
76     waveFormBox->addItem(QPixmap(lfowtri_xpm),"");
77     waveFormBox->addItem(QPixmap(lfowsawdn_xpm),"");
78     waveFormBox->addItem(QPixmap(lfowsquare_xpm),"");
79     waveFormBox->addItem(QPixmap(lfowcustm_xpm),"");
80     waveFormBox->setCurrentIndex(0);
81     waveFormBoxIndex = 0;
82     waveFormBox->setToolTip(tr("Waveform Basis"));
83 
84     connect(waveFormBox, SIGNAL(activated(int)), this,
85             SLOT(updateWaveForm(int)));
86 #ifdef APPBUILD
87     midiControl->addMidiLearnMenu("WaveForm", waveFormBox, 3);
88 #endif
89 
90     QLabel *freqBoxLabel = new QLabel(tr("&Frequency"));
91     freqBox = new QComboBox;
92     freqBoxLabel->setBuddy(freqBox);
93     QStringList names;
94     names << "1/32" << "1/16" << "1/8" << "1/4"
95         << "1/2" << "3/4" << "1" << "2" << "3"
96         << "4" << "5" << "6" << "7" << "8";
97     freqBox->insertItems(0, names);
98     freqBox->setCurrentIndex(4);
99     freqBoxIndex = 4;
100     freqBox->setToolTip(
101             tr("Frequency (cycles/beat): Number of wave cycles produced every beat"));
102     freqBox->setMinimumContentsLength(3);
103     connect(freqBox, SIGNAL(activated(int)), this,
104             SLOT(updateFreq(int)));
105 #ifdef APPBUILD
106     midiControl->addMidiLearnMenu("Frequency", freqBox, 4);
107 #endif
108     QLabel *resBoxLabel = new QLabel(tr("&Resolution"));
109     resBox = new QComboBox;
110     resBoxLabel->setBuddy(resBox);
111     names.clear();
112     names << "1" << "2" << "4" << "8" << "16" << "32" << "64" << "96" << "192";
113     resBox->insertItems(0, names);
114     resBox->setCurrentIndex(2);
115     resBoxIndex = 2;
116     resBox->setToolTip(
117             tr("Resolution (events/beat): Number of events produced every beat"));
118     resBox->setMinimumContentsLength(3);
119     connect(resBox, SIGNAL(activated(int)), this,
120             SLOT(updateRes(int)));
121 #ifdef APPBUILD
122     midiControl->addMidiLearnMenu("Resolution", resBox, 6);
123 #endif
124     QLabel *sizeBoxLabel = new QLabel(tr("&Length"));
125     sizeBox = new QComboBox;
126     sizeBoxLabel->setBuddy(sizeBox);
127     names.clear();
128     names << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8"
129             << "12" << "16" << "24" << "32" ;
130     sizeBox->insertItems(0, names);
131     sizeBox->setCurrentIndex(3);
132     sizeBoxIndex = 3;
133     sizeBox->setToolTip(tr("Length of LFO wave in beats"));
134     sizeBox->setMinimumContentsLength(3);
135     connect(sizeBox, SIGNAL(activated(int)), this,
136             SLOT(updateSize(int)));
137 #ifdef APPBUILD
138     midiControl->addMidiLearnMenu("Size", sizeBox, 7);
139 #endif
140     loopBox = new QComboBox;
141     names.clear();
142     names << "->_>" << " <_<-" << "->_<" << " >_<-" << "->_|" << " |_<-" << "RANDM";
143     loopBox->insertItems(0, names);
144     loopBox->setCurrentIndex(0);
145     loopBox->setToolTip(tr("Loop, bounce or play once going forward or backward"));
146     loopBox->setMinimumContentsLength(5);
147     connect(loopBox, SIGNAL(activated(int)), this,
148             SLOT(updateLoop(int)));
149 #ifdef APPBUILD
150     midiControl->addMidiLearnMenu("LoopMode", loopBox, 8);
151 #endif
152 
153     flipWaveVerticalAction = new QAction(QPixmap(lfowflip_xpm),tr("&Flip"), this);
154     flipWaveVerticalAction->setToolTip(tr("Do a vertical flip of the wave about its mid value"));
155     connect(flipWaveVerticalAction, SIGNAL(triggered(bool)), this, SLOT(updateFlipWaveVertical()));
156 
157     QToolButton *flipWaveVerticalButton = new QToolButton;
158     flipWaveVerticalButton->setDefaultAction(flipWaveVerticalAction);
159     flipWaveVerticalButton->setFixedSize(20, 20);
160 
161     QLabel *recordButtonLabel = new QLabel(tr("Re&cord"));
162     recordAction = new QAction(QPixmap(seqrecord_xpm), tr("Re&cord"), this);
163     recordAction->setToolTip(tr("Record incoming controller"));
164     recordAction->setCheckable(true);
165     QToolButton *recordButton = new QToolButton;
166     recordButton->setDefaultAction(recordAction);
167     recordButtonLabel->setBuddy(recordButton);
168     connect(recordAction, SIGNAL(toggled(bool)), this, SLOT(setRecord(bool)));
169 #ifdef APPBUILD
170     midiControl->addMidiLearnMenu("RecordToggle", recordButton, 5);
171 #endif
172     amplitude = new Slider(0, 127, 1, 8, 64, Qt::Horizontal,
173             tr("&Amplitude"), this);
174     connect(amplitude, SIGNAL(valueChanged(int)), this,
175             SLOT(updateAmp(int)));
176 #ifdef APPBUILD
177     midiControl->addMidiLearnMenu("Amplitude", amplitude, 1);
178 #endif
179 
180     offset = new Slider(0, 127, 1, 8, 0, Qt::Horizontal,
181             tr("&Offset"), this);
182     connect(offset, SIGNAL(valueChanged(int)), this,
183             SLOT(updateOffs(int)));
184 #ifdef APPBUILD
185     midiControl->addMidiLearnMenu("Offset", offset, 2);
186 #endif
187     QVBoxLayout* sliderLayout = new QVBoxLayout;
188     sliderLayout->addWidget(amplitude);
189     sliderLayout->addWidget(offset);
190     sliderLayout->addStretch();
191     if (compactStyle) {
192         sliderLayout->setSpacing(1);
193         sliderLayout->setMargin(2);
194     }
195 
196     QGridLayout *paramBoxLayout = new QGridLayout;
197     paramBoxLayout->addWidget(loopBox, 0, 0, 1, 2);
198     paramBoxLayout->addWidget(muteOut, 1, 0, 1, 1);
199     paramBoxLayout->addWidget(deferChangesButton, 1, 1, 1, 2);
200     paramBoxLayout->addWidget(recordButtonLabel, 2, 0);
201     paramBoxLayout->addWidget(recordButton, 2, 1);
202     paramBoxLayout->addWidget(waveFormBoxLabel, 0, 2);
203     paramBoxLayout->addWidget(waveFormBox, 0, 3);
204     paramBoxLayout->addWidget(freqBoxLabel, 1, 2);
205     paramBoxLayout->addWidget(freqBox, 1, 3);
206     paramBoxLayout->addWidget(resBoxLabel, 0, 4);
207     paramBoxLayout->addWidget(resBox, 0, 5);
208     paramBoxLayout->addWidget(sizeBoxLabel, 1, 4);
209     paramBoxLayout->addWidget(sizeBox, 1, 5);
210     paramBoxLayout->addWidget(flipWaveVerticalButton, 0, 6);
211     paramBoxLayout->setColumnStretch(7, 7);
212 
213     if (compactStyle) {
214         paramBoxLayout->setSpacing(1);
215         paramBoxLayout->setMargin(2);
216     }
217 
218     QGridLayout* waveBoxLayout = new QGridLayout;
219     waveBoxLayout->addWidget(screen, 0, 0);
220     waveBoxLayout->addWidget(cursor, 1, 0);
221     waveBoxLayout->addLayout(paramBoxLayout, 2, 0);
222     waveBoxLayout->addLayout(sliderLayout, 3, 0);
223     if (compactStyle) {
224         waveBoxLayout->setSpacing(0);
225         waveBoxLayout->setMargin(2);
226     }
227     waveBox->setLayout(waveBoxLayout);
228 
229 
230     QHBoxLayout *widgetLayout = new QHBoxLayout;
231     widgetLayout->addWidget(waveBox, 1);
232     widgetLayout->addWidget(hideInOutBoxButton, 0);
233     widgetLayout->addWidget(inOutBoxWidget, 0);
234 
235     muteOutAction->setChecked(mutedAdd);
236 
237     setLayout(widgetLayout);
238     updateAmp(64);
239 }
240 
241 #ifdef APPBUILD
242 MidiLfo *LfoWidget::getMidiWorker()
243 {
244     return (midiLfo);
245 }
246 
247 void LfoWidget::writeData(QXmlStreamWriter& xml)
248 {
249     QByteArray tempArray;
250     int l1;
251 
252         writeCommonData(xml);
253 
254         xml.writeStartElement("waveParams");
255             xml.writeTextElement("loopmode", QString::number(
256                 loopBox->currentIndex()));
257             xml.writeTextElement("waveform", QString::number(
258                 waveFormBox->currentIndex()));
259             xml.writeTextElement("frequency", QString::number(
260                 freqBox->currentIndex()));
261             xml.writeTextElement("resolution", QString::number(
262                 resBox->currentIndex()));
263             xml.writeTextElement("size", QString::number(
264                 sizeBox->currentIndex()));
265             xml.writeTextElement("amplitude", QString::number(
266                 midiLfo->amp));
267             xml.writeTextElement("offset", QString::number(
268                 midiLfo->offs));
269         xml.writeEndElement();
270 
271         tempArray.clear();
272         l1 = 0;
273         while (l1 < midiLfo->maxNPoints) {
274             tempArray.append(midiLfo->muteMask.at(l1));
275             l1++;
276         }
277         xml.writeStartElement("muteMask");
278             xml.writeTextElement("data", tempArray.toHex());
279         xml.writeEndElement();
280 
281         tempArray.clear();
282         l1 = 0;
283         while (l1 < midiLfo->maxNPoints) {
284             tempArray.append(midiLfo->customWave.at(l1).value);
285             l1++;
286         }
287         xml.writeStartElement("customWave");
288             xml.writeTextElement("data", tempArray.toHex());
289         xml.writeEndElement();
290 
291     xml.writeEndElement();
292 }
293 
294 void LfoWidget::readData(QXmlStreamReader& xml)
295 {
296     int tmp;
297     int wvtmp = 0;
298     Sample sample;
299 
300     while (!xml.atEnd()) {
301         xml.readNext();
302         if (xml.isEndElement())
303             break;
304 
305         readCommonData(xml);
306 
307         if (xml.isStartElement() && (xml.name() == "waveParams")) {
308             while (!xml.atEnd()) {
309                 xml.readNext();
310                 if (xml.isEndElement())
311                     break;
312                 if (xml.name() == "loopmode") {
313                     tmp = xml.readElementText().toInt();
314                     loopBox->setCurrentIndex(tmp);
315                     updateLoop(tmp);
316                 }
317                 else if (xml.name() == "waveform")
318                     wvtmp = xml.readElementText().toInt();
319                 else if (xml.name() == "frequency") {
320                     tmp = xml.readElementText().toInt();
321                     freqBox->setCurrentIndex(tmp);
322                     updateFreq(tmp);
323                 }
324                 else if (xml.name() == "resolution") {
325                     tmp = xml.readElementText().toInt();
326                     resBox->setCurrentIndex(tmp);
327                     updateRes(tmp);
328                 }
329                 else if (xml.name() == "size") {
330                     tmp = xml.readElementText().toInt();
331                     sizeBox->setCurrentIndex(tmp);
332                     updateSize(tmp);
333                 }
334                 else if (xml.name() == "amplitude")
335                     amplitude->setValue(xml.readElementText().toInt());
336                 else if (xml.name() == "offset")
337                     offset->setValue(xml.readElementText().toInt());
338                 else skipXmlElement(xml);
339             }
340         }
341         else if (xml.isStartElement() && (xml.name() == "muteMask")) {
342             while (!xml.atEnd()) {
343                 xml.readNext();
344                 if (xml.isEndElement())
345                     break;
346                 if (xml.isStartElement() && (xml.name() == "data")) {
347                     QByteArray tmpArray =
348                             QByteArray::fromHex(xml.readElementText().toLatin1());
349                     for (int l1 = 0; l1 < tmpArray.count(); l1++) {
350                         midiLfo->muteMask[l1] = tmpArray.at(l1);
351                     }
352                     midiLfo->maxNPoints = tmpArray.count();
353                 }
354                 else skipXmlElement(xml);
355             }
356         }
357         else if (xml.isStartElement() && (xml.name() == "customWave")) {
358             while (!xml.atEnd()) {
359                 xml.readNext();
360                 if (xml.isEndElement())
361                     break;
362                 if (xml.isStartElement() && (xml.name() == "data")) {
363                     QByteArray tmpArray =
364                             QByteArray::fromHex(xml.readElementText().toLatin1());
365                     int step = TPQN / midiLfo->res;
366                     int lt = 0;
367                     for (int l1 = 0; l1 < tmpArray.count(); l1++) {
368                         sample.value = tmpArray.at(l1);
369                         sample.tick = lt;
370                         sample.muted = midiLfo->muteMask[l1];
371                         midiLfo->customWave[l1] = sample;
372                         lt+=step;
373                     }
374                 }
375                 else skipXmlElement(xml);
376             }
377         }
378         else skipXmlElement(xml);
379     }
380 
381     updateChIn(chIn->currentIndex());
382     updateChannelOut(channelOut->currentIndex());
383     updatePortOut(portOut->currentIndex());
384     waveFormBox->setCurrentIndex(wvtmp);
385     updateWaveForm(wvtmp);
386     midiLfo->needsGUIUpdate = false;
387     modified = false;
388 }
389 #endif
390 
391 void LfoWidget::loadWaveForms()
392 {
393     waveForms << tr("Sine") << tr("Saw up") << tr("Triangle")
394         << tr("Saw down") << tr("Square") << tr("Custom");
395 }
396 
397 void LfoWidget::updateWaveForm(int val)
398 {
399     if (val > 5) return;
400     waveFormBoxIndex = val;
401     if (midiLfo) midiLfo->updateWaveForm(val);
402     std::vector<Sample> sdata;
403     if (midiLfo) midiLfo->getData(&sdata);
404     data=QVector<Sample>::fromStdVector(sdata);
405     if (midiLfo) screen->updateData(data);
406     bool isCustom = (val == 5);
407     if (isCustom && midiLfo) midiLfo->newCustomOffset();
408     amplitude->setDisabled(isCustom);
409     freqBox->setDisabled(isCustom);
410     modified = true;
411 
412 }
413 
414 void LfoWidget::updateFreq(int val)
415 {
416     if (val > 13) return;
417     freqBoxIndex = val;
418     modified = true;
419     if (!midiLfo) return;
420     midiLfo->updateFrequency(lfoFreqValues[val]);
421     std::vector<Sample> sdata;
422     midiLfo->getData(&sdata);
423     data=QVector<Sample>::fromStdVector(sdata);
424     screen->updateData(data);
425 }
426 
427 void LfoWidget::updateRes(int val)
428 {
429     if (val > 8) return;
430     resBoxIndex = val;
431     modified = true;
432     if (!midiLfo) return;
433     midiLfo->updateResolution(lfoResValues[val]);
434     std::vector<Sample> sdata;
435     midiLfo->getData(&sdata);
436     data=QVector<Sample>::fromStdVector(sdata);
437     screen->updateData(data);
438     if (waveFormBoxIndex == 5) midiLfo->newCustomOffset();
439 }
440 
441 void LfoWidget::updateSize(int val)
442 {
443     if (val > 11) return;
444     sizeBoxIndex = val;
445     modified = true;
446     if (!midiLfo) return;
447     midiLfo->updateSize(sizeBox->currentText().toInt());
448     std::vector<Sample> sdata;
449     midiLfo->getData(&sdata);
450     data=QVector<Sample>::fromStdVector(sdata);
451     screen->updateData(data);
452     if (waveFormBoxIndex == 5) midiLfo->newCustomOffset();
453 }
454 
455 void LfoWidget::updateLoop(int val)
456 {
457     if (val > 6) return;
458     if (midiLfo) midiLfo->updateLoop(val);
459     modified = true;
460 }
461 
462 void LfoWidget::updateAmp(int val)
463 {
464     modified = true;
465     if (!midiLfo) return;
466     midiLfo->updateAmplitude(val);
467     std::vector<Sample> sdata;
468     midiLfo->getData(&sdata);
469     data=QVector<Sample>::fromStdVector(sdata);
470     screen->updateData(data);
471 }
472 
473 void LfoWidget::updateOffs(int val)
474 {
475     modified = true;
476     if (!midiLfo) return;
477     midiLfo->updateOffset(val);
478     std::vector<Sample> sdata;
479     midiLfo->getData(&sdata);
480     data=QVector<Sample>::fromStdVector(sdata);
481     screen->updateData(data);
482 }
483 
484 void LfoWidget::copyToCustom()
485 {
486     if (midiLfo) midiLfo->copyToCustom();
487     waveFormBox->setCurrentIndex(5);
488     updateWaveForm(5);
489     modified = true;
490 }
491 
492 void LfoWidget::updateFlipWaveVertical()
493 {
494     modified = true;
495     if (!midiLfo) return;
496     if (waveFormBox->currentIndex() != 5) copyToCustom();
497     midiLfo->flipWaveVertical();
498     std::vector<Sample> sdata;
499     midiLfo->getData(&sdata);
500     data=QVector<Sample>::fromStdVector(sdata);
501     screen->updateData(data);
502 }
503 
504 void LfoWidget::mouseEvent(double mouseX, double mouseY, int buttons, int pressed)
505 {
506     if (!midiLfo) emit mouseSig(mouseX, mouseY, buttons, pressed);
507     else midiLfo->mouseEvent(mouseX, mouseY, buttons, pressed);
508 
509     if ((buttons == 1) && (waveFormBox->currentIndex() != 5)) {
510         waveFormBox->setCurrentIndex(5);
511         updateWaveForm(5);
512     }
513     modified = true;
514 }
515 
516 void LfoWidget::mouseWheel(int step)
517 {
518     int cv;
519     cv = offset->value() + step;
520     if ((cv < 127) && (cv > 0))
521     offset->setValue(cv + step);
522 }
523 
524 void LfoWidget::setRecord(bool on)
525 {
526     if (midiLfo) midiLfo->setRecordMode(on);
527     screen->setRecordMode(on);
528 }
529 
530 QVector<Sample> LfoWidget::getCustomWave()
531 {
532     return QVector<Sample>::fromStdVector(midiLfo->customWave);
533 }
534 
535 QVector<bool> LfoWidget::getMuteMask()
536 {
537     return QVector<bool>::fromStdVector(midiLfo->muteMask);
538 }
539 
540 #ifdef APPBUILD
541 
542 void LfoWidget::doStoreParams(int ix)
543 {
544     parStore->temp.ccnumberIn = ccnumberInBox->value();
545     parStore->temp.ccnumber = ccnumberBox->value();
546     parStore->temp.res = resBox->currentIndex();
547     parStore->temp.size = sizeBox->currentIndex();
548     parStore->temp.loopMode = loopBox->currentIndex();
549     parStore->temp.freq = freqBox->currentIndex();
550     parStore->temp.ampl = amplitude->value();
551     parStore->temp.offs = offset->value();
552     parStore->temp.waveForm = waveFormBox->currentIndex();
553 
554     if (midiLfo) parStore->temp.wave = getCustomWave().mid(0, midiLfo->maxNPoints);
555     if (midiLfo) parStore->temp.muteMask = getMuteMask().mid(0, midiLfo->maxNPoints);
556 
557     parStore->tempToList(ix);
558 }
559 
560 void LfoWidget::doRestoreParams(int ix)
561 {
562     midiLfo->applyPendingParChanges();
563     if (parStore->list.at(ix).empty) return;
564     for (int l1 = 0; l1 < parStore->list.at(ix).wave.count(); l1++) {
565         midiLfo->customWave[l1] = parStore->list.at(ix).wave.at(l1);
566         midiLfo->muteMask[l1] = parStore->list.at(ix).muteMask.at(l1);
567     }
568     sizeBox->setCurrentIndex(parStore->list.at(ix).size);
569     midiLfo->updateSize(sizeBox->currentText().toInt());
570 
571     midiLfo->updateResolution(lfoResValues[parStore->list.at(ix).res]);
572     midiLfo->updateWaveForm(parStore->list.at(ix).waveForm);
573     midiLfo->updateFrequency(lfoFreqValues[parStore->list.at(ix).freq]);
574     freqBox->setCurrentIndex(parStore->list.at(ix).freq);
575     resBox->setCurrentIndex(parStore->list.at(ix).res);
576     waveFormBox->setCurrentIndex(parStore->list.at(ix).waveForm);
577     loopBox->setCurrentIndex(parStore->list.at(ix).loopMode);
578     updateLoop(parStore->list.at(ix).loopMode);
579     updateWaveForm(parStore->list.at(ix).waveForm);
580     if (!parStore->onlyPatternList.at(ix)) {
581         amplitude->setValue(parStore->list.at(ix).ampl);
582         offset->setValue(parStore->list.at(ix).offs);
583         ccnumberInBox->setValue(parStore->list.at(ix).ccnumberIn);
584         ccnumberBox->setValue(parStore->list.at(ix).ccnumber);
585     }
586     midiLfo->setFramePtr(0);
587 }
588 
589 void LfoWidget::copyParamsFrom(LfoWidget *fromWidget)
590 {
591     int tmp;
592 
593     enableNoteOff->setChecked(fromWidget->enableNoteOff->isChecked());
594     enableRestartByKbd->setChecked(fromWidget->enableRestartByKbd->isChecked());
595     enableTrigByKbd->setChecked(fromWidget->enableTrigByKbd->isChecked());
596     enableTrigLegato->setChecked(fromWidget->enableTrigLegato->isChecked());
597 
598     for (int l1 = 0; l1 < 1; l1++) {
599         tmp = fromWidget->indexIn[l1]->value();
600         indexIn[l1]->setValue(tmp);
601     }
602     for (int l1 = 0; l1 < 1; l1++) {
603         tmp = fromWidget->rangeIn[l1]->value();
604         rangeIn[l1]->setValue(tmp);
605     }
606 
607     tmp = fromWidget->chIn->currentIndex();
608     chIn->setCurrentIndex(tmp);
609     updateChIn(tmp);
610     tmp = fromWidget->channelOut->currentIndex();
611     channelOut->setCurrentIndex(tmp);
612     updateChannelOut(tmp);
613     tmp = fromWidget->portOut->currentIndex();
614     portOut->setCurrentIndex(tmp);
615     updatePortOut(tmp);
616 
617     tmp = fromWidget->ccnumberInBox->value();
618     ccnumberInBox->setValue(tmp);
619     tmp = fromWidget->ccnumberBox->value();
620     ccnumberBox->setValue(tmp);
621 
622     tmp = fromWidget->resBox->currentIndex();
623     resBox->setCurrentIndex(tmp);
624     updateRes(tmp);
625     tmp = fromWidget->sizeBox->currentIndex();
626     sizeBox->setCurrentIndex(tmp);
627     updateSize(tmp);
628     tmp = fromWidget->loopBox->currentIndex();
629     loopBox->setCurrentIndex(tmp);
630     updateLoop(tmp);
631     tmp = fromWidget->freqBox->currentIndex();
632     freqBox->setCurrentIndex(tmp);
633     updateFreq(tmp);
634 
635     amplitude->setValue(fromWidget->amplitude->value());
636     offset->setValue(fromWidget->offset->value());
637 
638     for (int l1 = 0; l1 < fromWidget->getMidiWorker()->maxNPoints; l1++) {
639         midiLfo->customWave[l1] = fromWidget->getCustomWave().at(l1);
640         midiLfo->muteMask[l1] = midiLfo->customWave.at(l1).muted;
641     }
642     midiControl->setCcList(fromWidget->midiControl->ccList);
643     muteOutAction->setChecked(true);
644 
645     tmp = fromWidget->waveFormBox->currentIndex();
646     waveFormBox->setCurrentIndex(tmp);
647     updateWaveForm(tmp);
648 }
649 
650 void LfoWidget::handleController(int ccnumber, int channel, int value)
651 {
652     QVector<MidiCC> cclist= midiControl->ccList;
653 
654     for (int l2 = 0; l2 < cclist.count(); l2++) {
655         int min = cclist.at(l2).min;
656         int max = cclist.at(l2).max;
657         if ((ccnumber == cclist.at(l2).ccnumber) &&
658             (channel == cclist.at(l2).channel)) {
659             int sval = 0;
660             bool m = false;
661             switch (cclist.at(l2).ID) {
662                 case 0: if (min == max) {
663                             if (value == max) {
664                                 m = midiLfo->isMuted;
665                                 midiLfo->setMuted(!m);
666                             }
667                         }
668                         else {
669                             if (value == max) {
670                                 midiLfo->setMuted(false);
671                             }
672                             if (value == min) {
673                                 midiLfo->setMuted(true);
674                             }
675                         }
676                 break;
677 
678                 case 1:
679                         sval = min + ((double)value * (max - min) / 127);
680                         midiLfo->updateAmplitude(sval);
681                 break;
682 
683                 case 2:
684                         sval = min + ((double)value * (max - min) / 127);
685                         midiLfo->updateOffset(sval);
686                 break;
687                 case 3:
688                         sval = min + ((double)value * (max - min) / 127);
689                         if (sval < 6) waveFormBoxIndex = sval;
690                 break;
691                 case 4:
692                         sval = min + ((double)value * (max - min) / 127);
693                         if (sval < 14) freqBoxIndex = sval;
694                 break;
695                 case 5: if (min == max) {
696                             if (value == max) {
697                                 m = midiLfo->recordMode;
698                                 midiLfo->setRecordMode(!m);
699                                 return;
700                             }
701                         }
702                         else {
703                             if (value == max) {
704                                 midiLfo->setRecordMode(true);
705                             }
706                             if (value == min) {
707                                 midiLfo->setRecordMode(false);
708                             }
709                         }
710                 break;
711                 case 6:
712                         sval = min + ((double)value * (max - min) / 127);
713                         if (sval < 9) resBoxIndex = sval;
714                 break;
715                 case 7:
716                         sval = min + ((double)value * (max - min) / 127);
717                         if (sval < 12) sizeBoxIndex = sval;
718                 break;
719                 case 8:
720                         sval = min + ((double)value * (max - min) / 127);
721                         if (sval < 6) midiLfo->curLoopMode = sval;
722                 break;
723                 case 9:
724                         sval = min + ((double)value * (max - min) / 127);
725                         if ((sval < parStore->list.count())
726                                 && (sval != parStore->activeStore)
727                                 && (sval != parStore->currentRequest)) {
728                             parStore->requestDispState(sval, 2);
729                             parStore->restoreRequest = sval;
730                             parStore->restoreRunOnce = (parStore->jumpToList.at(sval) > -2);
731                         }
732                         else return;
733                 break;
734 
735 
736                 default:
737                 break;
738             }
739             needsGUIUpdate = true;
740         }
741     }
742 }
743 
744 void LfoWidget::updateDisplay()
745 {
746     QVector<Sample> data;
747     std::vector<Sample> sdata;
748 
749     parStore->updateDisplay(getFramePtr()/midiLfo->frameSize, midiLfo->reverse);
750 
751     if (midiLfo->dataChanged) {
752         midiLfo->getData(&sdata);
753         data = QVector<Sample>::fromStdVector(sdata);
754         screen->updateData(data);
755         cursor->updateNumbers(midiLfo->res, midiLfo->size);
756         offset->setValue(midiLfo->offs);
757         midiLfo->dataChanged = false;
758     }
759     screen->updateDraw();
760     cursor->updateDraw();
761     midiControl->update();
762 
763     if (!(needsGUIUpdate || midiLfo->needsGUIUpdate)) return;
764 
765     muteOut->setChecked(midiLfo->isMuted);
766     screen->newGrooveValues(midiLfo->newGrooveTick, midiLfo->grooveVelocity,
767                 midiLfo->grooveLength);
768     screen->setMuted(midiLfo->isMuted);
769     parStore->ndc->setMuted(midiLfo->isMuted);
770     recordAction->setChecked(midiLfo->recordMode);
771     screen->setRecordMode(midiLfo->recordMode);
772     resBox->setCurrentIndex(resBoxIndex);
773     updateRes(resBoxIndex);
774     sizeBox->setCurrentIndex(sizeBoxIndex);
775     updateSize(sizeBoxIndex);
776     freqBox->setCurrentIndex(freqBoxIndex);
777     updateFreq(freqBoxIndex);
778     loopBox->setCurrentIndex(midiLfo->curLoopMode);
779     amplitude->setValue(midiLfo->amp);
780     offset->setValue(midiLfo->offs);
781     if (waveFormBoxIndex != waveFormBox->currentIndex()) {
782         waveFormBox->setCurrentIndex(waveFormBoxIndex);
783         updateWaveForm(waveFormBoxIndex);
784     }
785     needsGUIUpdate = false;
786     midiLfo->needsGUIUpdate = false;
787 }
788 
789 #endif
790