| @@ -193,7 +193,7 @@ | |||||
| <x>0</x> | <x>0</x> | ||||
| <y>0</y> | <y>0</y> | ||||
| <width>1058</width> | <width>1058</width> | ||||
| <height>37</height> | |||||
| <height>20</height> | |||||
| </rect> | </rect> | ||||
| </property> | </property> | ||||
| <widget class="QMenu" name="menu_File"> | <widget class="QMenu" name="menu_File"> | ||||
| @@ -285,12 +285,23 @@ | |||||
| <addaction name="act_help_about_juce"/> | <addaction name="act_help_about_juce"/> | ||||
| <addaction name="act_help_about_qt"/> | <addaction name="act_help_about_qt"/> | ||||
| </widget> | </widget> | ||||
| <widget class="QMenu" name="menu_Secrets"> | |||||
| <property name="title"> | |||||
| <string>Secrets</string> | |||||
| </property> | |||||
| <addaction name="act_secret_1"/> | |||||
| <addaction name="act_secret_2"/> | |||||
| <addaction name="act_secret_3"/> | |||||
| <addaction name="act_secret_4"/> | |||||
| <addaction name="act_secret_5"/> | |||||
| </widget> | |||||
| <addaction name="menu_File"/> | <addaction name="menu_File"/> | ||||
| <addaction name="menu_Engine"/> | <addaction name="menu_Engine"/> | ||||
| <addaction name="menu_Plugin"/> | <addaction name="menu_Plugin"/> | ||||
| <addaction name="menu_Canvas"/> | <addaction name="menu_Canvas"/> | ||||
| <addaction name="menu_Settings"/> | <addaction name="menu_Settings"/> | ||||
| <addaction name="menu_Help"/> | <addaction name="menu_Help"/> | ||||
| <addaction name="menu_Secrets"/> | |||||
| </widget> | </widget> | ||||
| <widget class="QToolBar" name="toolBar"> | <widget class="QToolBar" name="toolBar"> | ||||
| <property name="windowTitle"> | <property name="windowTitle"> | ||||
| @@ -1101,6 +1112,31 @@ | |||||
| <string>Expand Slots</string> | <string>Expand Slots</string> | ||||
| </property> | </property> | ||||
| </action> | </action> | ||||
| <action name="act_secret_1"> | |||||
| <property name="text"> | |||||
| <string>Perform secret 1</string> | |||||
| </property> | |||||
| </action> | |||||
| <action name="act_secret_2"> | |||||
| <property name="text"> | |||||
| <string>Perform secret 2</string> | |||||
| </property> | |||||
| </action> | |||||
| <action name="act_secret_3"> | |||||
| <property name="text"> | |||||
| <string>Perform secret 3</string> | |||||
| </property> | |||||
| </action> | |||||
| <action name="act_secret_4"> | |||||
| <property name="text"> | |||||
| <string>Perform secret 4</string> | |||||
| </property> | |||||
| </action> | |||||
| <action name="act_secret_5"> | |||||
| <property name="text"> | |||||
| <string>Perform secret 5</string> | |||||
| </property> | |||||
| </action> | |||||
| </widget> | </widget> | ||||
| <customwidgets> | <customwidgets> | ||||
| <customwidget> | <customwidget> | ||||
| @@ -58,16 +58,14 @@ public: | |||||
| kEngine(engine), | kEngine(engine), | ||||
| kPlugin(plugin), | kPlugin(plugin), | ||||
| fShmIds(), | fShmIds(), | ||||
| fExtraArgs(), | |||||
| fProcess() {} | fProcess() {} | ||||
| void setData(const char* const shmIds, const char* const args) noexcept | |||||
| void setData(const char* const shmIds) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',); | CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',); | ||||
| CARLA_SAFE_ASSERT(! isThreadRunning()); | CARLA_SAFE_ASSERT(! isThreadRunning()); | ||||
| fShmIds = shmIds; | fShmIds = shmIds; | ||||
| fExtraArgs = args; | |||||
| } | } | ||||
| uintptr_t getProcessID() const noexcept | uintptr_t getProcessID() const noexcept | ||||
| @@ -100,8 +98,7 @@ protected: | |||||
| StringArray arguments; | StringArray arguments; | ||||
| // binary | // binary | ||||
| arguments.add(filename); | |||||
| arguments.addTokens(fExtraArgs, true); | |||||
| arguments.addTokens(filename, true); | |||||
| bool started; | bool started; | ||||
| @@ -181,7 +178,6 @@ private: | |||||
| CarlaPlugin* const kPlugin; | CarlaPlugin* const kPlugin; | ||||
| String fShmIds; | String fShmIds; | ||||
| String fExtraArgs; | |||||
| ScopedPointer<ChildProcess> fProcess; | ScopedPointer<ChildProcess> fProcess; | ||||
| @@ -1371,7 +1367,7 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| bool init(const char* const filename, const char* const name, const char* const args) | |||||
| bool init(const char* const filename, const char* const name) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false); | ||||
| @@ -1460,7 +1456,7 @@ public: | |||||
| std::strncpy(shmIdsStr+6*2, &fShmNonRtClientControl.filename[fShmNonRtClientControl.filename.length()-6], 6); | std::strncpy(shmIdsStr+6*2, &fShmNonRtClientControl.filename[fShmNonRtClientControl.filename.length()-6], 6); | ||||
| std::strncpy(shmIdsStr+6*3, &fShmNonRtServerControl.filename[fShmNonRtServerControl.filename.length()-6], 6); | std::strncpy(shmIdsStr+6*3, &fShmNonRtServerControl.filename[fShmNonRtServerControl.filename.length()-6], 6); | ||||
| fBridgeThread.setData(shmIdsStr, args); | |||||
| fBridgeThread.setData(shmIdsStr); | |||||
| fBridgeThread.startThread(); | fBridgeThread.startThread(); | ||||
| } | } | ||||
| @@ -1608,7 +1604,7 @@ CarlaPlugin* CarlaPlugin::newJackApp(const Initializer& init) | |||||
| CarlaPluginJack* const plugin(new CarlaPluginJack(init.engine, init.id)); | CarlaPluginJack* const plugin(new CarlaPluginJack(init.engine, init.id)); | ||||
| if (! plugin->init(init.filename, init.name, init.label)) | |||||
| if (! plugin->init(init.filename, init.name)) | |||||
| { | { | ||||
| delete plugin; | delete plugin; | ||||
| return nullptr; | return nullptr; | ||||
| @@ -27,11 +27,11 @@ from carla_config import * | |||||
| if config_UseQt5: | if config_UseQt5: | ||||
| from PyQt5.QtCore import qCritical, QFileInfo, QModelIndex, QPointF, QTimer | from PyQt5.QtCore import qCritical, QFileInfo, QModelIndex, QPointF, QTimer | ||||
| from PyQt5.QtGui import QImage, QPalette | from PyQt5.QtGui import QImage, QPalette | ||||
| from PyQt5.QtWidgets import QAction, QApplication, QFileSystemModel, QListWidgetItem, QMainWindow | |||||
| from PyQt5.QtWidgets import QAction, QApplication, QInputDialog, QFileSystemModel, QListWidgetItem, QMainWindow | |||||
| else: | else: | ||||
| from PyQt4.QtCore import qCritical, QFileInfo, QModelIndex, QPointF, QTimer | from PyQt4.QtCore import qCritical, QFileInfo, QModelIndex, QPointF, QTimer | ||||
| from PyQt4.QtGui import QImage, QPalette | from PyQt4.QtGui import QImage, QPalette | ||||
| from PyQt4.QtGui import QAction, QApplication, QFileSystemModel, QListWidgetItem, QMainWindow | |||||
| from PyQt4.QtGui import QAction, QApplication, QInputDialog, QFileSystemModel, QListWidgetItem, QMainWindow | |||||
| # ------------------------------------------------------------------------------------------------------------ | # ------------------------------------------------------------------------------------------------------------ | ||||
| # Imports (Custom) | # Imports (Custom) | ||||
| @@ -346,7 +346,13 @@ class HostWindow(QMainWindow): | |||||
| self.ui.act_help_about_juce.setMenuRole(QAction.ApplicationSpecificRole) | self.ui.act_help_about_juce.setMenuRole(QAction.ApplicationSpecificRole) | ||||
| self.ui.act_help_about_qt.setMenuRole(QAction.AboutQtRole) | self.ui.act_help_about_qt.setMenuRole(QAction.AboutQtRole) | ||||
| self.ui.menu_Settings.setTitle("Panels") | self.ui.menu_Settings.setTitle("Panels") | ||||
| self.ui.menu_Help.hide() | |||||
| self.ui.menu_Help.menuAction().setVisible(False) | |||||
| # ---------------------------------------------------------------------------------------------------- | |||||
| # Set up GUI (secrets when running local) | |||||
| if CWD != "/Shared/Personal/FOSS/GIT/falkTX/Carla/source": | |||||
| self.ui.menu_Secrets.menuAction().setVisible(False) | |||||
| # ---------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------- | ||||
| # Load Settings | # Load Settings | ||||
| @@ -414,6 +420,12 @@ class HostWindow(QMainWindow): | |||||
| self.ui.act_help_about_juce.triggered.connect(self.slot_aboutJuce) | self.ui.act_help_about_juce.triggered.connect(self.slot_aboutJuce) | ||||
| self.ui.act_help_about_qt.triggered.connect(self.slot_aboutQt) | self.ui.act_help_about_qt.triggered.connect(self.slot_aboutQt) | ||||
| self.ui.act_secret_1.triggered.connect(self.slot_runSecret1) | |||||
| self.ui.act_secret_2.triggered.connect(self.slot_runSecret2) | |||||
| self.ui.act_secret_3.triggered.connect(self.slot_runSecret3) | |||||
| self.ui.act_secret_4.triggered.connect(self.slot_runSecret4) | |||||
| self.ui.act_secret_5.triggered.connect(self.slot_runSecret5) | |||||
| self.ui.cb_disk.currentIndexChanged.connect(self.slot_diskFolderChanged) | self.ui.cb_disk.currentIndexChanged.connect(self.slot_diskFolderChanged) | ||||
| self.ui.b_disk_add.clicked.connect(self.slot_diskFolderAdd) | self.ui.b_disk_add.clicked.connect(self.slot_diskFolderAdd) | ||||
| self.ui.b_disk_remove.clicked.connect(self.slot_diskFolderRemove) | self.ui.b_disk_remove.clicked.connect(self.slot_diskFolderRemove) | ||||
| @@ -1497,6 +1509,43 @@ class HostWindow(QMainWindow): | |||||
| def slot_aboutQt(self): | def slot_aboutQt(self): | ||||
| QApplication.instance().aboutQt() | QApplication.instance().aboutQt() | ||||
| # -------------------------------------------------------------------------------------------------------- | |||||
| # Secret (menu actions) | |||||
| @pyqtSlot() | |||||
| def slot_runSecret1(self): | |||||
| print("secret 1") | |||||
| fname = "/usr/bin/audacious -p" | |||||
| self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, fname, "", "", 0, None, 0) | |||||
| @pyqtSlot() | |||||
| def slot_runSecret2(self): | |||||
| print("secret 2") | |||||
| fname = "/usr/bin/pulseaudio" | |||||
| fname += " --high-priority --realtime --exit-idle-time=-1 --file=/usr/share/cadence/pulse2jack/play+rec.pa -n" | |||||
| self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, fname, "", "", 0, None, 0) | |||||
| @pyqtSlot() | |||||
| def slot_runSecret3(self): | |||||
| print("secret 3") | |||||
| fname = "/usr/bin/lmms" | |||||
| self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, fname, "", "", 0, None, 0) | |||||
| @pyqtSlot() | |||||
| def slot_runSecret4(self): | |||||
| print("secret 4") | |||||
| ret = QInputDialog.getText(self, "Command", "command to run") | |||||
| if ret[1] and len(ret[0]) > 1: | |||||
| fname = ret[0] | |||||
| if not self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, fname, "", "", 0, None, 0): | |||||
| CustomMessageBox(self, QMessageBox.Critical, | |||||
| self.tr("Error"), self.tr("Failed to load plugin"), | |||||
| self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) | |||||
| @pyqtSlot() | |||||
| def slot_runSecret5(self): | |||||
| print("secret 5") | |||||
| # -------------------------------------------------------------------------------------------------------- | # -------------------------------------------------------------------------------------------------------- | ||||
| # Disk (menu actions) | # Disk (menu actions) | ||||
| @@ -52,6 +52,8 @@ def getPluginTypeAsString(ptype): | |||||
| return "SF2" | return "SF2" | ||||
| if ptype == PLUGIN_SFZ: | if ptype == PLUGIN_SFZ: | ||||
| return "SFZ" | return "SFZ" | ||||
| if ptype == PLUGIN_JACK: | |||||
| return "JACK" | |||||
| print("getPluginTypeAsString(%i) - invalid type" % ptype); | print("getPluginTypeAsString(%i) - invalid type" % ptype); | ||||
| return "Unknown" | return "Unknown" | ||||
| @@ -84,6 +86,8 @@ def getPluginTypeFromString(stype): | |||||
| return PLUGIN_SF2 | return PLUGIN_SF2 | ||||
| if stype == "sfz": | if stype == "sfz": | ||||
| return PLUGIN_SFZ | return PLUGIN_SFZ | ||||
| if stype == "jack": | |||||
| return PLUGIN_JACK | |||||
| print("getPluginTypeFromString(\"%s\") - invalid string type" % stype) | print("getPluginTypeFromString(\"%s\") - invalid string type" % stype) | ||||
| return PLUGIN_NONE | return PLUGIN_NONE | ||||
| @@ -490,6 +490,13 @@ public: | |||||
| // #ifdef DEBUG | // #ifdef DEBUG | ||||
| if (opcode != kPluginBridgeNonRtClientPing) | if (opcode != kPluginBridgeNonRtClientPing) | ||||
| { | { | ||||
| static int shownNull = 0; | |||||
| if (opcode == kPluginBridgeNonRtClientNull) | |||||
| { | |||||
| if (shownNull > 5) | |||||
| continue; | |||||
| ++shownNull; | |||||
| } | |||||
| carla_stdout("CarlaJackClient::handleNonRtData() - got opcode: %s", PluginBridgeNonRtClientOpcode2str(opcode)); | carla_stdout("CarlaJackClient::handleNonRtData() - got opcode: %s", PluginBridgeNonRtClientOpcode2str(opcode)); | ||||
| } | } | ||||
| // #endif | // #endif | ||||
| @@ -546,8 +553,15 @@ public: | |||||
| case kPluginBridgeNonRtClientSetMidiProgram: | case kPluginBridgeNonRtClientSetMidiProgram: | ||||
| case kPluginBridgeNonRtClientSetCustomData: | case kPluginBridgeNonRtClientSetCustomData: | ||||
| case kPluginBridgeNonRtClientSetChunkDataFile: | case kPluginBridgeNonRtClientSetChunkDataFile: | ||||
| case kPluginBridgeNonRtClientSetCtrlChannel: | |||||
| break; | |||||
| case kPluginBridgeNonRtClientSetOption: | case kPluginBridgeNonRtClientSetOption: | ||||
| fShmNonRtClientControl.readUInt(); | |||||
| fShmNonRtClientControl.readBool(); | |||||
| break; | |||||
| case kPluginBridgeNonRtClientSetCtrlChannel: | |||||
| fShmNonRtClientControl.readShort(); | |||||
| break; | break; | ||||
| case kPluginBridgeNonRtClientPrepareForSave: | case kPluginBridgeNonRtClientPrepareForSave: | ||||
| @@ -982,6 +996,15 @@ int jack_activate(jack_client_t* client) | |||||
| const JackClientState& jstate(jclient->fState); | const JackClientState& jstate(jclient->fState); | ||||
| CARLA_SAFE_ASSERT_RETURN(! jstate.activated, 1); | CARLA_SAFE_ASSERT_RETURN(! jstate.activated, 1); | ||||
| #if 0 | |||||
| // needed for pulseaudio | |||||
| static bool skipFirstActivate = true; | |||||
| if (skipFirstActivate) { | |||||
| skipFirstActivate = false; | |||||
| return 0; | |||||
| } | |||||
| #endif | |||||
| jclient->activate(); | jclient->activate(); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -1191,7 +1214,7 @@ int jack_transport_locate(jack_client_t*, jack_nframes_t) | |||||
| CARLA_EXPORT | CARLA_EXPORT | ||||
| jack_transport_state_t jack_transport_query(const jack_client_t* client, jack_position_t* pos) | jack_transport_state_t jack_transport_query(const jack_client_t* client, jack_position_t* pos) | ||||
| { | { | ||||
| carla_stdout("CarlaJackClient :: %s", __FUNCTION__); | |||||
| carla_debug("CarlaJackClient :: %s", __FUNCTION__); | |||||
| CarlaJackClient* const jclient = (CarlaJackClient*)client; | CarlaJackClient* const jclient = (CarlaJackClient*)client; | ||||
| CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, JackTransportStopped); | CARLA_SAFE_ASSERT_RETURN(jclient != nullptr, JackTransportStopped); | ||||
| @@ -1360,7 +1383,7 @@ const char** jack_get_ports(jack_client_t*, const char* a, const char* b, unsign | |||||
| static const char* playback_1 = "system:playback_1"; | static const char* playback_1 = "system:playback_1"; | ||||
| static const char* playback_2 = "system:playback_2"; | static const char* playback_2 = "system:playback_2"; | ||||
| if (flags == 0 || (flags & (JackPortIsInput|JackPortIsOutput)) != 0) | |||||
| if (flags == 0 || (flags & (JackPortIsInput|JackPortIsOutput)) == (JackPortIsInput|JackPortIsOutput)) | |||||
| { | { | ||||
| if (const char** const ret = (const char**)calloc(5, sizeof(const char*))) | if (const char** const ret = (const char**)calloc(5, sizeof(const char*))) | ||||
| { | { | ||||
| @@ -1482,6 +1505,25 @@ int jack_set_thread_init_callback(jack_client_t*, JackThreadInitCallback, void*) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| CARLA_EXPORT | |||||
| int jack_port_name_size(void) | |||||
| { | |||||
| return STR_MAX; | |||||
| } | |||||
| CARLA_EXPORT | |||||
| const char* JACK_METADATA_PRETTY_NAME; | |||||
| CARLA_EXPORT | |||||
| const char* JACK_METADATA_PRETTY_NAME = "http://jackaudio.org/metadata/pretty-name"; | |||||
| // jack_ringbuffer_create | |||||
| // jack_port_connected | |||||
| // jack_port_is_mine | |||||
| // jack_port_set_name | |||||
| // jack_port_get_all_connections | |||||
| // jack_port_uuid | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| #include "jackbridge/JackBridge2.cpp" | #include "jackbridge/JackBridge2.cpp" | ||||