| @@ -34,7 +34,7 @@ CARLA_BACKEND_START_NAMESPACE | |||
| } // Fix editor indentation | |||
| #endif | |||
| #ifndef BUILD_BRIDGE | |||
| #if 1//ndef BUILD_BRIDGE | |||
| /*! | |||
| * TODO. | |||
| */ | |||
| @@ -14,10 +14,11 @@ LINK_FLAGS += -lpthread | |||
| # -------------------------------------------------------------- | |||
| BUILD_CXX_FLAGS += -DWANT_NATIVE | |||
| ifeq ($(CARLA_PLUGIN_SUPPORT),true) | |||
| # BUILD_C_FLAGS += -DWANT_LV2 | |||
| # BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST | |||
| BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI | |||
| BUILD_C_FLAGS += -DWANT_LV2 | |||
| BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST | |||
| endif | |||
| ifeq ($(CARLA_RTAUDIO_SUPPORT),true) | |||
| @@ -35,7 +36,7 @@ BUILD_CXX_FLAGS += -DWANT_FLUIDSYNTH | |||
| endif | |||
| ifeq ($(HAVE_LINUXSAMPLER),true) | |||
| # BUILD_CXX_FLAGS += -DWANT_LINUXSAMPLER | |||
| BUILD_CXX_FLAGS += -DWANT_LINUXSAMPLER | |||
| endif | |||
| ifeq ($(HAVE_SUIL),true) | |||
| @@ -1256,6 +1256,7 @@ void CarlaPlugin::postponeRtEvent(const PluginPostRtEventType type, const int32_ | |||
| void CarlaPlugin::postRtEventsRun() | |||
| { | |||
| // TODO: optimize | |||
| unsigned short k = 0; | |||
| PluginPostRtEvent listData[MAX_RT_EVENTS]; | |||
| @@ -904,7 +904,7 @@ public: | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Check if not active before | |||
| if (! kData->activeBefore) | |||
| if (kData->needsReset || ! kData->activeBefore) | |||
| { | |||
| if (kData->event.portIn != nullptr) | |||
| { | |||
| @@ -931,6 +931,17 @@ public: | |||
| carla_zeroFloat(kData->latencyBuffers[i], kData->latency); | |||
| } | |||
| if (kData->activeBefore) | |||
| { | |||
| if (fDescriptor->deactivate != nullptr) | |||
| { | |||
| fDescriptor->deactivate(fHandle); | |||
| if (fHandle2 != nullptr) | |||
| fDescriptor->deactivate(fHandle2); | |||
| } | |||
| } | |||
| if (fDescriptor->activate != nullptr) | |||
| { | |||
| fDescriptor->activate(fHandle); | |||
| @@ -938,6 +949,8 @@ public: | |||
| if (fHandle2 != nullptr) | |||
| fDescriptor->activate(fHandle2); | |||
| } | |||
| kData->needsReset = false; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| @@ -977,6 +990,7 @@ public: | |||
| bool sampleAccurate = (fHints & PLUGIN_OPTION_FIXED_BUFFER) == 0; | |||
| uint32_t time, nEvents = kData->event.portIn->getEventCount(); | |||
| uint32_t startTime = 0; | |||
| uint32_t timeOffset = 0; | |||
| uint32_t nextBankId = 0; | |||
| @@ -996,10 +1010,18 @@ public: | |||
| if (time > timeOffset && sampleAccurate) | |||
| { | |||
| processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset, midiEventCount); | |||
| midiEventCount = 0; | |||
| nextBankId = 0; | |||
| timeOffset = time; | |||
| if (processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset, midiEventCount)) | |||
| { | |||
| midiEventCount = 0; | |||
| timeOffset = time; | |||
| if (kData->midiprog.current >= 0 && kData->midiprog.count > 0) | |||
| nextBankId = kData->midiprog.data[kData->midiprog.current].bank; | |||
| else | |||
| nextBankId = 0; | |||
| } | |||
| else | |||
| startTime += timeOffset; | |||
| } | |||
| // Control change | |||
| @@ -1158,8 +1180,7 @@ public: | |||
| carla_zeroStruct<snd_seq_event_t>(fMidiEvents[midiEventCount]); | |||
| if (! sampleAccurate) | |||
| fMidiEvents[midiEventCount].time.tick = time; | |||
| fMidiEvents[midiEventCount].time.tick = sampleAccurate ? startTime : time; | |||
| fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_CONTROLLER; | |||
| fMidiEvents[midiEventCount].data.control.channel = event.channel; | |||
| @@ -1183,8 +1204,7 @@ public: | |||
| carla_zeroStruct<snd_seq_event_t>(fMidiEvents[midiEventCount]); | |||
| if (! sampleAccurate) | |||
| fMidiEvents[midiEventCount].time.tick = time; | |||
| fMidiEvents[midiEventCount].time.tick = sampleAccurate ? startTime : time; | |||
| fMidiEvents[midiEventCount].type = SND_SEQ_EVENT_CONTROLLER; | |||
| fMidiEvents[midiEventCount].data.control.channel = event.channel; | |||
| @@ -1214,8 +1234,7 @@ public: | |||
| carla_zeroStruct<snd_seq_event_t>(fMidiEvents[midiEventCount]); | |||
| if (! sampleAccurate) | |||
| fMidiEvents[midiEventCount].time.tick = time - timeOffset; | |||
| fMidiEvents[midiEventCount].time.tick = sampleAccurate ? startTime : time; | |||
| if (MIDI_IS_STATUS_NOTE_OFF(status)) | |||
| { | |||
| @@ -1321,12 +1340,91 @@ public: | |||
| CARLA_PROCESS_CONTINUE_CHECK; | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Control Output | |||
| if (kData->event.portOut != nullptr) | |||
| { | |||
| float value; | |||
| for (k=0; k < kData->param.count; k++) | |||
| { | |||
| if (kData->param.data[k].type != PARAMETER_OUTPUT) | |||
| continue; | |||
| kData->param.ranges[k].fixValue(fParamBuffers[k]); | |||
| if (kData->param.data[k].midiCC > 0) | |||
| { | |||
| value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]); | |||
| kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value); | |||
| } | |||
| } | |||
| } // End of Control Output | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| kData->activeBefore = kData->active; | |||
| } | |||
| bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset, const uint32_t midiEventCount) | |||
| { | |||
| uint32_t i, k; | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Try lock, silence otherwise | |||
| if (! kData->mutex.tryLock()) | |||
| { | |||
| for (i=0; i < kData->audioOut.count; i++) | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| outBuffer[i][k+timeOffset] = 0.0f; | |||
| } | |||
| return false; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Fill plugin buffers | |||
| for (i=0; i < kData->audioIn.count; i++) | |||
| carla_copyFloat(fAudioInBuffers[i], inBuffer[i]+timeOffset, frames); | |||
| for (i=0; i < kData->audioOut.count; i++) | |||
| carla_zeroFloat(fAudioOutBuffers[i], frames); | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Run plugin | |||
| if (fDssiDescriptor->run_synth != nullptr) | |||
| { | |||
| fDssiDescriptor->run_synth(fHandle, frames, fMidiEvents, midiEventCount); | |||
| if (fHandle2 != nullptr) | |||
| fDssiDescriptor->run_synth(fHandle2, frames, fMidiEvents, midiEventCount); | |||
| } | |||
| else if (fDssiDescriptor->run_multiple_synths != nullptr) | |||
| { | |||
| unsigned long instances = (fHandle2 != nullptr) ? 2 : 1; | |||
| LADSPA_Handle handlePtr[2] = { fHandle, fHandle2 }; | |||
| snd_seq_event_t* midiEventsPtr[2] = { fMidiEvents, fMidiEvents }; | |||
| unsigned long midiEventCountPtr[2] = { midiEventCount, midiEventCount }; | |||
| fDssiDescriptor->run_multiple_synths(instances, handlePtr, frames, midiEventsPtr, midiEventCountPtr); | |||
| } | |||
| else | |||
| { | |||
| fDescriptor->run(fHandle, frames); | |||
| if (fHandle2 != nullptr) | |||
| fDescriptor->run(fHandle2, frames); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Post-processing (dry/wet, volume and balance) | |||
| { | |||
| const bool doDryWet = (fHints & PLUGIN_CAN_DRYWET) > 0 && kData->postProc.dryWet != 1.0f; | |||
| const bool doVolume = (fHints & PLUGIN_CAN_VOLUME) > 0 && kData->postProc.volume != 1.0f; | |||
| const bool doBalance = (fHints & PLUGIN_CAN_BALANCE) > 0 && (kData->postProc.balanceLeft != -1.0f || kData->postProc.balanceRight != 1.0f); | |||
| float bufValue, oldBufLeft[doBalance ? frames : 1]; | |||
| @@ -1336,17 +1434,6 @@ public: | |||
| // Dry/Wet | |||
| if (doDryWet) | |||
| { | |||
| #if 0 | |||
| for (k=0; k < frames; k++) | |||
| { | |||
| if (k < m_latency && m_latency < frames) | |||
| bufValue = (aIn.count == 1) ? m_latencyBuffers[0][k] : m_latencyBuffers[i][k]; | |||
| else | |||
| bufValue = (aIn.count == 1) ? inBuffer[0][k-m_latency] : inBuffer[i][k-m_latency]; | |||
| outBuffer[i][k] = (outBuffer[i][k]*x_dryWet)+(bufValue*(1.0-x_dryWet)); | |||
| } | |||
| #endif | |||
| for (k=0; k < frames; k++) | |||
| { | |||
| // TODO | |||
| @@ -1355,9 +1442,8 @@ public: | |||
| //else | |||
| // bufValue = (kData->audioIn.count == 1) ? inBuffer[0][k-m_latency] : inBuffer[i][k-m_latency]; | |||
| bufValue = inBuffer[ (kData->audioIn.count == 1) ? 0 : i ][k]; | |||
| outBuffer[i][k] = (outBuffer[i][k] * kData->postProc.dryWet) + (bufValue * (1.0f - kData->postProc.dryWet)); | |||
| bufValue = fAudioInBuffers[(kData->audioIn.count == 1) ? 0 : i][k]; | |||
| fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * kData->postProc.dryWet) + (bufValue * (1.0f - kData->postProc.dryWet)); | |||
| } | |||
| } | |||
| @@ -1365,7 +1451,7 @@ public: | |||
| if (doBalance) | |||
| { | |||
| if (i % 2 == 0) | |||
| carla_copyFloat(oldBufLeft, outBuffer[i], frames); | |||
| carla_copyFloat(oldBufLeft, fAudioOutBuffers[i], frames); | |||
| float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f; | |||
| float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f; | |||
| @@ -1375,23 +1461,22 @@ public: | |||
| if (i % 2 == 0) | |||
| { | |||
| // left | |||
| outBuffer[i][k] = oldBufLeft[k] * (1.0f - balRangeL); | |||
| outBuffer[i][k] += outBuffer[i+1][k] * (1.0f - balRangeR); | |||
| fAudioOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL); | |||
| fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR); | |||
| } | |||
| else | |||
| { | |||
| // right | |||
| outBuffer[i][k] = outBuffer[i][k] * balRangeR; | |||
| outBuffer[i][k] += oldBufLeft[k] * balRangeL; | |||
| fAudioOutBuffers[i][k] = fAudioOutBuffers[i][k] * balRangeR; | |||
| fAudioOutBuffers[i][k] += oldBufLeft[k] * balRangeL; | |||
| } | |||
| } | |||
| } | |||
| // Volume | |||
| if (doVolume) | |||
| // Volume (and buffer copy) | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| outBuffer[i][k] *= kData->postProc.volume; | |||
| outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * kData->postProc.volume; | |||
| } | |||
| } | |||
| @@ -1405,71 +1490,10 @@ public: | |||
| #endif | |||
| } // End of Post-processing | |||
| CARLA_PROCESS_CONTINUE_CHECK; | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Control Output | |||
| if (kData->event.portOut != nullptr) | |||
| { | |||
| float value; | |||
| for (k=0; k < kData->param.count; k++) | |||
| { | |||
| if (kData->param.data[k].type != PARAMETER_OUTPUT) | |||
| continue; | |||
| kData->param.ranges[k].fixValue(fParamBuffers[k]); | |||
| if (kData->param.data[k].midiCC > 0) | |||
| { | |||
| value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]); | |||
| kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value); | |||
| } | |||
| } | |||
| } // End of Control Output | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| kData->activeBefore = kData->active; | |||
| } | |||
| void processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset, const uint32_t midiEventCount) | |||
| { | |||
| for (uint32_t i=0; i < kData->audioIn.count; i++) | |||
| carla_copyFloat(fAudioInBuffers[i], inBuffer[i]+timeOffset, frames); | |||
| for (uint32_t i=0; i < kData->audioOut.count; i++) | |||
| carla_zeroFloat(fAudioOutBuffers[i], frames); | |||
| if (fDssiDescriptor->run_synth != nullptr) | |||
| { | |||
| fDssiDescriptor->run_synth(fHandle, frames, fMidiEvents, midiEventCount); | |||
| if (fHandle2 != nullptr) | |||
| fDssiDescriptor->run_synth(fHandle2, frames, fMidiEvents, midiEventCount); | |||
| } | |||
| else if (fDssiDescriptor->run_multiple_synths != nullptr) | |||
| { | |||
| unsigned long instances = (fHandle2 != nullptr) ? 2 : 1; | |||
| LADSPA_Handle handlePtr[2] = { fHandle, fHandle2 }; | |||
| snd_seq_event_t* midiEventsPtr[2] = { fMidiEvents, fMidiEvents }; | |||
| unsigned long midiEventCountPtr[2] = { midiEventCount, midiEventCount }; | |||
| fDssiDescriptor->run_multiple_synths(instances, handlePtr, frames, midiEventsPtr, midiEventCountPtr); | |||
| } | |||
| else | |||
| { | |||
| fDescriptor->run(fHandle, frames); | |||
| if (fHandle2 != nullptr) | |||
| fDescriptor->run(fHandle2, frames); | |||
| } | |||
| for (uint32_t i=0, k; i < kData->audioOut.count; i++) | |||
| { | |||
| for (k=0; k < frames; k++) | |||
| outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k]; | |||
| } | |||
| kData->mutex.unlock(); | |||
| return true; | |||
| } | |||
| void bufferSizeChanged(const uint32_t newBufferSize) | |||
| @@ -823,6 +823,7 @@ public: | |||
| //f_sfont->free(f_sfont); | |||
| #ifndef BUILD_BRIDGE | |||
| // Update OSC Names | |||
| if (kData->engine->isOscControlRegistered()) | |||
| { | |||
| @@ -831,6 +832,7 @@ public: | |||
| for (i=0; i < kData->midiprog.count; i++) | |||
| kData->engine->osc_send_control_set_midi_program_data(fId, i, kData->midiprog.data[i].bank, kData->midiprog.data[i].program, kData->midiprog.data[i].name); | |||
| } | |||
| #endif | |||
| if (init) | |||
| { | |||
| @@ -891,7 +893,7 @@ public: | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Check if active before | |||
| if (! kData->activeBefore) | |||
| if (kData->needsReset || ! kData->activeBefore) | |||
| { | |||
| for (int c=0; c < MAX_MIDI_CHANNELS; c++) | |||
| { | |||
| @@ -903,12 +905,14 @@ public: | |||
| fluid_synth_cc(f_synth, c, MIDI_CONTROL_ALL_NOTES_OFF, 0); | |||
| #endif | |||
| } | |||
| kData->needsReset = false; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| // Event Input and Processing | |||
| else | |||
| if (kData->activeBefore) | |||
| { | |||
| // ---------------------------------------------------------------------------------------------------- | |||
| // MIDI Input (External) | |||
| @@ -805,7 +805,7 @@ public: | |||
| fDescriptor->activate(fHandle2); | |||
| } | |||
| kData->needsReset = false; | |||
| kData->needsReset = false; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------- | |||
| @@ -19,11 +19,14 @@ | |||
| #ifdef WANT_LV2 | |||
| #include "carla_lib_utils.hpp" | |||
| #include "carla_lv2_utils.hpp" | |||
| #include "CarlaLv2Utils.hpp" | |||
| #include "CarlaLibUtils.hpp" | |||
| #include "lv2_atom_queue.hpp" | |||
| #include "Lv2AtomQueue.hpp" | |||
| extern "C" { | |||
| #include "rtmempool/rtmempool.h" | |||
| } | |||
| #include <set> | |||
| @@ -43,14 +46,7 @@ struct SuilInstanceImpl { | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| /*! | |||
| * @defgroup CarlaBackendLv2Plugin Carla Backend LV2 Plugin | |||
| * | |||
| * The Carla Backend LV2 Plugin.\n | |||
| * http://lv2plug.in/ | |||
| * @{ | |||
| */ | |||
| #if 0 | |||
| // static max values | |||
| const unsigned int MAX_EVENT_BUFFER = 8192; // 0x2000 | |||
| @@ -143,10 +139,12 @@ const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 18; | |||
| const uint32_t CARLA_URI_MAP_ID_COUNT = 19; | |||
| /**@}*/ | |||
| // ----------------------------------------------------- | |||
| struct Lv2EventData { | |||
| uint32_t type; | |||
| uint32_t rindex; | |||
| CarlaEngineMidiPort* port; | |||
| CarlaEngineEventPort* port; | |||
| union { | |||
| LV2_Atom_Sequence* atom; | |||
| LV2_Event_Buffer* event; | |||
| @@ -186,13 +184,22 @@ struct Lv2PluginOptions { | |||
| sampleRate(0.0) {} | |||
| }; | |||
| // ----------------------------------------------------- | |||
| Lv2PluginOptions lv2Options; | |||
| #endif | |||
| Lv2WorldClass lv2World; | |||
| // ----------------------------------------------------- | |||
| LV2_Atom_Event* getLv2AtomEvent(LV2_Atom_Sequence* const atom, const uint32_t offset) | |||
| { | |||
| return (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, atom) + offset); | |||
| } | |||
| // ----------------------------------------------------- | |||
| class Lv2Plugin : public CarlaPlugin | |||
| { | |||
| public: | |||
| @@ -201,6 +208,7 @@ public: | |||
| { | |||
| carla_debug("Lv2Plugin::Lv2Plugin(%p, %i)", engine, id); | |||
| #if 0 | |||
| m_type = PLUGIN_LV2; | |||
| m_count += 1; | |||
| @@ -309,6 +317,7 @@ public: | |||
| ft.options[3] = lv2Options.oSampleRate; | |||
| ft.options[4] = lv2Options.oNull; | |||
| } | |||
| #endif | |||
| lv2World.init(); | |||
| } | |||
| @@ -316,6 +325,7 @@ public: | |||
| ~Lv2Plugin() | |||
| { | |||
| carla_debug("Lv2Plugin::~Lv2Plugin()"); | |||
| #if 0 | |||
| m_count -= 1; | |||
| // close UI | |||
| @@ -486,11 +496,18 @@ public: | |||
| ft.stateMakePath = nullptr; | |||
| ft.stateMapPath = nullptr; | |||
| } | |||
| #endif | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Information (base) | |||
| PluginType type() const | |||
| { | |||
| return PLUGIN_LV2; | |||
| } | |||
| #if 0 | |||
| PluginCategory category() | |||
| { | |||
| CARLA_ASSERT(rdf_descriptor); | |||
| @@ -4518,8 +4535,10 @@ public: | |||
| return true; | |||
| } | |||
| #endif | |||
| private: | |||
| #if 0 | |||
| LV2_Handle handle, h2; | |||
| const LV2_Descriptor* descriptor; | |||
| const LV2_RDF_Descriptor* rdf_descriptor; | |||
| @@ -4576,20 +4595,20 @@ private: | |||
| LV2_State_Make_Path* stateMakePath; | |||
| LV2_State_Map_Path* stateMapPath; | |||
| } ft; | |||
| #endif | |||
| }; | |||
| /**@}*/ | |||
| // ------------------------------------------------------------------- | |||
| // static data | |||
| unsigned int Lv2Plugin::m_count = 0; | |||
| std::set<const LV2_Lib_Descriptor*> Lv2Plugin::libDescs; | |||
| //unsigned int Lv2Plugin::m_count = 0; | |||
| //std::set<const LV2_Lib_Descriptor*> Lv2Plugin::libDescs; | |||
| Lv2Plugin::Ft Lv2Plugin::ft = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; | |||
| //Lv2Plugin::Ft Lv2Plugin::ft = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; | |||
| // ------------------------------------------------------------------------------------------------------------------- | |||
| #if 0 | |||
| int CarlaEngineOsc::handleMsgLv2AtomTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||
| { | |||
| carla_debug("CarlaOsc::handleMsgLv2AtomTransfer()"); | |||
| @@ -4631,11 +4650,12 @@ int CarlaEngineOsc::handleMsgLv2EventTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||
| return 0; | |||
| } | |||
| #endif | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| #else // WANT_LV2 | |||
| //# warning Building without LV2 support | |||
| # warning Building without LV2 support | |||
| #endif | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| @@ -4645,17 +4665,9 @@ CarlaPlugin* CarlaPlugin::newLV2(const Initializer& init) | |||
| carla_debug("CarlaPlugin::newLV2(%p, \"%s\", \"%s\", \"%s\")", init.engine, init.filename, init.name, init.label); | |||
| #ifdef WANT_LV2 | |||
| short id = init.engine->getNewPluginId(); | |||
| if (id < 0 || id > init.engine->maxPluginNumber()) | |||
| { | |||
| init.engine->setLastError("Maximum number of plugins reached"); | |||
| return nullptr; | |||
| } | |||
| Lv2Plugin* const plugin = new Lv2Plugin(init.engine, id); | |||
| Lv2Plugin* const plugin = new Lv2Plugin(init.engine, init.id); | |||
| if (! plugin->init(init.filename, init.name, init.label)) | |||
| //if (! plugin->init(init.filename, init.name, init.label)) | |||
| { | |||
| delete plugin; | |||
| return nullptr; | |||
| @@ -4663,7 +4675,7 @@ CarlaPlugin* CarlaPlugin::newLV2(const Initializer& init) | |||
| plugin->reload(); | |||
| if (init.engine->getOptions().processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| if (init.engine->getProccessMode() == PROCESS_MODE_CONTINUOUS_RACK) | |||
| { | |||
| if (! (plugin->hints() & PLUGIN_CAN_FORCE_STEREO)) | |||
| { | |||
| @@ -4674,7 +4686,7 @@ CarlaPlugin* CarlaPlugin::newLV2(const Initializer& init) | |||
| } | |||
| plugin->registerToOscClient(); | |||
| plugin->updateUi(); | |||
| //plugin->updateUi(); | |||
| return plugin; | |||
| #else | |||
| @@ -31,7 +31,7 @@ endif | |||
| OBJS = \ | |||
| CarlaPlugin.cpp.o \ | |||
| CarlaPluginThread.cpp.o \ | |||
| CarlaBridge.cpp.o \ | |||
| BridgePlugin.cpp.o \ | |||
| NativePlugin.cpp.o \ | |||
| LadspaPlugin.cpp.o \ | |||
| DssiPlugin.cpp.o \ | |||
| @@ -17,6 +17,8 @@ | |||
| #include "CarlaPluginInternal.hpp" | |||
| #ifdef WANT_NATIVE | |||
| #include <QtGui/QFileDialog> | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| @@ -1630,23 +1632,23 @@ public: | |||
| static size_t getPluginCount() | |||
| { | |||
| maybeFirstInit(); | |||
| return sPluginDescriptors.size(); | |||
| return sPluginDescriptors.count(); | |||
| } | |||
| static const PluginDescriptor* getPlugin(const size_t index) | |||
| static const PluginDescriptor* getPluginDescriptor(const size_t index) | |||
| { | |||
| maybeFirstInit(); | |||
| CARLA_ASSERT(index < sPluginDescriptors.size()); | |||
| CARLA_ASSERT(index < sPluginDescriptors.count()); | |||
| if (index < sPluginDescriptors.size()) | |||
| return sPluginDescriptors[index]; | |||
| if (index < sPluginDescriptors.count()) | |||
| return sPluginDescriptors.getAt(index); | |||
| return nullptr; | |||
| } | |||
| static void registerPlugin(const PluginDescriptor* desc) | |||
| { | |||
| sPluginDescriptors.push_back(desc); | |||
| sPluginDescriptors.append(desc); | |||
| } | |||
| static void maybeFirstInit() | |||
| @@ -1693,9 +1695,10 @@ public: | |||
| // --------------------------------------------------------------- | |||
| // get descriptor that matches label | |||
| for (size_t i=0; i < sPluginDescriptors.size(); i++) | |||
| // FIXME - use itenerator when available | |||
| for (size_t i=0; i < sPluginDescriptors.count(); i++) | |||
| { | |||
| fDescriptor = sPluginDescriptors[i]; | |||
| fDescriptor = sPluginDescriptors.getAt(i); | |||
| if (fDescriptor == nullptr) | |||
| break; | |||
| @@ -1765,7 +1768,7 @@ private: | |||
| ::TimeInfo fTimeInfo; | |||
| static bool sFirstInit; | |||
| static std::vector<const PluginDescriptor*> sPluginDescriptors; | |||
| static NonRtList<const PluginDescriptor*> sPluginDescriptors; | |||
| // ------------------------------------------------------------------- | |||
| @@ -1786,7 +1789,7 @@ private: | |||
| return handlePtr->handleGetTimeInfo(); | |||
| } | |||
| static bool carla_host_write_midi_event(HostHandle handle, const MidiEvent* event) | |||
| static bool carla_host_write_midi_event(HostHandle handle, const ::MidiEvent* event) | |||
| { | |||
| return handlePtr->handleWriteMidiEvent(event); | |||
| } | |||
| @@ -1810,24 +1813,49 @@ private: | |||
| }; | |||
| bool NativePlugin::sFirstInit = true; | |||
| std::vector<const PluginDescriptor*> NativePlugin::sPluginDescriptors; | |||
| NonRtList<const PluginDescriptor*> NativePlugin::sPluginDescriptors; | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| void carla_register_native_plugin(const PluginDescriptor* desc) | |||
| { | |||
| CARLA_BACKEND_USE_NAMESPACE | |||
| NativePlugin::registerPlugin(desc); | |||
| } | |||
| #else // WANT_NATIVE | |||
| # warning Building without Internal plugin support | |||
| #endif | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| size_t CarlaPlugin::getNativePluginCount() | |||
| { | |||
| #ifdef WANT_NATIVE | |||
| return NativePlugin::getPluginCount(); | |||
| #else | |||
| return 0; | |||
| #endif | |||
| } | |||
| const PluginDescriptor* CarlaPlugin::getNativePluginDescriptor(const size_t index) | |||
| { | |||
| return NativePlugin::getPlugin(index); | |||
| #ifdef WANT_NATIVE | |||
| return NativePlugin::getPluginDescriptor(index); | |||
| #else | |||
| return nullptr; | |||
| // unused | |||
| (void)index; | |||
| #endif | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| CarlaPlugin* CarlaPlugin::newNative(const Initializer& init) | |||
| { | |||
| carla_debug("CarlaPlugin::newNative(%p, \"%s\", \"%s\", \"%s\")", init.engine, init.filename, init.name, init.label); | |||
| #ifdef WANT_NATIVE | |||
| NativePlugin* const plugin = new NativePlugin(init.engine, init.id); | |||
| if (! plugin->init(init.name, init.label)) | |||
| @@ -1848,16 +1876,10 @@ CarlaPlugin* CarlaPlugin::newNative(const Initializer& init) | |||
| plugin->registerToOscClient(); | |||
| return plugin; | |||
| #else | |||
| init.engine->setLastError("Internal plugins not available"); | |||
| return nullptr; | |||
| #endif | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| void carla_register_native_plugin(const PluginDescriptor* desc) | |||
| { | |||
| CARLA_BACKEND_USE_NAMESPACE | |||
| NativePlugin::registerPlugin(desc); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| @@ -27,13 +27,6 @@ | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| /*! | |||
| * @defgroup CarlaBackendVstPlugin Carla Backend VST Plugin | |||
| * | |||
| * The Carla Backend VST Plugin. | |||
| * @{ | |||
| */ | |||
| /*! | |||
| * @defgroup PluginHints Plugin Hints | |||
| * @{ | |||
| @@ -52,6 +45,7 @@ public: | |||
| { | |||
| carla_debug("VstPlugin::VstPlugin(%p, %i)", engine, id); | |||
| #if 0 | |||
| m_type = PLUGIN_VST; | |||
| effect = nullptr; | |||
| @@ -76,12 +70,14 @@ public: | |||
| // make plugin valid | |||
| srand(id); | |||
| unique1 = unique2 = rand(); | |||
| #endif | |||
| } | |||
| ~VstPlugin() | |||
| { | |||
| carla_debug("VstPlugin::~VstPlugin()"); | |||
| #if 0 | |||
| // make plugin invalid | |||
| unique2 += 1; | |||
| @@ -116,11 +112,18 @@ public: | |||
| effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f); | |||
| effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f); | |||
| } | |||
| #endif | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Information (base) | |||
| PluginType type() const | |||
| { | |||
| return PLUGIN_VST; | |||
| } | |||
| #if 0 | |||
| PluginCategory category() | |||
| { | |||
| CARLA_ASSERT(effect); | |||
| @@ -2344,6 +2347,7 @@ public: | |||
| return true; | |||
| } | |||
| #endif | |||
| private: | |||
| int unique1; | |||
| @@ -2361,7 +2365,7 @@ private: | |||
| VstTimeInfo_R vstTimeInfo; | |||
| struct { | |||
| GuiType type; | |||
| //GuiType type; | |||
| bool visible; | |||
| int width; | |||
| int height; | |||
| @@ -2376,12 +2380,10 @@ private: | |||
| VstPlugin* VstPlugin::lastVstPlugin = nullptr; | |||
| /**@}*/ | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| #else // WANT_VST | |||
| //# warning Building without VST support | |||
| # warning Building without VST support | |||
| #endif | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| @@ -2391,17 +2393,9 @@ CarlaPlugin* CarlaPlugin::newVST(const Initializer& init) | |||
| carla_debug("CarlaPlugin::newVST(%p, \"%s\", \"%s\", \"%s\")", init.engine, init.filename, init.name, init.label); | |||
| #ifdef WANT_VST | |||
| short id = init.engine->getNewPluginId(); | |||
| if (id < 0 || id > init.engine->maxPluginNumber()) | |||
| { | |||
| init.engine->setLastError("Maximum number of plugins reached"); | |||
| return nullptr; | |||
| } | |||
| VstPlugin* const plugin = new VstPlugin(init.engine, id); | |||
| VstPlugin* const plugin = new VstPlugin(init.engine, init.id); | |||
| if (! plugin->init(init.filename, init.name, init.label)) | |||
| //if (! plugin->init(init.filename, init.name, init.label)) | |||
| { | |||
| delete plugin; | |||
| return nullptr; | |||
| @@ -2409,7 +2403,7 @@ CarlaPlugin* CarlaPlugin::newVST(const Initializer& init) | |||
| plugin->reload(); | |||
| if (init.engine->getOptions().processMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
| if (init.engine->getProccessMode() == PROCESS_MODE_CONTINUOUS_RACK) | |||
| { | |||
| if (! (plugin->hints() & PLUGIN_CAN_FORCE_STEREO)) | |||
| { | |||
| @@ -56,6 +56,7 @@ LIBS = ../libcarla_engine.a | |||
| LIBS += ../libcarla_plugin.a | |||
| LIBS += ../libcarla_native.a | |||
| LIBS += ../../libs/rtmempool.a | |||
| LIBS += ../../libs/lilv.a | |||
| OBJS = \ | |||
| CarlaStandalone.cpp.o | |||
| @@ -3,7 +3,7 @@ | |||
| QT = core gui xml | |||
| CONFIG = debug link_pkgconfig qt warn_on | |||
| PKGCONFIG = jack liblo | |||
| PKGCONFIG = jack liblo fluidsynth linuxsampler | |||
| TARGET = carla-bridge-qtcreator | |||
| TEMPLATE = app | |||
| @@ -36,6 +36,7 @@ SOURCES += \ | |||
| SOURCES += \ | |||
| ../../backend/plugin/CarlaPlugin.cpp \ | |||
| ../../backend/plugin/CarlaPluginThread.cpp \ | |||
| ../../backend/plugin/BridgePlugin.cpp \ | |||
| ../../backend/plugin/NativePlugin.cpp \ | |||
| ../../backend/plugin/LadspaPlugin.cpp \ | |||
| ../../backend/plugin/DssiPlugin.cpp \ | |||
| @@ -112,8 +113,8 @@ DEFINES += DEBUG | |||
| DEFINES += BUILD_BRIDGE BUILD_BRIDGE_PLUGIN BRIDGE_PLUGIN | |||
| DEFINES += WANT_JACK | |||
| DEFINES += WANT_LADSPA WANT_DSSI | |||
| # WANT_LV2 WANT_VST | |||
| DEFINES += WANT_NATIVE WANT_LADSPA WANT_DSSI WANT_LV2 WANT_VST | |||
| DEFINES += WANT_FLUIDSYNTH WANT_LINUXSAMPLER | |||
| LIBS = -ldl \ | |||
| ../../libs/lilv.a \ | |||
| @@ -73,9 +73,9 @@ public: | |||
| return full; | |||
| } | |||
| bool lock() | |||
| void lock() | |||
| { | |||
| return mutex.lock(); | |||
| mutex.lock(); | |||
| } | |||
| bool tryLock() | |||
| @@ -83,9 +83,9 @@ public: | |||
| return mutex.tryLock(); | |||
| } | |||
| bool unlock() | |||
| void unlock() | |||
| { | |||
| return mutex.unlock(); | |||
| mutex.unlock(); | |||
| } | |||
| void put(const uint32_t portIndex, const LV2_Atom* const atom) | |||