| @@ -6,8 +6,8 @@ | |||||
| <rect> | <rect> | ||||
| <x>0</x> | <x>0</x> | ||||
| <y>0</y> | <y>0</y> | ||||
| <width>653</width> | |||||
| <height>125</height> | |||||
| <width>626</width> | |||||
| <height>274</height> | |||||
| </rect> | </rect> | ||||
| </property> | </property> | ||||
| <property name="windowTitle"> | <property name="windowTitle"> | ||||
| @@ -90,50 +90,249 @@ | |||||
| </layout> | </layout> | ||||
| </item> | </item> | ||||
| <item> | <item> | ||||
| <layout class="QHBoxLayout" name="horizontalLayout_2"> | |||||
| <item> | |||||
| <widget class="QLabel" name="label"> | |||||
| <property name="minimumSize"> | |||||
| <size> | |||||
| <width>100</width> | |||||
| <height>0</height> | |||||
| </size> | |||||
| </property> | |||||
| <property name="text"> | |||||
| <string>Command:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item> | |||||
| <widget class="QLineEdit" name="le_command"/> | |||||
| </item> | |||||
| </layout> | |||||
| <widget class="QGroupBox" name="group_command"> | |||||
| <property name="title"> | |||||
| <string>Command</string> | |||||
| </property> | |||||
| <layout class="QGridLayout" name="gridLayout"> | |||||
| <item row="1" column="0"> | |||||
| <widget class="QLabel" name="label"> | |||||
| <property name="text"> | |||||
| <string>Command:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="1" column="1" colspan="3"> | |||||
| <widget class="QLineEdit" name="le_command"/> | |||||
| </item> | |||||
| <item row="2" column="0"> | |||||
| <widget class="QLabel" name="label_6"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="text"> | |||||
| <string>Save trigger:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="2" column="1"> | |||||
| <widget class="QComboBox" name="cb_save_trigger"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <item> | |||||
| <property name="text"> | |||||
| <string>None / Manual</string> | |||||
| </property> | |||||
| </item> | |||||
| <item> | |||||
| <property name="text"> | |||||
| <string>SIGUSR1</string> | |||||
| </property> | |||||
| </item> | |||||
| <item> | |||||
| <property name="text"> | |||||
| <string>NSM</string> | |||||
| </property> | |||||
| </item> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="2" column="3"> | |||||
| <spacer name="horizontalSpacer_3"> | |||||
| <property name="orientation"> | |||||
| <enum>Qt::Horizontal</enum> | |||||
| </property> | |||||
| <property name="sizeHint" stdset="0"> | |||||
| <size> | |||||
| <width>274</width> | |||||
| <height>1</height> | |||||
| </size> | |||||
| </property> | |||||
| </spacer> | |||||
| </item> | |||||
| <item row="2" column="2"> | |||||
| <widget class="QLabel" name="label_9"> | |||||
| <property name="text"> | |||||
| <string>(Not Implemented Yet)</string> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="0" column="0"> | |||||
| <widget class="QLabel" name="label_10"> | |||||
| <property name="text"> | |||||
| <string>Name:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="0" column="1" colspan="3"> | |||||
| <widget class="QLineEdit" name="le_name"/> | |||||
| </item> | |||||
| </layout> | |||||
| </widget> | |||||
| </item> | </item> | ||||
| <item> | <item> | ||||
| <layout class="QHBoxLayout" name="horizontalLayout_3"> | |||||
| <item> | |||||
| <widget class="QLabel" name="label_2"> | |||||
| <property name="minimumSize"> | |||||
| <size> | |||||
| <width>100</width> | |||||
| <height>0</height> | |||||
| </size> | |||||
| </property> | |||||
| <property name="text"> | |||||
| <string>Flags:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item> | |||||
| <widget class="QLineEdit" name="le_flags"/> | |||||
| </item> | |||||
| </layout> | |||||
| <widget class="QGroupBox" name="group_setup"> | |||||
| <property name="title"> | |||||
| <string>Setup</string> | |||||
| </property> | |||||
| <layout class="QGridLayout" name="gridLayout_2"> | |||||
| <item row="0" column="0"> | |||||
| <widget class="QLabel" name="label_3"> | |||||
| <property name="text"> | |||||
| <string>Audio inputs:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="0" column="1"> | |||||
| <widget class="QSpinBox" name="sb_audio_ins"> | |||||
| <property name="maximum"> | |||||
| <number>64</number> | |||||
| </property> | |||||
| <property name="value"> | |||||
| <number>2</number> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="0" column="2" rowspan="2"> | |||||
| <widget class="Line" name="line"> | |||||
| <property name="orientation"> | |||||
| <enum>Qt::Vertical</enum> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="0" column="3"> | |||||
| <widget class="QLabel" name="label_5"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="text"> | |||||
| <string>CV inputs:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="0" column="4"> | |||||
| <widget class="QSpinBox" name="sb_cv_ins"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="maximum"> | |||||
| <number>64</number> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="0" column="5" rowspan="2"> | |||||
| <widget class="Line" name="line_2"> | |||||
| <property name="orientation"> | |||||
| <enum>Qt::Vertical</enum> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="0" column="6"> | |||||
| <widget class="QLabel" name="label_7"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="text"> | |||||
| <string>MIDI inputs:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="0" column="7"> | |||||
| <widget class="QSpinBox" name="sb_midi_ins"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="maximum"> | |||||
| <number>16</number> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="1" column="0"> | |||||
| <widget class="QLabel" name="label_4"> | |||||
| <property name="text"> | |||||
| <string>Audio outputs:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="1" column="1"> | |||||
| <widget class="QSpinBox" name="sb_audio_outs"> | |||||
| <property name="maximum"> | |||||
| <number>64</number> | |||||
| </property> | |||||
| <property name="value"> | |||||
| <number>2</number> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="1" column="3"> | |||||
| <widget class="QLabel" name="label_2"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="text"> | |||||
| <string>CV outputs:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="1" column="4"> | |||||
| <widget class="QSpinBox" name="sb_cv_outs"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="maximum"> | |||||
| <number>64</number> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="1" column="6"> | |||||
| <widget class="QLabel" name="label_8"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="text"> | |||||
| <string>MIDI outputs:</string> | |||||
| </property> | |||||
| <property name="alignment"> | |||||
| <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| <item row="1" column="7"> | |||||
| <widget class="QSpinBox" name="sb_midi_outs"> | |||||
| <property name="enabled"> | |||||
| <bool>false</bool> | |||||
| </property> | |||||
| <property name="maximum"> | |||||
| <number>16</number> | |||||
| </property> | |||||
| </widget> | |||||
| </item> | |||||
| </layout> | |||||
| </widget> | |||||
| </item> | </item> | ||||
| <item> | <item> | ||||
| <widget class="QDialogButtonBox" name="buttonBox"> | <widget class="QDialogButtonBox" name="buttonBox"> | ||||
| @@ -62,14 +62,17 @@ public: | |||||
| kEngine(engine), | kEngine(engine), | ||||
| kPlugin(plugin), | kPlugin(plugin), | ||||
| fShmIds(), | fShmIds(), | ||||
| fNumPorts(), | |||||
| fProcess() {} | fProcess() {} | ||||
| void setData(const char* const shmIds) noexcept | |||||
| void setData(const char* const shmIds, const char* const numPorts) noexcept | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',); | CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && shmIds[0] != '\0',); | ||||
| CARLA_SAFE_ASSERT_RETURN(numPorts != nullptr && numPorts[0] != '\0',); | |||||
| CARLA_SAFE_ASSERT(! isThreadRunning()); | CARLA_SAFE_ASSERT(! isThreadRunning()); | ||||
| fShmIds = shmIds; | |||||
| fShmIds = shmIds; | |||||
| fNumPorts = numPorts; | |||||
| } | } | ||||
| uintptr_t getProcessID() const noexcept | uintptr_t getProcessID() const noexcept | ||||
| @@ -122,7 +125,8 @@ protected: | |||||
| const ScopedEnvVar sev2("LD_LIBRARY_PATH", libjackdir.buffer()); | const ScopedEnvVar sev2("LD_LIBRARY_PATH", libjackdir.buffer()); | ||||
| carla_setenv("CARLA_FRONTEND_WIN_ID", strBuf); | carla_setenv("CARLA_FRONTEND_WIN_ID", strBuf); | ||||
| carla_setenv("CARLA_SHM_IDS", fShmIds.toRawUTF8()); | |||||
| carla_setenv("CARLA_SHM_IDS", fShmIds.buffer()); | |||||
| carla_setenv("CARLA_NUM_PORTS", fNumPorts.buffer()); | |||||
| started = fProcess->start(arguments); | started = fProcess->start(arguments); | ||||
| } | } | ||||
| @@ -177,7 +181,8 @@ private: | |||||
| CarlaEngine* const kEngine; | CarlaEngine* const kEngine; | ||||
| CarlaPlugin* const kPlugin; | CarlaPlugin* const kPlugin; | ||||
| String fShmIds; | |||||
| CarlaString fShmIds; | |||||
| CarlaString fNumPorts; | |||||
| ScopedPointer<ChildProcess> fProcess; | ScopedPointer<ChildProcess> fProcess; | ||||
| @@ -197,7 +202,7 @@ public: | |||||
| fTimedError(false), | fTimedError(false), | ||||
| fProcCanceled(false), | fProcCanceled(false), | ||||
| fProcWaitTime(0), | fProcWaitTime(0), | ||||
| fLastPongTime(-1), | |||||
| fLastPingTime(-1), | |||||
| fBridgeThread(engine, this), | fBridgeThread(engine, this), | ||||
| fShmAudioPool(), | fShmAudioPool(), | ||||
| fShmRtClientControl(), | fShmRtClientControl(), | ||||
| @@ -293,7 +298,7 @@ public: | |||||
| void getLabel(char* const strBuf) const noexcept override | void getLabel(char* const strBuf) const noexcept override | ||||
| { | { | ||||
| std::strncpy(strBuf, fInfo.label, STR_MAX); | |||||
| std::strncpy(strBuf, fInfo.setupLabel, STR_MAX); | |||||
| } | } | ||||
| void getMaker(char* const strBuf) const noexcept override | void getMaker(char* const strBuf) const noexcept override | ||||
| @@ -308,7 +313,8 @@ public: | |||||
| void getRealName(char* const strBuf) const noexcept override | void getRealName(char* const strBuf) const noexcept override | ||||
| { | { | ||||
| std::strncpy(strBuf, fInfo.name, STR_MAX); | |||||
| // FIXME | |||||
| std::strncpy(strBuf, "Carla's libjack", STR_MAX); | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -369,6 +375,14 @@ public: | |||||
| try { | try { | ||||
| handleNonRtData(); | handleNonRtData(); | ||||
| } CARLA_SAFE_EXCEPTION("handleNonRtData"); | } CARLA_SAFE_EXCEPTION("handleNonRtData"); | ||||
| if (fLastPingTime > 0 && Time::currentTimeMillis() > fLastPingTime + 30000) | |||||
| { | |||||
| carla_stderr("Did not receive ping message from server for 30 secs, closing..."); | |||||
| // TODO | |||||
| //threadShouldExit(); | |||||
| //callback(ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0f, nullptr); | |||||
| } | |||||
| } | } | ||||
| else if (fInitiated) | else if (fInitiated) | ||||
| { | { | ||||
| @@ -447,17 +461,15 @@ public: | |||||
| portName += ":"; | portName += ":"; | ||||
| } | } | ||||
| if (fInfo.aInNames != nullptr && fInfo.aInNames[j] != nullptr) | |||||
| if (fInfo.aIns > 1) | |||||
| { | { | ||||
| portName += fInfo.aInNames[j]; | |||||
| } | |||||
| else if (fInfo.aIns > 1) | |||||
| { | |||||
| portName += "input_"; | |||||
| portName += "audio_in_"; | |||||
| portName += CarlaString(j+1); | portName += CarlaString(j+1); | ||||
| } | } | ||||
| else | else | ||||
| portName += "input"; | |||||
| { | |||||
| portName += "audio_in"; | |||||
| } | |||||
| portName.truncate(portNameSize); | portName.truncate(portNameSize); | ||||
| @@ -476,17 +488,15 @@ public: | |||||
| portName += ":"; | portName += ":"; | ||||
| } | } | ||||
| if (fInfo.aOutNames != nullptr && fInfo.aOutNames[j] != nullptr) | |||||
| if (fInfo.aOuts > 1) | |||||
| { | { | ||||
| portName += fInfo.aOutNames[j]; | |||||
| } | |||||
| else if (fInfo.aOuts > 1) | |||||
| { | |||||
| portName += "output_"; | |||||
| portName += "audio_out_"; | |||||
| portName += CarlaString(j+1); | portName += CarlaString(j+1); | ||||
| } | } | ||||
| else | else | ||||
| portName += "output"; | |||||
| { | |||||
| portName += "audio_out"; | |||||
| } | |||||
| portName.truncate(portNameSize); | portName.truncate(portNameSize); | ||||
| @@ -1097,238 +1107,35 @@ public: | |||||
| carla_debug("CarlaPluginJack::handleNonRtData() - got opcode: %s", PluginBridgeNonRtServerOpcode2str(opcode)); | carla_debug("CarlaPluginJack::handleNonRtData() - got opcode: %s", PluginBridgeNonRtServerOpcode2str(opcode)); | ||||
| } | } | ||||
| //#endif | //#endif | ||||
| if (opcode != kPluginBridgeNonRtServerNull && fLastPongTime > 0) | |||||
| fLastPongTime = Time::currentTimeMillis(); | |||||
| if (opcode != kPluginBridgeNonRtServerNull && fLastPingTime > 0) | |||||
| fLastPingTime = Time::currentTimeMillis(); | |||||
| switch (opcode) | switch (opcode) | ||||
| { | { | ||||
| case kPluginBridgeNonRtServerNull: | case kPluginBridgeNonRtServerNull: | ||||
| case kPluginBridgeNonRtServerPong: | case kPluginBridgeNonRtServerPong: | ||||
| break; | |||||
| case kPluginBridgeNonRtServerPluginInfo1: | case kPluginBridgeNonRtServerPluginInfo1: | ||||
| // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readLong(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerPluginInfo2: { | |||||
| // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright) | |||||
| // realName | |||||
| const uint32_t realNameSize(fShmNonRtServerControl.readUInt()); | |||||
| char realName[realNameSize+1]; | |||||
| carla_zeroChars(realName, realNameSize+1); | |||||
| fShmNonRtServerControl.readCustomData(realName, realNameSize); | |||||
| // label | |||||
| const uint32_t labelSize(fShmNonRtServerControl.readUInt()); | |||||
| char label[labelSize+1]; | |||||
| carla_zeroChars(label, labelSize+1); | |||||
| fShmNonRtServerControl.readCustomData(label, labelSize); | |||||
| // maker | |||||
| const uint32_t makerSize(fShmNonRtServerControl.readUInt()); | |||||
| char maker[makerSize+1]; | |||||
| carla_zeroChars(maker, makerSize+1); | |||||
| fShmNonRtServerControl.readCustomData(maker, makerSize); | |||||
| // copyright | |||||
| const uint32_t copyrightSize(fShmNonRtServerControl.readUInt()); | |||||
| char copyright[copyrightSize+1]; | |||||
| carla_zeroChars(copyright, copyrightSize+1); | |||||
| fShmNonRtServerControl.readCustomData(copyright, copyrightSize); | |||||
| fInfo.name = realName; | |||||
| fInfo.label = label; | |||||
| if (pData->name == nullptr) | |||||
| pData->name = pData->engine->getUniquePluginName(realName); | |||||
| } break; | |||||
| case kPluginBridgeNonRtServerPluginInfo2: | |||||
| case kPluginBridgeNonRtServerAudioCount: | case kPluginBridgeNonRtServerAudioCount: | ||||
| // uint/ins, uint/outs | |||||
| fInfo.aIns = fShmNonRtServerControl.readUInt(); | |||||
| fInfo.aOuts = fShmNonRtServerControl.readUInt(); | |||||
| CARLA_SAFE_ASSERT(fInfo.aInNames == nullptr); | |||||
| CARLA_SAFE_ASSERT(fInfo.aOutNames == nullptr); | |||||
| if (fInfo.aIns > 0) | |||||
| { | |||||
| fInfo.aInNames = new const char*[fInfo.aIns]; | |||||
| carla_zeroPointers(fInfo.aInNames, fInfo.aIns); | |||||
| } | |||||
| if (fInfo.aOuts > 0) | |||||
| { | |||||
| fInfo.aOutNames = new const char*[fInfo.aOuts]; | |||||
| carla_zeroPointers(fInfo.aOutNames, fInfo.aOuts); | |||||
| } | |||||
| break; | |||||
| case kPluginBridgeNonRtServerMidiCount: | case kPluginBridgeNonRtServerMidiCount: | ||||
| // uint/ins, uint/outs | |||||
| fInfo.mIns = fShmNonRtServerControl.readUInt(); | |||||
| fInfo.mOuts = fShmNonRtServerControl.readUInt(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerCvCount: | case kPluginBridgeNonRtServerCvCount: | ||||
| // uint/ins, uint/outs | |||||
| fInfo.cvIns = fShmNonRtServerControl.readUInt(); | |||||
| fInfo.cvOuts = fShmNonRtServerControl.readUInt(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerParameterCount: | case kPluginBridgeNonRtServerParameterCount: | ||||
| // uint/count | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerProgramCount: | case kPluginBridgeNonRtServerProgramCount: | ||||
| // uint/count | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerMidiProgramCount: | case kPluginBridgeNonRtServerMidiProgramCount: | ||||
| // uint/count | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerPortName: { | |||||
| // byte/type, uint/index, uint/size, str[] (name) | |||||
| const uint8_t portType = fShmNonRtServerControl.readByte(); | |||||
| const uint32_t index = fShmNonRtServerControl.readUInt(); | |||||
| // name | |||||
| const uint32_t nameSize(fShmNonRtServerControl.readUInt()); | |||||
| char* const name = new char[nameSize+1]; | |||||
| carla_zeroChars(name, nameSize+1); | |||||
| fShmNonRtServerControl.readCustomData(name, nameSize); | |||||
| CARLA_SAFE_ASSERT_BREAK(portType > kPluginBridgePortNull && portType < kPluginBridgePortTypeCount); | |||||
| switch (portType) | |||||
| { | |||||
| case kPluginBridgePortAudioInput: | |||||
| CARLA_SAFE_ASSERT_BREAK(index < fInfo.aIns); | |||||
| fInfo.aInNames[index] = name; | |||||
| break; | |||||
| case kPluginBridgePortAudioOutput: | |||||
| CARLA_SAFE_ASSERT_BREAK(index < fInfo.aOuts); | |||||
| fInfo.aOutNames[index] = name; | |||||
| break; | |||||
| } | |||||
| } break; | |||||
| case kPluginBridgeNonRtServerPortName: | |||||
| case kPluginBridgeNonRtServerParameterData1: | case kPluginBridgeNonRtServerParameterData1: | ||||
| // uint/index, int/rindex, uint/type, uint/hints, int/cc | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readInt(); | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readShort(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerParameterData2: | case kPluginBridgeNonRtServerParameterData2: | ||||
| // uint/index, uint/size, str[] (name), uint/size, str[] (unit) | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| if (const uint32_t size = fShmNonRtServerControl.readUInt()) | |||||
| { | |||||
| char name[size]; | |||||
| fShmNonRtServerControl.readCustomData(name, size); | |||||
| } | |||||
| if (const uint32_t size = fShmNonRtServerControl.readUInt()) | |||||
| { | |||||
| char symbol[size]; | |||||
| fShmNonRtServerControl.readCustomData(symbol, size); | |||||
| } | |||||
| if (const uint32_t size = fShmNonRtServerControl.readUInt()) | |||||
| { | |||||
| char unit[size]; | |||||
| fShmNonRtServerControl.readCustomData(unit, size); | |||||
| } | |||||
| break; | |||||
| case kPluginBridgeNonRtServerParameterRanges: | case kPluginBridgeNonRtServerParameterRanges: | ||||
| // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readFloat(); | |||||
| fShmNonRtServerControl.readFloat(); | |||||
| fShmNonRtServerControl.readFloat(); | |||||
| fShmNonRtServerControl.readFloat(); | |||||
| fShmNonRtServerControl.readFloat(); | |||||
| fShmNonRtServerControl.readFloat(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerParameterValue: | case kPluginBridgeNonRtServerParameterValue: | ||||
| // uint/index, float/value | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readFloat(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerParameterValue2: | case kPluginBridgeNonRtServerParameterValue2: | ||||
| // uint/index, float/value | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readFloat(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerDefaultValue: | case kPluginBridgeNonRtServerDefaultValue: | ||||
| // uint/index, float/value | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readFloat(); | |||||
| break; | |||||
| case kPluginBridgeNonRtServerCurrentProgram: | case kPluginBridgeNonRtServerCurrentProgram: | ||||
| // int/index | |||||
| fShmNonRtServerControl.readInt(); | |||||
| case kPluginBridgeNonRtServerCurrentMidiProgram: | |||||
| case kPluginBridgeNonRtServerProgramName: | |||||
| case kPluginBridgeNonRtServerMidiProgramData: | |||||
| case kPluginBridgeNonRtServerSetCustomData: | |||||
| break; | break; | ||||
| case kPluginBridgeNonRtServerCurrentMidiProgram: { | |||||
| // int/index | |||||
| fShmNonRtServerControl.readInt(); | |||||
| } break; | |||||
| case kPluginBridgeNonRtServerProgramName: { | |||||
| // uint/index, uint/size, str[] (name) | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| const uint32_t nameSize(fShmNonRtServerControl.readUInt()); | |||||
| char name[nameSize]; | |||||
| fShmNonRtServerControl.readCustomData(name, nameSize); | |||||
| } break; | |||||
| case kPluginBridgeNonRtServerMidiProgramData: { | |||||
| // uint/index, uint/bank, uint/program, uint/size, str[] (name) | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| const uint32_t nameSize(fShmNonRtServerControl.readUInt()); | |||||
| char name[nameSize]; | |||||
| fShmNonRtServerControl.readCustomData(name, nameSize); | |||||
| } break; | |||||
| case kPluginBridgeNonRtServerSetCustomData: { | |||||
| // uint/size, str[], uint/size, str[], uint/size, str[] | |||||
| // type | |||||
| const uint32_t typeSize(fShmNonRtServerControl.readUInt()); | |||||
| char type[typeSize]; | |||||
| fShmNonRtServerControl.readCustomData(type, typeSize); | |||||
| // key | |||||
| const uint32_t keySize(fShmNonRtServerControl.readUInt()); | |||||
| char key[keySize]; | |||||
| fShmNonRtServerControl.readCustomData(key, keySize); | |||||
| // value | |||||
| const uint32_t valueSize(fShmNonRtServerControl.readUInt()); | |||||
| char value[valueSize]; | |||||
| fShmNonRtServerControl.readCustomData(value, valueSize); | |||||
| } break; | |||||
| case kPluginBridgeNonRtServerSetChunkDataFile: { | case kPluginBridgeNonRtServerSetChunkDataFile: { | ||||
| // uint/size, str[] (filename) | // uint/size, str[] (filename) | ||||
| const uint32_t chunkFilePathSize(fShmNonRtServerControl.readUInt()); | const uint32_t chunkFilePathSize(fShmNonRtServerControl.readUInt()); | ||||
| @@ -1337,8 +1144,6 @@ public: | |||||
| } break; | } break; | ||||
| case kPluginBridgeNonRtServerSetLatency: | case kPluginBridgeNonRtServerSetLatency: | ||||
| // uint | |||||
| fShmNonRtServerControl.readUInt(); | |||||
| break; | break; | ||||
| case kPluginBridgeNonRtServerReady: | case kPluginBridgeNonRtServerReady: | ||||
| @@ -1397,7 +1202,7 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| bool init(const char* const filename, const char* const name) | |||||
| bool init(const char* const filename, const char* const name, const char* const label) | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false); | ||||
| @@ -1410,16 +1215,52 @@ public: | |||||
| return false; | return false; | ||||
| } | } | ||||
| if (filename == nullptr || filename[0] == '\0') | |||||
| { | |||||
| pData->engine->setLastError("null filename"); | |||||
| return false; | |||||
| } | |||||
| if (label == nullptr || label[0] == '\0') | |||||
| { | |||||
| pData->engine->setLastError("null label"); | |||||
| return false; | |||||
| } | |||||
| // --------------------------------------------------------------- | |||||
| // check setup | |||||
| if (std::strlen(label) != 6) | |||||
| { | |||||
| pData->engine->setLastError("invalid application setup received"); | |||||
| return false; | |||||
| } | |||||
| for (int i=6; --i >= 0;) { | |||||
| CARLA_SAFE_ASSERT_RETURN(label[i] >= '0' && label[i] < '0'+64, false); | |||||
| } | |||||
| fInfo.aIns = label[0] - '0'; | |||||
| fInfo.aOuts = label[1] - '0'; | |||||
| fInfo.cvIns = label[2] - '0'; | |||||
| fInfo.cvOuts = label[3] - '0'; | |||||
| fInfo.mIns = label[4] - '0'; | |||||
| fInfo.mOuts = label[5] - '0'; | |||||
| fInfo.setupLabel = label; | |||||
| // TODO | |||||
| fInfo.cvIns = fInfo.cvOuts = fInfo.mIns = fInfo.mOuts = 0; | |||||
| // --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
| // set info | // set info | ||||
| pData->filename = carla_strdup(filename); | |||||
| if (name != nullptr && name[0] != '\0') | if (name != nullptr && name[0] != '\0') | ||||
| pData->name = pData->engine->getUniquePluginName(name); | pData->name = pData->engine->getUniquePluginName(name); | ||||
| if (filename != nullptr && filename[0] != '\0') | |||||
| pData->filename = carla_strdup(filename); | |||||
| else | else | ||||
| pData->filename = carla_strdup(""); | |||||
| pData->name = pData->engine->getUniquePluginName("Jack Application"); | |||||
| std::srand(static_cast<uint>(std::time(nullptr))); | std::srand(static_cast<uint>(std::time(nullptr))); | ||||
| @@ -1457,8 +1298,8 @@ public: | |||||
| } | } | ||||
| // --------------------------------------------------------------- | // --------------------------------------------------------------- | ||||
| // init bridge thread | // init bridge thread | ||||
| { | { | ||||
| char shmIdsStr[6*4+1]; | char shmIdsStr[6*4+1]; | ||||
| carla_zeroChars(shmIdsStr, 6*4+1); | carla_zeroChars(shmIdsStr, 6*4+1); | ||||
| @@ -1468,7 +1309,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); | |||||
| fBridgeThread.setData(shmIdsStr, label); | |||||
| } | } | ||||
| if (! restartBridgeThread()) | if (! restartBridgeThread()) | ||||
| @@ -1499,7 +1340,7 @@ private: | |||||
| bool fProcCanceled; | bool fProcCanceled; | ||||
| uint fProcWaitTime; | uint fProcWaitTime; | ||||
| int64_t fLastPongTime; | |||||
| int64_t fLastPingTime; | |||||
| CarlaPluginJackThread fBridgeThread; | CarlaPluginJackThread fBridgeThread; | ||||
| @@ -1514,10 +1355,7 @@ private: | |||||
| uint32_t mIns, mOuts; | uint32_t mIns, mOuts; | ||||
| PluginCategory category; | PluginCategory category; | ||||
| uint optionsAvailable; | uint optionsAvailable; | ||||
| CarlaString name; | |||||
| CarlaString label; | |||||
| const char** aInNames; | |||||
| const char** aOutNames; | |||||
| CarlaString setupLabel; | |||||
| std::vector<uint8_t> chunk; | std::vector<uint8_t> chunk; | ||||
| Info() | Info() | ||||
| @@ -1529,10 +1367,7 @@ private: | |||||
| mOuts(0), | mOuts(0), | ||||
| category(PLUGIN_CATEGORY_NONE), | category(PLUGIN_CATEGORY_NONE), | ||||
| optionsAvailable(0), | optionsAvailable(0), | ||||
| name(), | |||||
| label(), | |||||
| aInNames(nullptr), | |||||
| aOutNames(nullptr), | |||||
| setupLabel(), | |||||
| chunk() {} | chunk() {} | ||||
| CARLA_DECLARE_NON_COPY_STRUCT(Info) | CARLA_DECLARE_NON_COPY_STRUCT(Info) | ||||
| @@ -1567,13 +1402,6 @@ private: | |||||
| fInitError = false; | fInitError = false; | ||||
| fTimedError = false; | fTimedError = false; | ||||
| // cleanup of previous data | |||||
| delete[] fInfo.aInNames; | |||||
| fInfo.aInNames = nullptr; | |||||
| delete[] fInfo.aOutNames; | |||||
| fInfo.aOutNames = nullptr; | |||||
| // reset memory | // reset memory | ||||
| fProcCanceled = false; | fProcCanceled = false; | ||||
| fShmRtClientControl.data->procFlags = 0; | fShmRtClientControl.data->procFlags = 0; | ||||
| @@ -1613,8 +1441,8 @@ private: | |||||
| fBridgeThread.startThread(); | fBridgeThread.startThread(); | ||||
| fLastPongTime = Time::currentTimeMillis(); | |||||
| CARLA_SAFE_ASSERT(fLastPongTime > 0); | |||||
| fLastPingTime = Time::currentTimeMillis(); | |||||
| CARLA_SAFE_ASSERT(fLastPingTime > 0); | |||||
| static bool sFirstInit = true; | static bool sFirstInit = true; | ||||
| @@ -1626,7 +1454,7 @@ private: | |||||
| const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin; | const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin; | ||||
| for (; Time::currentTimeMillis() < fLastPongTime + timeoutEnd && fBridgeThread.isThreadRunning();) | |||||
| for (; Time::currentTimeMillis() < fLastPingTime + timeoutEnd && fBridgeThread.isThreadRunning();) | |||||
| { | { | ||||
| pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | ||||
| @@ -1643,7 +1471,7 @@ private: | |||||
| carla_msleep(20); | carla_msleep(20); | ||||
| } | } | ||||
| fLastPongTime = -1; | |||||
| fLastPingTime = -1; | |||||
| if (fInitError || ! fInitiated) | if (fInitError || ! fInitiated) | ||||
| { | { | ||||
| @@ -1677,7 +1505,7 @@ CarlaPlugin* CarlaPlugin::newJackApp(const Initializer& init) | |||||
| #ifdef CARLA_OS_LINUX | #ifdef CARLA_OS_LINUX | ||||
| 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)) | |||||
| if (! plugin->init(init.filename, init.name, init.label)) | |||||
| { | { | ||||
| delete plugin; | delete plugin; | ||||
| return nullptr; | return nullptr; | ||||
| @@ -1896,7 +1896,18 @@ class JackApplicationW(QDialog): | |||||
| self.host = host | self.host = host | ||||
| def getCommandAndFlags(self): | def getCommandAndFlags(self): | ||||
| return (self.ui.le_command.text(), self.ui.le_flags.text()) | |||||
| name = self.ui.le_name.text() | |||||
| command = self.ui.le_command.text() | |||||
| if not name: | |||||
| name = command.split(" ",1)[0] | |||||
| baseIntVal = ord('0') | |||||
| labelSetup = "%s%s%s%s%s%s" % (chr(baseIntVal+self.ui.sb_audio_ins.value()), | |||||
| chr(baseIntVal+self.ui.sb_audio_outs.value()), | |||||
| chr(baseIntVal+self.ui.sb_cv_ins.value()), | |||||
| chr(baseIntVal+self.ui.sb_cv_outs.value()), | |||||
| chr(baseIntVal+self.ui.sb_midi_ins.value()), | |||||
| chr(baseIntVal+self.ui.sb_midi_outs.value())) | |||||
| return (command, name, labelSetup) | |||||
| # -------------------------------------------------------------------------------------------------------- | # -------------------------------------------------------------------------------------------------------- | ||||
| @@ -962,9 +962,14 @@ class HostWindow(QMainWindow): | |||||
| if data is None: | if data is None: | ||||
| return | return | ||||
| filename, label = data | |||||
| filename, name, label = data | |||||
| if not self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, filename, None, label, 0, None, 0x0): | |||||
| if not filename: | |||||
| CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Cannot add jack application"), | |||||
| self.tr("command is empty"), QMessageBox.Ok, QMessageBox.Ok) | |||||
| return | |||||
| if not self.host.add_plugin(BINARY_NATIVE, PLUGIN_JACK, filename, name, label, 0, None, 0x0): | |||||
| CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), | CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), | ||||
| self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) | self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) | ||||
| @@ -39,15 +39,20 @@ public: | |||||
| fServer(), | fServer(), | ||||
| fIsValid(false), | fIsValid(false), | ||||
| fIsOffline(false), | fIsOffline(false), | ||||
| fLastPingTime(-1), | |||||
| fAudioIns(0), | |||||
| fAudioOuts(0) | |||||
| fLastPingTime(-1) | |||||
| { | { | ||||
| carla_debug("CarlaJackAppClient::CarlaJackAppClient()"); | carla_debug("CarlaJackAppClient::CarlaJackAppClient()"); | ||||
| const char* const shmIds(std::getenv("CARLA_SHM_IDS")); | const char* const shmIds(std::getenv("CARLA_SHM_IDS")); | ||||
| CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && std::strlen(shmIds) == 6*4,); | CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr && std::strlen(shmIds) == 6*4,); | ||||
| const char* const numPortsStr(std::getenv("CARLA_NUM_PORTS")); | |||||
| CARLA_SAFE_ASSERT_RETURN(numPortsStr != nullptr && std::strlen(numPortsStr) == 3*2,); | |||||
| for (int i=6; --i >= 0;) { | |||||
| CARLA_SAFE_ASSERT_RETURN(numPortsStr[i] >= '0' && numPortsStr[i] < '0'+64,); | |||||
| } | |||||
| std::memcpy(fBaseNameAudioPool, shmIds+6*0, 6); | std::memcpy(fBaseNameAudioPool, shmIds+6*0, 6); | ||||
| std::memcpy(fBaseNameRtClientControl, shmIds+6*1, 6); | std::memcpy(fBaseNameRtClientControl, shmIds+6*1, 6); | ||||
| std::memcpy(fBaseNameNonRtClientControl, shmIds+6*2, 6); | std::memcpy(fBaseNameNonRtClientControl, shmIds+6*2, 6); | ||||
| @@ -58,6 +63,13 @@ public: | |||||
| fBaseNameNonRtClientControl[6] = '\0'; | fBaseNameNonRtClientControl[6] = '\0'; | ||||
| fBaseNameNonRtServerControl[6] = '\0'; | fBaseNameNonRtServerControl[6] = '\0'; | ||||
| fNumPorts.audioIns = numPortsStr[0] - '0'; | |||||
| fNumPorts.audioOuts = numPortsStr[1] - '0'; | |||||
| fNumPorts.cvIns = numPortsStr[2] - '0'; | |||||
| fNumPorts.cvOuts = numPortsStr[3] - '0'; | |||||
| fNumPorts.midiIns = numPortsStr[4] - '0'; | |||||
| fNumPorts.midiOuts = numPortsStr[5] - '0'; | |||||
| startThread(10); | startThread(10); | ||||
| } | } | ||||
| @@ -65,7 +77,6 @@ public: | |||||
| { | { | ||||
| carla_debug("CarlaJackAppClient::~CarlaJackAppClient()"); | carla_debug("CarlaJackAppClient::~CarlaJackAppClient()"); | ||||
| carla_debug("CarlaEnginePlugin::close()"); | |||||
| fLastPingTime = -1; | fLastPingTime = -1; | ||||
| stopThread(5000); | stopThread(5000); | ||||
| @@ -84,12 +95,6 @@ public: | |||||
| fClients.clear(); | fClients.clear(); | ||||
| } | } | ||||
| void clear() noexcept; | |||||
| bool isValid() const noexcept; | |||||
| void activate(); | |||||
| void handleNonRtData(); | |||||
| JackClientState* addClient(const char* const name) | JackClientState* addClient(const char* const name) | ||||
| { | { | ||||
| JackClientState* const jclient(new JackClientState(fServer, name)); | JackClientState* const jclient(new JackClientState(fServer, name)); | ||||
| @@ -110,6 +115,11 @@ public: | |||||
| return true; | return true; | ||||
| } | } | ||||
| void clear() noexcept; | |||||
| bool isValid() const noexcept; | |||||
| void handleNonRtData(); | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| protected: | protected: | ||||
| @@ -130,8 +140,22 @@ private: | |||||
| bool fIsOffline; | bool fIsOffline; | ||||
| int64_t fLastPingTime; | int64_t fLastPingTime; | ||||
| uint32_t fAudioIns; | |||||
| uint32_t fAudioOuts; | |||||
| struct NumPorts { | |||||
| uint32_t audioIns; | |||||
| uint32_t audioOuts; | |||||
| uint32_t cvIns; | |||||
| uint32_t cvOuts; | |||||
| uint32_t midiIns; | |||||
| uint32_t midiOuts; | |||||
| NumPorts() | |||||
| : audioIns(0), | |||||
| audioOuts(0), | |||||
| cvIns(0), | |||||
| cvOuts(0), | |||||
| midiIns(0), | |||||
| midiOuts(0) {} | |||||
| } fNumPorts; | |||||
| CarlaMutex fRealtimeThreadMutex; | CarlaMutex fRealtimeThreadMutex; | ||||
| @@ -153,140 +177,6 @@ bool CarlaJackAppClient::isValid() const noexcept | |||||
| return fIsValid; | return fIsValid; | ||||
| } | } | ||||
| void CarlaJackAppClient::activate() | |||||
| { | |||||
| const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); | |||||
| { | |||||
| fLastPingTime = Time::currentTimeMillis(); | |||||
| CARLA_SAFE_ASSERT(fLastPingTime > 0); | |||||
| char bufStr[STR_MAX+1]; | |||||
| uint32_t bufStrSize; | |||||
| // kPluginBridgeNonRtServerPluginInfo1 | |||||
| { | |||||
| // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPluginInfo1); | |||||
| fShmNonRtServerControl.writeUInt(PLUGIN_CATEGORY_NONE); | |||||
| fShmNonRtServerControl.writeUInt(0x0); | |||||
| fShmNonRtServerControl.writeUInt(0x0); | |||||
| fShmNonRtServerControl.writeUInt(0x0); | |||||
| fShmNonRtServerControl.writeLong(0); | |||||
| fShmNonRtServerControl.commitWrite(); | |||||
| } | |||||
| // kPluginBridgeNonRtServerPluginInfo2 | |||||
| { | |||||
| // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright) | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPluginInfo2); | |||||
| carla_zeroChars(bufStr, STR_MAX); | |||||
| std::strncpy(bufStr, "Jack App", 64); | |||||
| bufStrSize = carla_fixedValue(1U, 64U, static_cast<uint32_t>(std::strlen(bufStr))); | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); | |||||
| carla_zeroChars(bufStr, STR_MAX); | |||||
| bufStrSize = 1; | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); | |||||
| fShmNonRtServerControl.commitWrite(); | |||||
| } | |||||
| // kPluginBridgeNonRtServerAudioCount | |||||
| { | |||||
| const uint32_t aIns = 2; //fClient.audioIns.count(); | |||||
| const uint32_t aOuts = 2; //fClient.audioOuts.count(); | |||||
| // uint/ins, uint/outs | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerAudioCount); | |||||
| fShmNonRtServerControl.writeUInt(aIns); | |||||
| fShmNonRtServerControl.writeUInt(aOuts); | |||||
| fShmNonRtServerControl.commitWrite(); | |||||
| // kPluginBridgeNonRtServerPortName | |||||
| for (uint32_t i=0; i<aIns; ++i) | |||||
| { | |||||
| //const JackPortState* const jport(fClient.audioIns.getAt(i, nullptr)); | |||||
| //CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr); | |||||
| //const char* const portName(jport->name); | |||||
| //CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr && portName[0] != '\0'); | |||||
| std::snprintf(bufStr, 64, "in_%i", i+1); | |||||
| // byte/type, uint/index, uint/size, str[] (name) | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPortName); | |||||
| fShmNonRtServerControl.writeByte(kPluginBridgePortAudioInput); | |||||
| fShmNonRtServerControl.writeUInt(i); | |||||
| bufStrSize = static_cast<uint32_t>(std::strlen(bufStr)); | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); | |||||
| } | |||||
| // kPluginBridgeNonRtServerPortName | |||||
| for (uint32_t i=0; i<aOuts; ++i) | |||||
| { | |||||
| //const JackPortState* const jport(fClient.audioOuts.getAt(i, nullptr)); | |||||
| //CARLA_SAFE_ASSERT_CONTINUE(jport != nullptr); | |||||
| //const char* const portName(jport->name); | |||||
| //CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr && portName[0] != '\0'); | |||||
| std::snprintf(bufStr, 64, "out_%i", i+1); | |||||
| // byte/type, uint/index, uint/size, str[] (name) | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPortName); | |||||
| fShmNonRtServerControl.writeByte(kPluginBridgePortAudioOutput); | |||||
| fShmNonRtServerControl.writeUInt(i); | |||||
| bufStrSize = static_cast<uint32_t>(std::strlen(bufStr)); | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); | |||||
| } | |||||
| } | |||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | |||||
| // kPluginBridgeNonRtServerMidiCount | |||||
| { | |||||
| const uint32_t mIns = 0; // fClient.midiIns.count(); | |||||
| const uint32_t mOuts = 0; // fClient.midiOuts.count(); | |||||
| // uint/ins, uint/outs | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerMidiCount); | |||||
| fShmNonRtServerControl.writeUInt(mIns); | |||||
| fShmNonRtServerControl.writeUInt(mOuts); | |||||
| fShmNonRtServerControl.commitWrite(); | |||||
| } | |||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | |||||
| // ready! | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerReady); | |||||
| fShmNonRtServerControl.commitWrite(); | |||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | |||||
| // must be static | |||||
| fAudioIns = 2; //fClient.audioIns.count(); | |||||
| fAudioOuts = 2; //fClient.audioOuts.count(); | |||||
| carla_stdout("Carla Jack Client Ready!"); | |||||
| fLastPingTime = Time::currentTimeMillis(); | |||||
| } | |||||
| } | |||||
| void CarlaJackAppClient::handleNonRtData() | void CarlaJackAppClient::handleNonRtData() | ||||
| { | { | ||||
| for (; fShmNonRtClientControl.isDataAvailableForReading();) | for (; fShmNonRtClientControl.isDataAvailableForReading();) | ||||
| @@ -485,13 +375,18 @@ void CarlaJackAppClient::run() | |||||
| { | { | ||||
| const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); | const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); | ||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPong); | |||||
| fLastPingTime = Time::currentTimeMillis(); | |||||
| CARLA_SAFE_ASSERT(fLastPingTime > 0); | |||||
| // ready! | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerReady); | |||||
| fShmNonRtServerControl.commitWrite(); | fShmNonRtServerControl.commitWrite(); | ||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | |||||
| } | } | ||||
| fIsValid = true; | fIsValid = true; | ||||
| activate(); | |||||
| fLastPingTime = Time::currentTimeMillis(); | |||||
| carla_stdout("Carla Jack Client Ready!"); | |||||
| #ifdef __SSE2_MATH__ | #ifdef __SSE2_MATH__ | ||||
| // Set FTZ and DAZ flags | // Set FTZ and DAZ flags | ||||
| @@ -591,11 +486,11 @@ void CarlaJackAppClient::run() | |||||
| if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated) | if (cmtl2.wasNotLocked() || jclient->processCb == nullptr || ! jclient->activated) | ||||
| { | { | ||||
| if (fAudioIns > 0) | |||||
| fdata += fServer.bufferSize*fAudioIns; | |||||
| if (fNumPorts.audioIns > 0) | |||||
| fdata += fServer.bufferSize*fNumPorts.audioIns; | |||||
| if (fAudioOuts > 0) | |||||
| carla_zeroFloats(fdata, fServer.bufferSize*fAudioOuts); | |||||
| if (fNumPorts.audioOuts > 0) | |||||
| carla_zeroFloats(fdata, fServer.bufferSize*fNumPorts.audioOuts); | |||||
| if (jclient->deactivated) | if (jclient->deactivated) | ||||
| { | { | ||||
| @@ -609,23 +504,23 @@ void CarlaJackAppClient::run() | |||||
| i = 0; | i = 0; | ||||
| for (LinkedList<JackPortState*>::Itenerator it = jclient->audioIns.begin2(); it.valid(); it.next()) | for (LinkedList<JackPortState*>::Itenerator it = jclient->audioIns.begin2(); it.valid(); it.next()) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_BREAK(i++ < fAudioIns); | |||||
| CARLA_SAFE_ASSERT_BREAK(i++ < fNumPorts.audioIns); | |||||
| if (JackPortState* const jport = it.getValue(nullptr)) | if (JackPortState* const jport = it.getValue(nullptr)) | ||||
| jport->buffer = fdata; | jport->buffer = fdata; | ||||
| fdata += fServer.bufferSize; | fdata += fServer.bufferSize; | ||||
| } | } | ||||
| for (; i++ < fAudioIns;) | |||||
| for (; i++ < fNumPorts.audioIns;) | |||||
| fdata += fServer.bufferSize; | fdata += fServer.bufferSize; | ||||
| i = 0; | i = 0; | ||||
| for (LinkedList<JackPortState*>::Itenerator it = jclient->audioOuts.begin2(); it.valid(); it.next()) | for (LinkedList<JackPortState*>::Itenerator it = jclient->audioOuts.begin2(); it.valid(); it.next()) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_BREAK(i++ < fAudioOuts); | |||||
| CARLA_SAFE_ASSERT_BREAK(i++ < fNumPorts.audioOuts); | |||||
| if (JackPortState* const jport = it.getValue(nullptr)) | if (JackPortState* const jport = it.getValue(nullptr)) | ||||
| jport->buffer = fdata; | jport->buffer = fdata; | ||||
| fdata += fServer.bufferSize; | fdata += fServer.bufferSize; | ||||
| } | } | ||||
| for (; i++ < fAudioOuts;) | |||||
| for (; i++ < fNumPorts.audioOuts;) | |||||
| { | { | ||||
| carla_zeroFloats(fdata, fServer.bufferSize); | carla_zeroFloats(fdata, fServer.bufferSize); | ||||
| fdata += fServer.bufferSize; | fdata += fServer.bufferSize; | ||||
| @@ -637,11 +532,11 @@ void CarlaJackAppClient::run() | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| if (fAudioIns > 0) | |||||
| fdata += fServer.bufferSize*fAudioIns; | |||||
| if (fNumPorts.audioIns > 0) | |||||
| fdata += fServer.bufferSize*fNumPorts.audioIns; | |||||
| if (fAudioOuts > 0) | |||||
| carla_zeroFloats(fdata, fServer.bufferSize*fAudioOuts); | |||||
| if (fNumPorts.audioOuts > 0) | |||||
| carla_zeroFloats(fdata, fServer.bufferSize*fNumPorts.audioOuts); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| @@ -301,7 +301,7 @@ bool CarlaStateSave::fillFromXmlElement(const XmlElement* const xmlElement) | |||||
| type = xmlSafeStringCharDup(text, false); | type = xmlSafeStringCharDup(text, false); | ||||
| else if (tag.equalsIgnoreCase("name")) | else if (tag.equalsIgnoreCase("name")) | ||||
| name = xmlSafeStringCharDup(text, false); | name = xmlSafeStringCharDup(text, false); | ||||
| else if (tag.equalsIgnoreCase("label") || tag.equalsIgnoreCase("identifier") || tag.equalsIgnoreCase("uri")) | |||||
| else if (tag.equalsIgnoreCase("label") || tag.equalsIgnoreCase("identifier") || tag.equalsIgnoreCase("uri") || tag.equalsIgnoreCase("setup")) | |||||
| label = xmlSafeStringCharDup(text, false); | label = xmlSafeStringCharDup(text, false); | ||||
| else if (tag.equalsIgnoreCase("binary") || tag.equalsIgnoreCase("bundle") || tag.equalsIgnoreCase("filename")) | else if (tag.equalsIgnoreCase("binary") || tag.equalsIgnoreCase("bundle") || tag.equalsIgnoreCase("filename")) | ||||
| binary = xmlSafeStringCharDup(text, false); | binary = xmlSafeStringCharDup(text, false); | ||||
| @@ -539,6 +539,7 @@ void CarlaStateSave::dumpToMemoryStream(MemoryOutputStream& content) const | |||||
| break; | break; | ||||
| case PLUGIN_JACK: | case PLUGIN_JACK: | ||||
| infoXml << " <Filename>" << xmlSafeString(binary, true) << "</Filename>\n"; | infoXml << " <Filename>" << xmlSafeString(binary, true) << "</Filename>\n"; | ||||
| infoXml << " <Setup>" << xmlSafeString(label, true) << "</Setup>\n"; | |||||
| break; | break; | ||||
| } | } | ||||