Skip to content

Commit 3214265

Browse files
pleiadianpleiadian
pleiadian
authored and
pleiadian
committed
Plugin Mode support. No more crashs on quit.
1 parent e9873ed commit 3214265

File tree

2 files changed

+124
-37
lines changed

2 files changed

+124
-37
lines changed

source/qkontrol.cpp

+123-37
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ qkontrolWindow::qkontrolWindow(QWidget* parent /* = 0 */, Qt::WindowFlags flags
131131
trackname = "";
132132
devicename = "";
133133

134-
// start in midi mode
134+
// start in midi mode and create empty parameter array
135135
pluginMode = false;
136+
paramName = QStringList() << NULL << NULL << NULL << NULL << NULL << NULL << NULL << NULL;
136137

137138
// make the switch / continous tab bars (pedals) invisible
138139
tabWidget_pedal1->findChild<QTabBar *>()->hide();
@@ -381,14 +382,23 @@ void qkontrolWindow::updateValues()
381382
}
382383
knobPainter->end();
383384
knobsButtons = DATA_IN;
385+
386+
// send values via OSC if the controller is in plugin mode
387+
if(pluginMode == true)
388+
{
389+
for(int i=0;i<=7;i++)
390+
udpSocket->writeDatagram(QByteArray("/device/param/"+QString::number(i+1).toUtf8()+"/value")+QByteArray::fromHex("0000002c690000000000")+DATA_IN[17+i*2], QHostAddress(hostname),remotePort);
391+
}
392+
393+
// qDebug() << DATA_IN.toHex();
384394
}
385395
if((res == 32) && (DATA_IN[0]==char(0x01)))
386396
{
387397
// if the button values are still the same, no other button has been pushed. Therefore: ignore
388-
if(DATA_IN.left(5) == oldButtonArray)
398+
if(DATA_IN.left(6) == oldButtonArray)
389399
return;
390400
else
391-
oldButtonArray = DATA_IN.left(5);
401+
oldButtonArray = DATA_IN.left(6);
392402

393403
if((DATA_IN[2]==char(0x10)) && (oscEnabled == true)) // play
394404
udpSocket->writeDatagram(QByteArray::fromHex("2f706c6179002c6900000000"),QHostAddress(hostname),remotePort);
@@ -411,15 +421,45 @@ void qkontrolWindow::updateValues()
411421
zapPreset(0);
412422
if(DATA_IN[3]==char(0x40)) // preset down
413423
zapPreset(1);
414-
if((DATA_IN[3]==char(0x80)) && kontrolPage > 0)
415-
setKontrolpage(kontrolPage-1);
416-
if((DATA_IN[3]==char(0x20)) && kontrolPage < 3)
417-
setKontrolpage(kontrolPage+1);
424+
425+
if(pluginMode == true) // use > and < buttons in MIDI mode to toggle parameter pages and in plugin mode to toggle plugins in track
426+
{
427+
if(DATA_IN[3]==char(0x80))
428+
udpSocket->writeDatagram(QByteArray::fromHex("2f6465766963652f2d00000000000000"),QHostAddress(hostname),remotePort);
429+
if(DATA_IN[3]==char(0x20))
430+
udpSocket->writeDatagram(QByteArray::fromHex("2f6465766963652f2b00000000000000"),QHostAddress(hostname),remotePort);
431+
}
432+
else
433+
{
434+
if((DATA_IN[3]==char(0x80)) && kontrolPage > 0)
435+
setKontrolpage(kontrolPage-1);
436+
if((DATA_IN[3]==char(0x20)) && kontrolPage < 3)
437+
setKontrolpage(kontrolPage+1);
438+
}
439+
418440
if(DATA_IN[4]==char(0x01))
419441
udpSocket->writeDatagram(QByteArray::fromHex("2f747261636b2f73656c65637465642f6d75746500000000002c6900000000"),QHostAddress(hostname),remotePort); // mute
420442
if(DATA_IN[4]==char(0x02))
421443
udpSocket->writeDatagram(QByteArray::fromHex("2f747261636b2f73656c65637465642f736f6c6f00000000002c6900000000"),QHostAddress(hostname),remotePort); // solo
422-
// qDebug() << DATA_IN.toHex();
444+
if(DATA_IN[5]==char(0x02)) // plug-in
445+
{
446+
pluginMode = true;
447+
lightArray.replace(33,1,QByteArray::fromHex("20"));
448+
lightArray.replace(34,1,QByteArray::fromHex("20"));
449+
lightArray.replace(37,1,QByteArray::fromHex("FF"));
450+
lightArray.replace(40,1,QByteArray::fromHex("20"));
451+
udpSocket->writeDatagram(QByteArray::fromHex("2f7265667265736800010000002c6900000000"),QHostAddress(hostname),remotePort); // refresh
452+
setButtons();
453+
setKeyzones();
454+
}
455+
if(DATA_IN[5]==char(0x20)) // midi
456+
{
457+
pluginMode = false;
458+
lightArray.replace(37,1,QByteArray::fromHex("20"));
459+
lightArray.replace(40,1,QByteArray::fromHex("FF"));
460+
setKontrolpage(kontrolPage);
461+
}
462+
// qDebug() << DATA_IN.toHex();
423463
}
424464
}
425465

