| @@ -561,6 +561,7 @@ public: | |||||
| char bufStr[STR_MAX+1]; | char bufStr[STR_MAX+1]; | ||||
| uint32_t bufStrSize; | uint32_t bufStrSize; | ||||
| const CarlaEngineClient* const client(plugin->getEngineClient()); | |||||
| const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); | const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); | ||||
| // kPluginBridgeNonRtServerPluginInfo1 | // kPluginBridgeNonRtServerPluginInfo1 | ||||
| @@ -609,13 +610,50 @@ public: | |||||
| // kPluginBridgeNonRtServerAudioCount | // kPluginBridgeNonRtServerAudioCount | ||||
| { | { | ||||
| const uint32_t aIns = plugin->getAudioInCount(); | |||||
| const uint32_t aOuts = plugin->getAudioOutCount(); | |||||
| // uint/ins, uint/outs | // uint/ins, uint/outs | ||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerAudioCount); | fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerAudioCount); | ||||
| fShmNonRtServerControl.writeUInt(plugin->getAudioInCount()); | |||||
| fShmNonRtServerControl.writeUInt(plugin->getAudioOutCount()); | |||||
| fShmNonRtServerControl.writeUInt(aIns); | |||||
| fShmNonRtServerControl.writeUInt(aOuts); | |||||
| fShmNonRtServerControl.commitWrite(); | fShmNonRtServerControl.commitWrite(); | ||||
| // kPluginBridgeNonRtServerPortName | |||||
| for (uint32_t i=0; i<aIns; ++i) | |||||
| { | |||||
| const char* const portName(client->getAudioPortName(true, i)); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr && portName[0] != '\0'); | |||||
| // byte/type, uint/index, uint/size, str[] (name) | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPortName); | |||||
| fShmNonRtServerControl.writeByte(kPluginBridgePortAudioInput); | |||||
| fShmNonRtServerControl.writeUInt(i); | |||||
| bufStrSize = std::strlen(portName); | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(portName, bufStrSize); | |||||
| } | |||||
| // kPluginBridgeNonRtServerPortName | |||||
| for (uint32_t i=0; i<aOuts; ++i) | |||||
| { | |||||
| const char* const portName(client->getAudioPortName(false, i)); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr && portName[0] != '\0'); | |||||
| // byte/type, uint/index, uint/size, str[] (name) | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPortName); | |||||
| fShmNonRtServerControl.writeByte(kPluginBridgePortAudioOutput); | |||||
| fShmNonRtServerControl.writeUInt(i); | |||||
| bufStrSize = std::strlen(portName); | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(portName, bufStrSize); | |||||
| } | |||||
| } | } | ||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | |||||
| // kPluginBridgeNonRtServerMidiCount | // kPluginBridgeNonRtServerMidiCount | ||||
| { | { | ||||
| // uint/ins, uint/outs | // uint/ins, uint/outs | ||||
| @@ -627,6 +665,17 @@ public: | |||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | fShmNonRtServerControl.waitIfDataIsReachingLimit(); | ||||
| // kPluginBridgeNonRtServerCvCount | |||||
| { | |||||
| // uint/ins, uint/outs | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerCvCount); | |||||
| fShmNonRtServerControl.writeUInt(plugin->getCVInCount()); | |||||
| fShmNonRtServerControl.writeUInt(plugin->getCVOutCount()); | |||||
| fShmNonRtServerControl.commitWrite(); | |||||
| } | |||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | |||||
| // kPluginBridgeNonRtServerParameter* | // kPluginBridgeNonRtServerParameter* | ||||
| if (const uint32_t count = plugin->getParameterCount()) | if (const uint32_t count = plugin->getParameterCount()) | ||||
| { | { | ||||
| @@ -1256,7 +1256,11 @@ public: | |||||
| portName += ":"; | portName += ":"; | ||||
| } | } | ||||
| if (fInfo.aIns > 1) | |||||
| if (fInfo.aInNames != nullptr && fInfo.aInNames[j] != nullptr) | |||||
| { | |||||
| portName += fInfo.aInNames[j]; | |||||
| } | |||||
| else if (fInfo.aIns > 1) | |||||
| { | { | ||||
| portName += "input_"; | portName += "input_"; | ||||
| portName += CarlaString(j+1); | portName += CarlaString(j+1); | ||||
| @@ -1281,7 +1285,11 @@ public: | |||||
| portName += ":"; | portName += ":"; | ||||
| } | } | ||||
| if (fInfo.aOuts > 1) | |||||
| if (fInfo.aOutNames != nullptr && fInfo.aOutNames[j] != nullptr) | |||||
| { | |||||
| portName += fInfo.aOutNames[j]; | |||||
| } | |||||
| else if (fInfo.aOuts > 1) | |||||
| { | { | ||||
| portName += "output_"; | portName += "output_"; | ||||
| portName += CarlaString(j+1); | portName += CarlaString(j+1); | ||||
| @@ -1295,6 +1303,8 @@ public: | |||||
| pData->audioOut.ports[j].rindex = j; | pData->audioOut.ports[j].rindex = j; | ||||
| } | } | ||||
| // TODO - MIDI | |||||
| // TODO - CV | // TODO - CV | ||||
| if (needsCtrlIn) | if (needsCtrlIn) | ||||
| @@ -2049,6 +2059,22 @@ public: | |||||
| // uint/ins, uint/outs | // uint/ins, uint/outs | ||||
| fInfo.aIns = fShmNonRtServerControl.readUInt(); | fInfo.aIns = fShmNonRtServerControl.readUInt(); | ||||
| fInfo.aOuts = 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; | } break; | ||||
| case kPluginBridgeNonRtServerMidiCount: { | case kPluginBridgeNonRtServerMidiCount: { | ||||
| @@ -2057,6 +2083,12 @@ public: | |||||
| fInfo.mOuts = fShmNonRtServerControl.readUInt(); | fInfo.mOuts = fShmNonRtServerControl.readUInt(); | ||||
| } break; | } break; | ||||
| case kPluginBridgeNonRtServerCvCount: { | |||||
| // uint/ins, uint/outs | |||||
| fInfo.cvIns = fShmNonRtServerControl.readUInt(); | |||||
| fInfo.cvOuts = fShmNonRtServerControl.readUInt(); | |||||
| } break; | |||||
| case kPluginBridgeNonRtServerParameterCount: { | case kPluginBridgeNonRtServerParameterCount: { | ||||
| // uint/count | // uint/count | ||||
| const uint32_t count = fShmNonRtServerControl.readUInt(); | const uint32_t count = fShmNonRtServerControl.readUInt(); | ||||
| @@ -2106,6 +2138,33 @@ public: | |||||
| } break; | } 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 kPluginBridgeNonRtServerParameterData1: { | case kPluginBridgeNonRtServerParameterData1: { | ||||
| // uint/index, int/rindex, uint/type, uint/hints, int/cc | // uint/index, int/rindex, uint/type, uint/hints, int/cc | ||||
| const uint32_t index = fShmNonRtServerControl.readUInt(); | const uint32_t index = fShmNonRtServerControl.readUInt(); | ||||
| @@ -2619,6 +2678,8 @@ private: | |||||
| CarlaString label; | CarlaString label; | ||||
| CarlaString maker; | CarlaString maker; | ||||
| CarlaString copyright; | CarlaString copyright; | ||||
| const char** aInNames; | |||||
| const char** aOutNames; | |||||
| std::vector<uint8_t> chunk; | std::vector<uint8_t> chunk; | ||||
| Info() | Info() | ||||
| @@ -2634,6 +2695,8 @@ private: | |||||
| label(), | label(), | ||||
| maker(), | maker(), | ||||
| copyright(), | copyright(), | ||||
| aInNames(nullptr), | |||||
| aOutNames(nullptr), | |||||
| chunk() {} | chunk() {} | ||||
| } fInfo; | } fInfo; | ||||
| @@ -87,9 +87,11 @@ enum PluginBridgeNonRtServerOpcode { | |||||
| kPluginBridgeNonRtServerPluginInfo2, // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright) | kPluginBridgeNonRtServerPluginInfo2, // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright) | ||||
| kPluginBridgeNonRtServerAudioCount, // uint/ins, uint/outs | kPluginBridgeNonRtServerAudioCount, // uint/ins, uint/outs | ||||
| kPluginBridgeNonRtServerMidiCount, // uint/ins, uint/outs | kPluginBridgeNonRtServerMidiCount, // uint/ins, uint/outs | ||||
| kPluginBridgeNonRtServerCvCount, // uint/ins, uint/outs | |||||
| kPluginBridgeNonRtServerParameterCount, // uint/count | kPluginBridgeNonRtServerParameterCount, // uint/count | ||||
| kPluginBridgeNonRtServerProgramCount, // uint/count | kPluginBridgeNonRtServerProgramCount, // uint/count | ||||
| kPluginBridgeNonRtServerMidiProgramCount, // uint/count | kPluginBridgeNonRtServerMidiProgramCount, // uint/count | ||||
| kPluginBridgeNonRtServerPortName, // byte/type, uint/index, uint/size, str[] (name) | |||||
| kPluginBridgeNonRtServerParameterData1, // uint/index, int/rindex, uint/type, uint/hints, short/cc | kPluginBridgeNonRtServerParameterData1, // uint/index, int/rindex, uint/type, uint/hints, short/cc | ||||
| kPluginBridgeNonRtServerParameterData2, // uint/index, uint/size, str[] (name), uint/size, str[] (symbol), uint/size, str[] (unit) | kPluginBridgeNonRtServerParameterData2, // uint/index, uint/size, str[] (name), uint/size, str[] (symbol), uint/size, str[] (unit) | ||||
| kPluginBridgeNonRtServerParameterRanges, // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge | kPluginBridgeNonRtServerParameterRanges, // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge | ||||
| @@ -109,6 +111,18 @@ enum PluginBridgeNonRtServerOpcode { | |||||
| kPluginBridgeNonRtServerError // uint/size, str[] | kPluginBridgeNonRtServerError // uint/size, str[] | ||||
| }; | }; | ||||
| // used for kPluginBridgeNonRtServerPortName | |||||
| enum PluginBridgePortType { | |||||
| kPluginBridgePortNull = 0, | |||||
| kPluginBridgePortAudioInput, | |||||
| kPluginBridgePortAudioOutput, | |||||
| kPluginBridgePortCvInput, | |||||
| kPluginBridgePortCvOutput, | |||||
| kPluginBridgePortMidiInput, | |||||
| kPluginBridgePortMidiOutput, | |||||
| kPluginBridgePortTypeCount | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| struct BridgeSemaphore { | struct BridgeSemaphore { | ||||
| @@ -271,12 +285,16 @@ const char* PluginBridgeNonRtServerOpcode2str(const PluginBridgeNonRtServerOpcod | |||||
| return "kPluginBridgeNonRtServerAudioCount"; | return "kPluginBridgeNonRtServerAudioCount"; | ||||
| case kPluginBridgeNonRtServerMidiCount: | case kPluginBridgeNonRtServerMidiCount: | ||||
| return "kPluginBridgeNonRtServerMidiCount"; | return "kPluginBridgeNonRtServerMidiCount"; | ||||
| case kPluginBridgeNonRtServerCvCount: | |||||
| return "kPluginBridgeNonRtServerCvCount"; | |||||
| case kPluginBridgeNonRtServerParameterCount: | case kPluginBridgeNonRtServerParameterCount: | ||||
| return "kPluginBridgeNonRtServerParameterCount"; | return "kPluginBridgeNonRtServerParameterCount"; | ||||
| case kPluginBridgeNonRtServerProgramCount: | case kPluginBridgeNonRtServerProgramCount: | ||||
| return "kPluginBridgeNonRtServerProgramCount"; | return "kPluginBridgeNonRtServerProgramCount"; | ||||
| case kPluginBridgeNonRtServerMidiProgramCount: | case kPluginBridgeNonRtServerMidiProgramCount: | ||||
| return "kPluginBridgeNonRtServerMidiProgramCount"; | return "kPluginBridgeNonRtServerMidiProgramCount"; | ||||
| case kPluginBridgeNonRtServerPortName: | |||||
| return "kPluginBridgeNonRtServerPortName"; | |||||
| case kPluginBridgeNonRtServerParameterData1: | case kPluginBridgeNonRtServerParameterData1: | ||||
| return "kPluginBridgeNonRtServerParameterData1"; | return "kPluginBridgeNonRtServerParameterData1"; | ||||
| case kPluginBridgeNonRtServerParameterData2: | case kPluginBridgeNonRtServerParameterData2: | ||||