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.

1666 lines
57KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2013-2017 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. #define CARLA_NATIVE_PLUGIN_LV2
  18. #include "carla-base.cpp"
  19. #include "CarlaLv2Utils.hpp"
  20. #include "CarlaMathUtils.hpp"
  21. #include "CarlaString.hpp"
  22. // -----------------------------------------------------------------------
  23. // LV2 descriptor functions
  24. class NativePlugin : public Lv2PluginBaseClass
  25. {
  26. public:
  27. static const uint32_t kMaxMidiEvents = 512;
  28. NativePlugin(const NativePluginDescriptor* const desc,
  29. const double sampleRate,
  30. const char* const bundlePath,
  31. const LV2_Feature* const* const features)
  32. : Lv2PluginBaseClass(sampleRate, features),
  33. fHandle(nullptr),
  34. fHost(),
  35. fDescriptor(desc),
  36. #ifdef CARLA_PROPER_CPP11_SUPPORT
  37. fProgramDesc({0, 0, nullptr}),
  38. #endif
  39. fMidiEventCount(0),
  40. fTimeInfo(),
  41. fLastPositionData(),
  42. fUI(),
  43. fPorts()
  44. {
  45. carla_zeroStruct(fHost);
  46. if (! loadedInProperHost())
  47. return;
  48. CarlaString resourceDir(bundlePath);
  49. resourceDir += CARLA_OS_SEP_STR "resources" CARLA_OS_SEP_STR;
  50. fHost.handle = this;
  51. fHost.resourceDir = resourceDir.dupSafe();
  52. fHost.uiName = nullptr;
  53. fHost.uiParentId = 0;
  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. }
  66. ~NativePlugin()
  67. {
  68. CARLA_SAFE_ASSERT(fHandle == nullptr);
  69. if (fHost.resourceDir != nullptr)
  70. {
  71. delete[] fHost.resourceDir;
  72. fHost.resourceDir = nullptr;
  73. }
  74. }
  75. bool init()
  76. {
  77. if (fHost.resourceDir == nullptr)
  78. return false;
  79. if (fDescriptor->instantiate == nullptr || fDescriptor->process == nullptr)
  80. {
  81. carla_stderr("Plugin is missing something...");
  82. return false;
  83. }
  84. carla_zeroStructs(fMidiEvents, kMaxMidiEvents);
  85. carla_zeroStruct(fTimeInfo);
  86. fHandle = fDescriptor->instantiate(&fHost);
  87. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr, false);
  88. if (fDescriptor->midiIns > 0)
  89. fUI.portOffset += fDescriptor->midiIns;
  90. else if (fDescriptor->hints & NATIVE_PLUGIN_USES_TIME)
  91. fUI.portOffset += 1;
  92. fUI.portOffset += fDescriptor->midiOuts;
  93. fUI.portOffset += 1; // freewheel
  94. fUI.portOffset += fDescriptor->audioIns;
  95. fUI.portOffset += fDescriptor->audioOuts;
  96. fPorts.init(fDescriptor, fHandle);
  97. return true;
  98. }
  99. // -------------------------------------------------------------------
  100. // LV2 functions
  101. void lv2_connect_port(const uint32_t port, void* const dataLocation)
  102. {
  103. fPorts.connectPort(fDescriptor, port, dataLocation);
  104. }
  105. void lv2_activate()
  106. {
  107. if (fDescriptor->activate != nullptr)
  108. fDescriptor->activate(fHandle);
  109. carla_zeroStruct(fTimeInfo);
  110. // hosts may not send all values, resulting on some invalid data
  111. fTimeInfo.bbt.bar = 1;
  112. fTimeInfo.bbt.beat = 1;
  113. fTimeInfo.bbt.tick = 0;
  114. fTimeInfo.bbt.barStartTick = 0;
  115. fTimeInfo.bbt.beatsPerBar = 4;
  116. fTimeInfo.bbt.beatType = 4;
  117. fTimeInfo.bbt.ticksPerBeat = 960.0;
  118. fTimeInfo.bbt.beatsPerMinute = 120.0;
  119. }
  120. void lv2_deactivate()
  121. {
  122. if (fDescriptor->deactivate != nullptr)
  123. fDescriptor->deactivate(fHandle);
  124. }
  125. void lv2_cleanup()
  126. {
  127. if (fDescriptor->cleanup != nullptr)
  128. fDescriptor->cleanup(fHandle);
  129. fHandle = nullptr;
  130. }
  131. void lv2_run(const uint32_t frames)
  132. {
  133. fIsOffline = (fPorts.freewheel != nullptr && *fPorts.freewheel >= 0.5f);
  134. // cache midi events and time information first
  135. if (fDescriptor->midiIns > 0 || (fDescriptor->hints & NATIVE_PLUGIN_USES_TIME) != 0)
  136. {
  137. fMidiEventCount = 0;
  138. carla_zeroStructs(fMidiEvents, kMaxMidiEvents);
  139. if (fDescriptor->hints & NATIVE_PLUGIN_USES_TIME)
  140. {
  141. LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[0], event)
  142. {
  143. if (event == nullptr)
  144. continue;
  145. if (event->body.type != fURIs.atomBlank && event->body.type != fURIs.atomObject)
  146. continue;
  147. const LV2_Atom_Object* const obj((const LV2_Atom_Object*)&event->body);
  148. if (obj->body.otype != fURIs.timePos)
  149. continue;
  150. LV2_Atom* bar = nullptr;
  151. LV2_Atom* barBeat = nullptr;
  152. LV2_Atom* beatUnit = nullptr;
  153. LV2_Atom* beatsPerBar = nullptr;
  154. LV2_Atom* beatsPerMinute = nullptr;
  155. LV2_Atom* frame = nullptr;
  156. LV2_Atom* speed = nullptr;
  157. LV2_Atom* ticksPerBeat = nullptr;
  158. lv2_atom_object_get(obj,
  159. fURIs.timeBar, &bar,
  160. fURIs.timeBarBeat, &barBeat,
  161. fURIs.timeBeatUnit, &beatUnit,
  162. fURIs.timeBeatsPerBar, &beatsPerBar,
  163. fURIs.timeBeatsPerMinute, &beatsPerMinute,
  164. fURIs.timeFrame, &frame,
  165. fURIs.timeSpeed, &speed,
  166. fURIs.timeTicksPerBeat, &ticksPerBeat,
  167. 0);
  168. // need to handle this first as other values depend on it
  169. if (ticksPerBeat != nullptr)
  170. {
  171. double ticksPerBeatValue = -1.0;
  172. /**/ if (ticksPerBeat->type == fURIs.atomDouble)
  173. ticksPerBeatValue = ((LV2_Atom_Double*)ticksPerBeat)->body;
  174. else if (ticksPerBeat->type == fURIs.atomFloat)
  175. ticksPerBeatValue = ((LV2_Atom_Float*)ticksPerBeat)->body;
  176. else if (ticksPerBeat->type == fURIs.atomInt)
  177. ticksPerBeatValue = static_cast<double>(((LV2_Atom_Int*)ticksPerBeat)->body);
  178. else if (ticksPerBeat->type == fURIs.atomLong)
  179. ticksPerBeatValue = static_cast<double>(((LV2_Atom_Long*)ticksPerBeat)->body);
  180. else
  181. carla_stderr("Unknown lv2 ticksPerBeat value type");
  182. if (ticksPerBeatValue > 0.0)
  183. fTimeInfo.bbt.ticksPerBeat = fLastPositionData.ticksPerBeat = ticksPerBeatValue;
  184. else
  185. carla_stderr("Invalid lv2 ticksPerBeat value");
  186. }
  187. // same
  188. if (speed != nullptr)
  189. {
  190. /**/ if (speed->type == fURIs.atomDouble)
  191. fLastPositionData.speed = ((LV2_Atom_Double*)speed)->body;
  192. else if (speed->type == fURIs.atomFloat)
  193. fLastPositionData.speed = ((LV2_Atom_Float*)speed)->body;
  194. else if (speed->type == fURIs.atomInt)
  195. fLastPositionData.speed = static_cast<double>(((LV2_Atom_Int*)speed)->body);
  196. else if (speed->type == fURIs.atomLong)
  197. fLastPositionData.speed = static_cast<double>(((LV2_Atom_Long*)speed)->body);
  198. else
  199. carla_stderr("Unknown lv2 speed value type");
  200. fTimeInfo.playing = carla_isNotZero(fLastPositionData.speed);
  201. if (fTimeInfo.playing && fLastPositionData.beatsPerMinute > 0.0f)
  202. {
  203. fTimeInfo.bbt.beatsPerMinute = fLastPositionData.beatsPerMinute*
  204. std::abs(fLastPositionData.speed);
  205. }
  206. }
  207. if (bar != nullptr)
  208. {
  209. int64_t barValue = -1;
  210. /**/ if (bar->type == fURIs.atomDouble)
  211. barValue = static_cast<int64_t>(((LV2_Atom_Double*)bar)->body);
  212. else if (bar->type == fURIs.atomFloat)
  213. barValue = static_cast<int64_t>(((LV2_Atom_Float*)bar)->body);
  214. else if (bar->type == fURIs.atomInt)
  215. barValue = ((LV2_Atom_Int*)bar)->body;
  216. else if (bar->type == fURIs.atomLong)
  217. barValue = ((LV2_Atom_Long*)bar)->body;
  218. else
  219. carla_stderr("Unknown lv2 bar value type");
  220. if (barValue >= 0 && barValue < INT32_MAX)
  221. {
  222. fLastPositionData.bar = static_cast<int32_t>(barValue);
  223. fLastPositionData.bar_f = static_cast<float>(barValue);
  224. fTimeInfo.bbt.bar = fLastPositionData.bar + 1;
  225. }
  226. else
  227. {
  228. carla_stderr("Invalid lv2 bar value");
  229. }
  230. }
  231. if (barBeat != nullptr)
  232. {
  233. double barBeatValue = -1.0;
  234. /**/ if (barBeat->type == fURIs.atomDouble)
  235. barBeatValue = ((LV2_Atom_Double*)barBeat)->body;
  236. else if (barBeat->type == fURIs.atomFloat)
  237. barBeatValue = ((LV2_Atom_Float*)barBeat)->body;
  238. else if (barBeat->type == fURIs.atomInt)
  239. barBeatValue = static_cast<float>(((LV2_Atom_Int*)barBeat)->body);
  240. else if (barBeat->type == fURIs.atomLong)
  241. barBeatValue = static_cast<float>(((LV2_Atom_Long*)barBeat)->body);
  242. else
  243. carla_stderr("Unknown lv2 barBeat value type");
  244. if (barBeatValue >= 0.0)
  245. {
  246. fLastPositionData.barBeat = static_cast<float>(barBeatValue);
  247. const double rest = std::fmod(barBeatValue, 1.0);
  248. fTimeInfo.bbt.beat = static_cast<int32_t>(barBeatValue-rest+1.0);
  249. fTimeInfo.bbt.tick = static_cast<int32_t>(rest*fTimeInfo.bbt.ticksPerBeat+0.5);
  250. }
  251. else
  252. {
  253. carla_stderr("Invalid lv2 barBeat value");
  254. }
  255. }
  256. if (beatUnit != nullptr)
  257. {
  258. int64_t beatUnitValue = -1;
  259. /**/ if (beatUnit->type == fURIs.atomDouble)
  260. beatUnitValue = static_cast<int64_t>(((LV2_Atom_Double*)beatUnit)->body);
  261. else if (beatUnit->type == fURIs.atomFloat)
  262. beatUnitValue = static_cast<int64_t>(((LV2_Atom_Float*)beatUnit)->body);
  263. else if (beatUnit->type == fURIs.atomInt)
  264. beatUnitValue = ((LV2_Atom_Int*)beatUnit)->body;
  265. else if (beatUnit->type == fURIs.atomLong)
  266. beatUnitValue = ((LV2_Atom_Long*)beatUnit)->body;
  267. else
  268. carla_stderr("Unknown lv2 beatUnit value type");
  269. if (beatUnitValue > 0 && beatUnitValue < UINT32_MAX)
  270. {
  271. fLastPositionData.beatUnit = static_cast<uint32_t>(beatUnitValue);
  272. fTimeInfo.bbt.beatType = static_cast<float>(beatUnitValue);
  273. }
  274. else
  275. {
  276. carla_stderr("Invalid lv2 beatUnit value");
  277. }
  278. }
  279. if (beatsPerBar != nullptr)
  280. {
  281. float beatsPerBarValue = -1.0f;
  282. /**/ if (beatsPerBar->type == fURIs.atomDouble)
  283. beatsPerBarValue = static_cast<float>(((LV2_Atom_Double*)beatsPerBar)->body);
  284. else if (beatsPerBar->type == fURIs.atomFloat)
  285. beatsPerBarValue = ((LV2_Atom_Float*)beatsPerBar)->body;
  286. else if (beatsPerBar->type == fURIs.atomInt)
  287. beatsPerBarValue = static_cast<float>(((LV2_Atom_Int*)beatsPerBar)->body);
  288. else if (beatsPerBar->type == fURIs.atomLong)
  289. beatsPerBarValue = static_cast<float>(((LV2_Atom_Long*)beatsPerBar)->body);
  290. else
  291. carla_stderr("Unknown lv2 beatsPerBar value type");
  292. if (beatsPerBarValue > 0.0f)
  293. fTimeInfo.bbt.beatsPerBar = fLastPositionData.beatsPerBar = beatsPerBarValue;
  294. else
  295. carla_stderr("Invalid lv2 beatsPerBar value");
  296. }
  297. if (beatsPerMinute != nullptr)
  298. {
  299. double beatsPerMinuteValue = -1.0;
  300. /**/ if (beatsPerMinute->type == fURIs.atomDouble)
  301. beatsPerMinuteValue = ((LV2_Atom_Double*)beatsPerMinute)->body;
  302. else if (beatsPerMinute->type == fURIs.atomFloat)
  303. beatsPerMinuteValue = ((LV2_Atom_Float*)beatsPerMinute)->body;
  304. else if (beatsPerMinute->type == fURIs.atomInt)
  305. beatsPerMinuteValue = static_cast<double>(((LV2_Atom_Int*)beatsPerMinute)->body);
  306. else if (beatsPerMinute->type == fURIs.atomLong)
  307. beatsPerMinuteValue = static_cast<double>(((LV2_Atom_Long*)beatsPerMinute)->body);
  308. else
  309. carla_stderr("Unknown lv2 beatsPerMinute value type");
  310. if (beatsPerMinuteValue >= 12.0 && beatsPerMinuteValue <= 999.0)
  311. {
  312. fTimeInfo.bbt.beatsPerMinute = fLastPositionData.beatsPerMinute = beatsPerMinuteValue;
  313. if (carla_isNotZero(fLastPositionData.speed))
  314. fTimeInfo.bbt.beatsPerMinute *= std::abs(fLastPositionData.speed);
  315. }
  316. else
  317. {
  318. carla_stderr("Invalid lv2 beatsPerMinute value");
  319. }
  320. }
  321. if (frame != nullptr)
  322. {
  323. int64_t frameValue = -1;
  324. /**/ if (frame->type == fURIs.atomDouble)
  325. frameValue = static_cast<int64_t>(((LV2_Atom_Double*)frame)->body);
  326. else if (frame->type == fURIs.atomFloat)
  327. frameValue = static_cast<int64_t>(((LV2_Atom_Float*)frame)->body);
  328. else if (frame->type == fURIs.atomInt)
  329. frameValue = ((LV2_Atom_Int*)frame)->body;
  330. else if (frame->type == fURIs.atomLong)
  331. frameValue = ((LV2_Atom_Long*)frame)->body;
  332. else
  333. carla_stderr("Unknown lv2 frame value type");
  334. if (frameValue >= 0)
  335. fTimeInfo.frame = fLastPositionData.frame = static_cast<uint64_t>(frameValue);
  336. else
  337. carla_stderr("Invalid lv2 frame value");
  338. }
  339. fTimeInfo.bbt.barStartTick = fTimeInfo.bbt.ticksPerBeat*
  340. fTimeInfo.bbt.beatsPerBar*
  341. (fTimeInfo.bbt.bar-1);
  342. fTimeInfo.bbt.valid = (fLastPositionData.beatsPerMinute > 0.0 &&
  343. fLastPositionData.beatUnit > 0 &&
  344. fLastPositionData.beatsPerBar > 0.0f);
  345. }
  346. }
  347. for (uint32_t i=0; i < fDescriptor->midiIns; ++i)
  348. {
  349. LV2_ATOM_SEQUENCE_FOREACH(fPorts.eventsIn[i], event)
  350. {
  351. if (event == nullptr)
  352. continue;
  353. if (event->body.type != fURIs.midiEvent)
  354. continue;
  355. if (event->body.size > 4)
  356. continue;
  357. if (event->time.frames >= frames)
  358. break;
  359. if (fMidiEventCount >= kMaxMidiEvents)
  360. break;
  361. const uint8_t* const data((const uint8_t*)(event + 1));
  362. NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]);
  363. nativeEvent.port = (uint8_t)i;
  364. nativeEvent.size = (uint8_t)event->body.size;
  365. nativeEvent.time = (uint32_t)event->time.frames;
  366. uint32_t j=0;
  367. for (uint32_t size=event->body.size; j<size; ++j)
  368. nativeEvent.data[j] = data[j];
  369. for (; j<4; ++j)
  370. nativeEvent.data[j] = 0;
  371. }
  372. }
  373. }
  374. // init midi out data
  375. if (fDescriptor->midiOuts > 0)
  376. {
  377. for (uint32_t i=0, size=fDescriptor->midiOuts; i<size; ++i)
  378. {
  379. LV2_Atom_Sequence* const seq(fPorts.midiOuts[i]);
  380. CARLA_SAFE_ASSERT_CONTINUE(seq != nullptr);
  381. Ports::MidiOutData& mData(fPorts.midiOutData[i]);
  382. mData.capacity = seq->atom.size;
  383. mData.offset = 0;
  384. seq->atom.size = sizeof(LV2_Atom_Sequence_Body);
  385. seq->atom.type = fURIs.atomSequence;
  386. seq->body.unit = 0;
  387. seq->body.pad = 0;
  388. }
  389. }
  390. // Check for updated parameters
  391. float curValue;
  392. for (uint32_t i=0; i < fPorts.paramCount; ++i)
  393. {
  394. if (fPorts.paramsOut[i])
  395. continue;
  396. CARLA_SAFE_ASSERT_CONTINUE(fPorts.paramsPtr[i] != nullptr)
  397. curValue = *fPorts.paramsPtr[i];
  398. if (carla_isEqual(fPorts.paramsLast[i], curValue))
  399. continue;
  400. fPorts.paramsLast[i] = curValue;
  401. fDescriptor->set_parameter_value(fHandle, i, curValue);
  402. }
  403. if (frames == 0)
  404. return updateParameterOutputs();
  405. // FIXME
  406. fDescriptor->process(fHandle,
  407. const_cast<float**>(fPorts.audioIns), fPorts.audioOuts, frames,
  408. fMidiEvents, fMidiEventCount);
  409. // update timePos for next callback
  410. if (carla_isNotZero(fLastPositionData.speed))
  411. {
  412. if (fLastPositionData.speed > 0.0)
  413. {
  414. // playing forwards
  415. fLastPositionData.frame += frames;
  416. }
  417. else
  418. {
  419. // playing backwards
  420. if (frames >= fLastPositionData.frame)
  421. fLastPositionData.frame = 0;
  422. else
  423. fLastPositionData.frame -= frames;
  424. }
  425. fTimeInfo.frame = fLastPositionData.frame;
  426. if (fTimeInfo.bbt.valid)
  427. {
  428. const double beatsPerMinute = fLastPositionData.beatsPerMinute * fLastPositionData.speed;
  429. const double framesPerBeat = 60.0 * fSampleRate / beatsPerMinute;
  430. const double addedBarBeats = double(frames) / framesPerBeat;
  431. if (fLastPositionData.barBeat >= 0.0f)
  432. {
  433. fLastPositionData.barBeat = std::fmod(fLastPositionData.barBeat+static_cast<float>(addedBarBeats),
  434. fLastPositionData.beatsPerBar);
  435. const double rest = std::fmod(fLastPositionData.barBeat, 1.0f);
  436. fTimeInfo.bbt.beat = static_cast<int32_t>(fLastPositionData.barBeat-rest+1.0);
  437. fTimeInfo.bbt.tick = static_cast<int32_t>(rest*fTimeInfo.bbt.ticksPerBeat+0.5);
  438. if (fLastPositionData.bar_f >= 0.0f)
  439. {
  440. fLastPositionData.bar_f += std::floor((fLastPositionData.barBeat+static_cast<float>(addedBarBeats))/
  441. fLastPositionData.beatsPerBar);
  442. if (fLastPositionData.bar_f <= 0.0f)
  443. {
  444. fLastPositionData.bar = 0;
  445. fLastPositionData.bar_f = 0.0f;
  446. }
  447. else
  448. {
  449. fLastPositionData.bar = static_cast<int32_t>(fLastPositionData.bar_f+0.5f);
  450. }
  451. fTimeInfo.bbt.bar = fLastPositionData.bar + 1;
  452. fTimeInfo.bbt.barStartTick = fTimeInfo.bbt.ticksPerBeat*
  453. fTimeInfo.bbt.beatsPerBar*
  454. (fTimeInfo.bbt.bar-1);
  455. }
  456. }
  457. }
  458. }
  459. updateParameterOutputs();
  460. }
  461. // -------------------------------------------------------------------
  462. uint32_t lv2_get_options(LV2_Options_Option* const /*options*/) const
  463. {
  464. // currently unused
  465. return LV2_OPTIONS_SUCCESS;
  466. }
  467. uint32_t lv2_set_options(const LV2_Options_Option* const options)
  468. {
  469. for (int i=0; options[i].key != 0; ++i)
  470. {
  471. if (options[i].key == fUridMap->map(fUridMap->handle, LV2_BUF_SIZE__nominalBlockLength))
  472. {
  473. if (options[i].type == fURIs.atomInt)
  474. {
  475. const int value(*(const int*)options[i].value);
  476. CARLA_SAFE_ASSERT_CONTINUE(value > 0);
  477. fBufferSize = static_cast<uint32_t>(value);
  478. if (fDescriptor->dispatcher != nullptr)
  479. fDescriptor->dispatcher(fHandle, NATIVE_PLUGIN_OPCODE_BUFFER_SIZE_CHANGED, 0, value, nullptr, 0.0f);
  480. }
  481. else
  482. carla_stderr("Host changed nominalBlockLength but with wrong value type");
  483. }
  484. else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_BUF_SIZE__maxBlockLength) && ! fUsingNominal)
  485. {
  486. if (options[i].type == fURIs.atomInt)
  487. {
  488. const int value(*(const int*)options[i].value);
  489. CARLA_SAFE_ASSERT_CONTINUE(value > 0);
  490. fBufferSize = static_cast<uint32_t>(value);
  491. if (fDescriptor->dispatcher != nullptr)
  492. fDescriptor->dispatcher(fHandle, NATIVE_PLUGIN_OPCODE_BUFFER_SIZE_CHANGED, 0, value, nullptr, 0.0f);
  493. }
  494. else
  495. carla_stderr("Host changed maxBlockLength but with wrong value type");
  496. }
  497. else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate))
  498. {
  499. if (options[i].type == fURIs.atomDouble)
  500. {
  501. const double value(*(const double*)options[i].value);
  502. CARLA_SAFE_ASSERT_CONTINUE(value > 0.0);
  503. fSampleRate = value;
  504. if (fDescriptor->dispatcher != nullptr)
  505. fDescriptor->dispatcher(fHandle, NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED, 0, 0, nullptr, (float)fSampleRate);
  506. }
  507. else
  508. carla_stderr("Host changed sampleRate but with wrong value type");
  509. }
  510. }
  511. return LV2_OPTIONS_SUCCESS;
  512. }
  513. const LV2_Program_Descriptor* lv2_get_program(const uint32_t index)
  514. {
  515. if (fDescriptor->category == NATIVE_PLUGIN_CATEGORY_SYNTH)
  516. return nullptr;
  517. if (fDescriptor->get_midi_program_count == nullptr)
  518. return nullptr;
  519. if (fDescriptor->get_midi_program_info == nullptr)
  520. return nullptr;
  521. if (index >= fDescriptor->get_midi_program_count(fHandle))
  522. return nullptr;
  523. const NativeMidiProgram* const midiProg(fDescriptor->get_midi_program_info(fHandle, index));
  524. if (midiProg == nullptr)
  525. return nullptr;
  526. fProgramDesc.bank = midiProg->bank;
  527. fProgramDesc.program = midiProg->program;
  528. fProgramDesc.name = midiProg->name;
  529. return &fProgramDesc;
  530. }
  531. void lv2_select_program(uint32_t bank, uint32_t program)
  532. {
  533. if (fDescriptor->category == NATIVE_PLUGIN_CATEGORY_SYNTH)
  534. return;
  535. if (fDescriptor->set_midi_program == nullptr)
  536. return;
  537. fDescriptor->set_midi_program(fHandle, 0, bank, program);
  538. for (uint32_t i=0; i < fPorts.paramCount; ++i)
  539. {
  540. fPorts.paramsLast[i] = fDescriptor->get_parameter_value(fHandle, i);
  541. if (fPorts.paramsPtr[i] != nullptr)
  542. *fPorts.paramsPtr[i] = fPorts.paramsLast[i];
  543. }
  544. }
  545. 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
  546. {
  547. if ((fDescriptor->hints & NATIVE_PLUGIN_USES_STATE) == 0 || fDescriptor->get_state == nullptr)
  548. return LV2_STATE_ERR_NO_FEATURE;
  549. if (char* const state = fDescriptor->get_state(fHandle))
  550. {
  551. store(handle, fUridMap->map(fUridMap->handle, "http://kxstudio.sf.net/ns/carla/chunk"), state, std::strlen(state)+1, fURIs.atomString, LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE);
  552. std::free(state);
  553. return LV2_STATE_SUCCESS;
  554. }
  555. return LV2_STATE_ERR_UNKNOWN;
  556. }
  557. 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
  558. {
  559. if ((fDescriptor->hints & NATIVE_PLUGIN_USES_STATE) == 0 || fDescriptor->set_state == nullptr)
  560. return LV2_STATE_ERR_NO_FEATURE;
  561. size_t size = 0;
  562. uint32_t type = 0;
  563. const void* const data = retrieve(handle, fUridMap->map(fUridMap->handle, "http://kxstudio.sf.net/ns/carla/chunk"), &size, &type, &flags);
  564. if (size == 0)
  565. return LV2_STATE_ERR_UNKNOWN;
  566. if (type == 0)
  567. return LV2_STATE_ERR_UNKNOWN;
  568. if (data == nullptr)
  569. return LV2_STATE_ERR_UNKNOWN;
  570. if (type != fURIs.atomString)
  571. return LV2_STATE_ERR_BAD_TYPE;
  572. fDescriptor->set_state(fHandle, (const char*)data);
  573. return LV2_STATE_SUCCESS;
  574. }
  575. // -------------------------------------------------------------------
  576. void lv2ui_instantiate(LV2UI_Write_Function writeFunction, LV2UI_Controller controller,
  577. LV2UI_Widget* widget, const LV2_Feature* const* features, const bool isEmbed)
  578. {
  579. fUI.writeFunction = writeFunction;
  580. fUI.controller = controller;
  581. fUI.isEmbed = isEmbed;
  582. #ifdef CARLA_OS_LINUX
  583. // ---------------------------------------------------------------
  584. // show embed UI if needed
  585. if (isEmbed)
  586. {
  587. intptr_t parentId = 0;
  588. const LV2UI_Resize* uiResize = nullptr;
  589. for (int i=0; features[i] != nullptr; ++i)
  590. {
  591. if (std::strcmp(features[i]->URI, LV2_UI__parent) == 0)
  592. {
  593. parentId = (intptr_t)features[i]->data;
  594. }
  595. else if (std::strcmp(features[i]->URI, LV2_UI__resize) == 0)
  596. {
  597. uiResize = (const LV2UI_Resize*)features[i]->data;
  598. }
  599. }
  600. // -----------------------------------------------------------
  601. // see if the host can really embed the UI
  602. if (parentId != 0)
  603. {
  604. // wait for remote side to be ready
  605. fDescriptor->dispatcher(fHandle, NATIVE_PLUGIN_OPCODE_NULL, (int32_t)0xDEADF00D, 0xC0C0B00B, nullptr, 0.0f);
  606. if (uiResize && uiResize->ui_resize != nullptr)
  607. uiResize->ui_resize(uiResize->handle, 740, 512);
  608. fHost.uiName = carla_strdup(fDescriptor->name);
  609. fUI.isVisible = true;
  610. char strBuf[0xff+1];
  611. strBuf[0xff] = '\0';
  612. std::snprintf(strBuf, 0xff, P_INTPTR, parentId);
  613. carla_setenv("CARLA_PLUGIN_EMBED_WINID", strBuf);
  614. fDescriptor->ui_show(fHandle, true);
  615. carla_setenv("CARLA_PLUGIN_EMBED_WINID", "0");
  616. const intptr_t winId(fDescriptor->dispatcher(fHandle, NATIVE_PLUGIN_OPCODE_NULL, (int32_t)0xDEADF00D, 0xC0C0B00B, nullptr, 0.0f));
  617. CARLA_SAFE_ASSERT_RETURN(winId != 0,);
  618. *widget = (LV2UI_Widget)winId;
  619. return;
  620. }
  621. }
  622. #endif
  623. // ---------------------------------------------------------------
  624. // see if the host supports external-ui
  625. for (int i=0; features[i] != nullptr; ++i)
  626. {
  627. if (std::strcmp(features[i]->URI, LV2_EXTERNAL_UI__Host) == 0 ||
  628. std::strcmp(features[i]->URI, LV2_EXTERNAL_UI_DEPRECATED_URI) == 0)
  629. {
  630. fUI.host = (const LV2_External_UI_Host*)features[i]->data;
  631. break;
  632. }
  633. }
  634. if (fUI.host != nullptr)
  635. {
  636. fHost.uiName = carla_strdup(fUI.host->plugin_human_id);
  637. *widget = (LV2_External_UI_Widget_Compat*)this;
  638. return;
  639. }
  640. // ---------------------------------------------------------------
  641. // no external-ui support, use showInterface
  642. for (int i=0; features[i] != nullptr; ++i)
  643. {
  644. if (std::strcmp(features[i]->URI, LV2_OPTIONS__options) == 0)
  645. {
  646. const LV2_Options_Option* const options((const LV2_Options_Option*)features[i]->data);
  647. for (int j=0; options[j].key != 0; ++j)
  648. {
  649. if (options[j].key == fUridMap->map(fUridMap->handle, LV2_UI__windowTitle))
  650. {
  651. fHost.uiName = carla_strdup((const char*)options[j].value);
  652. break;
  653. }
  654. }
  655. break;
  656. }
  657. }
  658. if (fHost.uiName == nullptr)
  659. fHost.uiName = carla_strdup(fDescriptor->name);
  660. *widget = nullptr;
  661. }
  662. void lv2ui_port_event(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer) const
  663. {
  664. if (format != 0 || bufferSize != sizeof(float) || buffer == nullptr)
  665. return;
  666. if (portIndex >= fUI.portOffset || ! fUI.isVisible)
  667. return;
  668. if (fDescriptor->ui_set_parameter_value == nullptr)
  669. return;
  670. const float value(*(const float*)buffer);
  671. fDescriptor->ui_set_parameter_value(fHandle, portIndex-fUI.portOffset, value);
  672. }
  673. void lv2ui_cleanup()
  674. {
  675. if (fUI.isVisible)
  676. handleUiHide();
  677. fUI.host = nullptr;
  678. fUI.writeFunction = nullptr;
  679. fUI.controller = nullptr;
  680. if (fHost.uiName != nullptr)
  681. {
  682. delete[] fHost.uiName;
  683. fHost.uiName = nullptr;
  684. }
  685. }
  686. // -------------------------------------------------------------------
  687. void lv2ui_select_program(uint32_t bank, uint32_t program) const
  688. {
  689. if (fDescriptor->category == NATIVE_PLUGIN_CATEGORY_SYNTH)
  690. return;
  691. if (fDescriptor->ui_set_midi_program == nullptr)
  692. return;
  693. fDescriptor->ui_set_midi_program(fHandle, 0, bank, program);
  694. }
  695. // -------------------------------------------------------------------
  696. int lv2ui_idle() const
  697. {
  698. if (! fUI.isVisible)
  699. return 1;
  700. handleUiRun();
  701. return 0;
  702. }
  703. int lv2ui_show()
  704. {
  705. handleUiShow();
  706. return 0;
  707. }
  708. int lv2ui_hide()
  709. {
  710. handleUiHide();
  711. return 0;
  712. }
  713. // -------------------------------------------------------------------
  714. protected:
  715. void handleUiRun() const override
  716. {
  717. if (fDescriptor->ui_idle != nullptr)
  718. fDescriptor->ui_idle(fHandle);
  719. }
  720. void handleUiShow() override
  721. {
  722. if (fDescriptor->ui_show != nullptr)
  723. fDescriptor->ui_show(fHandle, true);
  724. fUI.isVisible = true;
  725. }
  726. void handleUiHide() override
  727. {
  728. if (fDescriptor->ui_show != nullptr)
  729. fDescriptor->ui_show(fHandle, false);
  730. fUI.isVisible = false;
  731. }
  732. // -------------------------------------------------------------------
  733. bool handleWriteMidiEvent(const NativeMidiEvent* const event)
  734. {
  735. CARLA_SAFE_ASSERT_RETURN(fDescriptor->midiOuts > 0, false);
  736. CARLA_SAFE_ASSERT_RETURN(event != nullptr, false);
  737. CARLA_SAFE_ASSERT_RETURN(event->size > 0, false);
  738. const uint8_t port(event->port);
  739. CARLA_SAFE_ASSERT_RETURN(port < fDescriptor->midiOuts, false);
  740. LV2_Atom_Sequence* const seq(fPorts.midiOuts[port]);
  741. CARLA_SAFE_ASSERT_RETURN(seq != nullptr, false);
  742. Ports::MidiOutData& mData(fPorts.midiOutData[port]);
  743. if (sizeof(LV2_Atom_Event) + event->size > mData.capacity - mData.offset)
  744. return false;
  745. LV2_Atom_Event* const aev = (LV2_Atom_Event*)(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, seq) + mData.offset);
  746. aev->time.frames = event->time;
  747. aev->body.size = event->size;
  748. aev->body.type = fURIs.midiEvent;
  749. std::memcpy(LV2_ATOM_BODY(&aev->body), event->data, event->size);
  750. const uint32_t size = lv2_atom_pad_size(static_cast<uint32_t>(sizeof(LV2_Atom_Event) + event->size));
  751. mData.offset += size;
  752. seq->atom.size += size;
  753. return true;
  754. }
  755. void handleUiParameterChanged(const uint32_t index, const float value) const
  756. {
  757. if (fUI.writeFunction != nullptr && fUI.controller != nullptr)
  758. fUI.writeFunction(fUI.controller, index+fUI.portOffset, sizeof(float), 0, &value);
  759. }
  760. void handleUiCustomDataChanged(const char* const /*key*/, const char* const /*value*/) const
  761. {
  762. //storeCustomData(key, value);
  763. }
  764. void handleUiClosed()
  765. {
  766. if (fUI.host != nullptr && fUI.host->ui_closed != nullptr && fUI.controller != nullptr)
  767. fUI.host->ui_closed(fUI.controller);
  768. fUI.host = nullptr;
  769. fUI.writeFunction = nullptr;
  770. fUI.controller = nullptr;
  771. fUI.isVisible = false;
  772. }
  773. const char* handleUiOpenFile(const bool /*isDir*/, const char* const /*title*/, const char* const /*filter*/) const
  774. {
  775. // TODO
  776. return nullptr;
  777. }
  778. const char* handleUiSaveFile(const bool /*isDir*/, const char* const /*title*/, const char* const /*filter*/) const
  779. {
  780. // TODO
  781. return nullptr;
  782. }
  783. intptr_t handleDispatcher(const NativeHostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
  784. {
  785. carla_debug("NativePlugin::handleDispatcher(%i, %i, " P_INTPTR ", %p, %f)", opcode, index, value, ptr, opt);
  786. intptr_t ret = 0;
  787. switch (opcode)
  788. {
  789. case NATIVE_HOST_OPCODE_NULL:
  790. case NATIVE_HOST_OPCODE_UPDATE_PARAMETER:
  791. case NATIVE_HOST_OPCODE_UPDATE_MIDI_PROGRAM:
  792. case NATIVE_HOST_OPCODE_RELOAD_PARAMETERS:
  793. case NATIVE_HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
  794. case NATIVE_HOST_OPCODE_RELOAD_ALL:
  795. case NATIVE_HOST_OPCODE_HOST_IDLE:
  796. case NATIVE_HOST_OPCODE_INTERNAL_PLUGIN:
  797. // nothing
  798. break;
  799. case NATIVE_HOST_OPCODE_UI_UNAVAILABLE:
  800. handleUiClosed();
  801. break;
  802. }
  803. return ret;
  804. // unused for now
  805. (void)index;
  806. (void)value;
  807. (void)ptr;
  808. (void)opt;
  809. }
  810. void updateParameterOutputs()
  811. {
  812. for (uint32_t i=0; i < fPorts.paramCount; ++i)
  813. {
  814. if (! fPorts.paramsOut[i])
  815. continue;
  816. fPorts.paramsLast[i] = fDescriptor->get_parameter_value(fHandle, i);
  817. if (fPorts.paramsPtr[i] != nullptr)
  818. *fPorts.paramsPtr[i] = fPorts.paramsLast[i];
  819. }
  820. }
  821. // -------------------------------------------------------------------
  822. private:
  823. // Native data
  824. NativePluginHandle fHandle;
  825. NativeHostDescriptor fHost;
  826. const NativePluginDescriptor* const fDescriptor;
  827. LV2_Program_Descriptor fProgramDesc;
  828. uint32_t fMidiEventCount;
  829. NativeMidiEvent fMidiEvents[kMaxMidiEvents];
  830. NativeTimeInfo fTimeInfo;
  831. struct Lv2PositionData {
  832. int32_t bar;
  833. float bar_f;
  834. float barBeat;
  835. uint32_t beatUnit;
  836. float beatsPerBar;
  837. double beatsPerMinute;
  838. uint64_t frame;
  839. double speed;
  840. double ticksPerBeat;
  841. Lv2PositionData()
  842. : bar(-1),
  843. bar_f(-1.0f),
  844. barBeat(-1.0f),
  845. beatUnit(0),
  846. beatsPerBar(0.0f),
  847. beatsPerMinute(-1.0),
  848. frame(0),
  849. speed(0.0),
  850. ticksPerBeat(-1.0) {}
  851. } fLastPositionData;
  852. struct UI {
  853. const LV2_External_UI_Host* host;
  854. LV2UI_Write_Function writeFunction;
  855. LV2UI_Controller controller;
  856. uint32_t portOffset;
  857. bool isEmbed;
  858. bool isVisible;
  859. UI()
  860. : host(nullptr),
  861. writeFunction(nullptr),
  862. controller(nullptr),
  863. portOffset(0),
  864. isEmbed(false),
  865. isVisible(false) {}
  866. } fUI;
  867. struct Ports {
  868. // need to save current state
  869. struct MidiOutData {
  870. uint32_t capacity;
  871. uint32_t offset;
  872. MidiOutData()
  873. : capacity(0),
  874. offset(0) {}
  875. };
  876. const LV2_Atom_Sequence** eventsIn;
  877. /* */ LV2_Atom_Sequence** midiOuts;
  878. /* */ MidiOutData* midiOutData;
  879. const float** audioIns;
  880. /* */ float** audioOuts;
  881. float* freewheel;
  882. uint32_t paramCount;
  883. float* paramsLast;
  884. float** paramsPtr;
  885. bool* paramsOut;
  886. Ports()
  887. : eventsIn(nullptr),
  888. midiOuts(nullptr),
  889. midiOutData(nullptr),
  890. audioIns(nullptr),
  891. audioOuts(nullptr),
  892. freewheel(nullptr),
  893. paramCount(0),
  894. paramsLast(nullptr),
  895. paramsPtr(nullptr),
  896. paramsOut(nullptr) {}
  897. ~Ports()
  898. {
  899. if (eventsIn != nullptr)
  900. {
  901. delete[] eventsIn;
  902. eventsIn = nullptr;
  903. }
  904. if (midiOuts != nullptr)
  905. {
  906. delete[] midiOuts;
  907. midiOuts = nullptr;
  908. }
  909. if (midiOutData != nullptr)
  910. {
  911. delete[] midiOutData;
  912. midiOutData = nullptr;
  913. }
  914. if (audioIns != nullptr)
  915. {
  916. delete[] audioIns;
  917. audioIns = nullptr;
  918. }
  919. if (audioOuts != nullptr)
  920. {
  921. delete[] audioOuts;
  922. audioOuts = nullptr;
  923. }
  924. if (paramsLast != nullptr)
  925. {
  926. delete[] paramsLast;
  927. paramsLast = nullptr;
  928. }
  929. if (paramsPtr != nullptr)
  930. {
  931. delete[] paramsPtr;
  932. paramsPtr = nullptr;
  933. }
  934. if (paramsOut != nullptr)
  935. {
  936. delete[] paramsOut;
  937. paramsOut = nullptr;
  938. }
  939. }
  940. void init(const NativePluginDescriptor* const desc, NativePluginHandle handle)
  941. {
  942. CARLA_SAFE_ASSERT_RETURN(desc != nullptr && handle != nullptr,)
  943. if (desc->midiIns > 0)
  944. {
  945. eventsIn = new const LV2_Atom_Sequence*[desc->midiIns];
  946. for (uint32_t i=0; i < desc->midiIns; ++i)
  947. eventsIn[i] = nullptr;
  948. }
  949. else if (desc->hints & NATIVE_PLUGIN_USES_TIME)
  950. {
  951. eventsIn = new const LV2_Atom_Sequence*[1];
  952. eventsIn[0] = nullptr;
  953. }
  954. if (desc->midiOuts > 0)
  955. {
  956. midiOuts = new LV2_Atom_Sequence*[desc->midiOuts];
  957. midiOutData = new MidiOutData[desc->midiOuts];
  958. for (uint32_t i=0; i < desc->midiOuts; ++i)
  959. midiOuts[i] = nullptr;
  960. }
  961. if (desc->audioIns > 0)
  962. {
  963. audioIns = new const float*[desc->audioIns];
  964. for (uint32_t i=0; i < desc->audioIns; ++i)
  965. audioIns[i] = nullptr;
  966. }
  967. if (desc->audioOuts > 0)
  968. {
  969. audioOuts = new float*[desc->audioOuts];
  970. for (uint32_t i=0; i < desc->audioOuts; ++i)
  971. audioOuts[i] = nullptr;
  972. }
  973. if (desc->get_parameter_count != nullptr && desc->get_parameter_info != nullptr && desc->get_parameter_value != nullptr && desc->set_parameter_value != nullptr)
  974. {
  975. paramCount = desc->get_parameter_count(handle);
  976. if (paramCount > 0)
  977. {
  978. paramsLast = new float[paramCount];
  979. paramsPtr = new float*[paramCount];
  980. paramsOut = new bool[paramCount];
  981. for (uint32_t i=0; i < paramCount; ++i)
  982. {
  983. paramsLast[i] = desc->get_parameter_value(handle, i);
  984. paramsPtr [i] = nullptr;
  985. paramsOut [i] = (desc->get_parameter_info(handle, i)->hints & NATIVE_PARAMETER_IS_OUTPUT);
  986. }
  987. }
  988. }
  989. }
  990. void connectPort(const NativePluginDescriptor* const desc, const uint32_t port, void* const dataLocation)
  991. {
  992. uint32_t index = 0;
  993. if (desc->midiIns > 0 || (desc->hints & NATIVE_PLUGIN_USES_TIME) != 0)
  994. {
  995. if (port == index++)
  996. {
  997. eventsIn[0] = (LV2_Atom_Sequence*)dataLocation;
  998. return;
  999. }
  1000. }
  1001. for (uint32_t i=1; i < desc->midiIns; ++i)
  1002. {
  1003. if (port == index++)
  1004. {
  1005. eventsIn[i] = (LV2_Atom_Sequence*)dataLocation;
  1006. return;
  1007. }
  1008. }
  1009. for (uint32_t i=0; i < desc->midiOuts; ++i)
  1010. {
  1011. if (port == index++)
  1012. {
  1013. midiOuts[i] = (LV2_Atom_Sequence*)dataLocation;
  1014. return;
  1015. }
  1016. }
  1017. if (port == index++)
  1018. {
  1019. freewheel = (float*)dataLocation;
  1020. return;
  1021. }
  1022. for (uint32_t i=0; i < desc->audioIns; ++i)
  1023. {
  1024. if (port == index++)
  1025. {
  1026. audioIns[i] = (float*)dataLocation;
  1027. return;
  1028. }
  1029. }
  1030. for (uint32_t i=0; i < desc->audioOuts; ++i)
  1031. {
  1032. if (port == index++)
  1033. {
  1034. audioOuts[i] = (float*)dataLocation;
  1035. return;
  1036. }
  1037. }
  1038. for (uint32_t i=0; i < paramCount; ++i)
  1039. {
  1040. if (port == index++)
  1041. {
  1042. paramsPtr[i] = (float*)dataLocation;
  1043. return;
  1044. }
  1045. }
  1046. }
  1047. CARLA_DECLARE_NON_COPY_STRUCT(Ports);
  1048. } fPorts;
  1049. // -------------------------------------------------------------------
  1050. #define handlePtr ((NativePlugin*)handle)
  1051. static uint32_t host_get_buffer_size(NativeHostHandle handle)
  1052. {
  1053. return handlePtr->fBufferSize;
  1054. }
  1055. static double host_get_sample_rate(NativeHostHandle handle)
  1056. {
  1057. return handlePtr->fSampleRate;
  1058. }
  1059. static bool host_is_offline(NativeHostHandle handle)
  1060. {
  1061. return handlePtr->fIsOffline;
  1062. }
  1063. static const NativeTimeInfo* host_get_time_info(NativeHostHandle handle)
  1064. {
  1065. return &(handlePtr->fTimeInfo);
  1066. }
  1067. static bool host_write_midi_event(NativeHostHandle handle, const NativeMidiEvent* event)
  1068. {
  1069. return handlePtr->handleWriteMidiEvent(event);
  1070. }
  1071. static void host_ui_parameter_changed(NativeHostHandle handle, uint32_t index, float value)
  1072. {
  1073. handlePtr->handleUiParameterChanged(index, value);
  1074. }
  1075. static void host_ui_custom_data_changed(NativeHostHandle handle, const char* key, const char* value)
  1076. {
  1077. handlePtr->handleUiCustomDataChanged(key, value);
  1078. }
  1079. static void host_ui_closed(NativeHostHandle handle)
  1080. {
  1081. handlePtr->handleUiClosed();
  1082. }
  1083. static const char* host_ui_open_file(NativeHostHandle handle, bool isDir, const char* title, const char* filter)
  1084. {
  1085. return handlePtr->handleUiOpenFile(isDir, title, filter);
  1086. }
  1087. static const char* host_ui_save_file(NativeHostHandle handle, bool isDir, const char* title, const char* filter)
  1088. {
  1089. return handlePtr->handleUiSaveFile(isDir, title, filter);
  1090. }
  1091. static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt)
  1092. {
  1093. return handlePtr->handleDispatcher(opcode, index, value, ptr, opt);
  1094. }
  1095. #undef handlePtr
  1096. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePlugin)
  1097. };
  1098. // -----------------------------------------------------------------------
  1099. // LV2 plugin descriptor functions
  1100. static LV2_Handle lv2_instantiate(const LV2_Descriptor* lv2Descriptor, double sampleRate, const char* bundlePath, const LV2_Feature* const* features)
  1101. {
  1102. carla_debug("lv2_instantiate(%p, %g, %s, %p)", lv2Descriptor, sampleRate, bundlePath, features);
  1103. const NativePluginDescriptor* pluginDesc = nullptr;
  1104. const char* pluginLabel = nullptr;
  1105. if (std::strncmp(lv2Descriptor->URI, "http://kxstudio.sf.net/carla/plugins/", 37) == 0)
  1106. pluginLabel = lv2Descriptor->URI+37;
  1107. if (pluginLabel == nullptr)
  1108. {
  1109. carla_stderr("Failed to find carla native plugin with URI \"%s\"", lv2Descriptor->URI);
  1110. return nullptr;
  1111. }
  1112. carla_debug("lv2_instantiate() - looking up label \"%s\"", pluginLabel);
  1113. PluginListManager& plm(PluginListManager::getInstance());
  1114. for (LinkedList<const NativePluginDescriptor*>::Itenerator it = plm.descs.begin2(); it.valid(); it.next())
  1115. {
  1116. const NativePluginDescriptor* const& tmpDesc(it.getValue(nullptr));
  1117. CARLA_SAFE_ASSERT_CONTINUE(tmpDesc != nullptr);
  1118. if (std::strcmp(tmpDesc->label, pluginLabel) == 0)
  1119. {
  1120. pluginDesc = tmpDesc;
  1121. break;
  1122. }
  1123. }
  1124. if (pluginDesc == nullptr)
  1125. {
  1126. carla_stderr("Failed to find carla native plugin with label \"%s\"", pluginLabel);
  1127. return nullptr;
  1128. }
  1129. NativePlugin* const plugin(new NativePlugin(pluginDesc, sampleRate, bundlePath, features));
  1130. if (! plugin->init())
  1131. {
  1132. carla_stderr("Failed to init plugin");
  1133. delete plugin;
  1134. return nullptr;
  1135. }
  1136. return (LV2_Handle)plugin;
  1137. }
  1138. #define instancePtr ((NativePlugin*)instance)
  1139. static void lv2_connect_port(LV2_Handle instance, uint32_t port, void* dataLocation)
  1140. {
  1141. instancePtr->lv2_connect_port(port, dataLocation);
  1142. }
  1143. static void lv2_activate(LV2_Handle instance)
  1144. {
  1145. carla_debug("lv2_activate(%p)", instance);
  1146. instancePtr->lv2_activate();
  1147. }
  1148. static void lv2_run(LV2_Handle instance, uint32_t sampleCount)
  1149. {
  1150. instancePtr->lv2_run(sampleCount);
  1151. }
  1152. static void lv2_deactivate(LV2_Handle instance)
  1153. {
  1154. carla_debug("lv2_deactivate(%p)", instance);
  1155. instancePtr->lv2_deactivate();
  1156. }
  1157. static void lv2_cleanup(LV2_Handle instance)
  1158. {
  1159. carla_debug("lv2_cleanup(%p)", instance);
  1160. instancePtr->lv2_cleanup();
  1161. delete instancePtr;
  1162. }
  1163. static uint32_t lv2_get_options(LV2_Handle instance, LV2_Options_Option* options)
  1164. {
  1165. carla_debug("lv2_get_options(%p, %p)", instance, options);
  1166. return instancePtr->lv2_get_options(options);
  1167. }
  1168. static uint32_t lv2_set_options(LV2_Handle instance, const LV2_Options_Option* options)
  1169. {
  1170. carla_debug("lv2_set_options(%p, %p)", instance, options);
  1171. return instancePtr->lv2_set_options(options);
  1172. }
  1173. static const LV2_Program_Descriptor* lv2_get_program(LV2_Handle instance, uint32_t index)
  1174. {
  1175. carla_debug("lv2_get_program(%p, %i)", instance, index);
  1176. return instancePtr->lv2_get_program(index);
  1177. }
  1178. static void lv2_select_program(LV2_Handle instance, uint32_t bank, uint32_t program)
  1179. {
  1180. carla_debug("lv2_select_program(%p, %i, %i)", instance, bank, program);
  1181. return instancePtr->lv2_select_program(bank, program);
  1182. }
  1183. 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)
  1184. {
  1185. carla_debug("lv2_save(%p, %p, %p, %i, %p)", instance, store, handle, flags, features);
  1186. return instancePtr->lv2_save(store, handle, flags, features);
  1187. }
  1188. 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)
  1189. {
  1190. carla_debug("lv2_restore(%p, %p, %p, %i, %p)", instance, retrieve, handle, flags, features);
  1191. return instancePtr->lv2_restore(retrieve, handle, flags, features);
  1192. }
  1193. static const void* lv2_extension_data(const char* uri)
  1194. {
  1195. carla_debug("lv2_extension_data(\"%s\")", uri);
  1196. static const LV2_Options_Interface options = { lv2_get_options, lv2_set_options };
  1197. static const LV2_Programs_Interface programs = { lv2_get_program, lv2_select_program };
  1198. static const LV2_State_Interface state = { lv2_save, lv2_restore };
  1199. if (std::strcmp(uri, LV2_OPTIONS__interface) == 0)
  1200. return &options;
  1201. if (std::strcmp(uri, LV2_PROGRAMS__Interface) == 0)
  1202. return &programs;
  1203. if (std::strcmp(uri, LV2_STATE__interface) == 0)
  1204. return &state;
  1205. return nullptr;
  1206. }
  1207. #undef instancePtr
  1208. // -----------------------------------------------------------------------
  1209. // LV2 UI descriptor functions
  1210. static LV2UI_Handle lv2ui_instantiate(LV2UI_Write_Function writeFunction, LV2UI_Controller controller,
  1211. LV2UI_Widget* widget, const LV2_Feature* const* features, const bool isEmbed)
  1212. {
  1213. carla_debug("lv2ui_instantiate(..., %p, %p, %p)", writeFunction, controller, widget, features);
  1214. #ifndef CARLA_OS_LINUX
  1215. CARLA_SAFE_ASSERT_RETURN(! isEmbed, nullptr);
  1216. #endif
  1217. NativePlugin* plugin = nullptr;
  1218. for (int i=0; features[i] != nullptr; ++i)
  1219. {
  1220. if (std::strcmp(features[i]->URI, LV2_INSTANCE_ACCESS_URI) == 0)
  1221. {
  1222. plugin = (NativePlugin*)features[i]->data;
  1223. break;
  1224. }
  1225. }
  1226. if (plugin == nullptr)
  1227. {
  1228. carla_stderr("Host doesn't support instance-access, cannot show UI");
  1229. return nullptr;
  1230. }
  1231. plugin->lv2ui_instantiate(writeFunction, controller, widget, features, isEmbed);
  1232. return (LV2UI_Handle)plugin;
  1233. }
  1234. #ifdef CARLA_OS_LINUX
  1235. static LV2UI_Handle lv2ui_instantiate_embed(const LV2UI_Descriptor*, const char*, const char*,
  1236. LV2UI_Write_Function writeFunction, LV2UI_Controller controller,
  1237. LV2UI_Widget* widget, const LV2_Feature* const* features)
  1238. {
  1239. return lv2ui_instantiate(writeFunction, controller, widget, features, true);
  1240. }
  1241. #endif
  1242. static LV2UI_Handle lv2ui_instantiate_external(const LV2UI_Descriptor*, const char*, const char*,
  1243. LV2UI_Write_Function writeFunction, LV2UI_Controller controller,
  1244. LV2UI_Widget* widget, const LV2_Feature* const* features)
  1245. {
  1246. return lv2ui_instantiate(writeFunction, controller, widget, features, false);
  1247. }
  1248. #define uiPtr ((NativePlugin*)ui)
  1249. static void lv2ui_port_event(LV2UI_Handle ui, uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer)
  1250. {
  1251. carla_debug("lv2ui_port_event(%p, %i, %i, %i, %p)", ui, portIndex, bufferSize, format, buffer);
  1252. uiPtr->lv2ui_port_event(portIndex, bufferSize, format, buffer);
  1253. }
  1254. static void lv2ui_cleanup(LV2UI_Handle ui)
  1255. {
  1256. carla_debug("lv2ui_cleanup(%p)", ui);
  1257. uiPtr->lv2ui_cleanup();
  1258. }
  1259. static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t program)
  1260. {
  1261. carla_debug("lv2ui_select_program(%p, %i, %i)", ui, bank, program);
  1262. uiPtr->lv2ui_select_program(bank, program);
  1263. }
  1264. static int lv2ui_idle(LV2UI_Handle ui)
  1265. {
  1266. return uiPtr->lv2ui_idle();
  1267. }
  1268. static int lv2ui_show(LV2UI_Handle ui)
  1269. {
  1270. carla_debug("lv2ui_show(%p)", ui);
  1271. return uiPtr->lv2ui_show();
  1272. }
  1273. static int lv2ui_hide(LV2UI_Handle ui)
  1274. {
  1275. carla_debug("lv2ui_hide(%p)", ui);
  1276. return uiPtr->lv2ui_hide();
  1277. }
  1278. static const void* lv2ui_extension_data(const char* uri)
  1279. {
  1280. carla_stdout("lv2ui_extension_data(\"%s\")", uri);
  1281. static const LV2UI_Idle_Interface uiidle = { lv2ui_idle };
  1282. static const LV2UI_Show_Interface uishow = { lv2ui_show, lv2ui_hide };
  1283. static const LV2_Programs_UI_Interface uiprograms = { lv2ui_select_program };
  1284. if (std::strcmp(uri, LV2_UI__idleInterface) == 0)
  1285. return &uiidle;
  1286. if (std::strcmp(uri, LV2_UI__showInterface) == 0)
  1287. return &uishow;
  1288. if (std::strcmp(uri, LV2_PROGRAMS__UIInterface) == 0)
  1289. return &uiprograms;
  1290. return nullptr;
  1291. }
  1292. #undef uiPtr
  1293. // -----------------------------------------------------------------------
  1294. // Startup code
  1295. CARLA_EXPORT
  1296. const LV2_Descriptor* lv2_descriptor(uint32_t index)
  1297. {
  1298. carla_debug("lv2_descriptor(%i)", index);
  1299. PluginListManager& plm(PluginListManager::getInstance());
  1300. if (index >= plm.descs.count())
  1301. {
  1302. carla_debug("lv2_descriptor(%i) - out of bounds", index);
  1303. return nullptr;
  1304. }
  1305. if (index < plm.lv2Descs.count())
  1306. {
  1307. carla_debug("lv2_descriptor(%i) - found previously allocated", index);
  1308. return plm.lv2Descs.getAt(index, nullptr);
  1309. }
  1310. const NativePluginDescriptor* const pluginDesc(plm.descs.getAt(index, nullptr));
  1311. CARLA_SAFE_ASSERT_RETURN(pluginDesc != nullptr, nullptr);
  1312. CarlaString tmpURI;
  1313. tmpURI = "http://kxstudio.sf.net/carla/plugins/";
  1314. tmpURI += pluginDesc->label;
  1315. carla_debug("lv2_descriptor(%i) - not found, allocating new with uri \"%s\"", index, (const char*)tmpURI);
  1316. const LV2_Descriptor lv2DescTmp = {
  1317. /* URI */ carla_strdup(tmpURI),
  1318. /* instantiate */ lv2_instantiate,
  1319. /* connect_port */ lv2_connect_port,
  1320. /* activate */ lv2_activate,
  1321. /* run */ lv2_run,
  1322. /* deactivate */ lv2_deactivate,
  1323. /* cleanup */ lv2_cleanup,
  1324. /* extension_data */ lv2_extension_data
  1325. };
  1326. LV2_Descriptor* lv2Desc;
  1327. try {
  1328. lv2Desc = new LV2_Descriptor;
  1329. } CARLA_SAFE_EXCEPTION_RETURN("new LV2_Descriptor", nullptr);
  1330. std::memcpy(lv2Desc, &lv2DescTmp, sizeof(LV2_Descriptor));
  1331. plm.lv2Descs.append(lv2Desc);
  1332. return lv2Desc;
  1333. }
  1334. CARLA_EXPORT
  1335. const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
  1336. {
  1337. carla_debug("lv2ui_descriptor(%i)", index);
  1338. #ifdef CARLA_OS_LINUX
  1339. static const LV2UI_Descriptor lv2UiEmbedDesc = {
  1340. /* URI */ "http://kxstudio.sf.net/carla/ui-embed",
  1341. /* instantiate */ lv2ui_instantiate_embed,
  1342. /* cleanup */ lv2ui_cleanup,
  1343. /* port_event */ lv2ui_port_event,
  1344. /* extension_data */ lv2ui_extension_data
  1345. };
  1346. if (index == 0)
  1347. return &lv2UiEmbedDesc;
  1348. else
  1349. --index;
  1350. #endif
  1351. static const LV2UI_Descriptor lv2UiExtDesc = {
  1352. /* URI */ "http://kxstudio.sf.net/carla/ui-ext",
  1353. /* instantiate */ lv2ui_instantiate_external,
  1354. /* cleanup */ lv2ui_cleanup,
  1355. /* port_event */ lv2ui_port_event,
  1356. /* extension_data */ lv2ui_extension_data
  1357. };
  1358. return (index == 0) ? &lv2UiExtDesc : nullptr;
  1359. }
  1360. // -----------------------------------------------------------------------