@@ -564,7 +604,9 @@ void qkontrolWindow::setKeyzones()
564604

565605
if(pluginMode == true) // in plugin mode, we need to set some bytes to zero again to avoid MIDI
566606
{
567-
for(unsigned int i=1;i<=193;i+=12)
607+
for(unsigned int i=1;i<=181;i+=12) // avoid midi if the knobs are moved or buttons pushed
608+
knobsAndButtons.replace(i,1,QByteArray::fromHex("08"));
609+
for(unsigned int i=188;i<=200;i++) // turn off the backlight of all buttons
568610
knobsAndButtons.replace(i,1,QByteArray::fromHex("00"));
569611
}
570612

@@ -848,14 +890,16 @@ void qkontrolWindow::setKeyzones()
848890
image1->drawImage(0, 65, QImage(graphicsViewScreen1->currentFile).scaled(480, 140));
849891
if(QFile::exists(graphicsViewScreen2->currentFile))
850892
image2->drawImage(0, 65, QImage(graphicsViewScreen2->currentFile).scaled(480, 140));
893+
851894
if(p_ScreenCC->currentIndex() == 1)
852895
{
853896
image1->setFont(QFont("Arial", 16, QFont::Bold));
854897
image1->setPen(allColors["slider"]);
855898
image1->drawText(QPoint(30,110), sliderFunctionList[0]);
856899
image1->drawText(QPoint(30,140), sliderFunctionList[1]);
857900
image1->drawText(QPoint(30,170), sliderFunctionList[2]);
858-
image1->drawText(QPoint(370, 140), "page "+QString::number(kontrolPage+1)+"/4");
901+
if(pluginMode == false)
902+
image1->drawText(QPoint(370, 140), "page "+QString::number(kontrolPage+1)+"/4");
859903
}
860904
if(p_ScreenCC->currentIndex() == 2)
861905
{
@@ -864,7 +908,8 @@ void qkontrolWindow::setKeyzones()
864908
image2->drawText(QPoint(30,110), sliderFunctionList[0]);
865909
image2->drawText(QPoint(30,140), sliderFunctionList[1]);
866910
image2->drawText(QPoint(30,170), sliderFunctionList[2]);
867-
image2->drawText(QPoint(370, 140), "page "+QString::number(kontrolPage+1)+"/4");
911+
if(pluginMode == false)
912+
image2->drawText(QPoint(370, 140), "page "+QString::number(kontrolPage+1)+"/4");
868913
}
869914

870915
image1->setFont(QFont("Arial", 13, QFont::Bold));
@@ -877,24 +922,36 @@ void qkontrolWindow::setKeyzones()
877922

