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.

1328 lines
41KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "carla-native-base.cpp"
  18. #include "CarlaString.hpp"
  19. #include "lv2/atom.h"
  20. #include "lv2/atom-util.h"
  21. #include "lv2/buf-size.h"
  22. #include "lv2/instance-access.h"
  23. #include "lv2/midi.h"
  24. #include "lv2/options.h"
  25. #include "lv2/state.h"
  26. #include "lv2/time.h"
  27. #include "lv2/ui.h"
  28. #include "lv2/lv2_external_ui.h"
  29. #include "lv2/lv2_programs.h"
  30. using juce::FloatVectorOperations;
  31. // -----------------------------------------------------------------------
  32. // LV2 descriptor functions
  33. class NativePlugin : public LV2_External_UI_Widget
  34. {
  35. public:
  36. static const uint32_t kMaxMidiEvents = 512;
  37. NativePlugin(const PluginDescriptor* const desc, const double sampleRate, const char* const bundlePath, const LV2_Feature* const* features)
  38. : fHandle(nullptr),
  39. fDescriptor(desc),
  40. fMidiEventCount(0),
  41. fIsProcessing(false),
  42. fVolume(1.0f),
  43. fDryWet(1.0f),
  44. fBufferSize(0),
  45. fSampleRate(sampleRate),
  46. fUridMap(nullptr)
  47. {
  48. run = extui_run;
  49. show = extui_show;
  50. hide = extui_hide;
  51. fHost.handle = this;
  52. fHost.resourceDir = carla_strdup(bundlePath);
  53. fHost.uiName = nullptr;
  54. fHost.get_buffer_size = host_get_buffer_size;
  55. fHost.get_sample_rate = host_get_sample_rate;
  56. fHost.is_offline = host_is_offline;
  57. fHost.get_time_info = host_get_time_info;
  58. fHost.write_midi_event = host_write_midi_event;
  59. fHost.ui_parameter_changed = host_ui_parameter_changed;
  60. fHost.ui_custom_data_changed = host_ui_custom_data_changed;
  61. fHost.ui_closed = host_ui_closed;
  62. fHost.ui_open_file = host_ui_open_file;
  63. fHost.ui_save_file = host_ui_save_file;
  64. fHost.dispatcher = host_dispatcher;
  65. const LV2_Options_Option* options = nullptr;
  66. const LV2_URID_Map* uridMap = nullptr;
  67. for (int i=0; features[i] != nullptr; ++i)
  68. {
  69. if (std::strcmp(features[i]->URI, LV2_OPTIONS__options) == 0)
  70. options = (const LV2_Options_Option*)features[i]->data;
  71. else if (std::strcmp(features[i]->URI, LV2_URID__map) == 0)
  72. uridMap = (const LV2_URID_Map*)features[i]->data;
  73. }
  74. if (options == nullptr || uridMap == nullptr)
  75. {
  76. carla_stderr("Host doesn't provides option or urid-map features");
  77. return;
  78. }
  79. for (int i=0; options[i].key != 0; ++i)
  80. {
  81. if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength))
  82. {
  83. if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Int))
  84. fBufferSize = *(const int*)options[i].value;
  85. else
  86. carla_stderr("Host provides maxBlockLength but has wrong value type");
  87. break;
  88. }
  89. }
  90. fUridMap = uridMap;
  91. fUI.portOffset += (desc->midiIns > 0) ? desc->midiIns : 1;
  92. fUI.portOffset += desc->midiOuts;
  93. fUI.portOffset += 1; // freewheel
  94. fUI.portOffset += desc->audioIns;
  95. fUI.portOffset += desc->audioOuts;
  96. }
  97. ~NativePlugin()
  98. {
  99. CARLA_ASSERT(fHandle == nullptr);
  100. if (fHost.resourceDir != nullptr)
  101. {
  102. delete[] fHost.resourceDir;
  103. fHost.resourceDir = nullptr;
  104. }
  105. }
  106. bool init()
  107. {
  108. if (fDescriptor->instantiate == nullptr || fDescriptor->process == nullptr)
  109. {
  110. carla_stderr("Plugin is missing something...");
  111. return false;
  112. }
  113. if (fBufferSize == 0)
  114. {
  115. carla_stderr("Host is missing bufferSize feature");
  116. //return false;
  117. // as testing, continue for now
  118. fBufferSize = 1024;
  119. }
  120. fHandle = fDescriptor->instantiate(&fHost);
  121. if (fHandle == nullptr)
  122. return false;
  123. carla_zeroStruct<MidiEvent>(fMidiEvents, kMaxMidiEvents*2);
  124. carla_zeroStruct<TimeInfo>(fTimeInfo);
  125. fPorts.init(fDescriptor, fHandle);
  126. fUris.map(fUridMap);
  127. return true;
  128. }
  129. // -------------------------------------------------------------------
  130. // LV2 functions
  131. void lv2_connect_port(const uint32_t port, void* const dataLocation)
  132. {
  133. fPorts.connectPort(fDescriptor, port, dataLocation);
  134. }
  135. void lv2_activate()
  136. {
  137. if (fDescriptor->activate != nullptr)
  138. fDescriptor->activate(fHandle);
  139. carla_zeroStruct<TimeInfo>(fTimeInfo);
  140. }
  141. void lv2_deactivate()
  142. {
  143. if (fDescriptor->deactivate != nullptr)
  144. fDescriptor->deactivate(fHandle);
  145. }
  146. void lv2_cleanup()
  147. {
  148. if (fDescriptor->cleanup != nullptr)
  149. fDescriptor->cleanup(fHandle);
  150. fHandle = nullptr;
  151. }
  152. void lv2_run(const uint32_t frames)
  153. {
  154. if (frames == 0)
  155. {
  156. updateParameterOutputs();
  157. return;
  158. }
  159. // Check for updated parameters
  160. float curValue;
  161. for (uint32_t i=0; i < fPorts.paramCount; ++i)
  162. {
  163. CARLA_SAFE_ASSERT_CONTINUE(fPorts.paramsPtr[i] != nullptr)
  164. curValue = *fPorts.paramsPtr[i];
  165. if (fPorts.paramsLast[i] != curValue && (fDescriptor->get_parameter_info(fHandle, i)->hints & PARAMETER_IS_OUTPUT) == 0)
  166. {
  167. fPorts.paramsLast[i] = curValue;
  168. fDescriptor->set_parameter_value(fHandle, i, curValue);
  169. }
  170. }
  171. fMidiEventCount = 0;
  172. carla_zeroStruct<MidiEvent>(fMidiEvents, kMaxMidiEvents*2);
  173. LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[0], iter)
  174. {
  175. const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);
  176. if (event == nullptr)
  177. continue;
  178. if (event->body.size > 4)
  179. continue;
  180. if (event->time.frames >= frames)
  181. break;
  182. if (event->body.type == fUris.midiEvent)
  183. {
  184. if (fMidiEventCount >= kMaxMidiEvents*2)
  185. continue;
  186. const uint8_t* const data((const uint8_t*)(event + 1));
  187. fMidiEvents[fMidiEventCount].port = 0;
  188. fMidiEvents[fMidiEventCount].time = event->time.frames;
  189. fMidiEvents[fMidiEventCount].size = event->body.size;
  190. for (uint32_t i=0; i < event->body.size; ++i)
  191. fMidiEvents[fMidiEventCount].data[i] = data[i];
  192. fMidiEventCount += 1;
  193. continue;
  194. }
  195. if (event->body.type == fUris.atomBlank)
  196. {
  197. const LV2_Atom_Object* const obj((LV2_Atom_Object*)&event->body);
  198. if (obj->body.otype != fUris.timePos)
  199. continue;
  200. LV2_Atom* bar = nullptr;
  201. LV2_Atom* barBeat = nullptr;
  202. LV2_Atom* beatsPerBar = nullptr;
  203. LV2_Atom* bpm = nullptr;
  204. LV2_Atom* beatUnit = nullptr;
  205. LV2_Atom* frame = nullptr;
  206. LV2_Atom* speed = nullptr;
  207. lv2_atom_object_get(obj,
  208. fUris.timeBar, &bar,
  209. fUris.timeBarBeat, &barBeat,
  210. fUris.timeBeatsPerBar, &beatsPerBar,
  211. fUris.timeBeatsPerMinute, &bpm,
  212. fUris.timeBeatUnit, &beatUnit,
  213. fUris.timeFrame, &frame,
  214. fUris.timeSpeed, &speed,
  215. nullptr);
  216. if (bpm != nullptr && bpm->type == fUris.atomFloat)
  217. {
  218. fTimeInfo.bbt.beatsPerMinute = ((LV2_Atom_Float*)bpm)->body;
  219. fTimeInfo.bbt.valid = true;
  220. }
  221. if (beatsPerBar != nullptr && beatsPerBar->type == fUris.atomFloat)
  222. {
  223. float beatsPerBarValue = ((LV2_Atom_Float*)beatsPerBar)->body;
  224. fTimeInfo.bbt.beatsPerBar = beatsPerBarValue;
  225. if (bar != nullptr && bar->type == fUris.atomLong)
  226. {
  227. //float barValue = ((LV2_Atom_Long*)bar)->body;
  228. //curPosInfo.ppqPositionOfLastBarStart = barValue * beatsPerBarValue;
  229. if (barBeat != nullptr && barBeat->type == fUris.atomFloat)
  230. {
  231. //float barBeatValue = ((LV2_Atom_Float*)barBeat)->body;
  232. //curPosInfo.ppqPosition = curPosInfo.ppqPositionOfLastBarStart + barBeatValue;
  233. }
  234. }
  235. }
  236. if (beatUnit != nullptr && beatUnit->type == fUris.atomFloat)
  237. fTimeInfo.bbt.beatType = ((LV2_Atom_Float*)beatUnit)->body;
  238. if (frame != nullptr && frame->type == fUris.atomLong)
  239. fTimeInfo.frame = ((LV2_Atom_Long*)frame)->body;
  240. if (speed != nullptr && speed->type == fUris.atomFloat)
  241. fTimeInfo.playing = ((LV2_Atom_Float*)speed)->body == 1.0f;
  242. }
  243. }
  244. for (uint32_t i=1; i < fDescriptor->midiIns; ++i)
  245. {
  246. LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[i], iter)
  247. {
  248. const LV2_Atom_Event* const event((const LV2_Atom_Event*)iter);
  249. if (event == nullptr)
  250. continue;
  251. if (event->body.type != fUris.midiEvent)
  252. continue;
  253. if (event->body.size > 4)
  254. continue;
  255. if (event->time.frames >= frames)
  256. break;
  257. if (fMidiEventCount >= kMaxMidiEvents*2)
  258. break;
  259. const uint8_t* const data((const uint8_t*)(event + 1));
  260. fMidiEvents[fMidiEventCount].port = i;
  261. fMidiEvents[fMidiEventCount].time = event->time.frames;
  262. fMidiEvents[fMidiEventCount].size = event->body.size;
  263. for (uint32_t j=0; j < event->body.size; ++j)
  264. fMidiEvents[fMidiEventCount].data[j] = data[j];
  265. fMidiEventCount += 1;
  266. }
  267. }
  268. fIsProcessing = true;
  269. fDescriptor->process(fHandle, fPorts.audioIns, fPorts.audioOuts, frames, fMidiEvents, fMidiEventCount);
  270. fIsProcessing = false;
  271. if (fDryWet != 1.0f && fDescriptor->audioIns == fDescriptor->audioOuts)
  272. {
  273. for (uint32_t i=0; i < fDescriptor->audioOuts; ++i)
  274. {
  275. FloatVectorOperations::multiply(fPorts.audioIns[i], fVolume*(1.0f-fDryWet), frames);
  276. FloatVectorOperations::multiply(fPorts.audioOuts[i], fVolume*fDryWet, frames);
  277. FloatVectorOperations::add(fPorts.audioOuts[i], fPorts.audioIns[i], frames);
  278. }
  279. }
  280. else if (fVolume != 1.0f)
  281. {
  282. for (uint32_t i=0; i < fDescriptor->audioOuts; ++i)
  283. FloatVectorOperations::multiply(fPorts.audioOuts[i], fVolume, frames);
  284. }
  285. // TODO - midi out
  286. updateParameterOutputs();
  287. }
  288. // -------------------------------------------------------------------
  289. uint32_t lv2_get_options(LV2_Options_Option* const /*options*/) const
  290. {
  291. // currently unused
  292. return LV2_OPTIONS_SUCCESS;
  293. }
  294. uint32_t lv2_set_options(const LV2_Options_Option* const options)
  295. {
  296. for (int i=0; options[i].key != 0; ++i)
  297. {
  298. if (options[i].key == fUridMap->map(fUridMap->handle, LV2_BUF_SIZE__maxBlockLength))
  299. {
  300. if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Int))
  301. {
  302. fBufferSize = *(const int*)options[i].value;
  303. if (fDescriptor->dispatcher != nullptr)
  304. fDescriptor->dispatcher(fHandle, PLUGIN_OPCODE_BUFFER_SIZE_CHANGED, 0, fBufferSize, nullptr, 0.0f);
  305. }
  306. else
  307. carla_stderr("Host changed maxBlockLength but with wrong value type");
  308. }
  309. else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate))
  310. {
  311. if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Double))
  312. {
  313. fSampleRate = *(const double*)options[i].value;
  314. if (fDescriptor->dispatcher != nullptr)
  315. fDescriptor->dispatcher(fHandle, PLUGIN_OPCODE_SAMPLE_RATE_CHANGED, 0, 0, nullptr, fSampleRate);
  316. }
  317. else
  318. carla_stderr("Host changed sampleRate but with wrong value type");
  319. }
  320. }
  321. return LV2_OPTIONS_SUCCESS;
  322. }
  323. const LV2_Program_Descriptor* lv2_get_program(const uint32_t index) const
  324. {
  325. if (fDescriptor->hints & PLUGIN_IS_SYNTH)
  326. return nullptr;
  327. if (fDescriptor->get_midi_program_count == nullptr)
  328. return nullptr;
  329. if (fDescriptor->get_midi_program_info == nullptr)
  330. return nullptr;
  331. if (index >= fDescriptor->get_midi_program_count(fHandle))
  332. return nullptr;
  333. const MidiProgram* const midiProg(fDescriptor->get_midi_program_info(fHandle, index));
  334. if (midiProg == nullptr)
  335. return nullptr;
  336. static LV2_Program_Descriptor progDesc;
  337. progDesc.bank = midiProg->bank;
  338. progDesc.program = midiProg->program;
  339. progDesc.name = midiProg->name;
  340. return &progDesc;
  341. }
  342. void lv2_select_program(uint32_t bank, uint32_t program)
  343. {
  344. if (fDescriptor->hints & PLUGIN_IS_SYNTH)
  345. return;
  346. if (fDescriptor->set_midi_program == nullptr)
  347. return;
  348. fDescriptor->set_midi_program(fHandle, 0, bank, program);
  349. }
  350. LV2_State_Status lv2_save(const LV2_State_Store_Function store, const LV2_State_Handle handle, const uint32_t /*flags*/, const LV2_Feature* const* const /*features*/) const
  351. {
  352. if ((fDescriptor->hints & PLUGIN_USES_STATE) == 0 || fDescriptor->get_state == nullptr)
  353. return LV2_STATE_ERR_UNKNOWN;
  354. if (char* const state = fDescriptor->get_state(fHandle))
  355. {
  356. store(handle,
  357. fUridMap->map(fUridMap->handle, "http://kxstudio.sf.net/ns/carla/chunk"),
  358. state,
  359. std::strlen(state),
  360. fUridMap->map(fUridMap->handle, LV2_ATOM__String),
  361. LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE);
  362. return LV2_STATE_SUCCESS;
  363. }
  364. return LV2_STATE_ERR_UNKNOWN;
  365. }
  366. LV2_State_Status lv2_restore(const LV2_State_Retrieve_Function retrieve, const LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* const /*features*/) const
  367. {
  368. if ((fDescriptor->hints & PLUGIN_USES_STATE) == 0 || fDescriptor->set_state == nullptr)
  369. return LV2_STATE_ERR_UNKNOWN;
  370. size_t size = 0;
  371. uint32_t type = 0;
  372. const void* data = retrieve(handle, fUridMap->map(fUridMap->handle, "http://kxstudio.sf.net/ns/carla/chunk"), &size, &type, &flags);
  373. if (size == 0)
  374. return LV2_STATE_ERR_UNKNOWN;
  375. if (type == 0)
  376. return LV2_STATE_ERR_UNKNOWN;
  377. if (data == nullptr)
  378. return LV2_STATE_ERR_UNKNOWN;
  379. if (type != fUridMap->map(fUridMap->handle, LV2_ATOM__String))
  380. return LV2_STATE_ERR_BAD_TYPE;
  381. fDescriptor->set_state(fHandle, (const char*)data);
  382. return LV2_STATE_SUCCESS;
  383. }
  384. // -------------------------------------------------------------------
  385. bool lv2ui_instantiate(LV2UI_Write_Function writeFunction, LV2UI_Controller controller, LV2UI_Widget* widget,
  386. const LV2_Feature* const* features)
  387. {
  388. for (int i=0; features[i] != nullptr; ++i)
  389. {
  390. if (std::strcmp(features[i]->URI, LV2_EXTERNAL_UI__Host) == 0 ||
  391. std::strcmp(features[i]->URI, LV2_EXTERNAL_UI_DEPRECATED_URI) == 0)
  392. {
  393. fUI.host = (const LV2_External_UI_Host*)features[i]->data;
  394. break;
  395. }
  396. }
  397. if (fUI.host == nullptr)
  398. return false;
  399. fUI.writeFunction = writeFunction;
  400. fUI.controller = controller;
  401. *widget = this;
  402. fHost.uiName = fUI.host->plugin_human_id;
  403. return true;
  404. }
  405. void lv2ui_port_event(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer) const
  406. {
  407. if (format != 0 || bufferSize != sizeof(float) || buffer == nullptr)
  408. return;
  409. if (portIndex >= fUI.portOffset || ! fUI.isVisible)
  410. return;
  411. if (fDescriptor->ui_set_parameter_value == nullptr)
  412. return;
  413. const float value(*(const float*)buffer);
  414. fDescriptor->ui_set_parameter_value(fHandle, portIndex-fUI.portOffset, value);
  415. }
  416. void lv2ui_cleanup()
  417. {
  418. fUI.host = nullptr;
  419. fUI.writeFunction = nullptr;
  420. fUI.controller = nullptr;
  421. if (! fUI.isVisible)
  422. return;
  423. if (fDescriptor->ui_show != nullptr)
  424. fDescriptor->ui_show(fHandle, false);
  425. fUI.isVisible = false;
  426. }
  427. // -------------------------------------------------------------------
  428. void lv2ui_select_program(uint32_t bank, uint32_t program) const
  429. {
  430. if (fDescriptor->hints & PLUGIN_IS_SYNTH)
  431. return;
  432. if (fDescriptor->ui_set_midi_program == nullptr)
  433. return;
  434. fDescriptor->ui_set_midi_program(fHandle, 0, bank, program);
  435. }
  436. // -------------------------------------------------------------------
  437. protected:
  438. void handleUiRun()
  439. {
  440. if (fDescriptor->ui_idle != nullptr)
  441. fDescriptor->ui_idle(fHandle);
  442. }
  443. void handleUiShow()
  444. {
  445. if (fDescriptor->ui_show != nullptr)
  446. fDescriptor->ui_show(fHandle, true);
  447. fUI.isVisible = true;
  448. }
  449. void handleUiHide()
  450. {
  451. if (fDescriptor->ui_show != nullptr)
  452. fDescriptor->ui_show(fHandle, false);
  453. fUI.isVisible = false;
  454. }
  455. // -------------------------------------------------------------------
  456. uint32_t handleGetBufferSize() const
  457. {
  458. return fBufferSize;
  459. }
  460. double handleGetSampleRate() const
  461. {
  462. return fSampleRate;
  463. }
  464. bool handleIsOffline() const
  465. {
  466. CARLA_SAFE_ASSERT_RETURN(fIsProcessing, false);
  467. return (fPorts.freewheel != nullptr && *fPorts.freewheel >= 0.5f);
  468. }
  469. const TimeInfo* handleGetTimeInfo() const
  470. {
  471. CARLA_SAFE_ASSERT_RETURN(fIsProcessing, nullptr);
  472. return &fTimeInfo;
  473. }
  474. bool handleWriteMidiEvent(const MidiEvent* const event)
  475. {
  476. CARLA_SAFE_ASSERT_RETURN(fIsProcessing, false);
  477. CARLA_SAFE_ASSERT_RETURN(fDescriptor->midiOuts > 0, false);
  478. CARLA_SAFE_ASSERT_RETURN(event != nullptr, false);
  479. CARLA_SAFE_ASSERT_RETURN(event->data[0] != 0, false);
  480. // reverse-find first free event, and put it there
  481. for (uint32_t i=(kMaxMidiEvents*2)-1; i > fMidiEventCount; --i)
  482. {
  483. if (fMidiEvents[i].data[0] == 0)
  484. {
  485. std::memcpy(&fMidiEvents[i], event, sizeof(MidiEvent));
  486. return true;
  487. }
  488. }
  489. return false;
  490. }
  491. void handleUiParameterChanged(const uint32_t index, const float value)
  492. {
  493. if (fUI.writeFunction != nullptr && fUI.controller != nullptr)
  494. fUI.writeFunction(fUI.controller, index+fUI.portOffset, sizeof(float), 0, &value);
  495. }
  496. void handleUiCustomDataChanged(const char* const /*key*/, const char* const /*value*/)
  497. {
  498. //storeCustomData(key, value);
  499. }
  500. void handleUiClosed()
  501. {
  502. if (fUI.host != nullptr && fUI.host->ui_closed != nullptr && fUI.controller != nullptr)
  503. fUI.host->ui_closed(fUI.controller);
  504. fUI.host = nullptr;
  505. fUI.writeFunction = nullptr;
  506. fUI.controller = nullptr;
  507. fUI.isVisible = false;
  508. }
  509. const char* handleUiOpenFile(const bool /*isDir*/, const char* const /*title*/, const char* const /*filter*/) const
  510. {
  511. // TODO
  512. return nullptr;
  513. }
  514. const char* handleUiSaveFile(const bool /*isDir*/, const char* const /*title*/, const char* const /*filter*/) const
  515. {
  516. // TODO
  517. return nullptr;
  518. }
  519. intptr_t handleDispatcher(const HostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
  520. {
  521. carla_debug("NativePlugin::handleDispatcher(%i, %i, " P_INTPTR ", %p, %f)", opcode, index, value, ptr, opt);
  522. intptr_t ret = 0;
  523. switch (opcode)
  524. {
  525. case HOST_OPCODE_NULL:
  526. break;
  527. case HOST_OPCODE_SET_VOLUME:
  528. fVolume = opt;
  529. break;
  530. case HOST_OPCODE_SET_DRYWET:
  531. fDryWet = opt;
  532. break;
  533. case HOST_OPCODE_SET_BALANCE_LEFT:
  534. case HOST_OPCODE_SET_BALANCE_RIGHT:
  535. case HOST_OPCODE_SET_PANNING:
  536. // nothing
  537. break;
  538. case HOST_OPCODE_GET_PARAMETER_MIDI_CC:
  539. case HOST_OPCODE_SET_PARAMETER_MIDI_CC:
  540. case HOST_OPCODE_SET_PROCESS_PRECISION:
  541. case HOST_OPCODE_UPDATE_PARAMETER:
  542. case HOST_OPCODE_UPDATE_MIDI_PROGRAM:
  543. case HOST_OPCODE_RELOAD_PARAMETERS:
  544. case HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
  545. case HOST_OPCODE_RELOAD_ALL:
  546. // nothing
  547. break;
  548. case HOST_OPCODE_UI_UNAVAILABLE:
  549. handleUiClosed();
  550. break;
  551. }
  552. return ret;
  553. // unused for now
  554. (void)index;
  555. (void)value;
  556. (void)ptr;
  557. }
  558. void updateParameterOutputs()
  559. {
  560. for (uint32_t i=0; i < fPorts.paramCount; ++i)
  561. {
  562. if (fDescriptor->get_parameter_info(fHandle, i)->hints & PARAMETER_IS_OUTPUT)
  563. {
  564. fPorts.paramsLast[i] = fDescriptor->get_parameter_value(fHandle, i);
  565. if (fPorts.paramsPtr[i] != nullptr)
  566. *fPorts.paramsPtr[i] = fPorts.paramsLast[i];
  567. }
  568. }
  569. }
  570. // -------------------------------------------------------------------
  571. private:
  572. // Native data
  573. PluginHandle fHandle;
  574. HostDescriptor fHost;
  575. const PluginDescriptor* const fDescriptor;
  576. uint32_t fMidiEventCount;
  577. MidiEvent fMidiEvents[kMaxMidiEvents*2];
  578. TimeInfo fTimeInfo;
  579. bool fIsProcessing;
  580. float fVolume;
  581. float fDryWet;
  582. // Lv2 host data
  583. uint32_t fBufferSize;
  584. double fSampleRate;
  585. const LV2_URID_Map* fUridMap;
  586. struct URIDs {
  587. LV2_URID atomBlank;
  588. LV2_URID atomFloat;
  589. LV2_URID atomLong;
  590. LV2_URID atomSequence;
  591. LV2_URID midiEvent;
  592. LV2_URID timePos;
  593. LV2_URID timeBar;
  594. LV2_URID timeBarBeat;
  595. LV2_URID timeBeatsPerBar;
  596. LV2_URID timeBeatsPerMinute;
  597. LV2_URID timeBeatUnit;
  598. LV2_URID timeFrame;
  599. LV2_URID timeSpeed;
  600. URIDs()
  601. : atomBlank(0),
  602. atomFloat(0),
  603. atomLong(0),
  604. atomSequence(0),
  605. midiEvent(0),
  606. timePos(0),
  607. timeBar(0),
  608. timeBarBeat(0),
  609. timeBeatsPerBar(0),
  610. timeBeatsPerMinute(0),
  611. timeBeatUnit(0),
  612. timeFrame(0),
  613. timeSpeed(0) {}
  614. void map(const LV2_URID_Map* const uridMap)
  615. {
  616. atomBlank = uridMap->map(uridMap->handle, LV2_ATOM__Blank);
  617. atomFloat = uridMap->map(uridMap->handle, LV2_ATOM__Float);
  618. atomLong = uridMap->map(uridMap->handle, LV2_ATOM__Long);
  619. atomSequence = uridMap->map(uridMap->handle, LV2_ATOM__Sequence);
  620. midiEvent = uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent);
  621. timePos = uridMap->map(uridMap->handle, LV2_TIME__Position);
  622. timeBar = uridMap->map(uridMap->handle, LV2_TIME__bar);
  623. timeBarBeat = uridMap->map(uridMap->handle, LV2_TIME__barBeat);
  624. timeBeatUnit = uridMap->map(uridMap->handle, LV2_TIME__beatUnit);
  625. timeFrame = uridMap->map(uridMap->handle, LV2_TIME__frame);
  626. timeSpeed = uridMap->map(uridMap->handle, LV2_TIME__speed);
  627. timeBeatsPerBar = uridMap->map(uridMap->handle, LV2_TIME__beatsPerBar);
  628. timeBeatsPerMinute = uridMap->map(uridMap->handle, LV2_TIME__beatsPerMinute);
  629. }
  630. } fUris;
  631. struct UI {
  632. const LV2_External_UI_Host* host;
  633. LV2UI_Write_Function writeFunction;
  634. LV2UI_Controller controller;
  635. uint32_t portOffset;
  636. bool isVisible;
  637. UI()
  638. : host(nullptr),
  639. writeFunction(nullptr),
  640. controller(nullptr),
  641. portOffset(0),
  642. isVisible(false) {}
  643. } fUI;
  644. struct Ports {
  645. LV2_Atom_Sequence** eventsIn;
  646. LV2_Atom_Sequence** midiOuts;
  647. float** audioIns;
  648. float** audioOuts;
  649. float* freewheel;
  650. uint32_t paramCount;
  651. float* paramsLast;
  652. float** paramsPtr;
  653. Ports()
  654. : eventsIn(nullptr),
  655. midiOuts(nullptr),
  656. audioIns(nullptr),
  657. audioOuts(nullptr),
  658. freewheel(nullptr),
  659. paramCount(0),
  660. paramsLast(nullptr),
  661. paramsPtr(nullptr) {}
  662. ~Ports()
  663. {
  664. if (eventsIn != nullptr)
  665. {
  666. delete[] eventsIn;
  667. eventsIn = nullptr;
  668. }
  669. if (midiOuts != nullptr)
  670. {
  671. delete[] midiOuts;
  672. midiOuts = nullptr;
  673. }
  674. if (audioIns != nullptr)
  675. {
  676. delete[] audioIns;
  677. audioIns = nullptr;
  678. }
  679. if (audioOuts != nullptr)
  680. {
  681. delete[] audioOuts;
  682. audioOuts = nullptr;
  683. }
  684. if (paramsLast != nullptr)
  685. {
  686. delete[] paramsLast;
  687. paramsLast = nullptr;
  688. }
  689. if (paramsPtr != nullptr)
  690. {
  691. delete[] paramsPtr;
  692. paramsPtr = nullptr;
  693. }
  694. }
  695. void init(const PluginDescriptor* const desc, PluginHandle handle)
  696. {
  697. CARLA_SAFE_ASSERT_RETURN(desc != nullptr && handle != nullptr,)
  698. if (desc->midiIns > 0)
  699. {
  700. eventsIn = new LV2_Atom_Sequence*[desc->midiIns];
  701. for (uint32_t i=0; i < desc->midiIns; ++i)
  702. eventsIn[i] = nullptr;
  703. }
  704. else
  705. {
  706. eventsIn = new LV2_Atom_Sequence*[1];
  707. eventsIn[0] = nullptr;
  708. }
  709. if (desc->midiOuts > 0)
  710. {
  711. midiOuts = new LV2_Atom_Sequence*[desc->midiOuts];
  712. for (uint32_t i=0; i < desc->midiOuts; ++i)
  713. midiOuts[i] = nullptr;
  714. }
  715. if (desc->audioIns > 0)
  716. {
  717. audioIns = new float*[desc->audioIns];
  718. for (uint32_t i=0; i < desc->audioIns; ++i)
  719. audioIns[i] = nullptr;
  720. }
  721. if (desc->audioOuts > 0)
  722. {
  723. audioOuts = new float*[desc->audioOuts];
  724. for (uint32_t i=0; i < desc->audioOuts; ++i)
  725. audioOuts[i] = nullptr;
  726. }
  727. if (desc->get_parameter_count != nullptr && desc->get_parameter_info != nullptr && desc->get_parameter_value != nullptr && desc->set_parameter_value != nullptr)
  728. {
  729. paramCount = desc->get_parameter_count(handle);
  730. if (paramCount > 0)
  731. {
  732. paramsLast = new float[paramCount];
  733. paramsPtr = new float*[paramCount];
  734. for (uint32_t i=0; i < paramCount; ++i)
  735. {
  736. paramsLast[i] = desc->get_parameter_value(handle, i);
  737. paramsPtr[i] = nullptr;
  738. }
  739. }
  740. }
  741. }
  742. void connectPort(const PluginDescriptor* const desc, const uint32_t port, void* const dataLocation)
  743. {
  744. uint32_t index = 0;
  745. if (port == index++)
  746. {
  747. eventsIn[0] = (LV2_Atom_Sequence*)dataLocation;
  748. return;
  749. }
  750. for (uint32_t i=1; i < desc->midiIns; ++i)
  751. {
  752. if (port == index++)
  753. {
  754. eventsIn[i] = (LV2_Atom_Sequence*)dataLocation;
  755. return;
  756. }
  757. }
  758. for (uint32_t i=0; i < desc->midiOuts; ++i)
  759. {
  760. if (port == index++)
  761. {
  762. midiOuts[i] = (LV2_Atom_Sequence*)dataLocation;
  763. return;
  764. }
  765. }
  766. if (port == index++)
  767. {
  768. freewheel = (float*)dataLocation;
  769. return;
  770. }
  771. for (uint32_t i=0; i < desc->audioIns; ++i)
  772. {
  773. if (port == index++)
  774. {
  775. audioIns[i] = (float*)dataLocation;
  776. return;
  777. }
  778. }
  779. for (uint32_t i=0; i < desc->audioOuts; ++i)
  780. {
  781. if (port == index++)
  782. {
  783. audioOuts[i] = (float*)dataLocation;
  784. return;
  785. }
  786. }
  787. for (uint32_t i=0; i < paramCount; ++i)
  788. {
  789. if (port == index++)
  790. {
  791. paramsPtr[i] = (float*)dataLocation;
  792. return;
  793. }
  794. }
  795. }
  796. } fPorts;
  797. // -------------------------------------------------------------------
  798. #define handlePtr ((NativePlugin*)_this_)
  799. static void extui_run(LV2_External_UI_Widget* _this_)
  800. {
  801. handlePtr->handleUiRun();
  802. }
  803. static void extui_show(LV2_External_UI_Widget* _this_)
  804. {
  805. handlePtr->handleUiShow();
  806. }
  807. static void extui_hide(LV2_External_UI_Widget* _this_)
  808. {
  809. handlePtr->handleUiHide();
  810. }
  811. #undef handlePtr
  812. // -------------------------------------------------------------------
  813. #define handlePtr ((NativePlugin*)handle)
  814. static uint32_t host_get_buffer_size(HostHandle handle)
  815. {
  816. return handlePtr->handleGetBufferSize();
  817. }
  818. static double host_get_sample_rate(HostHandle handle)
  819. {
  820. return handlePtr->handleGetSampleRate();
  821. }
  822. static bool host_is_offline(HostHandle handle)
  823. {
  824. return handlePtr->handleIsOffline();
  825. }
  826. static const TimeInfo* host_get_time_info(HostHandle handle)
  827. {
  828. return handlePtr->handleGetTimeInfo();
  829. }
  830. static bool host_write_midi_event(HostHandle handle, const ::MidiEvent* event)
  831. {
  832. return handlePtr->handleWriteMidiEvent(event);
  833. }
  834. static void host_ui_parameter_changed(HostHandle handle, uint32_t index, float value)
  835. {
  836. handlePtr->handleUiParameterChanged(index, value);
  837. }
  838. static void host_ui_custom_data_changed(HostHandle handle, const char* key, const char* value)
  839. {
  840. handlePtr->handleUiCustomDataChanged(key, value);
  841. }
  842. static void host_ui_closed(HostHandle handle)
  843. {
  844. handlePtr->handleUiClosed();
  845. }
  846. static const char* host_ui_open_file(HostHandle handle, bool isDir, const char* title, const char* filter)
  847. {
  848. return handlePtr->handleUiOpenFile(isDir, title, filter);
  849. }
  850. static const char* host_ui_save_file(HostHandle handle, bool isDir, const char* title, const char* filter)
  851. {
  852. return handlePtr->handleUiSaveFile(isDir, title, filter);
  853. }
  854. static intptr_t host_dispatcher(HostHandle handle, HostDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt)
  855. {
  856. return handlePtr->handleDispatcher(opcode, index, value, ptr, opt);
  857. }
  858. #undef handlePtr
  859. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePlugin)
  860. };
  861. // -----------------------------------------------------------------------
  862. // LV2 descriptor functions
  863. static LV2_Handle lv2_instantiate(const LV2_Descriptor* lv2Descriptor, double sampleRate, const char* bundlePath, const LV2_Feature* const* features)
  864. {
  865. carla_debug("lv2_instantiate(%p, %g, %s, %p)", lv2Descriptor, sampleRate, bundlePath, features);
  866. const PluginDescriptor* pluginDesc = nullptr;
  867. const char* pluginLabel = nullptr;
  868. if (std::strncmp(lv2Descriptor->URI, "http://kxstudio.sf.net/carla/plugins/", 37) == 0)
  869. pluginLabel = lv2Descriptor->URI+37;
  870. else if (std::strcmp(lv2Descriptor->URI, "http://kxstudio.sf.net/carla") == 0)
  871. pluginLabel = lv2Descriptor->URI+23;
  872. if (pluginLabel == nullptr)
  873. {
  874. carla_stderr("Failed to find carla native plugin with URI \"%s\"", lv2Descriptor->URI);
  875. return nullptr;
  876. }
  877. carla_debug("lv2_instantiate() - looking up label \"%s\"", pluginLabel);
  878. for (NonRtList<const PluginDescriptor*>::Itenerator it = sPluginDescsMgr.descs.begin(); it.valid(); it.next())
  879. {
  880. const PluginDescriptor*& tmpDesc(*it);
  881. if (std::strcmp(tmpDesc->label, pluginLabel) == 0)
  882. {
  883. pluginDesc = tmpDesc;
  884. break;
  885. }
  886. }
  887. if (pluginDesc == nullptr)
  888. {
  889. carla_stderr("Failed to find carla native plugin with label \"%s\"", pluginLabel);
  890. return nullptr;
  891. }
  892. NativePlugin* const plugin(new NativePlugin(pluginDesc, sampleRate, bundlePath, features));
  893. if (! plugin->init())
  894. {
  895. carla_stderr("Failed to init plugin");
  896. delete plugin;
  897. return nullptr;
  898. }
  899. return (LV2_Handle)plugin;
  900. }
  901. #define instancePtr ((NativePlugin*)instance)
  902. static void lv2_connect_port(LV2_Handle instance, uint32_t port, void* dataLocation)
  903. {
  904. instancePtr->lv2_connect_port(port, dataLocation);
  905. }
  906. static void lv2_activate(LV2_Handle instance)
  907. {
  908. carla_debug("lv2_activate(%p)", instance);
  909. instancePtr->lv2_activate();
  910. }
  911. static void lv2_run(LV2_Handle instance, uint32_t sampleCount)
  912. {
  913. instancePtr->lv2_run(sampleCount);
  914. }
  915. static void lv2_deactivate(LV2_Handle instance)
  916. {
  917. carla_debug("lv2_deactivate(%p)", instance);
  918. instancePtr->lv2_deactivate();
  919. }
  920. static void lv2_cleanup(LV2_Handle instance)
  921. {
  922. carla_debug("lv2_cleanup(%p)", instance);
  923. instancePtr->lv2_cleanup();
  924. delete instancePtr;
  925. }
  926. static uint32_t lv2_get_options(LV2_Handle instance, LV2_Options_Option* options)
  927. {
  928. carla_debug("lv2_get_options(%p, %p)", instance, options);
  929. return instancePtr->lv2_get_options(options);
  930. }
  931. static uint32_t lv2_set_options(LV2_Handle instance, const LV2_Options_Option* options)
  932. {
  933. carla_debug("lv2_set_options(%p, %p)", instance, options);
  934. return instancePtr->lv2_set_options(options);
  935. }
  936. static const LV2_Program_Descriptor* lv2_get_program(LV2_Handle instance, uint32_t index)
  937. {
  938. carla_debug("lv2_get_program(%p, %i)", instance, index);
  939. return instancePtr->lv2_get_program(index);
  940. }
  941. static void lv2_select_program(LV2_Handle instance, uint32_t bank, uint32_t program)
  942. {
  943. carla_debug("lv2_select_program(%p, %i, %i)", instance, bank, program);
  944. return instancePtr->lv2_select_program(bank, program);
  945. }
  946. static LV2_State_Status lv2_save(LV2_Handle instance, LV2_State_Store_Function store, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features)
  947. {
  948. carla_debug("lv2_save(%p, %p, %p, %i, %p)", instance, store, handle, flags, features);
  949. return instancePtr->lv2_save(store, handle, flags, features);
  950. }
  951. static LV2_State_Status lv2_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features)
  952. {
  953. carla_debug("lv2_restore(%p, %p, %p, %i, %p)", instance, retrieve, handle, flags, features);
  954. return instancePtr->lv2_restore(retrieve, handle, flags, features);
  955. }
  956. static const void* lv2_extension_data(const char* uri)
  957. {
  958. carla_debug("lv2_extension_data(\"%s\")", uri);
  959. static const LV2_Options_Interface options = { lv2_get_options, lv2_set_options };
  960. static const LV2_Programs_Interface programs = { lv2_get_program, lv2_select_program };
  961. static const LV2_State_Interface state = { lv2_save, lv2_restore };
  962. if (std::strcmp(uri, LV2_OPTIONS__interface) == 0)
  963. return &options;
  964. if (std::strcmp(uri, LV2_PROGRAMS__Interface) == 0)
  965. return &programs;
  966. if (std::strcmp(uri, LV2_STATE__interface) == 0)
  967. return &state;
  968. return nullptr;
  969. }
  970. #undef instancePtr
  971. // -----------------------------------------------------------------------
  972. // Startup code
  973. static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char*, const char*, LV2UI_Write_Function writeFunction,
  974. LV2UI_Controller controller, LV2UI_Widget* widget, const LV2_Feature* const* features)
  975. {
  976. carla_debug("lv2ui_instantiate(..., %p, %p, %p)", writeFunction, controller, widget, features);
  977. NativePlugin* plugin = nullptr;
  978. for (int i=0; features[i] != nullptr; ++i)
  979. {
  980. if (std::strcmp(features[i]->URI, LV2_INSTANCE_ACCESS_URI) == 0)
  981. {
  982. plugin = (NativePlugin*)features[i]->data;
  983. break;
  984. }
  985. }
  986. if (plugin == nullptr)
  987. {
  988. carla_stderr("Host doesn't support instance-access, cannot show UI");
  989. return nullptr;
  990. }
  991. if (! plugin->lv2ui_instantiate(writeFunction, controller, widget, features))
  992. {
  993. carla_stderr("Host doesn't support external UI");
  994. return nullptr;
  995. }
  996. return (LV2UI_Handle)plugin;
  997. }
  998. #define uiPtr ((NativePlugin*)ui)
  999. static void lv2ui_port_event(LV2UI_Handle ui, uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer)
  1000. {
  1001. carla_debug("lv2ui_port_event(%p, %i, %i, %i, %p)", ui, portIndex, bufferSize, format, buffer);
  1002. uiPtr->lv2ui_port_event(portIndex, bufferSize, format, buffer);
  1003. }
  1004. static void lv2ui_cleanup(LV2UI_Handle ui)
  1005. {
  1006. carla_debug("lv2ui_cleanup(%p)", ui);
  1007. uiPtr->lv2ui_cleanup();
  1008. }
  1009. static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t program)
  1010. {
  1011. carla_debug("lv2ui_select_program(%p, %i, %i)", ui, bank, program);
  1012. uiPtr->lv2ui_select_program(bank, program);
  1013. }
  1014. static const void* lv2ui_extension_data(const char* uri)
  1015. {
  1016. carla_debug("lv2ui_extension_data(\"%s\")", uri);
  1017. static const LV2_Programs_UI_Interface uiprograms = { lv2ui_select_program };
  1018. if (std::strcmp(uri, LV2_PROGRAMS__UIInterface) == 0)
  1019. return &uiprograms;
  1020. return nullptr;
  1021. }
  1022. #undef uiPtr
  1023. // -----------------------------------------------------------------------
  1024. // Startup code
  1025. CARLA_EXPORT
  1026. const LV2_Descriptor* lv2_descriptor(uint32_t index)
  1027. {
  1028. carla_debug("lv2_descriptor(%i)", index);
  1029. if (index >= sPluginDescsMgr.descs.count())
  1030. {
  1031. carla_debug("lv2_descriptor(%i) - out of bounds", index);
  1032. return nullptr;
  1033. }
  1034. if (index < sPluginDescsMgr.lv2Descs.count())
  1035. {
  1036. carla_debug("lv2_descriptor(%i) - found previously allocated", index);
  1037. return sPluginDescsMgr.lv2Descs.getAt(index);
  1038. }
  1039. const PluginDescriptor*& pluginDesc(sPluginDescsMgr.descs.getAt(index));
  1040. CarlaString tmpURI;
  1041. if (std::strcmp(pluginDesc->label, "carla") == 0)
  1042. {
  1043. tmpURI = "http://kxstudio.sf.net/carla";
  1044. }
  1045. else
  1046. {
  1047. tmpURI = "http://kxstudio.sf.net/carla/plugins/";
  1048. tmpURI += pluginDesc->label;
  1049. }
  1050. carla_debug("lv2_descriptor(%i) - not found, allocating new with uri \"%s\"", index, (const char*)tmpURI);
  1051. const LV2_Descriptor* const lv2Desc(new const LV2_Descriptor{
  1052. /* URI */ carla_strdup(tmpURI),
  1053. /* instantiate */ lv2_instantiate,
  1054. /* connect_port */ lv2_connect_port,
  1055. /* activate */ lv2_activate,
  1056. /* run */ lv2_run,
  1057. /* deactivate */ lv2_deactivate,
  1058. /* cleanup */ lv2_cleanup,
  1059. /* extension_data */ lv2_extension_data
  1060. });
  1061. sPluginDescsMgr.lv2Descs.append(lv2Desc);
  1062. return lv2Desc;
  1063. }
  1064. CARLA_EXPORT
  1065. const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
  1066. {
  1067. carla_debug("lv2ui_descriptor(%i)", index);
  1068. static const LV2UI_Descriptor lv2UiDesc = {
  1069. /* URI */ "http://kxstudio.sf.net/carla#UI",
  1070. /* instantiate */ lv2ui_instantiate,
  1071. /* cleanup */ lv2ui_cleanup,
  1072. /* port_event */ lv2ui_port_event,
  1073. /* extension_data */ lv2ui_extension_data
  1074. };
  1075. return (index == 0) ? &lv2UiDesc : nullptr;
  1076. }
  1077. // -----------------------------------------------------------------------