Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LinuxSamplerPlugin.cpp 39KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. /*
  2. * Carla LinuxSampler Plugin
  3. * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #ifdef WANT_LINUXSAMPLER
  19. #include "linuxsampler/EngineFactory.h"
  20. #include <linuxsampler/Sampler.h>
  21. namespace LinuxSampler {
  22. using CarlaBackend::CarlaEngine;
  23. using CarlaBackend::CarlaPlugin;
  24. // -----------------------------------------------------------------------
  25. // LinuxSampler static values
  26. static const float VOLUME_MAX = 3.16227766f; // +10 dB
  27. static const float VOLUME_MIN = 0.0f; // -inf dB
  28. // -----------------------------------------------------------------------
  29. // LinuxSampler AudioOutputDevice Plugin
  30. class AudioOutputDevicePlugin : public AudioOutputDevice
  31. {
  32. public:
  33. AudioOutputDevicePlugin(CarlaBackend::CarlaEngine* const engine, CarlaBackend::CarlaPlugin* const plugin)
  34. : AudioOutputDevice(std::map<String, DeviceCreationParameter*>()),
  35. fEngine(engine),
  36. fPlugin(plugin)
  37. {
  38. CARLA_ASSERT(engine != nullptr);
  39. CARLA_ASSERT(plugin != nullptr);
  40. }
  41. // -------------------------------------------------------------------
  42. // LinuxSampler virtual methods
  43. void Play() override
  44. {
  45. }
  46. bool IsPlaying() override
  47. {
  48. return (fEngine->isRunning() && fPlugin->isEnabled());
  49. }
  50. void Stop() override
  51. {
  52. }
  53. uint MaxSamplesPerCycle() override
  54. {
  55. return fEngine->getBufferSize();
  56. }
  57. uint SampleRate() override
  58. {
  59. return fEngine->getSampleRate();
  60. }
  61. String Driver() override
  62. {
  63. return "AudioOutputDevicePlugin";
  64. }
  65. AudioChannel* CreateChannel(uint channelNr) override
  66. {
  67. return new AudioChannel(channelNr, nullptr, 0);
  68. }
  69. // -------------------------------------------------------------------
  70. // Give public access to the RenderAudio call
  71. int Render(const uint samples)
  72. {
  73. return RenderAudio(samples);
  74. }
  75. private:
  76. CarlaEngine* const fEngine;
  77. CarlaPlugin* const fPlugin;
  78. };
  79. // -----------------------------------------------------------------------
  80. // LinuxSampler MidiInputDevice Plugin
  81. class MidiInputDevicePlugin : public MidiInputDevice
  82. {
  83. public:
  84. MidiInputDevicePlugin(Sampler* const sampler)
  85. : MidiInputDevice(std::map<String, DeviceCreationParameter*>(), sampler)
  86. {
  87. }
  88. // -------------------------------------------------------------------
  89. // LinuxSampler virtual methods
  90. void Listen() override
  91. {
  92. }
  93. void StopListen() override
  94. {
  95. }
  96. String Driver() override
  97. {
  98. return "MidiInputDevicePlugin";
  99. }
  100. MidiInputPort* CreateMidiPort() override
  101. {
  102. return new MidiInputPortPlugin(this, Ports.size());
  103. }
  104. // -------------------------------------------------------------------
  105. // Properly delete port (destructor is protected)
  106. void DeleteMidiPort(MidiInputPort* const port)
  107. {
  108. delete (MidiInputPortPlugin*)port;
  109. }
  110. // -------------------------------------------------------------------
  111. // MIDI Port implementation for this plugin MIDI input driver
  112. // (Constructor and destructor are protected)
  113. class MidiInputPortPlugin : public MidiInputPort
  114. {
  115. protected:
  116. MidiInputPortPlugin(MidiInputDevicePlugin* const device, const int portNumber)
  117. : MidiInputPort(device, portNumber) {}
  118. friend class MidiInputDevicePlugin;
  119. };
  120. };
  121. } // namespace LinuxSampler
  122. // -----------------------------------------------------------------------
  123. CARLA_BACKEND_START_NAMESPACE
  124. #if 0
  125. }
  126. #endif
  127. class LinuxSamplerPlugin : public CarlaPlugin
  128. {
  129. public:
  130. LinuxSamplerPlugin(CarlaEngine* const engine, const unsigned short id, const bool isGIG, const bool use16Outs)
  131. : CarlaPlugin(engine, id),
  132. kIsGIG(isGIG),
  133. kUses16Outs(use16Outs),
  134. fSampler(new LinuxSampler::Sampler()),
  135. fSamplerChannel(nullptr),
  136. fEngine(nullptr),
  137. fEngineChannel(nullptr),
  138. fAudioOutputDevice(new LinuxSampler::AudioOutputDevicePlugin(engine, this)),
  139. fMidiInputDevice(new LinuxSampler::MidiInputDevicePlugin(fSampler)),
  140. fMidiInputPort(fMidiInputDevice->CreateMidiPort()),
  141. fInstrument(nullptr)
  142. {
  143. carla_debug("LinuxSamplerPlugin::LinuxSamplerPlugin(%p, %i, %s)", engine, id, bool2str(isGIG));
  144. }
  145. ~LinuxSamplerPlugin() override
  146. {
  147. carla_debug("LinuxSamplerPlugin::~LinuxSamplerPlugin()");
  148. pData->singleMutex.lock();
  149. pData->masterMutex.lock();
  150. if (pData->client != nullptr && pData->client->isActive())
  151. pData->client->deactivate();
  152. if (pData->active)
  153. {
  154. deactivate();
  155. pData->active = false;
  156. }
  157. if (fEngine != nullptr)
  158. {
  159. if (fSamplerChannel != nullptr)
  160. {
  161. fMidiInputPort->Disconnect(fSamplerChannel->GetEngineChannel());
  162. fEngineChannel->DisconnectAudioOutputDevice();
  163. fSampler->RemoveSamplerChannel(fSamplerChannel);
  164. }
  165. LinuxSampler::EngineFactory::Destroy(fEngine);
  166. }
  167. // destructor is private
  168. fMidiInputDevice->DeleteMidiPort(fMidiInputPort);
  169. delete fMidiInputDevice;
  170. delete fAudioOutputDevice;
  171. delete fSampler;
  172. fInstrumentIds.clear();
  173. clearBuffers();
  174. }
  175. // -------------------------------------------------------------------
  176. // Information (base)
  177. PluginType getType() const noexcept override
  178. {
  179. return kIsGIG ? PLUGIN_GIG : PLUGIN_SFZ;
  180. }
  181. PluginCategory getCategory() const override
  182. {
  183. return PLUGIN_CATEGORY_SYNTH;
  184. }
  185. // -------------------------------------------------------------------
  186. // Information (count)
  187. // nothing
  188. // -------------------------------------------------------------------
  189. // Information (current data)
  190. // nothing
  191. // -------------------------------------------------------------------
  192. // Information (per-plugin data)
  193. unsigned int getOptionsAvailable() const override
  194. {
  195. unsigned int options = 0x0;
  196. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  197. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  198. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  199. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  200. return options;
  201. }
  202. void getLabel(char* const strBuf) const override
  203. {
  204. std::strncpy(strBuf, (const char*)fLabel, STR_MAX);
  205. }
  206. void getMaker(char* const strBuf) const override
  207. {
  208. std::strncpy(strBuf, (const char*)fMaker, STR_MAX);
  209. }
  210. void getCopyright(char* const strBuf) const override
  211. {
  212. getMaker(strBuf);
  213. }
  214. void getRealName(char* const strBuf) const override
  215. {
  216. std::strncpy(strBuf, (const char*)fRealName, STR_MAX);
  217. }
  218. // -------------------------------------------------------------------
  219. // Set data (state)
  220. // nothing
  221. // -------------------------------------------------------------------
  222. // Set data (internal stuff)
  223. // nothing
  224. // -------------------------------------------------------------------
  225. // Set data (plugin-specific stuff)
  226. void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) override
  227. {
  228. CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count));
  229. if (index < -1)
  230. index = -1;
  231. else if (index > static_cast<int32_t>(pData->midiprog.count))
  232. return;
  233. if (pData->ctrlChannel < 0 || pData->ctrlChannel >= 16)
  234. return;
  235. if (index >= 0)
  236. {
  237. const uint32_t bank = pData->midiprog.data[index].bank;
  238. const uint32_t program = pData->midiprog.data[index].program;
  239. const uint32_t rIndex = bank*128 + program;
  240. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  241. if (pData->engine->isOffline())
  242. {
  243. fEngineChannel->PrepareLoadInstrument((const char*)pData->filename, rIndex);
  244. fEngineChannel->LoadInstrument();
  245. }
  246. else
  247. {
  248. fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], fEngineChannel);
  249. }
  250. }
  251. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
  252. }
  253. // -------------------------------------------------------------------
  254. // Plugin state
  255. void reload() override
  256. {
  257. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  258. CARLA_SAFE_ASSERT_RETURN(fInstrument != nullptr,);
  259. carla_debug("LinuxSamplerPlugin::reload() - start");
  260. const EngineProcessMode processMode(pData->engine->getProccessMode());
  261. // Safely disable plugin for reload
  262. const ScopedDisabler sd(this);
  263. if (pData->active)
  264. deactivate();
  265. clearBuffers();
  266. uint32_t aOuts;
  267. aOuts = 2;
  268. pData->audioOut.createNew(aOuts);
  269. const int portNameSize = pData->engine->getMaxPortNameSize();
  270. CarlaString portName;
  271. // ---------------------------------------
  272. // Audio Outputs
  273. {
  274. // out-left
  275. portName.clear();
  276. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  277. {
  278. portName = pData->name;
  279. portName += ":";
  280. }
  281. portName += "out-left";
  282. portName.truncate(portNameSize);
  283. pData->audioOut.ports[0].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  284. pData->audioOut.ports[0].rindex = 0;
  285. // out-right
  286. portName.clear();
  287. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  288. {
  289. portName = pData->name;
  290. portName += ":";
  291. }
  292. portName += "out-right";
  293. portName.truncate(portNameSize);
  294. pData->audioOut.ports[1].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  295. pData->audioOut.ports[1].rindex = 1;
  296. }
  297. // ---------------------------------------
  298. // Event Input
  299. {
  300. portName.clear();
  301. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  302. {
  303. portName = pData->name;
  304. portName += ":";
  305. }
  306. portName += "event-in";
  307. portName.truncate(portNameSize);
  308. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true);
  309. }
  310. // ---------------------------------------
  311. // plugin hints
  312. pData->hints = 0x0;
  313. //pData->hints |= PLUGIN_IS_SYNTH;
  314. pData->hints |= PLUGIN_CAN_VOLUME;
  315. pData->hints |= PLUGIN_CAN_BALANCE;
  316. // extra plugin hints
  317. pData->extraHints = 0x0;
  318. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  319. pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
  320. bufferSizeChanged(pData->engine->getBufferSize());
  321. reloadPrograms(true);
  322. if (pData->active)
  323. activate();
  324. carla_debug("LinuxSamplerPlugin::reload() - end");
  325. }
  326. void reloadPrograms(bool init) override
  327. {
  328. carla_debug("LinuxSamplerPlugin::reloadPrograms(%s)", bool2str(init));
  329. // Delete old programs
  330. pData->midiprog.clear();
  331. // Query new programs
  332. uint32_t i, count = fInstrumentIds.size();
  333. // sound kits must always have at least 1 midi-program
  334. CARLA_ASSERT(count > 0);
  335. if (count == 0)
  336. return;
  337. pData->midiprog.createNew(count);
  338. LinuxSampler::InstrumentManager::instrument_info_t info;
  339. for (i=0; i < pData->midiprog.count; ++i)
  340. {
  341. pData->midiprog.data[i].bank = i / 128;
  342. pData->midiprog.data[i].program = i % 128;
  343. try {
  344. info = fInstrument->GetInstrumentInfo(fInstrumentIds[i]);
  345. }
  346. catch (const LinuxSampler::InstrumentManagerException&)
  347. {
  348. continue;
  349. }
  350. pData->midiprog.data[i].name = carla_strdup(info.InstrumentName.c_str());
  351. }
  352. #ifndef BUILD_BRIDGE
  353. // Update OSC Names
  354. if (pData->engine->isOscControlRegistered())
  355. {
  356. pData->engine->oscSend_control_set_midi_program_count(pData->id, count);
  357. for (i=0; i < count; ++i)
  358. pData->engine->oscSend_control_set_midi_program_data(pData->id, i, pData->midiprog.data[i].bank, pData->midiprog.data[i].program, pData->midiprog.data[i].name);
  359. }
  360. #endif
  361. if (init)
  362. {
  363. setMidiProgram(0, false, false, false);
  364. }
  365. else
  366. {
  367. pData->engine->callback(ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0.0f, nullptr);
  368. }
  369. }
  370. // -------------------------------------------------------------------
  371. // Plugin processing
  372. void activate() override
  373. {
  374. CARLA_ASSERT(fAudioOutputDevice != nullptr);
  375. fAudioOutputDevice->Play();
  376. }
  377. void deactivate() override
  378. {
  379. CARLA_ASSERT(fAudioOutputDevice != nullptr);
  380. fAudioOutputDevice->Stop();
  381. }
  382. void process(float** const, float** const outBuffer, const uint32_t frames) override
  383. {
  384. uint32_t i, k;
  385. // --------------------------------------------------------------------------------------------------------
  386. // Check if active
  387. if (! pData->active)
  388. {
  389. // disable any output sound
  390. for (i=0; i < pData->audioOut.count; ++i)
  391. {
  392. #ifdef HAVE_JUCE
  393. FloatVectorOperations::clear(outBuffer[i], frames);
  394. #else
  395. #endif
  396. }
  397. return;
  398. }
  399. // --------------------------------------------------------------------------------------------------------
  400. // Check if needs reset
  401. if (pData->needsReset)
  402. {
  403. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  404. {
  405. for (k=0, i=MAX_MIDI_CHANNELS; k < MAX_MIDI_CHANNELS; ++k)
  406. {
  407. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, k);
  408. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, k);
  409. }
  410. }
  411. else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  412. {
  413. for (k=0; k < MAX_MIDI_NOTE; ++k)
  414. fMidiInputPort->DispatchNoteOff(k, 0, pData->ctrlChannel);
  415. }
  416. pData->needsReset = false;
  417. }
  418. // --------------------------------------------------------------------------------------------------------
  419. // Event Input and Processing
  420. {
  421. // ----------------------------------------------------------------------------------------------------
  422. // MIDI Input (External)
  423. if (pData->extNotes.mutex.tryLock())
  424. {
  425. while (! pData->extNotes.data.isEmpty())
  426. {
  427. const ExternalMidiNote& note(pData->extNotes.data.getFirst(true));
  428. CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  429. if (note.velo > 0)
  430. fMidiInputPort->DispatchNoteOn(note.note, note.velo, note.channel, 0);
  431. else
  432. fMidiInputPort->DispatchNoteOff(note.note, note.velo, note.channel, 0);
  433. }
  434. pData->extNotes.mutex.unlock();
  435. } // End of MIDI Input (External)
  436. // ----------------------------------------------------------------------------------------------------
  437. // Event Input (System)
  438. bool allNotesOffSent = false;
  439. bool sampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0;
  440. uint32_t time, nEvents = pData->event.portIn->getEventCount();
  441. uint32_t startTime = 0;
  442. uint32_t timeOffset = 0;
  443. uint32_t nextBankId = 0;
  444. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
  445. nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
  446. for (i=0; i < nEvents; ++i)
  447. {
  448. const EngineEvent& event(pData->event.portIn->getEvent(i));
  449. time = event.time;
  450. if (time >= frames)
  451. continue;
  452. CARLA_ASSERT_INT2(time >= timeOffset, time, timeOffset);
  453. if (time > timeOffset && sampleAccurate)
  454. {
  455. if (processSingle(outBuffer, time - timeOffset, timeOffset))
  456. {
  457. startTime = 0;
  458. timeOffset = time;
  459. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
  460. nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
  461. else
  462. nextBankId = 0;
  463. }
  464. else
  465. startTime += timeOffset;
  466. }
  467. // Control change
  468. switch (event.type)
  469. {
  470. case kEngineEventTypeNull:
  471. break;
  472. case kEngineEventTypeControl:
  473. {
  474. const EngineControlEvent& ctrlEvent = event.ctrl;
  475. switch (ctrlEvent.type)
  476. {
  477. case kEngineControlEventTypeNull:
  478. break;
  479. case kEngineControlEventTypeParameter:
  480. {
  481. #ifndef BUILD_BRIDGE
  482. // Control backend stuff
  483. if (event.channel == pData->ctrlChannel)
  484. {
  485. float value;
  486. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) > 0)
  487. {
  488. value = ctrlEvent.value;
  489. setDryWet(value, false, false);
  490. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  491. }
  492. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) > 0)
  493. {
  494. value = ctrlEvent.value*127.0f/100.0f;
  495. setVolume(value, false, false);
  496. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  497. }
  498. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) > 0)
  499. {
  500. float left, right;
  501. value = ctrlEvent.value/0.5f - 1.0f;
  502. if (value < 0.0f)
  503. {
  504. left = -1.0f;
  505. right = (value*2.0f)+1.0f;
  506. }
  507. else if (value > 0.0f)
  508. {
  509. left = (value*2.0f)-1.0f;
  510. right = 1.0f;
  511. }
  512. else
  513. {
  514. left = -1.0f;
  515. right = 1.0f;
  516. }
  517. setBalanceLeft(left, false, false);
  518. setBalanceRight(right, false, false);
  519. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  520. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  521. }
  522. }
  523. #endif
  524. // Control plugin parameters
  525. for (k=0; k < pData->param.count; ++k)
  526. {
  527. if (pData->param.data[k].midiChannel != event.channel)
  528. continue;
  529. if (pData->param.data[k].midiCC != ctrlEvent.param)
  530. continue;
  531. if ((pData->param.data[k].hints & PARAMETER_IS_INPUT) == 0)
  532. continue;
  533. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  534. continue;
  535. double value;
  536. if (pData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  537. {
  538. value = (ctrlEvent.value < 0.5f) ? pData->param.ranges[k].min : pData->param.ranges[k].max;
  539. }
  540. else
  541. {
  542. value = pData->param.ranges[k].getUnnormalizedValue(ctrlEvent.value);
  543. if (pData->param.data[k].hints & PARAMETER_IS_INTEGER)
  544. value = std::rint(value);
  545. }
  546. setParameterValue(k, value, false, false, false);
  547. pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  548. }
  549. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)
  550. {
  551. fMidiInputPort->DispatchControlChange(ctrlEvent.param, ctrlEvent.value*127.0f, event.channel, sampleAccurate ? startTime : time);
  552. }
  553. break;
  554. }
  555. case kEngineControlEventTypeMidiBank:
  556. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  557. nextBankId = ctrlEvent.param;
  558. break;
  559. case kEngineControlEventTypeMidiProgram:
  560. if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  561. {
  562. const uint32_t nextProgramId = ctrlEvent.param;
  563. for (k=0; k < pData->midiprog.count; ++k)
  564. {
  565. if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId)
  566. {
  567. setMidiProgram(k, false, false, false);
  568. pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0f);
  569. break;
  570. }
  571. }
  572. }
  573. break;
  574. case kEngineControlEventTypeAllSoundOff:
  575. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  576. {
  577. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, event.channel, sampleAccurate ? startTime : time);
  578. }
  579. break;
  580. case kEngineControlEventTypeAllNotesOff:
  581. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  582. {
  583. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  584. {
  585. allNotesOffSent = true;
  586. sendMidiAllNotesOffToCallback();
  587. }
  588. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, event.channel, sampleAccurate ? startTime : time);
  589. }
  590. break;
  591. }
  592. break;
  593. }
  594. case kEngineEventTypeMidi:
  595. {
  596. const EngineMidiEvent& midiEvent(event.midi);
  597. uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent.data);
  598. uint8_t channel = event.channel;
  599. // Fix bad note-off (per DSSI spec)
  600. if (MIDI_IS_STATUS_NOTE_ON(status) && midiEvent.data[2] == 0)
  601. status -= 0x10;
  602. int32_t fragmentPos = sampleAccurate ? startTime : time;
  603. if (MIDI_IS_STATUS_NOTE_OFF(status))
  604. {
  605. const uint8_t note = midiEvent.data[1];
  606. fMidiInputPort->DispatchNoteOff(note, 0, channel, fragmentPos);
  607. pData->postponeRtEvent(kPluginPostRtEventNoteOff, channel, note, 0.0f);
  608. }
  609. else if (MIDI_IS_STATUS_NOTE_ON(status))
  610. {
  611. const uint8_t note = midiEvent.data[1];
  612. const uint8_t velo = midiEvent.data[2];
  613. fMidiInputPort->DispatchNoteOn(note, velo, channel, fragmentPos);
  614. pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, note, velo);
  615. }
  616. else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status) && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) != 0)
  617. {
  618. //const uint8_t note = midiEvent.data[1];
  619. //const uint8_t pressure = midiEvent.data[2];
  620. // unsupported
  621. }
  622. else if (MIDI_IS_STATUS_CONTROL_CHANGE(status) && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0)
  623. {
  624. const uint8_t control = midiEvent.data[1];
  625. const uint8_t value = midiEvent.data[2];
  626. fMidiInputPort->DispatchControlChange(control, value, channel, fragmentPos);
  627. }
  628. else if (MIDI_IS_STATUS_CHANNEL_PRESSURE(status) && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) != 0)
  629. {
  630. //const uint8_t pressure = midiEvent.data[1];
  631. // unsupported
  632. }
  633. else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) != 0)
  634. {
  635. const uint8_t lsb = midiEvent.data[1];
  636. const uint8_t msb = midiEvent.data[2];
  637. fMidiInputPort->DispatchPitchbend(((msb << 7) | lsb) - 8192, channel, fragmentPos);
  638. }
  639. break;
  640. }
  641. }
  642. }
  643. pData->postRtEvents.trySplice();
  644. if (frames > timeOffset)
  645. processSingle(outBuffer, frames - timeOffset, timeOffset);
  646. } // End of Event Input and Processing
  647. }
  648. bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
  649. {
  650. CARLA_ASSERT(outBuffer != nullptr);
  651. CARLA_ASSERT(frames > 0);
  652. if (outBuffer == nullptr)
  653. return false;
  654. if (frames == 0)
  655. return false;
  656. uint32_t i, k;
  657. // --------------------------------------------------------------------------------------------------------
  658. // Try lock, silence otherwise
  659. if (pData->engine->isOffline())
  660. {
  661. pData->singleMutex.lock();
  662. }
  663. else if (! pData->singleMutex.tryLock())
  664. {
  665. for (i=0; i < pData->audioOut.count; ++i)
  666. {
  667. for (k=0; k < frames; ++k)
  668. outBuffer[i][k+timeOffset] = 0.0f;
  669. }
  670. return false;
  671. }
  672. // --------------------------------------------------------------------------------------------------------
  673. // Run plugin
  674. fAudioOutputDevice->Channel(0)->SetBuffer(outBuffer[0] + timeOffset);
  675. fAudioOutputDevice->Channel(1)->SetBuffer(outBuffer[1] + timeOffset);
  676. // QUESTION: Need to clear it before?
  677. fAudioOutputDevice->Render(frames);
  678. #ifndef BUILD_BRIDGE
  679. // --------------------------------------------------------------------------------------------------------
  680. // Post-processing (dry/wet, volume and balance)
  681. {
  682. const bool doVolume = (pData->hints & PLUGIN_CAN_VOLUME) > 0 && pData->postProc.volume != 1.0f;
  683. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) > 0 && (pData->postProc.balanceLeft != -1.0f || pData->postProc.balanceRight != 1.0f);
  684. float oldBufLeft[doBalance ? frames : 1];
  685. for (i=0; i < pData->audioOut.count; ++i)
  686. {
  687. // Balance
  688. if (doBalance)
  689. {
  690. if (i % 2 == 0)
  691. {
  692. #ifdef HAVE_JUCE
  693. FloatVectorOperations::copy(oldBufLeft, outBuffer[i], frames);
  694. #else
  695. #endif
  696. }
  697. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  698. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  699. for (k=0; k < frames; ++k)
  700. {
  701. if (i % 2 == 0)
  702. {
  703. // left
  704. outBuffer[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  705. outBuffer[i][k] += outBuffer[i+1][k] * (1.0f - balRangeR);
  706. }
  707. else
  708. {
  709. // right
  710. outBuffer[i][k] = outBuffer[i][k] * balRangeR;
  711. outBuffer[i][k] += oldBufLeft[k] * balRangeL;
  712. }
  713. }
  714. }
  715. // Volume
  716. if (doVolume)
  717. {
  718. for (k=0; k < frames; ++k)
  719. outBuffer[i][k+timeOffset] *= pData->postProc.volume;
  720. }
  721. }
  722. } // End of Post-processing
  723. #endif
  724. // --------------------------------------------------------------------------------------------------------
  725. pData->singleMutex.unlock();
  726. return true;
  727. }
  728. // -------------------------------------------------------------------
  729. // Plugin buffers
  730. // nothing
  731. // -------------------------------------------------------------------
  732. const void* getExtraStuff() const noexcept override
  733. {
  734. return kUses16Outs ? (const void*)0x1 : nullptr;
  735. }
  736. bool init(const char* filename, const char* const name, const char* label)
  737. {
  738. CARLA_ASSERT(pData->engine != nullptr);
  739. CARLA_ASSERT(pData->client == nullptr);
  740. CARLA_ASSERT(filename != nullptr);
  741. CARLA_ASSERT(label != nullptr);
  742. // ---------------------------------------------------------------
  743. // first checks
  744. if (pData->engine == nullptr)
  745. {
  746. return false;
  747. }
  748. if (pData->client != nullptr)
  749. {
  750. pData->engine->setLastError("Plugin client is already registered");
  751. return false;
  752. }
  753. if (filename == nullptr)
  754. {
  755. pData->engine->setLastError("null filename");
  756. return false;
  757. }
  758. if (label == nullptr)
  759. {
  760. pData->engine->setLastError("null label");
  761. return false;
  762. }
  763. // ---------------------------------------------------------------
  764. // Check if file exists
  765. {
  766. // QFileInfo file(filename);
  767. //
  768. // if (! (file.exists() && file.isFile() && file.isReadable()))
  769. // {
  770. // pData->engine->setLastError("Requested file is not valid or does not exist");
  771. // return false;
  772. // }
  773. }
  774. // ---------------------------------------------------------------
  775. // Create the LinuxSampler Engine
  776. const char* const stype = kIsGIG ? "gig" : "sfz";
  777. try {
  778. fEngine = LinuxSampler::EngineFactory::Create(stype);
  779. }
  780. catch (LinuxSampler::Exception& e)
  781. {
  782. pData->engine->setLastError(e.what());
  783. return false;
  784. }
  785. // ---------------------------------------------------------------
  786. // Get the Engine's Instrument Manager
  787. fInstrument = fEngine->GetInstrumentManager();
  788. if (fInstrument == nullptr)
  789. {
  790. pData->engine->setLastError("Failed to get LinuxSampler instrument manager");
  791. LinuxSampler::EngineFactory::Destroy(fEngine);
  792. fEngine = nullptr;
  793. return false;
  794. }
  795. // ---------------------------------------------------------------
  796. // Load the Instrument via filename
  797. try {
  798. fInstrumentIds = fInstrument->GetInstrumentFileContent(filename);
  799. }
  800. catch (const LinuxSampler::InstrumentManagerException& e)
  801. {
  802. pData->engine->setLastError(e.what());
  803. LinuxSampler::EngineFactory::Destroy(fEngine);
  804. fEngine = nullptr;
  805. return false;
  806. }
  807. // ---------------------------------------------------------------
  808. // Get info
  809. if (fInstrumentIds.size() == 0)
  810. {
  811. pData->engine->setLastError("Failed to find any instruments");
  812. LinuxSampler::EngineFactory::Destroy(fEngine);
  813. fEngine = nullptr;
  814. return false;
  815. }
  816. LinuxSampler::InstrumentManager::instrument_info_t info;
  817. try {
  818. info = fInstrument->GetInstrumentInfo(fInstrumentIds[0]);
  819. }
  820. catch (const LinuxSampler::InstrumentManagerException& e)
  821. {
  822. pData->engine->setLastError(e.what());
  823. LinuxSampler::EngineFactory::Destroy(fEngine);
  824. fEngine = nullptr;
  825. return false;
  826. }
  827. fRealName = info.InstrumentName.c_str();
  828. fLabel = info.Product.c_str();
  829. fMaker = info.Artists.c_str();
  830. pData->filename = filename;
  831. if (kUses16Outs && ! fLabel.endsWith(" (16 outs)"))
  832. fLabel += " (16 outs)";
  833. if (name != nullptr)
  834. pData->name = pData->engine->getUniquePluginName(name);
  835. else
  836. pData->name = pData->engine->getUniquePluginName((const char*)fRealName);
  837. // ---------------------------------------------------------------
  838. // Register client
  839. pData->client = pData->engine->addClient(this);
  840. if (pData->client == nullptr || ! pData->client->isOk())
  841. {
  842. pData->engine->setLastError("Failed to register plugin client");
  843. LinuxSampler::EngineFactory::Destroy(fEngine);
  844. fEngine = nullptr;
  845. return false;
  846. }
  847. // ---------------------------------------------------------------
  848. // Init LinuxSampler stuff
  849. fSamplerChannel = fSampler->AddSamplerChannel();
  850. fSamplerChannel->SetEngineType(stype);
  851. fSamplerChannel->SetAudioOutputDevice(fAudioOutputDevice);
  852. fEngineChannel = fSamplerChannel->GetEngineChannel();
  853. fEngineChannel->Connect(fAudioOutputDevice);
  854. fEngineChannel->Volume(LinuxSampler::VOLUME_MAX);
  855. fMidiInputPort->Connect(fSamplerChannel->GetEngineChannel(), LinuxSampler::midi_chan_all);
  856. // ---------------------------------------------------------------
  857. // load plugin settings
  858. {
  859. // set default options
  860. pData->options = 0x0;
  861. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  862. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  863. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  864. // load settings
  865. pData->idStr = kIsGIG ? "GIG" : "SFZ";
  866. pData->idStr += "/";
  867. pData->idStr += label;
  868. pData->options = pData->loadSettings(pData->options, getOptionsAvailable());
  869. }
  870. return true;
  871. }
  872. // -------------------------------------------------------------------
  873. static CarlaPlugin* newLinuxSampler(const Initializer& init, bool isGIG, const bool use16Outs);
  874. private:
  875. const bool kIsGIG; // sfz if false
  876. const bool kUses16Outs;
  877. CarlaString fRealName;
  878. CarlaString fLabel;
  879. CarlaString fMaker;
  880. LinuxSampler::Sampler* fSampler;
  881. LinuxSampler::SamplerChannel* fSamplerChannel;
  882. LinuxSampler::Engine* fEngine;
  883. LinuxSampler::EngineChannel* fEngineChannel;
  884. LinuxSampler::AudioOutputDevicePlugin* fAudioOutputDevice;
  885. LinuxSampler::MidiInputDevicePlugin* fMidiInputDevice;
  886. LinuxSampler::MidiInputPort* fMidiInputPort;
  887. LinuxSampler::InstrumentManager* fInstrument;
  888. std::vector<LinuxSampler::InstrumentManager::instrument_id_t> fInstrumentIds;
  889. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LinuxSamplerPlugin)
  890. };
  891. CarlaPlugin* LinuxSamplerPlugin::newLinuxSampler(const Initializer& init, const bool isGIG, const bool use16Outs)
  892. {
  893. carla_debug("LinuxSamplerPlugin::newLinuxSampler({%p, \"%s\", \"%s\", \"%s\"}, %s, %s)", init.engine, init.filename, init.name, init.label, bool2str(isGIG), bool2str(use16Outs));
  894. if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && use16Outs)
  895. {
  896. init.engine->setLastError("Carla's rack mode can only work with Stereo modules, please choose the 2-channel only sample-library version");
  897. return nullptr;
  898. }
  899. LinuxSamplerPlugin* const plugin(new LinuxSamplerPlugin(init.engine, init.id, isGIG, use16Outs));
  900. if (! plugin->init(init.filename, init.name, init.label))
  901. {
  902. delete plugin;
  903. return nullptr;
  904. }
  905. plugin->reload();
  906. return plugin;
  907. }
  908. CARLA_BACKEND_END_NAMESPACE
  909. #endif // WANT_LINUXSAMPLER
  910. CARLA_BACKEND_START_NAMESPACE
  911. CarlaPlugin* CarlaPlugin::newGIG(const Initializer& init, const bool use16Outs)
  912. {
  913. carla_debug("CarlaPlugin::newGIG({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs));
  914. #ifdef WANT_LINUXSAMPLER
  915. return LinuxSamplerPlugin::newLinuxSampler(init, true, use16Outs);
  916. #else
  917. init.engine->setLastError("linuxsampler support not available");
  918. return nullptr;
  919. // unused
  920. (void)use16Outs;
  921. #endif
  922. }
  923. CarlaPlugin* CarlaPlugin::newSFZ(const Initializer& init, const bool use16Outs)
  924. {
  925. carla_debug("CarlaPlugin::newSFZ({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs));
  926. #ifdef WANT_LINUXSAMPLER
  927. return LinuxSamplerPlugin::newLinuxSampler(init, false, use16Outs);
  928. #else
  929. init.engine->setLastError("linuxsampler support not available");
  930. return nullptr;
  931. // unused
  932. (void)use16Outs;
  933. #endif
  934. }
  935. CARLA_BACKEND_END_NAMESPACE