878923
for(int i=0;i<=7;i++)
879924
{
880-
switch(findChild<QComboBox *>("b_mode_"+QString::number(8*kontrolPage+i+1))->currentIndex())
925+
if(pluginMode == false)
881926
{
882-
case 0: image[floor(i/4)]->drawText(QRect(y[i], 10, 100, 27), Qt::AlignCenter, "OFF"); break;
883-
case 4: image[floor(i/4)]->drawText(QRect(y[i], 10, 100, 27), Qt::AlignCenter, "PRG "+QString::number(findChild<QSpinBox *>("b_CC_"+QString::number(8*kontrolPage+i+1))->value())); break;
884-
default: image[floor(i/4)]->drawText(QRect(y[i], 10, 100, 27), Qt::AlignCenter, "CC "+QString::number(findChild<QSpinBox *>("b_CC_"+QString::number(8*kontrolPage+i+1))->value())); break;
927+
switch(findChild<QComboBox *>("b_mode_"+QString::number(8*kontrolPage+i+1))->currentIndex())
928+
{
929+
case 0: image[floor(i/4)]->drawText(QRect(y[i], 10, 100, 27), Qt::AlignCenter, "OFF"); break;
930+
case 4: image[floor(i/4)]->drawText(QRect(y[i], 10, 100, 27), Qt::AlignCenter, "PRG "+QString::number(findChild<QSpinBox *>("b_CC_"+QString::number(8*kontrolPage+i+1))->value())); break;
931+
default: image[floor(i/4)]->drawText(QRect(y[i], 10, 100, 27), Qt::AlignCenter, "CC "+QString::number(findChild<QSpinBox *>("b_CC_"+QString::number(8*kontrolPage+i+1))->value())); break;
932+
}
885933
}
934+
else
935+
image[floor(i/4)]->drawText(QRect(y[i], 10, 100, 27), Qt::AlignCenter, "OFF");
886936
}
887937

888938
image1->setFont(QFont("Arial", 10));
889939
image2->setFont(QFont("Arial", 10));
890940

891941
for(int i=0;i<=7;i++)
892-
switch(findChild<QComboBox *>("k_mode_"+QString::number(8*kontrolPage+i+1))->currentIndex())
942+
{
943+
if(pluginMode == false)
893944
{
894-
case 0: image[floor(i/4)]->drawText(QPoint(y[i], 245), "OFF"); break;
895-
case 1: image[floor(i/4)]->drawText(QPoint(y[i], 245), "PRESET"); break;
896-
default: image[floor(i/4)]->drawText(QPoint(y[i], 245), "CC "+QString::number(findChild<QSpinBox *>("k_CC_"+QString::number(8*kontrolPage+i+1))->value())); break;
945+
switch(findChild<QComboBox *>("k_mode_"+QString::number(8*kontrolPage+i+1))->currentIndex())
946+
{
947+
case 0: image[floor(i/4)]->drawText(QPoint(y[i], 245), "OFF"); break;
948+
case 1: image[floor(i/4)]->drawText(QPoint(y[i], 245), "PRESET"); break;
949+
default: image[floor(i/4)]->drawText(QPoint(y[i], 245), "CC "+QString::number(findChild<QSpinBox *>("k_CC_"+QString::number(8*kontrolPage+i+1))->value())); break;
950+
}
897951
}
952+
else
953+
image[floor(i/4)]->drawText(QPoint(y[i], 245), "RC "+QString::number(i+1));
954+
}
898955

899956
image1->setFont(QFont("Arial", 9));
900957
image2->setFont(QFont("Arial", 9));
@@ -905,8 +962,13 @@ void qkontrolWindow::setKeyzones()
905962
for(int i=0;i<=7;i++)
906963
{
907964
if(findChild<QComboBox *>("k_mode_"+QString::number(8*kontrolPage+i+1))->currentIndex() == 2)
908-
image[floor(i/4)]->drawText(QPoint(y[i], 263), findChild<QLineEdit *>("k_description_"+QString::number(8*kontrolPage+i+1))->text());
909-
if(findChild<QComboBox *>("b_mode_"+QString::number(8*kontrolPage+i+1))->currentIndex() != 0)
965+
{
966+
if(pluginMode == false)
967+
image[floor(i/4)]->drawText(QPoint(y[i], 263), findChild<QLineEdit *>("k_description_"+QString::number(8*kontrolPage+i+1))->text());
968+
else
969+
image[floor(i/4)]->drawText(QPoint(y[i], 263), paramName[i]);
970+
}
971+
if((findChild<QComboBox *>("b_mode_"+QString::number(8*kontrolPage+i+1))->currentIndex() != 0) && (pluginMode == false))
910972
image[floor(i/4)]->drawText(QRect(y[i], 32, 100, 13), Qt::AlignCenter, findChild<QLineEdit *>("b_description_"+QString::number(8*kontrolPage+i+1))->text());
911973
}
912974

@@ -924,7 +986,6 @@ void qkontrolWindow::setKeyzones()
924986
image2->drawLine(240, 225, 240, 272);
925987
image2->drawLine(360, 225, 360, 272);
926988

927-
928989
drawImage(0, &screen1);
929990
drawImage(1, &screen2);
930991

