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

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415
  1. /*
  2. * Carla LinuxSampler Plugin
  3. * Copyright (C) 2011-2014 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. /* TODO
  18. * - implement buffer size changes
  19. * - implement sample rate changes
  20. * - call outDev->ReconnectAll() after changing buffer size or sample rate
  21. * - use CARLA_SAFE_ASSERT_RETURN with err
  22. */
  23. #include "CarlaPluginInternal.hpp"
  24. #include "CarlaEngine.hpp"
  25. #ifdef WANT_LINUXSAMPLER
  26. #include "CarlaBackendUtils.hpp"
  27. #include "CarlaMathUtils.hpp"
  28. #include "linuxsampler/EngineFactory.h"
  29. #include <linuxsampler/Sampler.h>
  30. #include <QtCore/QFileInfo>
  31. #include <QtCore/QStringList>
  32. namespace LinuxSampler {
  33. using CarlaBackend::CarlaEngine;
  34. using CarlaBackend::CarlaPlugin;
  35. // -----------------------------------------------------------------------
  36. // LinuxSampler static values
  37. static const float kVolumeMax = 3.16227766f; // +10 dB
  38. static const float kVolumeMin = 0.0f; // -inf dB
  39. // -----------------------------------------------------------------------
  40. // LinuxSampler AudioOutputDevice Plugin
  41. class AudioOutputDevicePlugin : public AudioOutputDevice
  42. {
  43. public:
  44. AudioOutputDevicePlugin(const CarlaEngine* const engine, const CarlaPlugin* const plugin, const bool uses16Outs)
  45. : AudioOutputDevice(std::map<String, DeviceCreationParameter*>()),
  46. fEngine(engine),
  47. fPlugin(plugin)
  48. {
  49. CARLA_ASSERT(engine != nullptr);
  50. CARLA_ASSERT(plugin != nullptr);
  51. AcquireChannels(uses16Outs ? 32 : 2);
  52. }
  53. ~AudioOutputDevicePlugin() override {}
  54. // -------------------------------------------------------------------
  55. // LinuxSampler virtual methods
  56. void Play() override
  57. {
  58. }
  59. bool IsPlaying() override
  60. {
  61. return (fEngine->isRunning() && fPlugin->isEnabled());
  62. }
  63. void Stop() override
  64. {
  65. }
  66. uint MaxSamplesPerCycle() override
  67. {
  68. return fEngine->getBufferSize();
  69. }
  70. uint SampleRate() override
  71. {
  72. return uint(fEngine->getSampleRate());
  73. }
  74. String Driver() override
  75. {
  76. return "AudioOutputDevicePlugin";
  77. }
  78. AudioChannel* CreateChannel(uint channelNr) override
  79. {
  80. return new AudioChannel(channelNr, nullptr, 0);
  81. }
  82. // -------------------------------------------------------------------
  83. // Give public access to the RenderAudio call
  84. int Render(const uint samples)
  85. {
  86. return RenderAudio(samples);
  87. }
  88. // -------------------------------------------------------------------
  89. private:
  90. const CarlaEngine* const fEngine;
  91. const CarlaPlugin* const fPlugin;
  92. };
  93. // -----------------------------------------------------------------------
  94. // LinuxSampler MidiInputPort Plugin
  95. class MidiInputPortPlugin : public MidiInputPort
  96. {
  97. public:
  98. MidiInputPortPlugin(MidiInputDevice* const device, const int portNum)
  99. : MidiInputPort(device, portNum)
  100. {
  101. }
  102. ~MidiInputPortPlugin() override {}
  103. };
  104. // -----------------------------------------------------------------------
  105. // LinuxSampler MidiInputDevice Plugin
  106. class MidiInputDevicePlugin : public MidiInputDevice
  107. {
  108. public:
  109. MidiInputDevicePlugin(Sampler* const sampler)
  110. : MidiInputDevice(std::map<String, DeviceCreationParameter*>(), sampler)
  111. {
  112. }
  113. // -------------------------------------------------------------------
  114. // LinuxSampler virtual methods
  115. void Listen() override
  116. {
  117. }
  118. void StopListen() override
  119. {
  120. }
  121. String Driver() override
  122. {
  123. return "MidiInputDevicePlugin";
  124. }
  125. MidiInputPort* CreateMidiPort() override
  126. {
  127. return new MidiInputPortPlugin(this, int(Ports.size()));
  128. }
  129. MidiInputPortPlugin* CreateMidiPortPlugin()
  130. {
  131. return new MidiInputPortPlugin(this, int(Ports.size()));
  132. }
  133. };
  134. } // namespace LinuxSampler
  135. // -----------------------------------------------------------------------
  136. CARLA_BACKEND_START_NAMESPACE
  137. #if 0
  138. }
  139. #endif
  140. class LinuxSamplerPlugin : public CarlaPlugin
  141. {
  142. public:
  143. LinuxSamplerPlugin(CarlaEngine* const engine, const unsigned int id, const char* const format, const bool use16Outs)
  144. : CarlaPlugin(engine, id),
  145. fUses16Outs(use16Outs),
  146. fFormat(carla_strdup(format)),
  147. fLabel(nullptr),
  148. fMaker(nullptr),
  149. fRealName(nullptr),
  150. fEngine(nullptr),
  151. fAudioOutputDevice(nullptr),
  152. fMidiInputDevice(nullptr),
  153. fMidiInputPort(nullptr),
  154. fInstrument(nullptr)
  155. {
  156. carla_debug("LinuxSamplerPlugin::LinuxSamplerPlugin(%p, %i, %s, %s)", engine, id, format, bool2str(use16Outs));
  157. for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
  158. {
  159. fCurMidiProgs[0] = 0;
  160. fSamplerChannels[i] = nullptr;
  161. fEngineChannels[i] = nullptr;
  162. }
  163. }
  164. ~LinuxSamplerPlugin() override
  165. {
  166. carla_debug("LinuxSamplerPlugin::~LinuxSamplerPlugin()");
  167. pData->singleMutex.lock();
  168. pData->masterMutex.lock();
  169. if (pData->client != nullptr && pData->client->isActive())
  170. pData->client->deactivate();
  171. if (pData->active)
  172. {
  173. deactivate();
  174. pData->active = false;
  175. }
  176. if (fEngine != nullptr)
  177. {
  178. if (fMidiInputDevice != nullptr)
  179. {
  180. if (fMidiInputPort != nullptr)
  181. {
  182. for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
  183. {
  184. if (fSamplerChannels[i] != nullptr)
  185. {
  186. if (fEngineChannels[i] != nullptr)
  187. {
  188. fMidiInputPort->Disconnect(fEngineChannels[i]);
  189. fEngineChannels[i]->DisconnectAudioOutputDevice();
  190. fEngineChannels[i] = nullptr;
  191. }
  192. fSampler.RemoveSamplerChannel(fSamplerChannels[i]);
  193. fSamplerChannels[i] = nullptr;
  194. }
  195. }
  196. delete fMidiInputPort;
  197. fMidiInputPort = nullptr;
  198. }
  199. delete fMidiInputDevice;
  200. fMidiInputDevice = nullptr;
  201. }
  202. if (fAudioOutputDevice != nullptr)
  203. {
  204. delete fAudioOutputDevice;
  205. fAudioOutputDevice = nullptr;
  206. }
  207. fInstrument = nullptr;
  208. LinuxSampler::EngineFactory::Destroy(fEngine);
  209. fEngine = nullptr;
  210. }
  211. fInstrumentIds.clear();
  212. if (fFormat != nullptr)
  213. {
  214. delete[] fFormat;
  215. fFormat = nullptr;
  216. }
  217. if (fLabel != nullptr)
  218. {
  219. delete[] fLabel;
  220. fLabel = nullptr;
  221. }
  222. if (fMaker != nullptr)
  223. {
  224. delete[] fMaker;
  225. fMaker = nullptr;
  226. }
  227. if (fRealName != nullptr)
  228. {
  229. delete[] fRealName;
  230. fRealName = nullptr;
  231. }
  232. clearBuffers();
  233. }
  234. // -------------------------------------------------------------------
  235. // Information (base)
  236. PluginType getType() const noexcept override
  237. {
  238. return getPluginTypeFromString(fFormat);
  239. }
  240. PluginCategory getCategory() const noexcept override
  241. {
  242. return PLUGIN_CATEGORY_SYNTH;
  243. }
  244. // -------------------------------------------------------------------
  245. // Information (count)
  246. // nothing
  247. // -------------------------------------------------------------------
  248. // Information (current data)
  249. // nothing
  250. // -------------------------------------------------------------------
  251. // Information (per-plugin data)
  252. unsigned int getOptionsAvailable() const noexcept override
  253. {
  254. unsigned int options = 0x0;
  255. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  256. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  257. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  258. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  259. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  260. return options;
  261. }
  262. void getLabel(char* const strBuf) const noexcept override
  263. {
  264. if (fLabel != nullptr)
  265. std::strncpy(strBuf, fLabel, STR_MAX);
  266. else
  267. CarlaPlugin::getLabel(strBuf);
  268. }
  269. void getMaker(char* const strBuf) const noexcept override
  270. {
  271. if (fMaker != nullptr)
  272. std::strncpy(strBuf, fMaker, STR_MAX);
  273. else
  274. CarlaPlugin::getMaker(strBuf);
  275. }
  276. void getCopyright(char* const strBuf) const noexcept override
  277. {
  278. getMaker(strBuf);
  279. }
  280. void getRealName(char* const strBuf) const noexcept override
  281. {
  282. if (fRealName != nullptr)
  283. std::strncpy(strBuf, fRealName, STR_MAX);
  284. else
  285. CarlaPlugin::getRealName(strBuf);
  286. }
  287. // -------------------------------------------------------------------
  288. // Set data (state)
  289. void prepareForSave() override
  290. {
  291. char strBuf[STR_MAX+1];
  292. std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i", fCurMidiProgs[0], fCurMidiProgs[1], fCurMidiProgs[2], fCurMidiProgs[3],
  293. fCurMidiProgs[4], fCurMidiProgs[5], fCurMidiProgs[6], fCurMidiProgs[7],
  294. fCurMidiProgs[8], fCurMidiProgs[9], fCurMidiProgs[10], fCurMidiProgs[11],
  295. fCurMidiProgs[12], fCurMidiProgs[13], fCurMidiProgs[14], fCurMidiProgs[15]);
  296. CarlaPlugin::setCustomData(CUSTOM_DATA_TYPE_STRING, "midiPrograms", strBuf, false);
  297. }
  298. // -------------------------------------------------------------------
  299. // Set data (internal stuff)
  300. void setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) noexcept override
  301. {
  302. if (channel < MAX_MIDI_CHANNELS)
  303. pData->midiprog.current = fCurMidiProgs[channel];
  304. CarlaPlugin::setCtrlChannel(channel, sendOsc, sendCallback);
  305. }
  306. // -------------------------------------------------------------------
  307. // Set data (plugin-specific stuff)
  308. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
  309. {
  310. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
  311. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  312. CARLA_SAFE_ASSERT_RETURN(value != nullptr && value[0] != '\0',);
  313. carla_debug("LinuxSamplerPlugin::setCustomData(%s, \"%s\", \"%s\", %s)", type, key, value, bool2str(sendGui));
  314. if (std::strcmp(type, CUSTOM_DATA_TYPE_STRING) != 0)
  315. return carla_stderr2("LinuxSamplerPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui));
  316. if (std::strcmp(key, "midiPrograms") != 0)
  317. return carla_stderr2("LinuxSamplerPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui));
  318. if (fUses16Outs)
  319. {
  320. QStringList midiProgramList(QString(value).split(":", QString::SkipEmptyParts));
  321. if (midiProgramList.count() == MAX_MIDI_CHANNELS)
  322. {
  323. uint i = 0;
  324. foreach (const QString& midiProg, midiProgramList)
  325. {
  326. CARLA_SAFE_ASSERT_BREAK(i < MAX_MIDI_CHANNELS);
  327. bool ok;
  328. int index = midiProg.toInt(&ok);
  329. if (ok && index >= 0 && index < static_cast<int>(pData->midiprog.count))
  330. {
  331. const uint32_t bank = pData->midiprog.data[index].bank;
  332. const uint32_t program = pData->midiprog.data[index].program;
  333. const uint32_t rIndex = bank*128 + program;
  334. /*if (pData->engine->isOffline())
  335. {
  336. fEngineChannels[i]->PrepareLoadInstrument(pData->filename, rIndex);
  337. fEngineChannels[i]->LoadInstrument();
  338. }
  339. else*/
  340. {
  341. fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], fEngineChannels[i]);
  342. }
  343. fCurMidiProgs[i] = index;
  344. if (pData->ctrlChannel == static_cast<int32_t>(i))
  345. {
  346. pData->midiprog.current = index;
  347. pData->engine->callback(ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED, pData->id, index, 0, 0.0f, nullptr);
  348. }
  349. }
  350. ++i;
  351. }
  352. CARLA_SAFE_ASSERT(i == MAX_MIDI_CHANNELS);
  353. }
  354. }
  355. CarlaPlugin::setCustomData(type, key, value, sendGui);
  356. }
  357. void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  358. {
  359. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);
  360. if (index >= 0 && pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  361. {
  362. const uint32_t bank = pData->midiprog.data[index].bank;
  363. const uint32_t program = pData->midiprog.data[index].program;
  364. const uint32_t rIndex = bank*128 + program;
  365. LinuxSampler::EngineChannel* const engineChannel(fEngineChannels[pData->ctrlChannel]);
  366. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  367. /*if (pData->engine->isOffline())
  368. {
  369. engineChannel->PrepareLoadInstrument(pData->filename, rIndex);
  370. engineChannel->LoadInstrument();
  371. }
  372. else*/
  373. {
  374. try {
  375. fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], engineChannel);
  376. } catch(...) {}
  377. }
  378. fCurMidiProgs[pData->ctrlChannel] = index;
  379. }
  380. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
  381. }
  382. // -------------------------------------------------------------------
  383. // Set ui stuff
  384. // nothing
  385. // -------------------------------------------------------------------
  386. // Plugin state
  387. void reload() override
  388. {
  389. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  390. CARLA_SAFE_ASSERT_RETURN(fInstrument != nullptr,);
  391. carla_debug("LinuxSamplerPlugin::reload() - start");
  392. const EngineProcessMode processMode(pData->engine->getProccessMode());
  393. // Safely disable plugin for reload
  394. const ScopedDisabler sd(this);
  395. if (pData->active)
  396. deactivate();
  397. clearBuffers();
  398. uint32_t aOuts;
  399. aOuts = fUses16Outs ? 32 : 2;
  400. pData->audioOut.createNew(aOuts);
  401. const uint portNameSize(pData->engine->getMaxPortNameSize());
  402. CarlaString portName;
  403. // ---------------------------------------
  404. // Audio Outputs
  405. if (fUses16Outs)
  406. {
  407. for (uint32_t i=0; i < 32; ++i)
  408. {
  409. portName.clear();
  410. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  411. {
  412. portName = pData->name;
  413. portName += ":";
  414. }
  415. portName += "out-";
  416. if ((i+2)/2 < 9)
  417. portName += "0";
  418. portName += CarlaString((i+2)/2);
  419. if (i % 2 == 0)
  420. portName += "L";
  421. else
  422. portName += "R";
  423. portName.truncate(portNameSize);
  424. pData->audioOut.ports[i].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  425. pData->audioOut.ports[i].rindex = i;
  426. }
  427. }
  428. else
  429. {
  430. // out-left
  431. portName.clear();
  432. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  433. {
  434. portName = pData->name;
  435. portName += ":";
  436. }
  437. portName += "out-left";
  438. portName.truncate(portNameSize);
  439. pData->audioOut.ports[0].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  440. pData->audioOut.ports[0].rindex = 0;
  441. // out-right
  442. portName.clear();
  443. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  444. {
  445. portName = pData->name;
  446. portName += ":";
  447. }
  448. portName += "out-right";
  449. portName.truncate(portNameSize);
  450. pData->audioOut.ports[1].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false);
  451. pData->audioOut.ports[1].rindex = 1;
  452. }
  453. // ---------------------------------------
  454. // Event Input
  455. {
  456. portName.clear();
  457. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  458. {
  459. portName = pData->name;
  460. portName += ":";
  461. }
  462. portName += "events-in";
  463. portName.truncate(portNameSize);
  464. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true);
  465. }
  466. // ---------------------------------------
  467. // plugin hints
  468. pData->hints = 0x0;
  469. pData->hints |= PLUGIN_IS_SYNTH;
  470. pData->hints |= PLUGIN_CAN_VOLUME;
  471. if (! fUses16Outs)
  472. pData->hints |= PLUGIN_CAN_BALANCE;
  473. // extra plugin hints
  474. pData->extraHints = 0x0;
  475. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  476. if (fUses16Outs)
  477. pData->extraHints |= PLUGIN_EXTRA_HINT_USES_MULTI_PROGS;
  478. else
  479. pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
  480. bufferSizeChanged(pData->engine->getBufferSize());
  481. reloadPrograms(true);
  482. if (pData->active)
  483. activate();
  484. carla_debug("LinuxSamplerPlugin::reload() - end");
  485. }
  486. void reloadPrograms(bool doInit) override
  487. {
  488. carla_debug("LinuxSamplerPlugin::reloadPrograms(%s)", bool2str(doInit));
  489. // Delete old programs
  490. pData->midiprog.clear();
  491. // Query new programs
  492. uint32_t count = uint32_t(fInstrumentIds.size());
  493. // sound kits must always have at least 1 midi-program
  494. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  495. pData->midiprog.createNew(count);
  496. // Update data
  497. LinuxSampler::InstrumentManager::instrument_info_t info;
  498. for (uint32_t i=0; i < pData->midiprog.count; ++i)
  499. {
  500. pData->midiprog.data[i].bank = i / 128;
  501. pData->midiprog.data[i].program = i % 128;
  502. try {
  503. info = fInstrument->GetInstrumentInfo(fInstrumentIds[i]);
  504. }
  505. catch (const LinuxSampler::InstrumentManagerException&)
  506. {
  507. continue;
  508. }
  509. pData->midiprog.data[i].name = carla_strdup(info.InstrumentName.c_str());
  510. }
  511. #ifndef BUILD_BRIDGE
  512. // Update OSC Names
  513. if (pData->engine->isOscControlRegistered())
  514. {
  515. pData->engine->oscSend_control_set_midi_program_count(pData->id, count);
  516. for (uint32_t i=0; i < count; ++i)
  517. 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);
  518. }
  519. #endif
  520. if (doInit)
  521. {
  522. for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
  523. {
  524. CARLA_SAFE_ASSERT_CONTINUE(fEngineChannels[i] != nullptr);
  525. /*fEngineChannels[i]->PrepareLoadInstrument(pData->filename, 0);
  526. fEngineChannels[i]->LoadInstrument();*/
  527. fInstrument->LoadInstrumentInBackground(fInstrumentIds[0], fEngineChannels[i]);
  528. fCurMidiProgs[i] = 0;
  529. }
  530. pData->midiprog.current = 0;
  531. }
  532. else
  533. {
  534. pData->engine->callback(ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0.0f, nullptr);
  535. }
  536. }
  537. // -------------------------------------------------------------------
  538. // Plugin processing
  539. #if 0
  540. void activate() override
  541. {
  542. for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
  543. {
  544. if (fAudioOutputDevices[i] != nullptr)
  545. fAudioOutputDevices[i]->Play();
  546. }
  547. }
  548. void deactivate() override
  549. {
  550. for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
  551. {
  552. if (fAudioOutputDevices[i] != nullptr)
  553. fAudioOutputDevices[i]->Stop();
  554. }
  555. }
  556. #endif
  557. void process(float** const, float** const outBuffer, const uint32_t frames) override
  558. {
  559. // --------------------------------------------------------------------------------------------------------
  560. // Check if active
  561. if (! pData->active)
  562. {
  563. // disable any output sound
  564. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  565. FLOAT_CLEAR(outBuffer[i], frames);
  566. return;
  567. }
  568. // --------------------------------------------------------------------------------------------------------
  569. // Check if needs reset
  570. if (pData->needsReset)
  571. {
  572. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  573. {
  574. for (uint i=0; i < MAX_MIDI_CHANNELS; ++i)
  575. {
  576. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, i);
  577. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, i);
  578. }
  579. }
  580. else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  581. {
  582. for (uint8_t i=0; i < MAX_MIDI_NOTE; ++i)
  583. fMidiInputPort->DispatchNoteOff(i, 0, uint(pData->ctrlChannel));
  584. }
  585. pData->needsReset = false;
  586. }
  587. // --------------------------------------------------------------------------------------------------------
  588. // Event Input and Processing
  589. {
  590. // ----------------------------------------------------------------------------------------------------
  591. // MIDI Input (External)
  592. if (pData->extNotes.mutex.tryLock())
  593. {
  594. while (! pData->extNotes.data.isEmpty())
  595. {
  596. const ExternalMidiNote& note(pData->extNotes.data.getFirst(true));
  597. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  598. if (note.velo > 0)
  599. fMidiInputPort->DispatchNoteOn(note.note, note.velo, static_cast<uint>(note.channel));
  600. else
  601. fMidiInputPort->DispatchNoteOff(note.note, note.velo, static_cast<uint>(note.channel));
  602. }
  603. pData->extNotes.mutex.unlock();
  604. } // End of MIDI Input (External)
  605. // ----------------------------------------------------------------------------------------------------
  606. // Event Input (System)
  607. bool allNotesOffSent = false;
  608. bool sampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0;
  609. uint32_t nEvents = pData->event.portIn->getEventCount();
  610. uint32_t startTime = 0;
  611. uint32_t timeOffset = 0;
  612. uint32_t nextBankIds[MAX_MIDI_CHANNELS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0 };
  613. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0 && pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  614. nextBankIds[pData->ctrlChannel] = pData->midiprog.data[pData->midiprog.current].bank;
  615. for (uint32_t i=0; i < nEvents; ++i)
  616. {
  617. const EngineEvent& event(pData->event.portIn->getEvent(i));
  618. CARLA_SAFE_ASSERT_CONTINUE(event.time < frames);
  619. CARLA_SAFE_ASSERT_BREAK(event.time >= timeOffset);
  620. if (event.time > timeOffset && sampleAccurate)
  621. {
  622. if (processSingle(outBuffer, event.time - timeOffset, timeOffset))
  623. {
  624. startTime = 0;
  625. timeOffset = event.time;
  626. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0 && pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  627. nextBankIds[pData->ctrlChannel] = pData->midiprog.data[pData->midiprog.current].bank;
  628. }
  629. else
  630. startTime += timeOffset;
  631. }
  632. // Control change
  633. switch (event.type)
  634. {
  635. case kEngineEventTypeNull:
  636. break;
  637. case kEngineEventTypeControl:
  638. {
  639. const EngineControlEvent& ctrlEvent = event.ctrl;
  640. switch (ctrlEvent.type)
  641. {
  642. case kEngineControlEventTypeNull:
  643. break;
  644. case kEngineControlEventTypeParameter:
  645. {
  646. #ifndef BUILD_BRIDGE
  647. // Control backend stuff
  648. if (event.channel == pData->ctrlChannel)
  649. {
  650. float value;
  651. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  652. {
  653. value = ctrlEvent.value;
  654. setDryWet(value, false, false);
  655. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  656. }
  657. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  658. {
  659. value = ctrlEvent.value*127.0f/100.0f;
  660. setVolume(value, false, false);
  661. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  662. }
  663. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  664. {
  665. float left, right;
  666. value = ctrlEvent.value/0.5f - 1.0f;
  667. if (value < 0.0f)
  668. {
  669. left = -1.0f;
  670. right = (value*2.0f)+1.0f;
  671. }
  672. else if (value > 0.0f)
  673. {
  674. left = (value*2.0f)-1.0f;
  675. right = 1.0f;
  676. }
  677. else
  678. {
  679. left = -1.0f;
  680. right = 1.0f;
  681. }
  682. setBalanceLeft(left, false, false);
  683. setBalanceRight(right, false, false);
  684. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  685. pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  686. }
  687. }
  688. #endif
  689. // Control plugin parameters
  690. for (uint32_t k=0; k < pData->param.count; ++k)
  691. {
  692. if (pData->param.data[k].midiChannel != event.channel)
  693. continue;
  694. if (pData->param.data[k].midiCC != ctrlEvent.param)
  695. continue;
  696. if (pData->param.data[k].hints != PARAMETER_INPUT)
  697. continue;
  698. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  699. continue;
  700. float value;
  701. if (pData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  702. {
  703. value = (ctrlEvent.value < 0.5f) ? pData->param.ranges[k].min : pData->param.ranges[k].max;
  704. }
  705. else
  706. {
  707. value = pData->param.ranges[k].getUnnormalizedValue(ctrlEvent.value);
  708. if (pData->param.data[k].hints & PARAMETER_IS_INTEGER)
  709. value = std::rint(value);
  710. }
  711. setParameterValue(k, value, false, false, false);
  712. pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  713. }
  714. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)
  715. {
  716. fMidiInputPort->DispatchControlChange(uint8_t(ctrlEvent.param), uint8_t(ctrlEvent.value*127.0f), event.channel, static_cast<int32_t>(sampleAccurate ? startTime : event.time));
  717. }
  718. break;
  719. }
  720. case kEngineControlEventTypeMidiBank:
  721. if (event.channel < MAX_MIDI_CHANNELS && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  722. nextBankIds[event.channel] = ctrlEvent.param;
  723. break;
  724. case kEngineControlEventTypeMidiProgram:
  725. if (event.channel < MAX_MIDI_CHANNELS && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  726. {
  727. const uint32_t bankId(nextBankIds[event.channel]);
  728. const uint32_t progId(ctrlEvent.param);
  729. const uint32_t rIndex = bankId*128 + progId;
  730. for (uint32_t k=0; k < pData->midiprog.count; ++k)
  731. {
  732. if (pData->midiprog.data[k].bank == bankId && pData->midiprog.data[k].program == progId)
  733. {
  734. LinuxSampler::EngineChannel* const engineChannel(fEngineChannels[pData->ctrlChannel]);
  735. /*if (pData->engine->isOffline())
  736. {
  737. engineChannel->PrepareLoadInstrument(pData->filename, rIndex);
  738. engineChannel->LoadInstrument();
  739. }
  740. else*/
  741. {
  742. fInstrument->LoadInstrumentInBackground(fInstrumentIds[rIndex], engineChannel);
  743. }
  744. fCurMidiProgs[event.channel] = static_cast<int32_t>(k);
  745. if (event.channel == pData->ctrlChannel)
  746. pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, static_cast<int32_t>(k), 0, 0.0f);
  747. break;
  748. }
  749. }
  750. }
  751. break;
  752. case kEngineControlEventTypeAllSoundOff:
  753. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  754. {
  755. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_SOUND_OFF, 0, event.channel, static_cast<int32_t>(sampleAccurate ? startTime : event.time));
  756. }
  757. break;
  758. case kEngineControlEventTypeAllNotesOff:
  759. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  760. {
  761. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  762. {
  763. allNotesOffSent = true;
  764. sendMidiAllNotesOffToCallback();
  765. }
  766. fMidiInputPort->DispatchControlChange(MIDI_CONTROL_ALL_NOTES_OFF, 0, event.channel, static_cast<int32_t>(sampleAccurate ? startTime : event.time));
  767. }
  768. break;
  769. }
  770. break;
  771. }
  772. case kEngineEventTypeMidi:
  773. {
  774. const EngineMidiEvent& midiEvent(event.midi);
  775. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data));
  776. uint8_t channel = event.channel;
  777. // Fix bad note-off
  778. if (MIDI_IS_STATUS_NOTE_ON(status) && midiEvent.data[2] == 0)
  779. status = MIDI_STATUS_NOTE_OFF;
  780. if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status) && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  781. continue;
  782. if (MIDI_IS_STATUS_CONTROL_CHANGE(status) && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  783. continue;
  784. if (MIDI_IS_STATUS_CHANNEL_PRESSURE(status) && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  785. continue;
  786. if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  787. continue;
  788. // put back channel in data
  789. uint8_t data[EngineMidiEvent::kDataSize];
  790. std::memcpy(data, event.midi.data, EngineMidiEvent::kDataSize);
  791. if (status < 0xF0 && channel < MAX_MIDI_CHANNELS)
  792. data[0] = uint8_t(data[0] + channel);
  793. fMidiInputPort->DispatchRaw(data, static_cast<int32_t>(sampleAccurate ? startTime : event.time));
  794. if (status == MIDI_STATUS_NOTE_ON)
  795. pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, data[1], data[2]);
  796. else if (status == MIDI_STATUS_NOTE_OFF)
  797. pData->postponeRtEvent(kPluginPostRtEventNoteOff, channel,data[1], 0.0f);
  798. break;
  799. }
  800. }
  801. }
  802. pData->postRtEvents.trySplice();
  803. if (frames > timeOffset)
  804. processSingle(outBuffer, frames - timeOffset, timeOffset);
  805. } // End of Event Input and Processing
  806. }
  807. bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
  808. {
  809. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  810. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  811. // --------------------------------------------------------------------------------------------------------
  812. // Try lock, silence otherwise
  813. if (pData->engine->isOffline())
  814. {
  815. pData->singleMutex.lock();
  816. }
  817. else if (! pData->singleMutex.tryLock())
  818. {
  819. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  820. {
  821. for (uint32_t k=0; k < frames; ++k)
  822. outBuffer[i][k+timeOffset] = 0.0f;
  823. }
  824. return false;
  825. }
  826. // --------------------------------------------------------------------------------------------------------
  827. // Run plugin
  828. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  829. {
  830. if (LinuxSampler::AudioChannel* const outDev = fAudioOutputDevice->Channel(i))
  831. outDev->SetBuffer(outBuffer[i] + timeOffset);
  832. }
  833. fAudioOutputDevice->Render(frames);
  834. #ifndef BUILD_BRIDGE
  835. // --------------------------------------------------------------------------------------------------------
  836. // Post-processing (dry/wet, volume and balance)
  837. {
  838. const bool doVolume = (pData->hints & PLUGIN_CAN_VOLUME) > 0 && pData->postProc.volume != 1.0f;
  839. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) > 0 && (pData->postProc.balanceLeft != -1.0f || pData->postProc.balanceRight != 1.0f);
  840. float oldBufLeft[doBalance ? frames : 1];
  841. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  842. {
  843. // Balance
  844. if (doBalance)
  845. {
  846. if (i % 2 == 0)
  847. FLOAT_COPY(oldBufLeft, outBuffer[i], frames);
  848. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  849. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  850. for (uint32_t k=0; k < frames; ++k)
  851. {
  852. if (i % 2 == 0)
  853. {
  854. // left
  855. outBuffer[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  856. outBuffer[i][k] += outBuffer[i+1][k] * (1.0f - balRangeR);
  857. }
  858. else
  859. {
  860. // right
  861. outBuffer[i][k] = outBuffer[i][k] * balRangeR;
  862. outBuffer[i][k] += oldBufLeft[k] * balRangeL;
  863. }
  864. }
  865. }
  866. // Volume
  867. if (doVolume)
  868. {
  869. for (uint32_t k=0; k < frames; ++k)
  870. outBuffer[i][k+timeOffset] *= pData->postProc.volume;
  871. }
  872. }
  873. } // End of Post-processing
  874. #endif
  875. // --------------------------------------------------------------------------------------------------------
  876. pData->singleMutex.unlock();
  877. return true;
  878. }
  879. #ifndef CARLA_OS_WIN // FIXME, need to update linuxsampler win32 build
  880. void bufferSizeChanged(const uint32_t) override
  881. {
  882. CARLA_SAFE_ASSERT_RETURN(fAudioOutputDevice != nullptr,);
  883. fAudioOutputDevice->ReconnectAll();
  884. }
  885. void sampleRateChanged(const double) override
  886. {
  887. CARLA_SAFE_ASSERT_RETURN(fAudioOutputDevice != nullptr,);
  888. fAudioOutputDevice->ReconnectAll();
  889. }
  890. #endif
  891. // -------------------------------------------------------------------
  892. // Plugin buffers
  893. // nothing
  894. // -------------------------------------------------------------------
  895. const void* getExtraStuff() const noexcept override
  896. {
  897. static const char xtrue[] = "true";
  898. static const char xfalse[] = "false";
  899. return fUses16Outs ? xtrue : xfalse;
  900. }
  901. bool init(const char* const filename, const char* const name, const char* const label)
  902. {
  903. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  904. // ---------------------------------------------------------------
  905. // first checks
  906. if (pData->client != nullptr)
  907. {
  908. pData->engine->setLastError("Plugin client is already registered");
  909. return false;
  910. }
  911. if (filename == nullptr || filename[0] == '\0')
  912. {
  913. pData->engine->setLastError("null filename");
  914. return false;
  915. }
  916. if (label == nullptr || label[0] == '\0')
  917. {
  918. pData->engine->setLastError("null label");
  919. return false;
  920. }
  921. // ---------------------------------------------------------------
  922. // Store format
  923. CarlaString cstype(fFormat);
  924. cstype.toLower();
  925. const char* const ctype(cstype.buffer());
  926. // ---------------------------------------------------------------
  927. // Create the LinuxSampler Engine
  928. try {
  929. fEngine = LinuxSampler::EngineFactory::Create(ctype);
  930. }
  931. catch (LinuxSampler::Exception& e)
  932. {
  933. pData->engine->setLastError(e.what());
  934. return false;
  935. }
  936. // ---------------------------------------------------------------
  937. // Init LinuxSampler stuff
  938. fAudioOutputDevice = new LinuxSampler::AudioOutputDevicePlugin(pData->engine, this, fUses16Outs);
  939. fMidiInputDevice = new LinuxSampler::MidiInputDevicePlugin(&fSampler);
  940. fMidiInputPort = fMidiInputDevice->CreateMidiPortPlugin();
  941. for (uint i=0; i < MAX_MIDI_CHANNELS; ++i)
  942. {
  943. fSamplerChannels[i] = fSampler.AddSamplerChannel();
  944. CARLA_SAFE_ASSERT_CONTINUE(fSamplerChannels[i] != nullptr);
  945. fSamplerChannels[i]->SetEngineType(ctype);
  946. fSamplerChannels[i]->SetAudioOutputDevice(fAudioOutputDevice);
  947. fEngineChannels[i] = fSamplerChannels[i]->GetEngineChannel();
  948. CARLA_SAFE_ASSERT_CONTINUE(fEngineChannels[i] != nullptr);
  949. fEngineChannels[i]->Connect(fAudioOutputDevice);
  950. fEngineChannels[i]->Volume(LinuxSampler::kVolumeMax);
  951. if (fUses16Outs)
  952. {
  953. fEngineChannels[i]->SetOutputChannel(0, i*2);
  954. fEngineChannels[i]->SetOutputChannel(1, i*2 +1);
  955. }
  956. else
  957. {
  958. fEngineChannels[i]->SetOutputChannel(0, 0);
  959. fEngineChannels[i]->SetOutputChannel(1, 1);
  960. }
  961. fMidiInputPort->Connect(fEngineChannels[i], static_cast<LinuxSampler::midi_chan_t>(i));
  962. }
  963. // ---------------------------------------------------------------
  964. // Get the Engine's Instrument Manager
  965. fInstrument = fEngine->GetInstrumentManager();
  966. if (fInstrument == nullptr)
  967. {
  968. pData->engine->setLastError("Failed to get LinuxSampler instrument manager");
  969. return false;
  970. }
  971. // ---------------------------------------------------------------
  972. // Load the Instrument via filename
  973. try {
  974. fInstrumentIds = fInstrument->GetInstrumentFileContent(filename);
  975. }
  976. catch (const LinuxSampler::InstrumentManagerException& e)
  977. {
  978. pData->engine->setLastError(e.what());
  979. return false;
  980. }
  981. // ---------------------------------------------------------------
  982. // Get info
  983. if (fInstrumentIds.size() == 0)
  984. {
  985. pData->engine->setLastError("Failed to find any instruments");
  986. return false;
  987. }
  988. LinuxSampler::InstrumentManager::instrument_info_t info;
  989. try {
  990. info = fInstrument->GetInstrumentInfo(fInstrumentIds[0]);
  991. }
  992. catch (const LinuxSampler::InstrumentManagerException& e)
  993. {
  994. pData->engine->setLastError(e.what());
  995. return false;
  996. }
  997. CarlaString label2(label);
  998. if (fUses16Outs && ! label2.endsWith(" (16 outs)"))
  999. label2 += " (16 outs)";
  1000. fLabel = label2.dup();
  1001. fMaker = carla_strdup(info.Artists.c_str());
  1002. fRealName = carla_strdup(info.InstrumentName.c_str());
  1003. pData->filename = carla_strdup(filename);
  1004. if (name != nullptr && name[0] != '\0')
  1005. pData->name = pData->engine->getUniquePluginName(name);
  1006. else if (fRealName[0] != '\0')
  1007. pData->name = pData->engine->getUniquePluginName(fRealName);
  1008. else
  1009. pData->name = pData->engine->getUniquePluginName(label);
  1010. // ---------------------------------------------------------------
  1011. // register client
  1012. pData->client = pData->engine->addClient(this);
  1013. if (pData->client == nullptr || ! pData->client->isOk())
  1014. {
  1015. pData->engine->setLastError("Failed to register plugin client");
  1016. return false;
  1017. }
  1018. // ---------------------------------------------------------------
  1019. // load plugin settings
  1020. {
  1021. // set default options
  1022. pData->options = 0x0;
  1023. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  1024. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  1025. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  1026. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  1027. // set identifier string
  1028. CarlaString identifier(fFormat);
  1029. identifier += "/";
  1030. if (const char* const shortname = std::strrchr(filename, OS_SEP))
  1031. identifier += shortname+1;
  1032. else
  1033. identifier += label;
  1034. pData->identifier = identifier.dup();
  1035. // load settings
  1036. pData->options = pData->loadSettings(pData->options, getOptionsAvailable());
  1037. }
  1038. return true;
  1039. }
  1040. // -------------------------------------------------------------------
  1041. private:
  1042. const bool fUses16Outs;
  1043. const char* fFormat;
  1044. const char* fLabel;
  1045. const char* fMaker;
  1046. const char* fRealName;
  1047. int32_t fCurMidiProgs[MAX_MIDI_CHANNELS];
  1048. LinuxSampler::Sampler fSampler;
  1049. LinuxSampler::Engine* fEngine;
  1050. LinuxSampler::SamplerChannel* fSamplerChannels[MAX_MIDI_CHANNELS];
  1051. LinuxSampler::EngineChannel* fEngineChannels[MAX_MIDI_CHANNELS];
  1052. LinuxSampler::AudioOutputDevicePlugin* fAudioOutputDevice;
  1053. LinuxSampler::MidiInputDevicePlugin* fMidiInputDevice;
  1054. LinuxSampler::MidiInputPortPlugin* fMidiInputPort;
  1055. LinuxSampler::InstrumentManager* fInstrument;
  1056. std::vector<LinuxSampler::InstrumentManager::instrument_id_t> fInstrumentIds;
  1057. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LinuxSamplerPlugin)
  1058. };
  1059. CARLA_BACKEND_END_NAMESPACE
  1060. #endif // WANT_LINUXSAMPLER
  1061. CARLA_BACKEND_START_NAMESPACE
  1062. CarlaPlugin* CarlaPlugin::newLinuxSampler(const Initializer& init, const char* const format, const bool use16Outs)
  1063. {
  1064. carla_debug("LinuxSamplerPlugin::newLinuxSampler({%p, \"%s\", \"%s\", \"%s\", " P_INT64 "}, %s, %s)", init.engine, init.filename, init.name, init.label, init.uniqueId, format, bool2str(use16Outs));
  1065. #ifdef WANT_LINUXSAMPLER
  1066. if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && use16Outs)
  1067. {
  1068. init.engine->setLastError("Carla's rack mode can only work with Stereo modules, please choose the 2-channel only sample-library version");
  1069. return nullptr;
  1070. }
  1071. // -------------------------------------------------------------------
  1072. // Check if file exists
  1073. {
  1074. QFileInfo file(init.filename);
  1075. if (! file.exists())
  1076. {
  1077. init.engine->setLastError("Requested file does not exist");
  1078. return nullptr;
  1079. }
  1080. if (! file.isFile())
  1081. {
  1082. init.engine->setLastError("Requested file is not valid");
  1083. return nullptr;
  1084. }
  1085. if (! file.isReadable())
  1086. {
  1087. init.engine->setLastError("Requested file is not readable");
  1088. return nullptr;
  1089. }
  1090. }
  1091. LinuxSamplerPlugin* const plugin(new LinuxSamplerPlugin(init.engine, init.id, format, use16Outs));
  1092. if (! plugin->init(init.filename, init.name, init.label))
  1093. {
  1094. delete plugin;
  1095. return nullptr;
  1096. }
  1097. plugin->reload();
  1098. return plugin;
  1099. #else
  1100. init.engine->setLastError("linuxsampler support not available");
  1101. return nullptr;
  1102. // unused
  1103. (void)format;
  1104. (void)use16Outs;
  1105. #endif
  1106. }
  1107. CARLA_BACKEND_END_NAMESPACE