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.

537 lines
15KB

  1. /*
  2. * Carla Plugin Engine
  3. * Copyright (C) 2012-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. #ifdef WANT_PLUGIN
  18. #include "CarlaEngineInternal.hpp"
  19. #include "CarlaBackendUtils.hpp"
  20. #include "CarlaMIDI.h"
  21. #include "DistrhoPlugin.hpp"
  22. using DISTRHO::d_cconst;
  23. using DISTRHO::d_string;
  24. CARLA_BACKEND_START_NAMESPACE
  25. // -----------------------------------------
  26. // Parameters
  27. static const unsigned char paramMap[] = {
  28. 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  29. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
  30. 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
  31. 0x50, 0x51, 0x52, 0x53, 0x54, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
  32. };
  33. static const unsigned int paramVolume = 5;
  34. static const unsigned int paramBalance = 6;
  35. static const unsigned int paramPan = 8;
  36. static const unsigned int paramCount = sizeof(paramMap);
  37. static const unsigned int programCount = 128;
  38. static const unsigned int stateCount = MAX_RACK_PLUGINS;
  39. // -----------------------------------------
  40. class CarlaEnginePlugin : public CarlaEngine,
  41. public DISTRHO::Plugin
  42. {
  43. public:
  44. CarlaEnginePlugin()
  45. : CarlaEngine(),
  46. DISTRHO::Plugin(paramCount, programCount, stateCount),
  47. paramBuffers{0.0f},
  48. prevParamBuffers{0.0f}
  49. {
  50. carla_debug("CarlaEnginePlugin::CarlaEnginePlugin()");
  51. // init parameters
  52. paramBuffers[paramVolume] = 100.0f;
  53. paramBuffers[paramBalance] = 63.5f;
  54. paramBuffers[paramPan] = 63.5f;
  55. prevParamBuffers[paramVolume] = 100.0f;
  56. prevParamBuffers[paramBalance] = 63.5f;
  57. prevParamBuffers[paramPan] = 63.5f;
  58. // set-up engine
  59. fOptions.processMode = PROCESS_MODE_CONTINUOUS_RACK;
  60. fOptions.transportMode = TRANSPORT_MODE_INTERNAL;
  61. fOptions.forceStereo = true;
  62. fOptions.preferPluginBridges = false;
  63. fOptions.preferUiBridges = false;
  64. init("Carla");
  65. }
  66. ~CarlaEnginePlugin() override
  67. {
  68. carla_debug("CarlaEnginePlugin::~CarlaEnginePlugin()");
  69. setAboutToClose();
  70. removeAllPlugins();
  71. close();
  72. }
  73. // -------------------------------------
  74. // CarlaEngine virtual calls
  75. bool init(const char* const clientName) override
  76. {
  77. carla_debug("CarlaEnginePlugin::init(\"%s\")", clientName);
  78. fBufferSize = d_bufferSize();
  79. fSampleRate = d_sampleRate();
  80. CarlaEngine::init(clientName);
  81. return true;
  82. }
  83. bool close() override
  84. {
  85. carla_debug("CarlaEnginePlugin::close()");
  86. CarlaEngine::close();
  87. return true;
  88. }
  89. bool isRunning() const override
  90. {
  91. return true;
  92. }
  93. bool isOffline() const override
  94. {
  95. return false;
  96. }
  97. EngineType type() const override
  98. {
  99. return kEngineTypePlugin;
  100. }
  101. protected:
  102. // ---------------------------------------------
  103. // DISTRHO Plugin Information
  104. const char* d_label() const override
  105. {
  106. return "Carla";
  107. }
  108. const char* d_maker() const override
  109. {
  110. return "falkTX";
  111. }
  112. const char* d_license() const override
  113. {
  114. return "GPL v2+";
  115. }
  116. uint32_t d_version() const override
  117. {
  118. return 0x0600;
  119. }
  120. long d_uniqueId() const override
  121. {
  122. return d_cconst('C', 'r', 'l', 'a');
  123. }
  124. // ---------------------------------------------
  125. // DISTRHO Plugin Init
  126. void d_initParameter(uint32_t index, DISTRHO::Parameter& parameter) override
  127. {
  128. if (index >= paramCount)
  129. return;
  130. parameter.hints = DISTRHO::PARAMETER_IS_AUTOMABLE;
  131. parameter.ranges.def = 0.0f;
  132. parameter.ranges.min = 0.0f;
  133. parameter.ranges.max = 127.0f;
  134. if (index == paramVolume)
  135. parameter.ranges.def = 100.0f;
  136. else if (index == paramBalance)
  137. parameter.ranges.def = 63.5f;
  138. else if (index == paramPan)
  139. parameter.ranges.def = 63.5f;
  140. switch (paramMap[index])
  141. {
  142. case 0x01:
  143. parameter.name = "0x01 Modulation";
  144. break;
  145. case 0x02:
  146. parameter.name = "0x02 Breath";
  147. break;
  148. case 0x03:
  149. parameter.name = "0x03 (Undefined)";
  150. break;
  151. case 0x04:
  152. parameter.name = "0x04 Foot";
  153. break;
  154. case 0x05:
  155. parameter.name = "0x05 Portamento";
  156. break;
  157. case 0x07:
  158. parameter.name = "0x07 Volume";
  159. break;
  160. case 0x08:
  161. parameter.name = "0x08 Balance";
  162. break;
  163. case 0x09:
  164. parameter.name = "0x09 (Undefined)";
  165. break;
  166. case 0x0A:
  167. parameter.name = "0x0A Pan";
  168. break;
  169. case 0x0B:
  170. parameter.name = "0x0B Expression";
  171. break;
  172. case 0x0C:
  173. parameter.name = "0x0C FX Control 1";
  174. break;
  175. case 0x0D:
  176. parameter.name = "0x0D FX Control 2";
  177. break;
  178. case 0x0E:
  179. parameter.name = "0x0E (Undefined)";
  180. break;
  181. case 0x0F:
  182. parameter.name = "0x0F (Undefined)";
  183. break;
  184. case 0x10:
  185. parameter.name = "0x10 General Purpose 1";
  186. break;
  187. case 0x11:
  188. parameter.name = "0x11 General Purpose 2";
  189. break;
  190. case 0x12:
  191. parameter.name = "0x12 General Purpose 3";
  192. break;
  193. case 0x13:
  194. parameter.name = "0x13 General Purpose 4";
  195. break;
  196. case 0x14:
  197. parameter.name = "0x14 (Undefined)";
  198. break;
  199. case 0x15:
  200. parameter.name = "0x15 (Undefined)";
  201. break;
  202. case 0x16:
  203. parameter.name = "0x16 (Undefined)";
  204. break;
  205. case 0x17:
  206. parameter.name = "0x17 (Undefined)";
  207. break;
  208. case 0x18:
  209. parameter.name = "0x18 (Undefined)";
  210. break;
  211. case 0x19:
  212. parameter.name = "0x19 (Undefined)";
  213. break;
  214. case 0x1A:
  215. parameter.name = "0x1A (Undefined)";
  216. break;
  217. case 0x1B:
  218. parameter.name = "0x1B (Undefined)";
  219. break;
  220. case 0x1C:
  221. parameter.name = "0x1C (Undefined)";
  222. break;
  223. case 0x1D:
  224. parameter.name = "0x1D (Undefined)";
  225. break;
  226. case 0x1E:
  227. parameter.name = "0x1E (Undefined)";
  228. break;
  229. case 0x1F:
  230. parameter.name = "0x1F (Undefined)";
  231. break;
  232. case 0x46:
  233. parameter.name = "0x46 Control 1 [Variation]";
  234. break;
  235. case 0x47:
  236. parameter.name = "0x47 Control 2 [Timbre]";
  237. break;
  238. case 0x48:
  239. parameter.name = "0x48 Control 3 [Release]";
  240. break;
  241. case 0x49:
  242. parameter.name = "0x49 Control 4 [Attack]";
  243. break;
  244. case 0x4A:
  245. parameter.name = "0x4A Control 5 [Brightness]";
  246. break;
  247. case 0x4B:
  248. parameter.name = "0x4B Control 6 [Decay]";
  249. break;
  250. case 0x4C:
  251. parameter.name = "0x4C Control 7 [Vib Rate]";
  252. break;
  253. case 0x4D:
  254. parameter.name = "0x4D Control 8 [Vib Depth]";
  255. break;
  256. case 0x4E:
  257. parameter.name = "0x4E Control 9 [Vib Delay]";
  258. break;
  259. case 0x4F:
  260. parameter.name = "0x4F Control 10 [Undefined]";
  261. break;
  262. case 0x50:
  263. parameter.name = "0x50 General Purpose 5";
  264. break;
  265. case 0x51:
  266. parameter.name = "0x51 General Purpose 6";
  267. break;
  268. case 0x52:
  269. parameter.name = "0x52 General Purpose 7";
  270. break;
  271. case 0x53:
  272. parameter.name = "0x53 General Purpose 8";
  273. break;
  274. case 0x54:
  275. parameter.name = "0x54 Portamento Control";
  276. break;
  277. case 0x5B:
  278. parameter.name = "0x5B FX 1 Depth [Reverb]";
  279. break;
  280. case 0x5C:
  281. parameter.name = "0x5C FX 2 Depth [Tremolo]";
  282. break;
  283. case 0x5D:
  284. parameter.name = "0x5D FX 3 Depth [Chorus]";
  285. break;
  286. case 0x5E:
  287. parameter.name = "0x5E FX 4 Depth [Detune]";
  288. break;
  289. case 0x5F:
  290. parameter.name = "0x5F FX 5 Depth [Phaser]";
  291. break;
  292. }
  293. }
  294. void d_initProgramName(uint32_t index, d_string& programName) override
  295. {
  296. programName = "Program #" + d_string(index);
  297. }
  298. void d_initStateKey(uint32_t index, d_string& stateKey) override
  299. {
  300. stateKey = "Plugin #" + d_string(index);
  301. }
  302. // ---------------------------------------------
  303. // DISTRHO Plugin Internal data
  304. float d_parameterValue(uint32_t index) override
  305. {
  306. if (index >= paramCount)
  307. return 0.0f;
  308. return paramBuffers[index];
  309. }
  310. void d_setParameterValue(uint32_t index, float value) override
  311. {
  312. if (index >= paramCount)
  313. return;
  314. paramBuffers[index] = value;
  315. }
  316. void d_setProgram(uint32_t index) override
  317. {
  318. if (index >= programCount)
  319. return;
  320. if (kData->curPluginCount == 0)
  321. return;
  322. if (CarlaPlugin* const plugin = getPlugin(0))
  323. {
  324. if (plugin->programCount() > 0)
  325. {
  326. if (index <= plugin->programCount())
  327. plugin->setProgram(index, true, true, false);
  328. }
  329. else if (plugin->midiProgramCount())
  330. {
  331. if (index <= plugin->midiProgramCount())
  332. plugin->setMidiProgram(index, true, true, false);
  333. }
  334. }
  335. }
  336. void d_setState(const char* key, const char* value) override
  337. {
  338. // TODO
  339. (void)key;
  340. (void)value;
  341. }
  342. // ---------------------------------------------
  343. // DISTRHO Plugin Process
  344. void d_activate() override
  345. {
  346. static bool firstTestInit = true;
  347. if (firstTestInit)
  348. {
  349. firstTestInit = false;
  350. if (! addPlugin(PLUGIN_INTERNAL, nullptr, nullptr, "zynaddsubfx"))
  351. carla_stderr2("Plugin add zynaddsubfx failed");
  352. if (! addPlugin(PLUGIN_INTERNAL, nullptr, nullptr, "PingPongPan"))
  353. carla_stderr2("Plugin add Pan failed");
  354. }
  355. for (unsigned int i=0; i < kData->curPluginCount; ++i)
  356. {
  357. CarlaPlugin* const plugin(getPluginUnchecked(i));
  358. if (plugin != nullptr && plugin->enabled())
  359. plugin->setActive(true, true, false);
  360. }
  361. carla_copyFloat(prevParamBuffers, paramBuffers, paramCount);
  362. }
  363. void d_deactivate() override
  364. {
  365. for (unsigned int i=0; i < kData->curPluginCount; ++i)
  366. {
  367. CarlaPlugin* const plugin(getPluginUnchecked(i));
  368. if (plugin != nullptr && plugin->enabled())
  369. plugin->setActive(false, true, false);
  370. }
  371. }
  372. void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const DISTRHO::MidiEvent* midiEvents) override
  373. {
  374. if (kData->curPluginCount == 0)
  375. {
  376. carla_zeroFloat(outputs[0], frames);
  377. carla_zeroFloat(outputs[1], frames);
  378. return;
  379. }
  380. // create audio buffers
  381. float* inBuf[2] = { inputs[0], inputs[1] };
  382. float* outBuf[2] = { outputs[0], outputs[1] };
  383. // initialize input events
  384. carla_zeroStruct<EngineEvent>(kData->rack.in, RACK_EVENT_COUNT);
  385. {
  386. uint32_t engineEventIndex = 0;
  387. for (unsigned int i=0; i < paramCount && engineEventIndex+midiEventCount < RACK_EVENT_COUNT; ++i)
  388. {
  389. if (paramBuffers[i] == prevParamBuffers[i])
  390. continue;
  391. EngineEvent* const engineEvent = &kData->rack.in[engineEventIndex++];
  392. engineEvent->clear();
  393. engineEvent->type = kEngineEventTypeControl;
  394. engineEvent->time = 0;
  395. engineEvent->channel = 0;
  396. engineEvent->ctrl.type = kEngineControlEventTypeParameter;
  397. engineEvent->ctrl.param = paramMap[i];
  398. engineEvent->ctrl.value = paramBuffers[i]/127.0f;
  399. prevParamBuffers[i] = paramBuffers[i];
  400. }
  401. const DISTRHO::MidiEvent* midiEvent;
  402. for (uint32_t i=0; i < midiEventCount && engineEventIndex < RACK_EVENT_COUNT; ++i)
  403. {
  404. midiEvent = &midiEvents[i];
  405. if (midiEvent->size > 4)
  406. continue;
  407. EngineEvent* const engineEvent = &kData->rack.in[engineEventIndex++];
  408. engineEvent->clear();
  409. engineEvent->type = kEngineEventTypeMidi;
  410. engineEvent->time = midiEvent->frame;
  411. engineEvent->channel = MIDI_GET_CHANNEL_FROM_DATA(midiEvent->buf);
  412. engineEvent->midi.data[0] = MIDI_GET_STATUS_FROM_DATA(midiEvent->buf);
  413. engineEvent->midi.data[1] = midiEvent->buf[1];
  414. engineEvent->midi.data[2] = midiEvent->buf[2];
  415. engineEvent->midi.data[3] = midiEvent->buf[3];
  416. engineEvent->midi.size = midiEvent->size;
  417. }
  418. }
  419. processRack(inBuf, outBuf, frames);
  420. }
  421. // ---------------------------------------------
  422. // Callbacks
  423. void d_bufferSizeChanged(uint32_t newBufferSize) override
  424. {
  425. if (fBufferSize == newBufferSize)
  426. return;
  427. fBufferSize = newBufferSize;
  428. bufferSizeChanged(newBufferSize);
  429. }
  430. void d_sampleRateChanged(double newSampleRate) override
  431. {
  432. if (fSampleRate == newSampleRate)
  433. return;
  434. fSampleRate = newSampleRate;
  435. sampleRateChanged(newSampleRate);
  436. }
  437. // ---------------------------------------------
  438. private:
  439. float paramBuffers[paramCount];
  440. float prevParamBuffers[paramCount];
  441. };
  442. CARLA_BACKEND_END_NAMESPACE
  443. // -------------------------------------------------
  444. START_NAMESPACE_DISTRHO
  445. Plugin* createPlugin()
  446. {
  447. return new CarlaBackend::CarlaEnginePlugin();
  448. }
  449. END_NAMESPACE_DISTRHO
  450. // -------------------------------------------------
  451. #include "DistrhoPluginMain.cpp"
  452. #endif // CARLA_ENGINE_PLUGIN