@@ -1010,6 +1071,7 @@ void qkontrolWindow::setValuetextcolor() { selectColor("value"); }
10101071

10111072
void qkontrolWindow::updateBacklights()
10121073
{
1074+
bool updateParams;
10131075
QByteArray datagram;
10141076
QString uData;
10151077

@@ -1022,25 +1084,25 @@ void qkontrolWindow::updateBacklights()
10221084
uData = datagram.data();
10231085
if(datagram.toHex().contains("2f706c61790000002c69000000000000")) // stopped
10241086
{
1025-
lightArray.replace(30,1,QByteArray::fromHex("21"));
1026-
lightArray.replace(31,1,QByteArray::fromHex("21"));
1087+
lightArray.replace(30,1,QByteArray::fromHex("20"));
1088+
lightArray.replace(31,1,QByteArray::fromHex("20"));
10271089
lightArray.replace(32,1,QByteArray::fromHex("FF"));
10281090
}
10291091
if(datagram.toHex().contains("2f706c61790000002c69000000000001")) // playing
10301092
{
10311093
lightArray.replace(30,1,QByteArray::fromHex("FF"));
1032-
lightArray.replace(32,1,QByteArray::fromHex("21"));
1094+
lightArray.replace(32,1,QByteArray::fromHex("20"));
10331095
}
10341096
if(datagram.toHex().contains("2f7265636f7264002c69000000000000")) // record off
1035-
lightArray.replace(31,1,QByteArray::fromHex("21"));
1097+
lightArray.replace(31,1,QByteArray::fromHex("20"));
10361098
if(datagram.toHex().contains("2f7265636f7264002c69000000000001")) // record on
10371099
lightArray.replace(31,1,QByteArray::fromHex("FF"));
10381100
if(datagram.toHex().contains("2f726570656174002c69000000000000")) // loop off
1039-
lightArray.replace(25,1,QByteArray::fromHex("21"));
1101+
lightArray.replace(25,1,QByteArray::fromHex("20"));
10401102
if(datagram.toHex().contains("2f726570656174002c69000000000001")) // loop on
10411103
lightArray.replace(25,1,QByteArray::fromHex("FF"));
10421104
if(datagram.toHex().contains("2f636c69636b00002c69000000000000")) // metronome off
1043-
lightArray.replace(26,1,QByteArray::fromHex("21"));
1105+
lightArray.replace(26,1,QByteArray::fromHex("20"));
10441106
if(datagram.toHex().contains("2f636c69636b00002c69000000000001")) // metronome on
10451107
lightArray.replace(26,1,QByteArray::fromHex("FF"));
10461108
if(datagram.contains("/track/selected/mute"))
@@ -1070,20 +1132,37 @@ void qkontrolWindow::updateBacklights()
10701132
}
10711133
if(datagram.contains("/beat/str"))
10721134
{
1073-
beatstring = QString(datagram.replace(0x00,0x20)).split("/beat/str")[1].split(",s")[1].split(",")[0].split(" ")[1];
1135+
beatstring = QString(datagram.replace(0x00,0x20)).split("/beat/str")[1].split(",s")[1].split(",")[0].split(" ")[1].replace(":",".");
10741136
changeTrackinfo = true;
10751137
}
10761138
if(datagram.contains("/time/str"))
10771139
{
1078-
timestring = QString(datagram.replace(0x00,0x20)).split("/time/str")[1].split(",s")[1].split(",")[0].split(" ")[1];
1140+
timestring = QString(datagram.replace(0x00,0x20)).split("/time/str")[1].split(",s")[1].split(",")[0].split(" ")[1].replace(":","-").replace(".",":").replace("-","."); // quirk
10791141
changeTrackinfo = true;
10801142
}
1143+
if(pluginMode == true)
1144+
{
1145+
updateParams = false;
1146+
for(int i=1;i<=8;i++)
1147+
if(datagram.contains("/device/param/"+QString::number(i).toUtf8()+"/name"))
1148+
{
1149+
paramName = QStringList() << NULL << NULL << NULL << NULL << NULL << NULL << NULL << NULL;
1150+
updateParams = true;
1151+
break;
1152+
}
1153+
for(int i=1;i<=8;i++)
1154+
if(datagram.contains("/device/param/"+QString::number(i).toUtf8()+"/name"))
1155+
paramName[i-1] = QString(datagram.replace(0x00,0x20)).split("/device/param/"+QString::number(i).toUtf8()+"/name")[1].split(",s")[1].split(",")[0].split(" ")[1];
1156+
if(updateParams == true)
1157+
setKeyzones();
1158+
}
10811159
if(changeTrackinfo == true)
10821160
updateOSCInfo();
10831161

