| @@ -51,14 +51,15 @@ const unsigned int MAX_PARAMETERS = 200; //!< Default value for the maximum numb | |||||
| * \see CarlaPlugin::hints() | * \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; | m_type = PLUGIN_INTERNAL; | ||||
| descriptor = nullptr; | |||||
| handle = nullptr; | |||||
| descriptor = nullptr; | |||||
| handle = h2 = nullptr; | |||||
| host.handle = this; | host.handle = this; | ||||
| host.get_buffer_size = carla_host_get_buffer_size; | host.get_buffer_size = carla_host_get_buffer_size; | ||||
| @@ -103,16 +103,16 @@ public: | |||||
| { | { | ||||
| if (handle) | if (handle) | ||||
| descriptor->deactivate(handle); | descriptor->deactivate(handle); | ||||
| //if (h2) | |||||
| // descriptor->deactivate(h2); | |||||
| if (h2) | |||||
| descriptor->deactivate(h2); | |||||
| } | } | ||||
| if (descriptor->cleanup) | if (descriptor->cleanup) | ||||
| { | { | ||||
| if (handle) | if (handle) | ||||
| descriptor->cleanup(handle); | descriptor->cleanup(handle); | ||||
| //if (h2) | |||||
| // descriptor->cleanup(h2); | |||||
| if (h2) | |||||
| descriptor->cleanup(h2); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -688,7 +688,7 @@ public: | |||||
| param.count = params; | param.count = params; | ||||
| // plugin checks | // 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)) | if (aOuts > 0 && (aIns == aOuts || aIns == 1)) | ||||
| m_hints |= PLUGIN_CAN_DRYWET; | m_hints |= PLUGIN_CAN_DRYWET; | ||||
| @@ -699,6 +699,9 @@ public: | |||||
| if (aOuts >= 2 && aOuts%2 == 0) | if (aOuts >= 2 && aOuts%2 == 0) | ||||
| m_hints |= PLUGIN_CAN_BALANCE; | 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); | m_hints |= getPluginHintsFromNative(descriptor->hints); | ||||
| reloadPrograms(true); | reloadPrograms(true); | ||||
| @@ -1561,7 +1564,7 @@ public: | |||||
| private: | private: | ||||
| const PluginDescriptor* descriptor; | const PluginDescriptor* descriptor; | ||||
| PluginHandle handle; | |||||
| PluginHandle handle, h2; | |||||
| HostDescriptor host; | HostDescriptor host; | ||||
| bool isProcessing; | bool isProcessing; | ||||
| @@ -1598,6 +1601,17 @@ CarlaPlugin* CarlaPlugin::newNative(const initializer& init) | |||||
| } | } | ||||
| plugin->reload(); | 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(); | plugin->registerToOsc(); | ||||
| return plugin; | return plugin; | ||||
| @@ -671,7 +671,7 @@ public: | |||||
| param.count = params; | param.count = params; | ||||
| // plugin checks | // 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) | if (midi.portMin && aOut.count > 0) | ||||
| m_hints |= PLUGIN_IS_SYNTH; | m_hints |= PLUGIN_IS_SYNTH; | ||||
| @@ -693,6 +693,9 @@ public: | |||||
| if (aOuts >= 2 && aOuts%2 == 0) | if (aOuts >= 2 && aOuts%2 == 0) | ||||
| m_hints |= PLUGIN_CAN_BALANCE; | m_hints |= PLUGIN_CAN_BALANCE; | ||||
| if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0)) | |||||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||||
| reloadPrograms(true); | reloadPrograms(true); | ||||
| x_client->activate(); | x_client->activate(); | ||||
| @@ -1552,10 +1555,7 @@ CarlaPlugin* CarlaPlugin::newDSSI(const initializer& init, const void* const ext | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | 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!"); | setLastError("Carla's rack mode can only work with Mono or Stereo DSSI plugins, sorry!"); | ||||
| delete plugin; | delete plugin; | ||||
| @@ -716,11 +716,12 @@ public: | |||||
| param.count = params; | param.count = params; | ||||
| // plugin checks | // 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_IS_SYNTH; | ||||
| m_hints |= PLUGIN_CAN_VOLUME; | m_hints |= PLUGIN_CAN_VOLUME; | ||||
| m_hints |= PLUGIN_CAN_BALANCE; | m_hints |= PLUGIN_CAN_BALANCE; | ||||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||||
| reloadPrograms(true); | reloadPrograms(true); | ||||
| @@ -651,7 +651,7 @@ public: | |||||
| param.count = params; | param.count = params; | ||||
| // plugin checks | // 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)) | if (aOuts > 0 && (aIns == aOuts || aIns == 1)) | ||||
| m_hints |= PLUGIN_CAN_DRYWET; | m_hints |= PLUGIN_CAN_DRYWET; | ||||
| @@ -662,6 +662,9 @@ public: | |||||
| if (aOuts >= 2 && aOuts%2 == 0) | if (aOuts >= 2 && aOuts%2 == 0) | ||||
| m_hints |= PLUGIN_CAN_BALANCE; | 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(); | x_client->activate(); | ||||
| qDebug("LadspaPlugin::reload() - end"); | qDebug("LadspaPlugin::reload() - end"); | ||||
| @@ -1160,10 +1163,7 @@ CarlaPlugin* CarlaPlugin::newLADSPA(const initializer& init, const void* const e | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | 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!"); | setLastError("Carla's rack mode can only work with Mono or Stereo LADSPA plugins, sorry!"); | ||||
| delete plugin; | delete plugin; | ||||
| @@ -199,11 +199,12 @@ public: | |||||
| aOut.count = aOuts; | aOut.count = aOuts; | ||||
| // plugin checks | // 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_IS_SYNTH; | ||||
| m_hints |= PLUGIN_CAN_VOLUME; | m_hints |= PLUGIN_CAN_VOLUME; | ||||
| m_hints |= PLUGIN_CAN_BALANCE; | m_hints |= PLUGIN_CAN_BALANCE; | ||||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||||
| reloadPrograms(true); | reloadPrograms(true); | ||||
| @@ -54,9 +54,9 @@ const unsigned int MAX_EVENT_BUFFER = 8192; // 0x2000 | |||||
| * @defgroup PluginHints Plugin Hints | * @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; | 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 | #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); | h2 = descriptor->instantiate(descriptor, sampleRate, rdf_descriptor->Bundle, features); | ||||
| @@ -1678,7 +1695,7 @@ public: | |||||
| param.count = params; | param.count = params; | ||||
| // plugin checks | // 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)) | if (LV2_IS_GENERATOR(rdf_descriptor->Type)) | ||||
| m_hints |= PLUGIN_IS_SYNTH; | m_hints |= PLUGIN_IS_SYNTH; | ||||
| @@ -1692,21 +1709,15 @@ public: | |||||
| if (aOuts >= 2 && aOuts%2 == 0) | if (aOuts >= 2 && aOuts%2 == 0) | ||||
| m_hints |= PLUGIN_CAN_BALANCE; | 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); | reloadPrograms(true); | ||||
| @@ -4495,12 +4506,9 @@ CarlaPlugin* CarlaPlugin::newLV2(const initializer& init) | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | 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; | delete plugin; | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| @@ -38,10 +38,10 @@ CARLA_BACKEND_START_NAMESPACE | |||||
| * @defgroup PluginHints Plugin Hints | * @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 | class VstPlugin : public CarlaPlugin | ||||
| @@ -687,7 +687,7 @@ public: | |||||
| param.count = params; | param.count = params; | ||||
| // plugin checks | // 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); | intptr_t vstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f); | ||||
| @@ -706,6 +706,9 @@ public: | |||||
| if (aOuts >= 2 && aOuts%2 == 0) | if (aOuts >= 2 && aOuts%2 == 0) | ||||
| m_hints |= PLUGIN_CAN_BALANCE; | m_hints |= PLUGIN_CAN_BALANCE; | ||||
| if ((aIns == 0 || aIns == 2) && (aOuts == 0 || aOuts == 2)) | |||||
| m_hints |= PLUGIN_CAN_FORCE_STEREO; | |||||
| reloadPrograms(true); | reloadPrograms(true); | ||||
| x_client->activate(); | x_client->activate(); | ||||
| @@ -2302,13 +2305,7 @@ CarlaPlugin* CarlaPlugin::newVST(const initializer& init) | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| if (carlaOptions.processMode == PROCESS_MODE_CONTINUOUS_RACK) | 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!"); | setLastError("Carla's rack mode can only work with Stereo VST plugins, sorry!"); | ||||
| delete plugin; | delete plugin; | ||||
| @@ -59,14 +59,15 @@ MAX_PLUGINS = 99 | |||||
| MAX_PARAMETERS = 200 | MAX_PARAMETERS = 200 | ||||
| # plugin hints | # 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 hints | ||||
| PARAMETER_IS_BOOLEAN = 0x01 | PARAMETER_IS_BOOLEAN = 0x01 | ||||