diff --git a/source/backend/plugin/CarlaPluginLinuxSampler.cpp b/source/backend/plugin/CarlaPluginLinuxSampler.cpp index 406661e4b..4b024b9e9 100644 --- a/source/backend/plugin/CarlaPluginLinuxSampler.cpp +++ b/source/backend/plugin/CarlaPluginLinuxSampler.cpp @@ -131,8 +131,6 @@ public: : MidiInputPort(device, portNum), leakDetector_MidiInputPortPlugin() {} - ~MidiInputPortPlugin() override {} - CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MidiInputPortPlugin) }; @@ -144,7 +142,17 @@ class MidiInputDevicePlugin : public MidiInputDevice public: MidiInputDevicePlugin(Sampler* const sampler) : MidiInputDevice(std::map(), sampler), - leakDetector_MidiInputDevicePlugin() {} + leakDetector_MidiInputDevicePlugin() + { + AcquirePorts(1); + } + + ~MidiInputDevicePlugin() override + { + for (std::map::iterator it = Ports.begin(), end = Ports.end(); it != end; ++it) + delete dynamic_cast(it->second); + Ports.clear(); + } // ------------------------------------------------------------------- // LinuxSampler virtual methods @@ -159,7 +167,7 @@ public: MidiInputPort* CreateMidiPort() override { - return new MidiInputPortPlugin(this, int(Ports.size())); + return new MidiInputPortPlugin(this, int(PortCount())); } // ------------------------------------------------------------------- @@ -196,18 +204,21 @@ public: fMaker(nullptr), fRealName(nullptr), sSampler(), - fAudioOutputDevice(nullptr), + fAudioOutputDevice(engine, this, kUses16Outs), fMidiInputDevice(sSampler), fMidiInputPort(nullptr), - fInstrument(nullptr), fInstrumentIds(), + fInstrumentInfo(), leakDetector_CarlaPluginLinuxSampler() { carla_debug("CarlaPluginLinuxSampler::CarlaPluginLinuxSampler(%p, %i, %s, %s)", engine, id, bool2str(isGIG), bool2str(use16Outs)); + sSampler->SetGlobalMaxStreams(300); + sSampler->SetGlobalMaxVoices(300); + carla_zeroStruct(fCurProgs, MAX_MIDI_CHANNELS); - carla_zeroStruct(fEngineChannels, MAX_MIDI_CHANNELS); carla_zeroStruct(fSamplerChannels, MAX_MIDI_CHANNELS); + carla_zeroStruct(fEngineChannels, MAX_MIDI_CHANNELS); if (use16Outs && ! isGIG) carla_stderr("Tried to use SFZ with 16 stereo outs, this doesn't make much sense so single stereo mode will be used instead"); @@ -229,36 +240,26 @@ public: pData->active = false; } - if (fMidiInputPort != nullptr) + fMidiInputPort = nullptr; + + for (uint i=0; iDisconnect(fEngineChannels[i]); - fEngineChannels[i]->DisconnectAudioOutputDevice(); - fEngineChannels[i] = nullptr; - } - - sSampler->sampler.RemoveSamplerChannel(fSamplerChannels[i]); - fSamplerChannels[i] = nullptr; + fEngineChannels[i]->DisconnectAudioOutputDevice(); + fEngineChannels[i]->DisconnectAllMidiInputPorts(); + fEngineChannels[i] = nullptr; } - } - - delete fMidiInputPort; - fMidiInputPort = nullptr; - } - if (fAudioOutputDevice != nullptr) - { - delete fAudioOutputDevice; - fAudioOutputDevice = nullptr; + sSampler->RemoveSamplerChannel(fSamplerChannels[i]); + fSamplerChannels[i] = nullptr; + } } - fInstrument = nullptr; fInstrumentIds.clear(); + fInstrumentInfo.clear(); if (fLabel != nullptr) { @@ -430,7 +431,7 @@ public: else { try { - fInstrument->LoadInstrumentInBackground(fInstrumentIds[uindex], engineChannel); + LinuxSampler::InstrumentManager::LoadInstrumentInBackground(fInstrumentIds[uindex], engineChannel); } CARLA_SAFE_EXCEPTION("LoadInstrumentInBackground"); } @@ -478,7 +479,7 @@ public: else { try { - fInstrument->LoadInstrumentInBackground(fInstrumentIds[uindex], engineChannel); + LinuxSampler::InstrumentManager::LoadInstrumentInBackground(fInstrumentIds[uindex], engineChannel); } CARLA_SAFE_EXCEPTION("LoadInstrumentInBackground"); } @@ -499,7 +500,6 @@ public: void reload() override { CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,); - CARLA_SAFE_ASSERT_RETURN(fInstrument != nullptr,); carla_debug("CarlaPluginLinuxSampler::reload() - start"); const EngineProcessMode processMode(pData->engine->getProccessMode()); @@ -641,7 +641,7 @@ public: pData->prog.clear(); // Query new programs - const uint32_t count(static_cast(fInstrumentIds.size())); + const uint32_t count(static_cast(fInstrumentInfo.size())); // sound kits must always have at least 1 midi-program CARLA_SAFE_ASSERT_RETURN(count > 0,); @@ -649,16 +649,8 @@ public: pData->prog.createNew(count); // Update data - LinuxSampler::InstrumentManager::instrument_info_t info; - for (uint32_t i=0; i < pData->prog.count; ++i) - { - try { - info = fInstrument->GetInstrumentInfo(fInstrumentIds[i]); - } CARLA_SAFE_EXCEPTION_CONTINUE("GetInstrumentInfo"); - - pData->prog.names[i] = carla_strdup_safe(info.InstrumentName.c_str()); - } + pData->prog.names[i] = carla_strdup_safe(fInstrumentInfo[i].InstrumentName.c_str()); #ifndef BUILD_BRIDGE // Update OSC Names @@ -679,7 +671,7 @@ public: CARLA_SAFE_ASSERT_CONTINUE(engineChannel != nullptr); try { - fInstrument->LoadInstrumentInBackground(fInstrumentIds[0], engineChannel); + LinuxSampler::InstrumentManager::LoadInstrumentInBackground(fInstrumentIds[0], engineChannel); } CARLA_SAFE_EXCEPTION("LoadInstrumentInBackground"); fCurProgs[i] = 0; @@ -931,7 +923,7 @@ public: else { try { - fInstrument->LoadInstrumentInBackground(fInstrumentIds[programId], engineChannel); + LinuxSampler::InstrumentManager::LoadInstrumentInBackground(fInstrumentIds[programId], engineChannel); } CARLA_SAFE_EXCEPTION("LoadInstrumentInBackground"); } @@ -1038,11 +1030,11 @@ public: for (uint32_t i=0; i < pData->audioOut.count; ++i) { - if (LinuxSampler::AudioChannel* const outDev = fAudioOutputDevice->Channel(i)) + if (LinuxSampler::AudioChannel* const outDev = fAudioOutputDevice.Channel(i)) outDev->SetBuffer(outBuffer[i] + timeOffset); } - fAudioOutputDevice->Render(frames); + fAudioOutputDevice.Render(frames); #ifndef BUILD_BRIDGE // -------------------------------------------------------------------------------------------------------- @@ -1102,16 +1094,12 @@ public: #ifndef CARLA_OS_WIN // FIXME, need to update linuxsampler win32 build void bufferSizeChanged(const uint32_t) override { - CARLA_SAFE_ASSERT_RETURN(fAudioOutputDevice != nullptr,); - - fAudioOutputDevice->ReconnectAll(); + fAudioOutputDevice.ReconnectAll(); } void sampleRateChanged(const double) override { - CARLA_SAFE_ASSERT_RETURN(fAudioOutputDevice != nullptr,); - - fAudioOutputDevice->ReconnectAll(); + fAudioOutputDevice.ReconnectAll(); } #endif @@ -1151,40 +1139,52 @@ public: // --------------------------------------------------------------- // Init LinuxSampler stuff - fAudioOutputDevice = new LinuxSampler::AudioOutputDevicePlugin(pData->engine, this, kUses16Outs); - fMidiInputDevice = new LinuxSampler::MidiInputDevicePlugin(sSampler); - fMidiInputPort = new LinuxSampler::MidiInputPortPlugin(fMidiInputDevice); + fMidiInputPort = fMidiInputDevice.GetPort(0); + + if (fMidiInputPort == nullptr) + { + pData->engine->setLastError("Failed to create LinuxSampler midi input port"); + return false; + } for (uint i=0; iAddSamplerChannel(); - CARLA_SAFE_ASSERT_CONTINUE(fSamplerChannels[i] != nullptr); + LinuxSampler::SamplerChannel* const samplerChannel(sSampler->AddSamplerChannel()); + CARLA_SAFE_ASSERT_CONTINUE(samplerChannel != nullptr); - fSamplerChannels[i]->SetEngineType(kIsGIG ? "GIG" : "SFZ"); - fSamplerChannels[i]->SetAudioOutputDevice(fAudioOutputDevice); + samplerChannel->SetEngineType(kIsGIG ? "GIG" : "SFZ"); + samplerChannel->SetAudioOutputDevice(&fAudioOutputDevice); + samplerChannel->SetMidiInputDevice(&fMidiInputDevice); + //samplerChannel->Connect(fMidiInputPort); - LinuxSampler::EngineChannel* const engineChannel(fSamplerChannels[i]->GetEngineChannel()); + LinuxSampler::EngineChannel* const engineChannel(samplerChannel->GetEngineChannel()); CARLA_SAFE_ASSERT_CONTINUE(engineChannel != nullptr); - // TODO REMOVE - fEngineChannels[i] = engineChannel; - engineChannel->Pan(0.0f); engineChannel->Volume(kIsGIG ? LinuxSampler::kVolumeMax/10.0f : LinuxSampler::kVolumeMax); // FIXME - engineChannel->Connect(fAudioOutputDevice); + engineChannel->SetMidiInstrumentMapToDefault(); if (kUses16Outs) { engineChannel->SetOutputChannel(0, i*2); engineChannel->SetOutputChannel(1, i*2 +1); - fMidiInputPort->Connect(engineChannel, static_cast(i)); + samplerChannel->SetMidiInputChannel(static_cast(i)); } else { engineChannel->SetOutputChannel(0, 0); engineChannel->SetOutputChannel(1, 1); - fMidiInputPort->Connect(engineChannel, LinuxSampler::midi_chan_all); + samplerChannel->SetMidiInputChannel(LinuxSampler::midi_chan_all); } + + fSamplerChannels[i] = samplerChannel; + fEngineChannels[i] = engineChannel; + } + + if (fSamplerChannels[0] == nullptr || fEngineChannels[0] == nullptr) + { + pData->engine->setLastError("Failed to get LinuxSampler engine channels"); + return false; } // --------------------------------------------------------------- @@ -1194,16 +1194,16 @@ public: if (engine == nullptr) { - pData->engine->setLastError("Failed to get LinuxSampler instrument manager"); + pData->engine->setLastError("Failed to get LinuxSampler engine via channel"); return false; } // --------------------------------------------------------------- // Get the Engine's Instrument Manager - fInstrument = engine->GetInstrumentManager(); + LinuxSampler::InstrumentManager* const instrumentMgr(engine->GetInstrumentManager()); - if (fInstrument == nullptr) + if (instrumentMgr == nullptr) { pData->engine->setLastError("Failed to get LinuxSampler instrument manager"); return false; @@ -1213,7 +1213,7 @@ public: // Load the Instrument via filename try { - fInstrumentIds = fInstrument->GetInstrumentFileContent(filename); + fInstrumentIds = instrumentMgr->GetInstrumentFileContent(filename); } catch (const LinuxSampler::InstrumentManagerException& e) { @@ -1224,22 +1224,23 @@ public: // --------------------------------------------------------------- // Get info - if (fInstrumentIds.size() == 0) + const std::size_t numInstruments(fInstrumentIds.size()); + + if (numInstruments == 0) { pData->engine->setLastError("Failed to find any instruments"); return false; } - LinuxSampler::InstrumentManager::instrument_info_t info; - - try { - info = fInstrument->GetInstrumentInfo(fInstrumentIds[0]); - } - catch (const LinuxSampler::InstrumentManagerException& e) + for (std::size_t i=0; iengine->setLastError(e.what()); - return false; + try { + fInstrumentInfo.push_back(instrumentMgr->GetInstrumentInfo(fInstrumentIds[i])); + } CARLA_SAFE_EXCEPTION("GetInstrumentInfo"); } + CARLA_SAFE_ASSERT(fInstrumentInfo.size() == numInstruments); + + LinuxSampler::InstrumentManager::instrument_info_t& info(fInstrumentInfo[0]); CarlaString label2(label != nullptr ? label : File(filename).getFileNameWithoutExtension().toRawUTF8()); @@ -1297,15 +1298,15 @@ private: SharedResourcePointer sSampler; - LinuxSampler::AudioOutputDevicePlugin* fAudioOutputDevice; - LinuxSampler::MidiInputDevicePlugin* fMidiInputDevice; - LinuxSampler::MidiInputPortPlugin* fMidiInputPort; + LinuxSampler::AudioOutputDevicePlugin fAudioOutputDevice; + LinuxSampler::MidiInputDevicePlugin fMidiInputDevice; + LinuxSampler::MidiInputPort* fMidiInputPort; LinuxSampler::SamplerChannel* fSamplerChannels[MAX_MIDI_CHANNELS]; - LinuxSampler::EngineChannel* fEngineChannels[MAX_MIDI_CHANNELS]; // TODO remove + LinuxSampler::EngineChannel* fEngineChannels[MAX_MIDI_CHANNELS]; - /* */ LinuxSampler::InstrumentManager* fInstrument; - std::vector fInstrumentIds; + std::vector fInstrumentIds; + std::vector fInstrumentInfo; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginLinuxSampler) };