10841162
// qDebug() << datagram.toHex() << datagram;
10851163
}
10861164

1165+
// function to change the visible colors inside the color buttons
10871166
void qkontrolWindow::updateColors()
10881167
{
10891168
QPixmap pixmapColors(color_CC->width()-4, color_CC->height()-4);
@@ -1101,6 +1180,7 @@ void qkontrolWindow::updateColors()
11011180

11021181
qkontrolWindow::~qkontrolWindow()
11031182
{
1183+
hid_close(handle);
11041184
res = hid_exit();
11051185
}
11061186

@@ -1334,15 +1414,17 @@ void qkontrolWindow::oscConfig()
13341414

13351415
if(oscEnabled==true)
13361416
{
1337-
// enable mute, solo, loop, metro, play, stop and record buttons
1417+
// enable mute, solo, loop, metro, play, stop, record, plug-in and midi buttons
13381418
lightArray.replace(1,1,QByteArray::fromHex("04"));
13391419
lightArray.replace(2,1,QByteArray::fromHex("10"));
1340-
// lightArray.replace(15,1,QByteArray::fromHex("21")); // shift
1341-
lightArray.replace(25,1,QByteArray::fromHex("21"));
1342-
lightArray.replace(26,1,QByteArray::fromHex("21"));
1343-
lightArray.replace(30,1,QByteArray::fromHex("21"));
1344-
lightArray.replace(31,1,QByteArray::fromHex("21"));
1420+
// lightArray.replace(15,1,QByteArray::fromHex("20")); // shift
1421+
lightArray.replace(25,1,QByteArray::fromHex("20"));
1422+
lightArray.replace(26,1,QByteArray::fromHex("20"));
1423+
lightArray.replace(30,1,QByteArray::fromHex("20"));
1424+
lightArray.replace(31,1,QByteArray::fromHex("20"));
13451425
lightArray.replace(32,1,QByteArray::fromHex("FF"));
1426+
lightArray.replace(37,1,QByteArray::fromHex("20"));
1427+
lightArray.replace(40,1,QByteArray::fromHex("FF"));
13461428

13471429
// watch for incoming UDP traffic and call a function to update the button backlights
13481430
udpSocket->bind(QHostAddress(hostname), localPort, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
@@ -1353,7 +1435,7 @@ void qkontrolWindow::oscConfig()
13531435
}
13541436
else
13551437
{
1356-
// disable mute, solo, loop, metro, play, stop and record buttons
1438+
// disable mute, solo, loop, metro, play, stop, record, plug-in and midi buttons
13571439
lightArray.replace(1,1,QByteArray::fromHex("00"));
13581440
lightArray.replace(2,1,QByteArray::fromHex("00"));
13591441
lightArray.replace(15,1,QByteArray::fromHex("00"));
@@ -1362,10 +1444,14 @@ void qkontrolWindow::oscConfig()
13621444
lightArray.replace(30,1,QByteArray::fromHex("00"));
13631445
lightArray.replace(31,1,QByteArray::fromHex("00"));
13641446
lightArray.replace(32,1,QByteArray::fromHex("00"));
1447+
lightArray.replace(37,1,QByteArray::fromHex("00"));
1448+
lightArray.replace(40,1,QByteArray::fromHex("00"));
13651449

13661450
// disable UDP and slot connection
13671451
udpSocket->close();
13681452
}
1453+
1454+
// finally call the functions to apply the button backlight settings and the screen information
13691455
setButtons();
13701456
setKeyzones();
13711457
}

source/qkontrol.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class qkontrolWindow : public QMainWindow , protected Ui_mainwindow
3535
QTemporaryFile leftScreen, rightScreen; // image files to be displayed on the screens
3636
QTimer *hid_data;
3737
QString getControlName(uint8_t CC);
38+
QStringList paramName;
3839
QDir dirName;
3940
bool load(QString filename); // function to load a preset
4041
QUdpSocket *udpSocket; // UDP socket to be used on OSC

0 commit comments

Comments
 (0)