1
//=============================================================================
4
// $Id: osc.cpp,v 1.0.0.0 2010/04/22 03:39:58 terminator356 Exp $
6
// Copyright (C) 1999-2010 by Werner Schweer and others
7
// OSC module added by Tim.
9
// This program is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU General Public License version 2.
12
// This program is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with this program; if not, write to the Free Software
19
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
//=============================================================================
26
// Turn on debugging messages
36
//#include <alsa/asoundlib.h>
40
#include <qstringlist.h>
41
#include <qfileinfo.h>
42
//#include <qpopupmenu.h>
51
#include "stringparam.h"
57
//#include "jackaudio.h"
59
//#include "midiport.h"
63
//#include "midictrl.h"
64
//#include "ladspaplugin.h"
68
#include "globaldefs.h"
71
static lo_server_thread serverThread = 0;
72
///static char osc_path_tmp[1024];
74
static bool oscServerRunning = false;
76
//---------------------------------------------------------
78
//---------------------------------------------------------
80
static void oscError(int num, const char *msg, const char *path)
82
fprintf(stderr, "MusE: liblo server error %d in path %s: %s\n",
86
//---------------------------------------------------------
88
//---------------------------------------------------------
90
static int oscDebugHandler(const char* path, const char* types, lo_arg** argv,
91
int argc, void*, void*)
93
printf("MusE: got unhandled OSC message:\n path: <%s>\n", path);
94
for (int i = 0; i < argc; i++) {
95
printf(" arg %d '%c' ", i, types[i]);
96
lo_arg_pp(lo_type(types[i]), argv[i]);
102
//---------------------------------------------------------
104
//---------------------------------------------------------
106
int oscMessageHandler(const char* path, const char* types, lo_arg** argv,
107
int argc, void* data, void* user_data)
109
const char* p = path;
114
printf("oscMessageHandler: path:%s argc:%d\n", path, argc);
115
for(int i = 0; i < argc; ++i)
118
lo_arg_pp((lo_type)types[i], argv[i]);
124
printf("%s\n", path);
125
printf("oscMessageHandler: no args, path:%s\n", path);
129
bool isSynth = false;
132
if(strncmp(p, "/dssi_synth/", 12) == 0)
139
if(strncmp(p, "/ladspa_efx/", 12) == 0)
144
return oscDebugHandler(path, types, argv, argc, data, user_data);
146
TrackList* tl = song->tracks();
151
fprintf(stderr, "oscMessageHandler: got message for dssi synth...\n");
153
fprintf(stderr, "oscMessageHandler: got message for ladspa effect...\n");
156
// FIXME: Slowdowns: Shouldn't need these retries but they are needed, only upon creation of the synth.
157
// Need to fix the real source of the problem! The instance is taking too long to appear after creation.
159
///for(int retry = 0; retry < 5000; ++retry)
162
///fprintf(stderr, "oscMessageHandler: search retry number:%d ...\n", retry);
171
// Message is meant for a dssi synth. Check dssi synth instances...
172
SynthIList* sl = song->syntis();
173
for(iSynthI si = sl->begin(); si != sl->end(); ++si)
178
fprintf(stderr, "oscMessageHandler: searching for:%s checking synth instance:%s\n", p, synti->name().latin1());
181
const char* sub = strstr(p, synti->name().latin1());
185
//DssiSynthIF* instance = (DssiSynthIF*)synti->sif();
186
DssiSynthIF* instance = dynamic_cast<DssiSynthIF*>(synti->sif());
190
p = sub + strlen(synti->name().latin1());
192
if (*p != '/' || *(p + 1) == 0)
194
fprintf(stderr, "oscMessageHandler error: synth: end of path or no /\n");
195
return oscDebugHandler(path, types, argv, argc, data, user_data);
201
fprintf(stderr, "oscMessageHandler: synth track:%s method:%s\n", synti->name().latin1(), p);
204
OscIF& oscif = instance->oscIF();
206
if (!strcmp(p, "configure") && argc == 2 && !strcmp(types, "ss"))
207
return oscif.oscConfigure(argv);
208
else if (!strcmp(p, "control") && argc == 2 && !strcmp(types, "if"))
209
return oscif.oscControl(argv);
210
else if (!strcmp(p, "midi") && argc == 1 && !strcmp(types, "m"))
211
return oscif.oscMidi(argv);
212
else if (!strcmp(p, "program") && argc == 2 && !strcmp(types, "ii"))
213
return oscif.oscProgram(argv);
214
else if (!strcmp(p, "update") && argc == 1 && !strcmp(types, "s"))
215
return oscif.oscUpdate(argv);
216
else if (!strcmp(p, "exiting") && argc == 0)
217
return oscif.oscExiting(argv);
218
return oscDebugHandler(path, types, argv, argc, data, user_data);
222
#endif //DSSI_SUPPORT
223
// Message is meant for a ladspa effect. Check all ladspa effect instances...
224
for(ciTrack it = tl->begin(); it != tl->end(); ++it)
226
if((*it)->isMidiTrack())
229
Pipeline* efxPipe = ((AudioTrack*)*it)->efxPipe();
232
for(ciPluginI ip = efxPipe->begin(); ip != efxPipe->end(); ++ip)
234
PluginI* instance = *ip;
239
fprintf(stderr, "oscMessageHandler: searching for:%s checking effect instance:%s label:%s lib:%s\n",
240
p, instance->name().latin1(), instance->label().latin1(), instance->lib().latin1());
243
//const char* sub = strstr(p, instance->name().latin1());
244
const char* sub = strstr(p, instance->label().latin1());
248
Plugin* plugin = instance->plugin();
252
//p = sub + strlen(instance->name().latin1());
253
p = sub + strlen(instance->label().latin1());
255
if (*p != '/' || *(p + 1) == 0)
257
fprintf(stderr, "oscMessageHandler: error: effect: end of path or no /\n");
258
return oscDebugHandler(path, types, argv, argc, data, user_data);
264
//fprintf(stderr, "oscMessageHandler: effect:%s method:%s\n", instance->name().latin1(), p);
265
fprintf(stderr, "oscMessageHandler: effect:%s method:%s\n", instance->label().latin1(), p);
268
OscIF& oscif = instance->oscIF();
270
if (!strcmp(p, "configure") && argc == 2 && !strcmp(types, "ss"))
271
return oscif.oscConfigure(argv);
272
else if (!strcmp(p, "control") && argc == 2 && !strcmp(types, "if"))
273
return oscif.oscControl(argv);
274
else if (!strcmp(p, "midi") && argc == 1 && !strcmp(types, "m"))
275
return oscif.oscMidi(argv);
276
else if (!strcmp(p, "program") && argc == 2 && !strcmp(types, "ii"))
277
return oscif.oscProgram(argv);
278
else if (!strcmp(p, "update") && argc == 1 && !strcmp(types, "s"))
279
return oscif.oscUpdate(argv);
280
else if (!strcmp(p, "exiting") && argc == 0)
281
return oscif.oscExiting(argv);
282
return oscDebugHandler(path, types, argv, argc, data, user_data);
290
fprintf(stderr, "oscMessageHandler: timeout error: no synth or effect instance found for given path\n");
291
return oscDebugHandler(path, types, argv, argc, data, user_data);
295
//---------------------------------------------------------
297
//---------------------------------------------------------
306
// Only if not created yet.
309
serverThread = lo_server_thread_new(0, oscError);
312
printf("initOSC() Failed to create OSC server!\n");
317
///snprintf(osc_path_tmp, 31, "/dssi");
318
// Test: Clear the temp path:
319
//snprintf(osc_path_tmp, 31, "");
321
///char* tmp = lo_server_thread_get_url(serverThread);
323
url = lo_server_thread_get_url(serverThread);
326
lo_server_thread_free(serverThread);
327
printf("initOSC() Failed to get OSC server thread url !\n");
331
///url = (char *)malloc(strlen(tmp) + strlen(osc_path_tmp));
332
//url = (char *)malloc(strlen(tmp));
334
///sprintf(url, "%s%s", tmp, osc_path_tmp + 1);
335
//sprintf(url, "%s", tmp, osc_path_tmp + 1);
340
meth = lo_server_thread_add_method(serverThread, 0, 0, oscMessageHandler, 0);
343
printf("initOSC() Failed to add oscMessageHandler method to OSC server!\n");
344
// Does not return a value.
345
lo_server_thread_free(serverThread);
352
// Does not return a value.
353
lo_server_thread_start(serverThread);
356
//---------------------------------------------------------
358
//---------------------------------------------------------
362
oscServerRunning = false;
365
// Does not return a value.
366
lo_server_thread_stop(serverThread);
367
lo_server_thread_free(serverThread);
372
//---------------------------------------------------------
374
//---------------------------------------------------------
379
// Does not return a value.
380
lo_server_thread_start(serverThread);
381
oscServerRunning = true;
384
//---------------------------------------------------------
386
//---------------------------------------------------------
391
// Does not return a value.
392
lo_server_thread_stop(serverThread);
393
oscServerRunning = false;
398
//---------------------------------------------------------
401
// return true on fifo overflow
402
//---------------------------------------------------------
404
bool OscControlFifo::put(const OscControlValue& event)
406
if (size < OSC_FIFO_SIZE) {
407
fifo[wIndex] = event;
408
wIndex = (wIndex + 1) % OSC_FIFO_SIZE;
409
// q_atomic_increment(&size);
416
//---------------------------------------------------------
418
//---------------------------------------------------------
420
OscControlValue OscControlFifo::get()
422
OscControlValue event(fifo[rIndex]);
423
rIndex = (rIndex + 1) % OSC_FIFO_SIZE;
424
// q_atomic_decrement(&size);
429
//---------------------------------------------------------
431
//---------------------------------------------------------
433
const OscControlValue& OscControlFifo::peek(int n)
435
int idx = (rIndex + n) % OSC_FIFO_SIZE;
439
//---------------------------------------------------------
441
//---------------------------------------------------------
443
void OscControlFifo::remove()
445
rIndex = (rIndex + 1) % OSC_FIFO_SIZE;
446
// q_atomic_decrement(&size);
452
//---------------------------------------------------------
454
// Open Sound Control Interface
455
//---------------------------------------------------------
461
//#ifdef DSSI_SUPPORT
466
_uiOscSampleRatePath = 0;
468
_uiOscControlPath = 0;
469
_uiOscConfigurePath = 0;
470
_uiOscProgramPath = 0;
474
_oscGuiVisible = false;
476
_oscControlFifos = 0;
482
// kill(guiPid, SIGHUP);
485
if(_oscGuiQProc->isRunning())
488
printf("OscIF::~OscIF terminating _oscGuiQProc\n");
491
//_oscGuiQProc->kill();
492
// "This tries to terminate the process the nice way. If the process is still running after 5 seconds,
493
// it terminates the process the hard way. The timeout should be chosen depending on the time the
494
// process needs to do all its cleanup: use a higher value if the process is likely to do a lot of
495
// computation or I/O on cleanup."
496
_oscGuiQProc->tryTerminate();
497
QTimer::singleShot( 5000, _oscGuiQProc, SLOT( kill() ) );
499
//delete _oscGuiQProc;
503
lo_address_free(_uiOscTarget);
504
if(_uiOscSampleRatePath)
505
free(_uiOscSampleRatePath);
507
free(_uiOscShowPath);
508
if(_uiOscControlPath)
509
free(_uiOscControlPath);
510
if(_uiOscConfigurePath)
511
free(_uiOscConfigurePath);
512
if(_uiOscProgramPath)
513
free(_uiOscProgramPath);
518
delete[] _oscControlFifos;
521
//---------------------------------------------------------
523
//---------------------------------------------------------
525
OscControlFifo* OscIF::oscFifo(unsigned long i) const
527
if(!_oscControlFifos)
529
return &_oscControlFifos[i];
532
//---------------------------------------------------------
534
//---------------------------------------------------------
536
int OscIF::oscUpdate(lo_arg **argv)
538
const char *purl = (char *)&argv[0]->s;
541
lo_address_free(_uiOscTarget);
543
char* host = lo_url_get_hostname(purl);
544
char* port = lo_url_get_port(purl);
545
_uiOscTarget = lo_address_new(host, port);
553
_uiOscPath = lo_url_get_path(purl);
554
int pl = strlen(_uiOscPath);
556
if(_uiOscSampleRatePath)
557
free(_uiOscSampleRatePath);
558
_uiOscSampleRatePath = (char *)malloc(pl + 14);
559
sprintf(_uiOscSampleRatePath, "%s/sample-rate", _uiOscPath);
561
if (_uiOscControlPath)
562
free(_uiOscControlPath);
563
_uiOscControlPath = (char *)malloc(pl + 10);
564
sprintf(_uiOscControlPath, "%s/control", _uiOscPath);
566
if (_uiOscConfigurePath)
567
free(_uiOscConfigurePath);
568
_uiOscConfigurePath = (char *)malloc(pl + 12);
569
sprintf(_uiOscConfigurePath, "%s/configure", _uiOscPath);
571
if (_uiOscProgramPath)
572
free(_uiOscProgramPath);
573
_uiOscProgramPath = (char *)malloc(pl + 10);
574
sprintf(_uiOscProgramPath, "%s/program", _uiOscPath);
577
free(_uiOscShowPath);
578
_uiOscShowPath = (char *)malloc(pl + 10);
579
sprintf(_uiOscShowPath, "%s/show", _uiOscPath);
581
/* At this point a more substantial host might also call
582
* configure() on the UI to set any state that it had remembered
583
* for the plugin instance. But we don't remember state for
584
* plugin instances (see our own configure() implementation in
585
* osc_configure_handler), and so we have nothing to send except
586
* the optional project directory.
590
printf("OscIF::oscUpdate: _uiOscTarget:%p\n", _uiOscTarget);
592
printf(" server url:%s\n", url);
594
printf(" no server url!\n");
595
printf(" update path:%s\n", purl);
596
printf(" _uiOscPath:%s\n", _uiOscPath);
597
printf(" _uiOscSampleRatePath:%s\n", _uiOscSampleRatePath);
598
printf(" _uiOscConfigurePath:%s\n", _uiOscConfigurePath);
599
printf(" _uiOscProgramPath:%s\n", _uiOscProgramPath);
600
printf(" _uiOscControlPath:%s\n",_uiOscControlPath);
601
printf(" _uiOscShowPath:%s\n", _uiOscShowPath);
602
printf(" museProject:%s\n", museProject.latin1());
606
lo_send(_uiOscTarget, _uiOscSampleRatePath, "i", sampleRate);
608
// Send project directory.
609
//lo_send(_uiOscTarget, _uiOscConfigurePath, "ss",
610
// DSSI_PROJECT_DIRECTORY_KEY, museProject.latin1()); // song->projectPath()
612
// Done in sub-classes.
615
//lo_send(_uiOscTarget, _uiOscConfigurePath, "ss",
616
//DSSI_PROJECT_DIRECTORY_KEY, song->projectPath().toAscii().data());
617
lo_send(_uiOscTarget, _uiOscConfigurePath, "ss",
618
DSSI_PROJECT_DIRECTORY_KEY, museProject.latin1());
622
for(ciStringParamMap r = _oscSynthIF->synthI->_stringParamMap.begin(); r != synti->_stringParamMap.end(); ++r)
625
rv = dssi->configure(handle, r->first.c_str(), r->second.c_str());
628
fprintf(stderr, "MusE: Warning: plugin config key: %s value: %s \"%s\"\n", r->first.c_str(), r->second.c_str(), rv);
637
char uiOscGuiPath[strlen(_uiOscPath)+6];
638
sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, "show");
641
printf("OscIF::oscUpdate Sending show uiOscGuiPath:%s\n", uiOscGuiPath);
644
lo_send(_uiOscTarget, uiOscGuiPath, "");
646
sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, "hide");
649
printf("OscIF::oscUpdate Sending hide uiOscGuiPath:%s\n", uiOscGuiPath);
652
lo_send(_uiOscTarget, uiOscGuiPath, "");
656
/* Send current bank/program (-FIX- another race...) */
657
if (instance->pendingProgramChange < 0) {
658
unsigned long bank = instance->currentBank;
659
unsigned long program = instance->currentProgram;
660
instance->uiNeedsProgramUpdate = 0;
661
if (instance->uiTarget) {
662
lo_send(instance->uiTarget, instance->ui_osc_program_path, "ii", bank, program);
666
/* Send control ports */
667
for (i = 0; i < instance->plugin->controlIns; i++) {
668
int in = i + instance->firstControlIn;
669
int port = pluginControlInPortNumbers[in];
670
lo_send(instance->uiTarget, instance->ui_osc_control_path, "if", port,
671
pluginControlIns[in]);
672
/* Avoid overloading the GUI if there are lots and lots of ports */
680
//---------------------------------------------------------
682
//---------------------------------------------------------
684
int OscIF::oscExiting(lo_arg**)
686
// The gui is gone now, right?
687
_oscGuiVisible = false;
691
if(_oscGuiQProc->isRunning())
694
printf("OscIF::oscExiting terminating _oscGuiQProc\n");
697
//_oscGuiQProc->kill();
698
// "This tries to terminate the process the nice way. If the process is still running after 5 seconds,
699
// it terminates the process the hard way. The timeout should be chosen depending on the time the
700
// process needs to do all its cleanup: use a higher value if the process is likely to do a lot of
701
// computation or I/O on cleanup."
702
_oscGuiQProc->tryTerminate();
703
QTimer::singleShot( 5000, _oscGuiQProc, SLOT( kill() ) );
705
//delete _oscGuiQProc;
709
lo_address_free(_uiOscTarget);
711
if(_uiOscSampleRatePath)
712
free(_uiOscSampleRatePath);
713
_uiOscSampleRatePath = 0;
715
free(_uiOscShowPath);
717
if(_uiOscControlPath)
718
free(_uiOscControlPath);
719
_uiOscControlPath = 0;
720
if(_uiOscConfigurePath)
721
free(_uiOscConfigurePath);
722
_uiOscConfigurePath = 0;
723
if(_uiOscProgramPath)
724
free(_uiOscProgramPath);
725
_uiOscProgramPath = 0;
730
//if(_oscControlFifos)
731
// delete[] _oscControlFifos;
733
//const DSSI_Descriptor* dssi = synth->dssi;
734
//const LADSPA_Descriptor* ld = dssi->LADSPA_Plugin;
736
// ld->deactivate(handle);
739
if (_uiOscPath == 0) {
740
printf("OscIF::oscExiting(): no _uiOscPath\n");
743
char uiOscGuiPath[strlen(_uiOscPath)+6];
745
sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, "quit");
747
printf("OscIF::oscExiting(): sending quit to uiOscGuiPath:%s\n", uiOscGuiPath);
750
lo_send(_uiOscTarget, uiOscGuiPath, "");
757
printf("MusE: OSC: got exiting notification for instance %d\n",
761
if (instance->plugin) {
763
/*!!! No, this isn't safe -- plugins deactivated in this way
764
would still be included in a run_multiple_synths call unless
765
we re-jigged the instance array at the same time -- leave it
767
if (instance->plugin->descriptor->LADSPA_Plugin->deactivate) {
768
instance->plugin->descriptor->LADSPA_Plugin->deactivate
769
(instanceHandles[instance->number]);
772
/* Leave this flag though, as we need it to determine when to exit */
773
instance->inactive = 1;
776
/* Do we have any plugins left running? */
778
for (i = 0; i < instance_count; ++i) {
779
if (!instances[i].inactive)
784
printf("MusE: That was the last remaining plugin, exiting...\n");
791
//---------------------------------------------------------
793
//---------------------------------------------------------
795
void OscIF::oscSendProgram(unsigned long prog, unsigned long bank)
797
if(_uiOscTarget && _uiOscProgramPath)
798
lo_send(_uiOscTarget, _uiOscProgramPath, "ii", bank, prog);
801
//---------------------------------------------------------
803
//---------------------------------------------------------
805
void OscIF::oscSendControl(unsigned long dssiPort, float v)
807
if(_uiOscTarget && _uiOscControlPath)
808
lo_send(_uiOscTarget, _uiOscControlPath, "if", dssiPort, v);
811
//---------------------------------------------------------
813
//---------------------------------------------------------
815
void OscIF::oscSendConfigure(const char *key, const char *val)
817
if(_uiOscTarget && _uiOscConfigurePath)
818
lo_send(_uiOscTarget, _uiOscConfigurePath, "ss", key, val);
821
//---------------------------------------------------------
823
//---------------------------------------------------------
825
//bool OscIF::oscInitGui()
826
bool OscIF::oscInitGui(const QString& typ, const QString& baseName, const QString& name,
827
const QString& label, const QString& filePath, const QString& dirPath)
829
// Are we already running? We don't want to allow another process do we...
830
if((_oscGuiQProc != 0) && (_oscGuiQProc->isRunning()))
835
fprintf(stderr, "OscIF::oscInitGui no server url!\n");
842
//static char oscUrl[1024];
856
//snprintf(oscUrl, 1024, "%s/%s", url, synti->name().toAscii().data());
857
//snprintf(oscUrl, 1024, "%s/%s", url, synti->name().ascii());
858
//snprintf(oscUrl, 1024, "%s/%s/%s", url, synth->info.baseName().ascii(), synti->name().ascii());
859
typ = QT_TR_NOOP("dssi_synth");
860
baseName = _oscSynthIF->dssiSynth()->baseName(false);
861
label = _oscSynthIF->dssiSynthI()->name();
862
name = _oscSynthIF->dssiSynth()->name();
864
dirPath = _oscSynthIF->dssiSynth()->dirPath(false);
865
filePath = _oscSynthIF->dssiSynth()->filePath();
871
typ = QT_TR_NOOP("ladspa_efx");
872
baseName = _oscPluginI->plugin()->lib(false);
873
//name = _oscPluginI->name();
874
name = _oscPluginI->plugin()->label();
875
label = _oscPluginI->label();
877
dirPath = _oscPluginI->plugin()->dirPath(false);
878
//dirPath.replace("ladspa", "dssi", true);
880
filePath = _oscPluginI->plugin()->filePath();
881
//filePath.replace("ladspa", "dssi", true);
887
//snprintf(oscUrl, 1024, "%s/%s/%s", url, baseName.ascii(), name.ascii());
888
//snprintf(oscUrl, 1024, "%s%s/%s/%s", url, typ.latin1(), baseName.latin1(), name.latin1());
889
//oscUrl = QString("%1%2/%3/%4").arg(QString(QT_TR_NOOP(url))).arg(typ).arg(baseName).arg(name);
890
oscUrl = QString("%1%2/%3/%4").arg(QString(QT_TR_NOOP(url))).arg(typ).arg(baseName).arg(label);
892
//QString guiPath(info.path() + "/" + info.baseName());
893
//QString guiPath(synth->info.dirPath() + "/" + synth->info.baseName());
894
QString guiPath(dirPath + "/" + baseName);
897
fprintf(stderr, "OscIF::oscInitGui guiPath:%s\n", guiPath.latin1());
900
QDir guiDir(guiPath, "*", QDir::Unsorted, QDir::Files);
903
//const QFileInfoList list = guiDir.entryInfoList();
904
QStringList list = guiDir.entryList();
906
//for (int i = 0; i < list.size(); ++i) {
907
for (unsigned int i = 0; i < list.count(); ++i)
910
//QFileInfo fi = list.at(i);
911
QFileInfo fi(guiPath + QString("/") + list[i]);
913
QString gui(fi.filePath());
914
if (gui.contains('_') == 0)
918
//if (stat(gui.toAscii().data(), &buf)) {
919
if (stat(gui.latin1(), &buf)) {
921
perror("stat failed");
926
fprintf(stderr, "OscIF::oscInitGui %s %s %s %s\n",
927
//fi.filePath().toAscii().data(),
928
//fi.fileName().toAscii().data(),
929
fi.filePath().latin1(),
930
//fi.fileName().ascii(),
934
//synth->info.filePath().ascii(),
937
//name().toAscii().data(),
938
//synth->name().ascii());
942
if ((S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode)) &&
943
(buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
946
// fork + execlp were causing the processes to remain after closing gui, requiring manual kill.
947
// Changed to QProcess, works OK now.
948
//if((guiPid = fork()) == 0)
950
// No QProcess created yet? Do it now. Only once per SynthIF instance. Exists until parent destroyed.
951
if(_oscGuiQProc == 0)
952
_oscGuiQProc = new QProcess(muse);
954
// Don't forget this, he he...
955
_oscGuiQProc->clearArguments();
957
_oscGuiQProc->addArgument(fi.filePath());
958
//_oscGuiQProc->addArgument(fi.fileName()); // No conventional 'Arg0' here.
959
//_oscGuiQProc->addArgument(QString(oscUrl));
960
_oscGuiQProc->addArgument(oscUrl);
961
//_oscGuiQProc->addArgument(synth->info.filePath());
962
_oscGuiQProc->addArgument(filePath);
963
//_oscGuiQProc->addArgument(synth->name());
964
_oscGuiQProc->addArgument(name);
965
_oscGuiQProc->addArgument(QString("channel-1"));
968
fprintf(stderr, "OscIF::oscInitGui starting QProcess\n");
971
if(_oscGuiQProc->start() == TRUE)
974
fprintf(stderr, "OscIF::oscInitGui started QProcess\n");
977
//guiPid = _oscGuiQProc->processIdentifier();
984
//fi.filePath().toAscii().data(),
985
//fi.fileName().toAscii().data(),
986
fi.filePath().ascii(),
987
fi.fileName().ascii(),
991
//info.filePath().toAscii().data(),
992
//name().toAscii().data(),
993
synth->info.filePath().ascii(),
994
synth->name().ascii(),
996
"channel 1", (void*)0);
999
fprintf(stderr, "exec %s %s %s %s failed: %s\n",
1000
//fi.filePath().toAscii().data(),
1001
//fi.fileName().toAscii().data(),
1002
fi.filePath().latin1(),
1003
fi.fileName().latin1(),
1007
//name().toAscii().data(),
1008
//synth->name().ascii(),
1013
// It's Ok, Keep going. So nothing happens. So what. The timeout in showGui will just leave.
1014
// Maybe it's a 'busy' issue somewhere - allow to try again later + save work now.
1020
fprintf(stderr, "OscIF::oscInitGui after QProcess\n");
1025
//synth->_hasGui = true;
1028
printf("OscIF::oscInitGui %s: no dir for gui found: %s\n",
1029
//name().toAscii().data(), guiPath.toAscii().data());
1030
//synth->name().ascii(), guiPath.ascii());
1031
name.latin1(), guiPath.latin1());
1033
//synth->_hasGui = false;
1040
//---------------------------------------------------------
1042
//---------------------------------------------------------
1044
void OscIF::oscShowGui(bool v)
1047
printf("OscIF::oscShowGui(): v:%d visible:%d\n", v, oscGuiVisible());
1050
if (v == oscGuiVisible())
1054
if((_oscGuiQProc == 0) || (!_oscGuiQProc->isRunning()))
1056
// We need an indicator that update was called - update must have been called to get new path etc...
1057
// If the process is not running this path is invalid, right?
1063
printf("OscIF::oscShowGui(): No QProcess or process not running. Starting gui...\n");
1068
printf("OscIF::oscShowGui(): failed to initialize gui on oscInitGui()\n");
1073
//for (int i = 0; i < 5; ++i) {
1074
for (int i = 0; i < 10; ++i) { // Give it a wee bit more time?
1079
if (_uiOscPath == 0) {
1080
printf("OscIF::oscShowGui(): no _uiOscPath. Error: Timeout - synth gui did not start within 10 seconds.\n");
1084
char uiOscGuiPath[strlen(_uiOscPath)+6];
1085
sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, v ? "show" : "hide");
1088
printf("OscIF::oscShowGui(): Sending show/hide uiOscGuiPath:%s\n", uiOscGuiPath);
1091
lo_send(_uiOscTarget, uiOscGuiPath, "");
1095
//---------------------------------------------------------
1097
//---------------------------------------------------------
1099
bool OscIF::oscGuiVisible() const
1101
return _oscGuiVisible;
1106
//---------------------------------------------------------
1109
//---------------------------------------------------------
1111
//void OscIF::oscSetSynthIF(DssiSynthIF* s)
1112
void OscDssiIF::oscSetSynthIF(DssiSynthIF* s)
1115
if(_oscControlFifos)
1116
delete[] _oscControlFifos;
1117
_oscControlFifos = 0;
1119
if(_oscSynthIF && _oscSynthIF->dssiSynth())
1121
unsigned long ports = _oscSynthIF->dssiSynth()->inControls();
1122
_oscControlFifos = new OscControlFifo[ports];
1126
//---------------------------------------------------------
1128
//---------------------------------------------------------
1130
int OscDssiIF::oscUpdate(lo_arg **argv)
1132
// Make sure to call base method.
1133
OscIF::oscUpdate(argv);
1135
// Send sample rate. No, done in base class.
1136
//lo_send(_uiOscTarget, _uiOscSampleRatePath, "i", sampleRate);
1138
// Send project directory. No, done in DssiSynthIF.
1139
//lo_send(_uiOscTarget, _uiOscConfigurePath, "ss",
1140
// DSSI_PROJECT_DIRECTORY_KEY, museProject.latin1()); // song->projectPath()
1143
_oscSynthIF->oscUpdate();
1148
// Send current string configuration parameters.
1149
StringParamMap& map = _oscSynthIF->dssiSynthI()->stringParameters();
1151
for(ciStringParamMap r = map.begin(); r != map.end(); ++r)
1153
lo_send(_uiOscTarget, _uiOscConfigurePath, "ss", r->first.c_str(), r->second.c_str());
1154
// Avoid overloading the GUI if there are lots and lots of params.
1160
// Send current bank and program.
1161
unsigned long bank, prog;
1162
_oscSynthIF->dssiSynthI()->currentProg(&prog, &bank, 0);
1163
lo_send(_uiOscTarget, _uiOscProgramPath, "ii", bank, prog);
1165
// Send current control values.
1166
unsigned long ports = _oscSynthIF->dssiSynth()->inControls();
1167
for(unsigned long i = 0; i < ports; ++i)
1169
unsigned long k = _oscSynthIF->dssiSynth()->inControlPortIdx(i);
1170
lo_send(_uiOscTarget, _uiOscControlPath, "if", k, _oscSynthIF->getParameter(i));
1171
// Avoid overloading the GUI if there are lots and lots of ports.
1179
char uiOscGuiPath[strlen(_uiOscPath)+6];
1180
sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, "show");
1183
printf("OscIF::oscUpdate Sending show uiOscGuiPath:%s\n", uiOscGuiPath);
1186
lo_send(_uiOscTarget, uiOscGuiPath, "");
1188
sprintf(uiOscGuiPath, "%s/%s", _uiOscPath, "hide");
1191
printf("OscIF::oscUpdate Sending hide uiOscGuiPath:%s\n", uiOscGuiPath);
1194
lo_send(_uiOscTarget, uiOscGuiPath, "");
1198
/* Send current bank/program (-FIX- another race...) */
1199
if (instance->pendingProgramChange < 0) {
1200
unsigned long bank = instance->currentBank;
1201
unsigned long program = instance->currentProgram;
1202
instance->uiNeedsProgramUpdate = 0;
1203
if (instance->uiTarget) {
1204
lo_send(instance->uiTarget, instance->ui_osc_program_path, "ii", bank, program);
1208
/* Send control ports */
1209
for (i = 0; i < instance->plugin->controlIns; i++) {
1210
int in = i + instance->firstControlIn;
1211
int port = pluginControlInPortNumbers[in];
1212
lo_send(instance->uiTarget, instance->ui_osc_control_path, "if", port,
1213
pluginControlIns[in]);
1214
/* Avoid overloading the GUI if there are lots and lots of ports */
1215
if ((i+1) % 50 == 0)
1223
//---------------------------------------------------------
1225
//---------------------------------------------------------
1227
int OscDssiIF::oscConfigure(lo_arg** argv)
1229
//OscIF::oscConfigure(argv);
1232
_oscSynthIF->oscConfigure((const char*)&argv[0]->s, (const char*)&argv[1]->s);
1236
//---------------------------------------------------------
1238
//---------------------------------------------------------
1240
int OscDssiIF::oscMidi(lo_arg** argv)
1242
//OscIF::oscMidi(argv);
1245
_oscSynthIF->oscMidi(argv[0]->m[1], argv[0]->m[2], argv[0]->m[3]);
1250
//---------------------------------------------------------
1252
//---------------------------------------------------------
1254
int OscDssiIF::oscProgram(lo_arg** argv)
1256
//OscIF::oscProgram(argv);
1259
_oscSynthIF->oscProgram(argv[1]->i, argv[0]->i);
1264
//---------------------------------------------------------
1266
//---------------------------------------------------------
1268
int OscDssiIF::oscControl(lo_arg** argv)
1270
//OscIF::oscControl(argv);
1272
int port = argv[0]->i;
1277
_oscSynthIF->oscControl(argv[0]->i, argv[1]->f);
1282
//---------------------------------------------------------
1284
//---------------------------------------------------------
1285
bool OscDssiIF::oscInitGui()
1290
return OscIF::oscInitGui(QT_TR_NOOP("dssi_synth"), _oscSynthIF->dssiSynth()->baseName(false),
1291
_oscSynthIF->dssiSynth()->name(), _oscSynthIF->dssiSynthI()->name(),
1292
_oscSynthIF->dssiSynth()->filePath(), _oscSynthIF->dssiSynth()->dirPath(false));
1295
#endif // DSSI_SUPPORT
1298
//---------------------------------------------------------
1301
//---------------------------------------------------------
1303
void OscEffectIF::oscSetPluginI(PluginI* s)
1306
if(_oscControlFifos)
1307
delete[] _oscControlFifos;
1308
_oscControlFifos = 0;
1310
if(_oscPluginI && _oscPluginI->plugin())
1312
unsigned long ports = _oscPluginI->plugin()->controlInPorts();
1313
_oscControlFifos = new OscControlFifo[ports];
1317
//---------------------------------------------------------
1319
//---------------------------------------------------------
1321
int OscEffectIF::oscUpdate(lo_arg** argv)
1323
// Make sure to call base method.
1324
OscIF::oscUpdate(argv);
1326
// Send project directory. No, done in PluginI.
1327
//lo_send(_uiOscTarget, _uiOscConfigurePath, "ss",
1328
// DSSI_PROJECT_DIRECTORY_KEY, museProject.latin1()); // song->projectPath()
1331
_oscPluginI->oscUpdate();
1336
//---------------------------------------------------------
1338
//---------------------------------------------------------
1340
int OscEffectIF::oscConfigure(lo_arg** argv)
1342
//OscIF::oscConfigure(argv);
1345
_oscPluginI->oscConfigure((const char*)&argv[0]->s, (const char*)&argv[1]->s);
1350
//---------------------------------------------------------
1352
//---------------------------------------------------------
1354
int OscEffectIF::oscControl(lo_arg** argv)
1356
//OscIF::oscControl(argv);
1358
int port = argv[0]->i;
1363
_oscPluginI->oscControl(argv[0]->i, argv[1]->f);
1368
//---------------------------------------------------------
1370
//---------------------------------------------------------
1371
bool OscEffectIF::oscInitGui()
1376
return OscIF::oscInitGui(QT_TR_NOOP("ladspa_efx"), _oscPluginI->plugin()->lib(false),
1377
_oscPluginI->plugin()->label(), _oscPluginI->label(),
1378
_oscPluginI->plugin()->filePath(), _oscPluginI->plugin()->dirPath(false));