@@ -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" | ||||