| @@ -51,14 +51,15 @@ const unsigned int MAX_PARAMETERS = 200; //!< Default value for the maximum numb | |||
| * \see CarlaPlugin::hints() | |||
| * @{ | |||
| */ | |||
| const unsigned int PLUGIN_IS_BRIDGE = 0x01; //!< Plugin is a bridge (ie, BridgePlugin). This hint is required because "bridge" itself is not a plugin type. | |||
| const unsigned int PLUGIN_IS_SYNTH = 0x02; //!< Plugin is a synthesizer (produces sound). | |||
| const unsigned int PLUGIN_HAS_GUI = 0x04; //!< Plugin has its own custom GUI. | |||
| const unsigned int PLUGIN_USES_CHUNKS = 0x08; //!< Plugin uses chunks to save internal data.\see CarlaPlugin::chunkData() | |||
| const unsigned int PLUGIN_USES_SINGLE_THREAD = 0x10; //!< Plugin has its own custom GUI. | |||
| const unsigned int PLUGIN_CAN_DRYWET = 0x20; //!< Plugin can make use of Dry/Wet controls. | |||
| const unsigned int PLUGIN_CAN_VOLUME = 0x40; //!< Plugin can make use of Volume controls. | |||
| const unsigned int PLUGIN_CAN_BALANCE = 0x80; //!< Plugin can make use of Left & Right Balance controls. | |||
| const unsigned int PLUGIN_IS_BRIDGE = 0x001; //!< Plugin is a bridge (ie, BridgePlugin). This hint is required because "bridge" itself is not a plugin type. | |||
| const unsigned int PLUGIN_IS_SYNTH = 0x002; //!< Plugin is a synthesizer (produces sound). | |||
| const unsigned int PLUGIN_HAS_GUI = 0x004; //!< Plugin has its own custom GUI. | |||
| const unsigned int PLUGIN_USES_CHUNKS = 0x008; //!< Plugin uses chunks to save internal data.\see CarlaPlugin::chunkData() | |||
| const unsigned int PLUGIN_USES_SINGLE_THREAD = 0x010; //!< Plugin has its own custom GUI. | |||
| const unsigned int PLUGIN_CAN_DRYWET = 0x020; //!< Plugin can make use of Dry/Wet controls. | |||
| const unsigned int PLUGIN_CAN_VOLUME = 0x040; //!< Plugin can make use of Volume controls. | |||
| const unsigned int PLUGIN_CAN_BALANCE = 0x080; //!< Plugin can make use of Left & Right Balance controls. | |||
| const unsigned int PLUGIN_CAN_FORCE_STEREO = 0x100; //!< Plugin can be used in forced-stereo mode. | |||
| /**@}*/ | |||
| /*! | |||
| @@ -78,8 +78,8 @@ public: | |||
| m_type = PLUGIN_INTERNAL; | |||
| descriptor = nullptr; | |||
| handle = nullptr; | |||
| descriptor = nullptr; | |||
| handle = h2 = nullptr; | |||
| host.handle = this; | |||
| host.get_buffer_size = carla_host_get_buffer_size; | |||
| @@ -103,16 +103,16 @@ public: | |||
| { | |||
| if (handle) | |||
| descriptor->deactivate(handle); | |||
| //if (h2) | |||
| // descriptor->deactivate(h2); | |||
| if (h2) | |||
| descriptor->deactivate(h2); | |||
| } | |||
| if (descriptor->cleanup) | |||
| { | |||
| if (handle) | |||
| descriptor->cleanup(handle); | |||
| //if (h2) | |||
| // descriptor->cleanup(h2); | |||
| if (h2) | |||
| descriptor->cleanup(h2); | |||
| } | |||
| } | |||
| } | |||
| @@ -688,7 +688,7 @@ public: | |||
| param.count = params; | |||
| // plugin checks | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE); | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE | PLUGIN_CAN_FORCE_STEREO); | |||
| if (aOuts > 0 && (aIns == aOuts || aIns == 1)) | |||
| m_hints |= PLUGIN_CAN_DRYWET; | |||
| @@ -699,6 +699,9 @@ public: | |||
| if (aOuts >= 2 && aOuts%2 == 0) | |||
| m_hints |= PLUGIN_CAN_BALANCE; | |||
| if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0) && mIns <= 1 && mOuts <= 1) | |||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||
| m_hints |= getPluginHintsFromNative(descriptor->hints); | |||
| reloadPrograms(true); | |||
| @@ -1561,7 +1564,7 @@ public: | |||
| private: | |||
| const PluginDescriptor* descriptor; | |||
| PluginHandle handle; | |||
| PluginHandle handle, h2; | |||
| HostDescriptor host; | |||
| bool isProcessing; | |||
| @@ -1598,6 +1601,17 @@ CarlaPlugin* CarlaPlugin::newNative(const initializer& init) | |||
| } | |||
| plugin->reload(); | |||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| { | |||
| if (! plugin->hints() & PLUGIN_CAN_FORCE_STEREO) | |||
| { | |||
| setLastError("Carla's rack mode can only work with Mono or Stereo Internal plugins, sorry!"); | |||
| delete plugin; | |||
| return nullptr; | |||
| } | |||
| } | |||
| plugin->registerToOsc(); | |||
| return plugin; | |||
| @@ -671,7 +671,7 @@ public: | |||
| param.count = params; | |||
| // plugin checks | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE); | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE | PLUGIN_CAN_FORCE_STEREO); | |||
| if (midi.portMin && aOut.count > 0) | |||
| m_hints |= PLUGIN_IS_SYNTH; | |||
| @@ -693,6 +693,9 @@ public: | |||
| if (aOuts >= 2 && aOuts%2 == 0) | |||
| m_hints |= PLUGIN_CAN_BALANCE; | |||
| if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0)) | |||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||
| reloadPrograms(true); | |||
| x_client->activate(); | |||
| @@ -1552,10 +1555,7 @@ CarlaPlugin* CarlaPlugin::newDSSI(const initializer& init, const void* const ext | |||
| #ifndef BUILD_BRIDGE | |||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| { | |||
| const uint32_t ins = plugin->audioInCount(); | |||
| const uint32_t outs = plugin->audioOutCount(); | |||
| if (ins > 2 || outs > 2 || (ins != outs && ins != 0 && outs != 0)) | |||
| if (! plugin->hints() & PLUGIN_CAN_FORCE_STEREO) | |||
| { | |||
| setLastError("Carla's rack mode can only work with Mono or Stereo DSSI plugins, sorry!"); | |||
| delete plugin; | |||
| @@ -716,11 +716,12 @@ public: | |||
| param.count = params; | |||
| // plugin checks | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE); | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE | PLUGIN_CAN_FORCE_STEREO); | |||
| m_hints |= PLUGIN_IS_SYNTH; | |||
| m_hints |= PLUGIN_CAN_VOLUME; | |||
| m_hints |= PLUGIN_CAN_BALANCE; | |||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||
| reloadPrograms(true); | |||
| @@ -651,7 +651,7 @@ public: | |||
| param.count = params; | |||
| // plugin checks | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE); | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE | PLUGIN_CAN_FORCE_STEREO); | |||
| if (aOuts > 0 && (aIns == aOuts || aIns == 1)) | |||
| m_hints |= PLUGIN_CAN_DRYWET; | |||
| @@ -662,6 +662,9 @@ public: | |||
| if (aOuts >= 2 && aOuts%2 == 0) | |||
| m_hints |= PLUGIN_CAN_BALANCE; | |||
| if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0)) | |||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||
| x_client->activate(); | |||
| qDebug("LadspaPlugin::reload() - end"); | |||
| @@ -1160,10 +1163,7 @@ CarlaPlugin* CarlaPlugin::newLADSPA(const initializer& init, const void* const e | |||
| #ifndef BUILD_BRIDGE | |||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| { | |||
| const uint32_t ins = plugin->audioInCount(); | |||
| const uint32_t outs = plugin->audioOutCount(); | |||
| if (ins > 2 || outs > 2 || (ins != outs && ins != 0 && outs != 0)) | |||
| if (! plugin->hints() & PLUGIN_CAN_FORCE_STEREO) | |||
| { | |||
| setLastError("Carla's rack mode can only work with Mono or Stereo LADSPA plugins, sorry!"); | |||
| delete plugin; | |||
| @@ -199,11 +199,12 @@ public: | |||
| aOut.count = aOuts; | |||
| // plugin checks | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE); | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE | PLUGIN_CAN_FORCE_STEREO); | |||
| m_hints |= PLUGIN_IS_SYNTH; | |||
| m_hints |= PLUGIN_CAN_VOLUME; | |||
| m_hints |= PLUGIN_CAN_BALANCE; | |||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||
| reloadPrograms(true); | |||
| @@ -54,9 +54,9 @@ const unsigned int MAX_EVENT_BUFFER = 8192; // 0x2000 | |||
| * @defgroup PluginHints Plugin Hints | |||
| * @{ | |||
| */ | |||
| const unsigned int PLUGIN_HAS_EXTENSION_PROGRAMS = 0x100; //!< LV2 Plugin has Programs extension | |||
| const unsigned int PLUGIN_HAS_EXTENSION_STATE = 0x200; //!< LV2 Plugin has State extension | |||
| const unsigned int PLUGIN_HAS_EXTENSION_WORKER = 0x400; //!< LV2 Plugin has Worker extension | |||
| const unsigned int PLUGIN_HAS_EXTENSION_PROGRAMS = 0x1000; //!< LV2 Plugin has Programs extension | |||
| const unsigned int PLUGIN_HAS_EXTENSION_STATE = 0x2000; //!< LV2 Plugin has State extension | |||
| const unsigned int PLUGIN_HAS_EXTENSION_WORKER = 0x4000; //!< LV2 Plugin has Worker extension | |||
| /**@}*/ | |||
| /*! | |||
| @@ -1144,8 +1144,25 @@ public: | |||
| params += 1; | |||
| } | |||
| // check extensions | |||
| ext.state = nullptr; | |||
| ext.worker = nullptr; | |||
| ext.programs = nullptr; | |||
| if (descriptor->extension_data) | |||
| { | |||
| if (m_hints & PLUGIN_HAS_EXTENSION_PROGRAMS) | |||
| ext.programs = (const LV2_Programs_Interface*)descriptor->extension_data(LV2_PROGRAMS__Interface); | |||
| if (m_hints & PLUGIN_HAS_EXTENSION_STATE) | |||
| ext.state = (const LV2_State_Interface*)descriptor->extension_data(LV2_STATE__interface); | |||
| if (m_hints & PLUGIN_HAS_EXTENSION_WORKER) | |||
| ext.worker = (const LV2_Worker_Interface*)descriptor->extension_data(LV2_WORKER__interface); | |||
| } | |||
| #ifndef BUILD_BRIDGE | |||
| if (carlaOptions.forceStereo && (aIns == 1 || aOuts == 1) && ! h2) | |||
| if (carlaOptions.forceStereo && (aIns == 1 || aOuts == 1) && ! (h2 || ext.state || ext.worker)) | |||
| { | |||
| h2 = descriptor->instantiate(descriptor, sampleRate, rdf_descriptor->Bundle, features); | |||
| @@ -1678,7 +1695,7 @@ public: | |||
| param.count = params; | |||
| // plugin checks | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE); | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE | PLUGIN_CAN_FORCE_STEREO); | |||
| if (LV2_IS_GENERATOR(rdf_descriptor->Type)) | |||
| m_hints |= PLUGIN_IS_SYNTH; | |||
| @@ -1692,21 +1709,15 @@ public: | |||
| if (aOuts >= 2 && aOuts%2 == 0) | |||
| m_hints |= PLUGIN_CAN_BALANCE; | |||
| // check extensions | |||
| ext.state = nullptr; | |||
| ext.worker = nullptr; | |||
| ext.programs = nullptr; | |||
| if (descriptor->extension_data) | |||
| if (ext.state || ext.worker) | |||
| { | |||
| if (m_hints & PLUGIN_HAS_EXTENSION_PROGRAMS) | |||
| ext.programs = (const LV2_Programs_Interface*)descriptor->extension_data(LV2_PROGRAMS__Interface); | |||
| if (m_hints & PLUGIN_HAS_EXTENSION_STATE) | |||
| ext.state = (const LV2_State_Interface*)descriptor->extension_data(LV2_STATE__interface); | |||
| if (m_hints & PLUGIN_HAS_EXTENSION_WORKER) | |||
| ext.worker = (const LV2_Worker_Interface*)descriptor->extension_data(LV2_WORKER__interface); | |||
| if ((aIns == 0 || aIns == 2) && (aOuts == 0 || aOuts == 2) && evIn.count <= 1 && evOut.count <= 1) | |||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||
| } | |||
| else | |||
| { | |||
| if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0) && evIn.count <= 1 && evOut.count <= 1) | |||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||
| } | |||
| reloadPrograms(true); | |||
| @@ -4495,12 +4506,9 @@ CarlaPlugin* CarlaPlugin::newLV2(const initializer& init) | |||
| #ifndef BUILD_BRIDGE | |||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| { | |||
| const uint32_t ins = plugin->audioInCount(); | |||
| const uint32_t outs = plugin->audioOutCount(); | |||
| if (ins > 2 || outs > 2 || (ins != outs && ins != 0 && outs != 0)) | |||
| if (! plugin->hints() & PLUGIN_CAN_FORCE_STEREO) | |||
| { | |||
| setLastError("Carla's rack mode can only work with Mono or Stereo LV2 plugins, sorry!"); | |||
| setLastError("Carla's rack mode can only work with Mono (simple) or Stereo LV2 plugins, sorry!"); | |||
| delete plugin; | |||
| return nullptr; | |||
| } | |||
| @@ -38,10 +38,10 @@ CARLA_BACKEND_START_NAMESPACE | |||
| * @defgroup PluginHints Plugin Hints | |||
| * @{ | |||
| */ | |||
| const unsigned int PLUGIN_CAN_PROCESS_REPLACING = 0x100; //!< VST Plugin cas use processReplacing() | |||
| const unsigned int PLUGIN_HAS_COCKOS_EXTENSIONS = 0x200; //!< VST Plugin has Cockos extensions | |||
| const unsigned int PLUGIN_USES_OLD_VSTSDK = 0x400; //!< VST Plugin uses an old VST SDK | |||
| const unsigned int PLUGIN_WANTS_MIDI_INPUT = 0x800; //!< VST Plugin wants MIDI input | |||
| const unsigned int PLUGIN_CAN_PROCESS_REPLACING = 0x1000; //!< VST Plugin cas use processReplacing() | |||
| const unsigned int PLUGIN_HAS_COCKOS_EXTENSIONS = 0x2000; //!< VST Plugin has Cockos extensions | |||
| const unsigned int PLUGIN_USES_OLD_VSTSDK = 0x4000; //!< VST Plugin uses an old VST SDK | |||
| const unsigned int PLUGIN_WANTS_MIDI_INPUT = 0x8000; //!< VST Plugin wants MIDI input | |||
| /**@}*/ | |||
| class VstPlugin : public CarlaPlugin | |||
| @@ -687,7 +687,7 @@ public: | |||
| param.count = params; | |||
| // plugin checks | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE); | |||
| m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE | PLUGIN_CAN_FORCE_STEREO); | |||
| intptr_t vstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f); | |||
| @@ -706,6 +706,9 @@ public: | |||
| if (aOuts >= 2 && aOuts%2 == 0) | |||
| m_hints |= PLUGIN_CAN_BALANCE; | |||
| if ((aIns == 0 || aIns == 2) && (aOuts == 0 || aOuts == 2)) | |||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||
| reloadPrograms(true); | |||
| x_client->activate(); | |||
| @@ -2302,13 +2305,7 @@ CarlaPlugin* CarlaPlugin::newVST(const initializer& init) | |||
| #ifndef BUILD_BRIDGE | |||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| { | |||
| const uint32_t ins = plugin->audioInCount(); | |||
| const uint32_t outs = plugin->audioOutCount(); | |||
| const bool stereoInput = ins == 0 || ins == 2; | |||
| const bool stereoOutput = outs == 0 || outs == 2; | |||
| if (! (stereoInput && stereoOutput)) | |||
| if (! plugin->hints() & PLUGIN_CAN_FORCE_STEREO) | |||
| { | |||
| setLastError("Carla's rack mode can only work with Stereo VST plugins, sorry!"); | |||
| delete plugin; | |||
| @@ -59,14 +59,15 @@ MAX_PLUGINS = 99 | |||
| MAX_PARAMETERS = 200 | |||
| # plugin hints | |||
| PLUGIN_IS_BRIDGE = 0x01 | |||
| PLUGIN_IS_SYNTH = 0x02 | |||
| PLUGIN_HAS_GUI = 0x04 | |||
| PLUGIN_USES_CHUNKS = 0x08 | |||
| PLUGIN_USES_SINGLE_THREAD = 0x10 | |||
| PLUGIN_CAN_DRYWET = 0x20 | |||
| PLUGIN_CAN_VOLUME = 0x40 | |||
| PLUGIN_CAN_BALANCE = 0x80 | |||
| PLUGIN_IS_BRIDGE = 0x001 | |||
| PLUGIN_IS_SYNTH = 0x002 | |||
| PLUGIN_HAS_GUI = 0x004 | |||
| PLUGIN_USES_CHUNKS = 0x008 | |||
| PLUGIN_USES_SINGLE_THREAD = 0x010 | |||
| PLUGIN_CAN_DRYWET = 0x020 | |||
| PLUGIN_CAN_VOLUME = 0x040 | |||
| PLUGIN_CAN_BALANCE = 0x080 | |||
| PLUGIN_CAN_FORCE_STEREO = 0x100 | |||
| # parameter hints | |||
| PARAMETER_IS_BOOLEAN = 0x01 | |||