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 37KB

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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  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 GPL.txt file
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #ifdef WANT_LINUXSAMPLER
  19. #include "linuxsampler/EngineFactory.h"
  20. #include <linuxsampler/Sampler.h>
  21. #include <QtCore/QFileInfo>
  22. // TODO - setMidiProgram()
  23. namespace LinuxSampler {
  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. kEngine(engine),
  36. kPlugin(plugin)
  37. {
  38. CARLA_ASSERT(engine != nullptr);
  39. CARLA_ASSERT(plugin != nullptr);
  40. }
  41. // -------------------------------------------------------------------
  42. // LinuxSampler virtual methods
  43. void Play()
  44. {
  45. }
  46. bool IsPlaying()
  47. {
  48. return (kEngine->isRunning() && kPlugin->enabled());
  49. }
  50. void Stop()
  51. {
  52. }
  53. uint MaxSamplesPerCycle()
  54. {
  55. return kEngine->getBufferSize();
  56. }
  57. uint SampleRate()
  58. {
  59. return kEngine->getSampleRate();
  60. }
  61. String Driver()
  62. {
  63. return "AudioOutputDevicePlugin";
  64. }
  65. AudioChannel* CreateChannel(uint channelNr)
  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. CarlaBackend::CarlaEngine* const kEngine;
  77. CarlaBackend::CarlaPlugin* const kPlugin;
  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()
  91. {
  92. }
  93. void StopListen()
  94. {
  95. }
  96. String Driver()
  97. {
  98. return "MidiInputDevicePlugin";
  99. }
  100. MidiInputPort* CreateMidiPort()
  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. {
  119. }
  120. friend class MidiInputDevicePlugin;
  121. };
  122. };
  123. } // namespace LinuxSampler
  124. // -----------------------------------------------------------------------
  125. CARLA_BACKEND_START_NAMESPACE
  126. class LinuxSamplerPlugin : public CarlaPlugin
  127. {
  128. public:
  129. LinuxSamplerPlugin(CarlaEngine* const engine, const unsigned short id, const bool isGIG, const bool use16Outs)
  130. : CarlaPlugin(engine, id),
  131. kIsGIG(isGIG),
  132. kUses16Outs(use16Outs),
  133. fSampler(nullptr),
  134. fSamplerChannel(nullptr),
  135. fEngine(nullptr),
  136. fEngineChannel(nullptr),
  137. fAudioOutputDevice(nullptr),
  138. fMidiInputDevice(nullptr),
  139. fMidiInputPort(nullptr),
  140. fInstrument(nullptr)
  141. {
  142. carla_debug("LinuxSamplerPlugin::LinuxSamplerPlugin(%p, %i, %s)", engine, id, bool2str(isGIG));
  143. fSampler = new LinuxSampler::Sampler;
  144. fAudioOutputDevice = new LinuxSampler::AudioOutputDevicePlugin(engine, this);
  145. fMidiInputDevice = new LinuxSampler::MidiInputDevicePlugin(fSampler);
  146. fMidiInputPort = fMidiInputDevice->CreateMidiPort();
  147. }
  148. ~LinuxSamplerPlugin()
  149. {
  150. carla_debug("LinuxSamplerPlugin::~LinuxSamplerPlugin()");
  151. kData->singleMutex.lock();
  152. kData->masterMutex.lock();
  153. if (kData->activeBefore)
  154. fAudioOutputDevice->Stop();
  155. if (fEngine != nullptr)
  156. {
  157. if (fSamplerChannel != nullptr)
  158. {
  159. fMidiInputPort->Disconnect(fSamplerChannel->GetEngineChannel());
  160. fEngineChannel->DisconnectAudioOutputDevice();
  161. fSampler->RemoveSamplerChannel(fSamplerChannel);
  162. }
  163. LinuxSampler::EngineFactory::Destroy(fEngine);
  164. }
  165. // destructor is private
  166. fMidiInputDevice->DeleteMidiPort(fMidiInputPort);
  167. delete fMidiInputDevice;
  168. delete fAudioOutputDevice;
  169. delete fSampler;
  170. fInstrumentIds.clear();
  171. }
  172. // -------------------------------------------------------------------
  173. // Information (base)
  174. PluginType type() const
  175. {
  176. return kIsGIG ? PLUGIN_GIG : PLUGIN_SFZ;
  177. }
  178. PluginCategory category()
  179. {
  180. return PLUGIN_CATEGORY_SYNTH;
  181. }
  182. // -------------------------------------------------------------------
  183. // Information (per-plugin data)
  184. unsigned int availableOptions()
  185. {
  186. unsigned int options = 0x0;
  187. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  188. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  189. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  190. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  191. return options;
  192. }
  193. void getLabel(char* const strBuf)
  194. {
  195. std::strncpy(strBuf, (const char*)fLabel, STR_MAX);
  196. }
  197. void getMaker(char* const strBuf)
  198. {
  199. std::strncpy(strBuf, (const char*)fMaker, STR_MAX);
  200. }
  201. void getCopyright(char* const strBuf)
  202. {
  203. getMaker(strBuf);
  204. }
  205. void getRealName(char* const strBuf)
  206. {
  207. std::strncpy(strBuf, (const char*)fRealName, STR_MAX);
  208. }
  209. // -------------------------------------------------------------------
  210. // Set data (plugin-specific stuff)
  211. void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback)
  212. {
  213. CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count));
  214. if (index < -1)
  215. index = -1;
  216. else if (index > static_cast<int32_t>(kData->midiprog.count))
  217. return;
  218. if (kData->ctrlChannel < 0 || kData->ctrlChannel >= 16)
  219. return;
  220. if (index >= 0)
  221. {
  222. // TODO
  223. //const uint32_t bank = kData->midiprog.data[index].bank;
  224. //const uint32_t program = kData->midiprog.data[index].program;
  225. //const ScopedProcessLocker spl(this);
  226. //fluid_synth_program_select(fSynth, kData->ctrlChannel, fSynthId, bank, program);
  227. }
  228. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
  229. }
  230. // -------------------------------------------------------------------
  231. // Plugin state
  232. void reload()
  233. {
  234. carla_debug("LinuxSamplerPlugin::reload() - start");
  235. CARLA_ASSERT(kData->engine != nullptr);
  236. CARLA_ASSERT(fInstrument != nullptr);
  237. if (kData->engine == nullptr)
  238. return;
  239. if (fInstrument == nullptr)
  240. return;
  241. const ProcessMode processMode(kData->engine->getProccessMode());
  242. // Safely disable plugin for reload
  243. const ScopedDisabler sd(this);
  244. deleteBuffers();
  245. uint32_t aOuts;
  246. aOuts = 2;
  247. kData->audioOut.createNew(aOuts);
  248. const int portNameSize = kData->engine->maxPortNameSize();
  249. CarlaString portName;
  250. // ---------------------------------------
  251. // Audio Outputs
  252. {
  253. // out-left
  254. portName.clear();
  255. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  256. {
  257. portName = fName;
  258. portName += ":";
  259. }
  260. portName += "out-left";
  261. portName.truncate(portNameSize);
  262. kData->audioOut.ports[0].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, false);
  263. kData->audioOut.ports[0].rindex = 0;
  264. // out-right
  265. portName.clear();
  266. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  267. {
  268. portName = fName;
  269. portName += ":";
  270. }
  271. portName += "out-right";
  272. portName.truncate(portNameSize);
  273. kData->audioOut.ports[1].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, false);
  274. kData->audioOut.ports[1].rindex = 1;
  275. }
  276. // ---------------------------------------
  277. // Event Input
  278. {
  279. portName.clear();
  280. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  281. {
  282. portName = fName;
  283. portName += ":";
  284. }
  285. portName += "event-in";
  286. portName.truncate(portNameSize);
  287. kData->event.portIn = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true);
  288. }
  289. // ---------------------------------------
  290. // plugin hints
  291. fHints = 0x0;
  292. fHints |= PLUGIN_IS_RTSAFE;
  293. fHints |= PLUGIN_IS_SYNTH;
  294. fHints |= PLUGIN_CAN_VOLUME;
  295. fHints |= PLUGIN_CAN_BALANCE;
  296. // extra plugin hints
  297. kData->extraHints = 0x0;
  298. kData->extraHints |= PLUGIN_HINT_CAN_RUN_RACK;
  299. // plugin options
  300. fOptions = 0x0;
  301. fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  302. fOptions |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  303. fOptions |= PLUGIN_OPTION_SEND_PITCHBEND;
  304. fOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  305. bufferSizeChanged(kData->engine->getBufferSize());
  306. reloadPrograms(true);
  307. carla_debug("LinuxSamplerPlugin::reload() - end");
  308. }
  309. void reloadPrograms(bool init)
  310. {
  311. carla_debug("LinuxSamplerPlugin::reloadPrograms(%s)", bool2str(init));
  312. // Delete old programs
  313. kData->midiprog.clear();
  314. // Query new programs
  315. uint32_t i, count = 0; fInstrumentIds.size();
  316. // sound kits must always have at least 1 midi-program
  317. CARLA_SAFE_ASSERT(count > 0); // FIXME
  318. if (count == 0)
  319. return;
  320. kData->midiprog.createNew(count);
  321. // Update data
  322. for (i=0; i < kData->midiprog.count; i++)
  323. {
  324. LinuxSampler::InstrumentManager::instrument_info_t info = fInstrument->GetInstrumentInfo(fInstrumentIds[i]);
  325. kData->midiprog.data[i].bank = i / 128;
  326. kData->midiprog.data[i].program = i % 128;
  327. kData->midiprog.data[i].name = carla_strdup(info.InstrumentName.c_str());
  328. }
  329. #ifndef BUILD_BRIDGE
  330. // Update OSC Names
  331. if (kData->engine->isOscControlRegistered())
  332. {
  333. kData->engine->osc_send_control_set_midi_program_count(fId, count);
  334. for (i=0; i < count; i++)
  335. 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);
  336. }
  337. #endif
  338. if (init)
  339. {
  340. setMidiProgram(0, false, false, false);
  341. }
  342. else
  343. {
  344. kData->engine->callback(CALLBACK_RELOAD_PROGRAMS, fId, 0, 0, 0.0f, nullptr);
  345. }
  346. }
  347. // -------------------------------------------------------------------
  348. // Plugin processing
  349. void process(float** const, float** const outBuffer, const uint32_t frames)
  350. {
  351. uint32_t i, k;
  352. // --------------------------------------------------------------------------------------------------------
  353. // Check if active
  354. if (! kData->active)
  355. {
  356. // disable any output sound
  357. for (i=0; i < kData->audioOut.count; i++)
  358. carla_zeroFloat(outBuffer[i], frames);
  359. if (kData->activeBefore)
  360. fAudioOutputDevice->Stop();
  361. kData->activeBefore = kData->active;
  362. return;
  363. }
  364. // --------------------------------------------------------------------------------------------------------
  365. // Check if not active before
  366. if (kData->needsReset || ! kData->activeBefore)
  367. {
  368. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  369. {
  370. for (k=0, i=MAX_MIDI_CHANNELS; k < MAX_MIDI_CHANNELS; k++)
  371. {
  372. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, k, 0);
  373. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, k, 0);
  374. }
  375. }
  376. if (kData->activeBefore)
  377. fAudioOutputDevice->Stop();
  378. fAudioOutputDevice->Play();
  379. kData->needsReset = false;
  380. }
  381. // --------------------------------------------------------------------------------------------------------
  382. // Event Input and Processing
  383. if (kData->event.portIn != nullptr && kData->activeBefore)
  384. {
  385. // ----------------------------------------------------------------------------------------------------
  386. // MIDI Input (External)
  387. if (kData->extNotes.mutex.tryLock())
  388. {
  389. while (! kData->extNotes.data.isEmpty())
  390. {
  391. const ExternalMidiNote& note = kData->extNotes.data.getFirst(true);
  392. CARLA_ASSERT(note.channel >= 0);
  393. if (note.velo > 0)
  394. fMidiInputPort->DispatchNoteOn(note.note, note.velo, note.channel, 0);
  395. else
  396. fMidiInputPort->DispatchNoteOff(note.note, note.velo, note.channel, 0);
  397. }
  398. kData->extNotes.mutex.unlock();
  399. } // End of MIDI Input (External)
  400. // ----------------------------------------------------------------------------------------------------
  401. // Event Input (System)
  402. bool allNotesOffSent = false;
  403. bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;
  404. uint32_t time, nEvents = kData->event.portIn->getEventCount();
  405. uint32_t startTime = 0;
  406. uint32_t timeOffset = 0;
  407. uint32_t nextBankId = 0;
  408. if (kData->midiprog.current >= 0 && kData->midiprog.count > 0)
  409. nextBankId = kData->midiprog.data[kData->midiprog.current].bank;
  410. for (i=0; i < nEvents; i++)
  411. {
  412. const EngineEvent& event = kData->event.portIn->getEvent(i);
  413. time = event.time;
  414. if (time >= frames)
  415. continue;
  416. CARLA_ASSERT_INT2(time >= timeOffset, time, timeOffset);
  417. if (time > timeOffset && sampleAccurate)
  418. {
  419. if (processSingle(outBuffer, time - timeOffset, timeOffset))
  420. {
  421. startTime = 0;
  422. timeOffset = time;
  423. if (kData->midiprog.current >= 0 && kData->midiprog.count > 0)
  424. nextBankId = kData->midiprog.data[kData->midiprog.current].bank;
  425. else
  426. nextBankId = 0;
  427. }
  428. else
  429. startTime += timeOffset;
  430. }
  431. // Control change
  432. switch (event.type)
  433. {
  434. case kEngineEventTypeNull:
  435. break;
  436. case kEngineEventTypeControl:
  437. {
  438. const EngineControlEvent& ctrlEvent = event.ctrl;
  439. switch (ctrlEvent.type)
  440. {
  441. case kEngineControlEventTypeNull:
  442. break;
  443. case kEngineControlEventTypeParameter:
  444. {
  445. // Control backend stuff
  446. if (event.channel == kData->ctrlChannel)
  447. {
  448. double value;
  449. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (fHints & PLUGIN_CAN_DRYWET) > 0)
  450. {
  451. value = ctrlEvent.value;
  452. setDryWet(value, false, false);
  453. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  454. continue;
  455. }
  456. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (fHints & PLUGIN_CAN_VOLUME) > 0)
  457. {
  458. value = ctrlEvent.value*127/100;
  459. setVolume(value, false, false);
  460. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  461. continue;
  462. }
  463. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (fHints & PLUGIN_CAN_BALANCE) > 0)
  464. {
  465. double left, right;
  466. value = ctrlEvent.value/0.5 - 1.0;
  467. if (value < 0.0)
  468. {
  469. left = -1.0;
  470. right = (value*2)+1.0;
  471. }
  472. else if (value > 0.0)
  473. {
  474. left = (value*2)-1.0;
  475. right = 1.0;
  476. }
  477. else
  478. {
  479. left = -1.0;
  480. right = 1.0;
  481. }
  482. setBalanceLeft(left, false, false);
  483. setBalanceRight(right, false, false);
  484. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  485. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  486. continue;
  487. }
  488. }
  489. // Control plugin parameters
  490. for (k=0; k < kData->param.count; k++)
  491. {
  492. if (kData->param.data[k].midiChannel != event.channel)
  493. continue;
  494. if (kData->param.data[k].midiCC != ctrlEvent.param)
  495. continue;
  496. if (kData->param.data[k].type != PARAMETER_INPUT)
  497. continue;
  498. if ((kData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  499. continue;
  500. double value;
  501. if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  502. {
  503. value = (ctrlEvent.value < 0.5f) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
  504. }
  505. else
  506. {
  507. value = kData->param.ranges[i].unnormalizeValue(ctrlEvent.value);
  508. if (kData->param.data[k].hints & PARAMETER_IS_INTEGER)
  509. value = std::rint(value);
  510. }
  511. setParameterValue(k, value, false, false, false);
  512. postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  513. }
  514. break;
  515. }
  516. case kEngineControlEventTypeMidiBank:
  517. if (event.channel == kData->ctrlChannel && (fOptions & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  518. nextBankId = ctrlEvent.param;
  519. break;
  520. case kEngineControlEventTypeMidiProgram:
  521. if (event.channel == kData->ctrlChannel && (fOptions & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  522. {
  523. const uint32_t nextProgramId = ctrlEvent.param;
  524. for (k=0; k < kData->midiprog.count; k++)
  525. {
  526. if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId)
  527. {
  528. setMidiProgram(k, false, false, false);
  529. postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0f);
  530. break;
  531. }
  532. }
  533. }
  534. break;
  535. case kEngineControlEventTypeAllSoundOff:
  536. if (event.channel == kData->ctrlChannel)
  537. {
  538. if (! allNotesOffSent)
  539. {
  540. allNotesOffSent = true;
  541. sendMidiAllNotesOff();
  542. }
  543. fAudioOutputDevice->Stop();
  544. fAudioOutputDevice->Play();
  545. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f);
  546. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f);
  547. }
  548. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  549. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, k, sampleAccurate ? startTime : time);
  550. break;
  551. case kEngineControlEventTypeAllNotesOff:
  552. if (event.channel == kData->ctrlChannel)
  553. {
  554. if (! allNotesOffSent)
  555. {
  556. allNotesOffSent = true;
  557. sendMidiAllNotesOff();
  558. }
  559. }
  560. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  561. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, k, sampleAccurate ? startTime : time);
  562. break;
  563. }
  564. break;
  565. }
  566. case kEngineEventTypeMidi:
  567. {
  568. const EngineMidiEvent& midiEvent = event.midi;
  569. uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent.data);
  570. uint8_t channel = event.channel;
  571. // Fix bad note-off (per DSSI spec)
  572. if (MIDI_IS_STATUS_NOTE_ON(status) && midiEvent.data[2] == 0)
  573. status -= 0x10;
  574. int32_t fragmentPos = sampleAccurate ? startTime : time;
  575. if (MIDI_IS_STATUS_NOTE_OFF(status))
  576. {
  577. const uint8_t note = midiEvent.data[1];
  578. fMidiInputPort->DispatchNoteOff(note, 0, channel, fragmentPos);
  579. postponeRtEvent(kPluginPostRtEventNoteOff, channel, note, 0.0f);
  580. }
  581. else if (MIDI_IS_STATUS_NOTE_ON(status))
  582. {
  583. const uint8_t note = midiEvent.data[1];
  584. const uint8_t velo = midiEvent.data[2];
  585. fMidiInputPort->DispatchNoteOn(note, velo, channel, fragmentPos);
  586. postponeRtEvent(kPluginPostRtEventNoteOn, channel, note, velo);
  587. }
  588. else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status) && (fOptions & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) != 0)
  589. {
  590. //const uint8_t note = midiEvent.data[1];
  591. //const uint8_t pressure = midiEvent.data[2];
  592. // unsupported
  593. }
  594. else if (MIDI_IS_STATUS_CONTROL_CHANGE(status) && (fOptions & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0)
  595. {
  596. const uint8_t control = midiEvent.data[1];
  597. const uint8_t value = midiEvent.data[2];
  598. fMidiInputPort->DispatchControlChange(control, value, channel, fragmentPos);
  599. }
  600. else if (MIDI_IS_STATUS_AFTERTOUCH(status) && (fOptions & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) != 0)
  601. {
  602. //const uint8_t pressure = midiEvent.data[1];
  603. // unsupported
  604. }
  605. else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) && (fOptions & PLUGIN_OPTION_SEND_PITCHBEND) != 0)
  606. {
  607. const uint8_t lsb = midiEvent.data[1];
  608. const uint8_t msb = midiEvent.data[2];
  609. fMidiInputPort->DispatchPitchbend(((msb << 7) | lsb) - 8192, channel, fragmentPos);
  610. }
  611. break;
  612. }
  613. }
  614. }
  615. kData->postRtEvents.trySplice();
  616. if (frames > timeOffset)
  617. processSingle(outBuffer, frames - timeOffset, timeOffset);
  618. } // End of Event Input and Processing
  619. // --------------------------------------------------------------------------------------------------------
  620. // Plugin processing (no events)
  621. else
  622. {
  623. processSingle(outBuffer, frames, 0);
  624. } // End of Plugin processing (no events)
  625. // --------------------------------------------------------------------------------------------------------
  626. kData->activeBefore = kData->active;
  627. }
  628. bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
  629. {
  630. CARLA_ASSERT(outBuffer != nullptr);
  631. CARLA_ASSERT(frames > 0);
  632. if (outBuffer == nullptr)
  633. return false;
  634. if (frames == 0)
  635. return false;
  636. uint32_t i, k;
  637. // --------------------------------------------------------------------------------------------------------
  638. // Try lock, silence otherwise
  639. if (kData->engine->isOffline())
  640. {
  641. kData->singleMutex.lock();
  642. }
  643. else if (! kData->singleMutex.tryLock())
  644. {
  645. for (i=0; i < kData->audioOut.count; i++)
  646. {
  647. for (k=0; k < frames; k++)
  648. outBuffer[i][k+timeOffset] = 0.0f;
  649. }
  650. return false;
  651. }
  652. // --------------------------------------------------------------------------------------------------------
  653. // Run plugin
  654. fAudioOutputDevice->Channel(0)->SetBuffer(outBuffer[0] + timeOffset);
  655. fAudioOutputDevice->Channel(1)->SetBuffer(outBuffer[1] + timeOffset);
  656. // QUESTION: Need to clear it before?
  657. fAudioOutputDevice->Render(frames);
  658. // --------------------------------------------------------------------------------------------------------
  659. // Post-processing (dry/wet, volume and balance)
  660. {
  661. const bool doVolume = (fHints & PLUGIN_CAN_VOLUME) > 0 && kData->postProc.volume != 1.0f;
  662. const bool doBalance = (fHints & PLUGIN_CAN_BALANCE) > 0 && (kData->postProc.balanceLeft != -1.0f || kData->postProc.balanceRight != 1.0f);
  663. float oldBufLeft[doBalance ? frames : 1];
  664. for (i=0; i < kData->audioOut.count; i++)
  665. {
  666. // Balance
  667. if (doBalance)
  668. {
  669. if (i % 2 == 0)
  670. carla_copyFloat(oldBufLeft, outBuffer[i], frames);
  671. float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f;
  672. float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f;
  673. for (k=0; k < frames; k++)
  674. {
  675. if (i % 2 == 0)
  676. {
  677. // left
  678. outBuffer[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  679. outBuffer[i][k] += outBuffer[i+1][k] * (1.0f - balRangeR);
  680. }
  681. else
  682. {
  683. // right
  684. outBuffer[i][k] = outBuffer[i][k] * balRangeR;
  685. outBuffer[i][k] += oldBufLeft[k] * balRangeL;
  686. }
  687. }
  688. }
  689. // Volume
  690. if (doVolume)
  691. {
  692. for (k=0; k < frames; k++)
  693. outBuffer[i][k+timeOffset] *= kData->postProc.volume;
  694. }
  695. }
  696. } // End of Post-processing
  697. // --------------------------------------------------------------------------------------------------------
  698. kData->singleMutex.unlock();
  699. return true;
  700. }
  701. // -------------------------------------------------------------------
  702. bool init(const char* filename, const char* const name, const char* label)
  703. {
  704. CARLA_ASSERT(kData->engine != nullptr);
  705. CARLA_ASSERT(kData->client == nullptr);
  706. CARLA_ASSERT(filename != nullptr);
  707. CARLA_ASSERT(label != nullptr);
  708. // ---------------------------------------------------------------
  709. // first checks
  710. if (kData->engine == nullptr)
  711. {
  712. return false;
  713. }
  714. if (kData->client != nullptr)
  715. {
  716. kData->engine->setLastError("Plugin client is already registered");
  717. return false;
  718. }
  719. if (filename == nullptr)
  720. {
  721. kData->engine->setLastError("null filename");
  722. return false;
  723. }
  724. if (label == nullptr)
  725. {
  726. kData->engine->setLastError("null label");
  727. return false;
  728. }
  729. // ---------------------------------------------------------------
  730. // Check if file exists
  731. {
  732. QFileInfo file(filename);
  733. if (! (file.exists() && file.isFile() && file.isReadable()))
  734. {
  735. kData->engine->setLastError("Requested file is not valid or does not exist");
  736. return false;
  737. }
  738. }
  739. // ---------------------------------------------------------------
  740. // Create the LinuxSampler Engine
  741. const char* const stype = kIsGIG ? "gig" : "sfz";
  742. try {
  743. fEngine = LinuxSampler::EngineFactory::Create(stype);
  744. }
  745. catch (LinuxSampler::Exception& e)
  746. {
  747. kData->engine->setLastError(e.what());
  748. return false;
  749. }
  750. // ---------------------------------------------------------------
  751. // Get the Engine's Instrument Manager
  752. try {
  753. fInstrument = fEngine->GetInstrumentManager();
  754. }
  755. catch (LinuxSampler::Exception& e)
  756. {
  757. kData->engine->setLastError(e.what());
  758. LinuxSampler::EngineFactory::Destroy(fEngine);
  759. return false;
  760. }
  761. // ---------------------------------------------------------------
  762. // Load the Instrument via filename
  763. try {
  764. fInstrumentIds = fInstrument->GetInstrumentFileContent(filename);
  765. }
  766. catch (LinuxSampler::Exception& e)
  767. {
  768. kData->engine->setLastError(e.what());
  769. LinuxSampler::EngineFactory::Destroy(fEngine);
  770. return false;
  771. }
  772. // ---------------------------------------------------------------
  773. // Get info
  774. if (fInstrumentIds.size() == 0)
  775. {
  776. kData->engine->setLastError("Failed to find any instruments");
  777. LinuxSampler::EngineFactory::Destroy(fEngine);
  778. return false;
  779. }
  780. else
  781. {
  782. LinuxSampler::InstrumentManager::instrument_info_t info = fInstrument->GetInstrumentInfo(fInstrumentIds[0]);
  783. fRealName = info.InstrumentName.c_str();
  784. fLabel = info.Product.c_str();
  785. fMaker = info.Artists.c_str();
  786. fFilename = filename;
  787. if (name != nullptr)
  788. fName = kData->engine->getNewUniquePluginName(name);
  789. else
  790. fName = kData->engine->getNewUniquePluginName((const char*)fRealName);
  791. }
  792. // ---------------------------------------------------------------
  793. // Register client
  794. kData->client = kData->engine->addClient(this);
  795. if (kData->client == nullptr || ! kData->client->isOk())
  796. {
  797. kData->engine->setLastError("Failed to register plugin client");
  798. LinuxSampler::EngineFactory::Destroy(fEngine);
  799. return false;
  800. }
  801. // ---------------------------------------------------------------
  802. // Init LinuxSampler stuff
  803. fSamplerChannel = fSampler->AddSamplerChannel();
  804. fSamplerChannel->SetEngineType(stype);
  805. fSamplerChannel->SetAudioOutputDevice(fAudioOutputDevice);
  806. fEngineChannel = fSamplerChannel->GetEngineChannel();
  807. fEngineChannel->Connect(fAudioOutputDevice);
  808. fEngineChannel->PrepareLoadInstrument(filename, 0); // todo - find instrument from label
  809. fEngineChannel->LoadInstrument();
  810. fEngineChannel->Volume(LinuxSampler::VOLUME_MAX);
  811. fMidiInputPort->Connect(fSamplerChannel->GetEngineChannel(), LinuxSampler::midi_chan_all);
  812. return true;
  813. }
  814. // -------------------------------------------------------------------
  815. static CarlaPlugin* newLinuxSampler(const Initializer& init, bool isGIG, const bool use16Outs);
  816. private:
  817. const bool kIsGIG;
  818. const bool kUses16Outs;
  819. CarlaString fRealName;
  820. CarlaString fLabel;
  821. CarlaString fMaker;
  822. LinuxSampler::Sampler* fSampler;
  823. LinuxSampler::SamplerChannel* fSamplerChannel;
  824. LinuxSampler::Engine* fEngine;
  825. LinuxSampler::EngineChannel* fEngineChannel;
  826. LinuxSampler::AudioOutputDevicePlugin* fAudioOutputDevice;
  827. LinuxSampler::MidiInputDevicePlugin* fMidiInputDevice;
  828. LinuxSampler::MidiInputPort* fMidiInputPort;
  829. LinuxSampler::InstrumentManager* fInstrument;
  830. std::vector<LinuxSampler::InstrumentManager::instrument_id_t> fInstrumentIds;
  831. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LinuxSamplerPlugin)
  832. };
  833. CarlaPlugin* LinuxSamplerPlugin::newLinuxSampler(const Initializer& init, const bool isGIG, const bool use16Outs)
  834. {
  835. carla_debug("LinuxSamplerPlugin::newLinuxSampler({%p, \"%s\", \"%s\", \"%s\"}, %s, %s)", init.engine, init.filename, init.name, init.label, bool2str(isGIG), bool2str(use16Outs));
  836. LinuxSamplerPlugin* const plugin = new LinuxSamplerPlugin(init.engine, init.id, isGIG, use16Outs);
  837. if (! plugin->init(init.filename, init.name, init.label))
  838. {
  839. delete plugin;
  840. return nullptr;
  841. }
  842. plugin->reload();
  843. return plugin;
  844. }
  845. CARLA_BACKEND_END_NAMESPACE
  846. #else // WANT_LINUXSAMPLER
  847. # warning linuxsampler not available (no GIG and SFZ support)
  848. #endif
  849. CARLA_BACKEND_START_NAMESPACE
  850. CarlaPlugin* CarlaPlugin::newGIG(const Initializer& init, const bool use16Outs)
  851. {
  852. carla_debug("CarlaPlugin::newGIG({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs));
  853. #ifdef WANT_LINUXSAMPLER
  854. return LinuxSamplerPlugin::newLinuxSampler(init, true, use16Outs);
  855. #else
  856. init.engine->setLastError("linuxsampler support not available");
  857. return nullptr;
  858. #endif
  859. }
  860. CarlaPlugin* CarlaPlugin::newSFZ(const Initializer& init, const bool use16Outs)
  861. {
  862. carla_debug("CarlaPlugin::newSFZ({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs));
  863. #ifdef WANT_LINUXSAMPLER
  864. return LinuxSamplerPlugin::newLinuxSampler(init, false, use16Outs);
  865. #else
  866. init.engine->setLastError("linuxsampler support not available");
  867. return nullptr;
  868. #endif
  869. }
  870. CARLA_BACKEND_END_NAMESPACE