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.

1120 lines
38KB

  1. /*
  2. * Carla Bridge UI, LV2 version
  3. * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the GPL.txt file
  16. */
  17. #ifdef BRIDGE_LV2
  18. #include "CarlaBridgeClient.hpp"
  19. #include "CarlaLv2Utils.hpp"
  20. #include "CarlaMIDI.h"
  21. extern "C" {
  22. #include "rtmempool/rtmempool-lv2.h"
  23. }
  24. #include <vector>
  25. #include <QtCore/QDir>
  26. Lv2WorldClass gLv2World;
  27. CARLA_BRIDGE_START_NAMESPACE
  28. // -------------------------------------------------------------------------
  29. // fake values
  30. uint32_t bufferSize = 512;
  31. double sampleRate = 44100.0;
  32. // static max values
  33. const unsigned int MAX_EVENT_BUFFER = 8192; // 0x2000
  34. // feature ids
  35. const uint32_t lv2_feature_id_bufsize_bounded = 0;
  36. const uint32_t lv2_feature_id_bufsize_fixed = 1;
  37. const uint32_t lv2_feature_id_bufsize_powerof2 = 2;
  38. const uint32_t lv2_feature_id_event = 3;
  39. const uint32_t lv2_feature_id_logs = 4;
  40. const uint32_t lv2_feature_id_options = 5;
  41. const uint32_t lv2_feature_id_programs = 6;
  42. const uint32_t lv2_feature_id_rtmempool = 7;
  43. const uint32_t lv2_feature_id_state_make_path = 8;
  44. const uint32_t lv2_feature_id_state_map_path = 9;
  45. const uint32_t lv2_feature_id_strict_bounds = 10;
  46. const uint32_t lv2_feature_id_uri_map = 11;
  47. const uint32_t lv2_feature_id_urid_map = 12;
  48. const uint32_t lv2_feature_id_urid_unmap = 13;
  49. const uint32_t lv2_feature_id_ui_parent = 14;
  50. const uint32_t lv2_feature_id_ui_port_map = 15;
  51. const uint32_t lv2_feature_id_ui_resize = 16;
  52. const uint32_t lv2_feature_count = 17;
  53. // pre-set uri[d] map ids
  54. const uint32_t CARLA_URI_MAP_ID_NULL = 0;
  55. const uint32_t CARLA_URI_MAP_ID_ATOM_CHUNK = 1;
  56. const uint32_t CARLA_URI_MAP_ID_ATOM_DOUBLE = 2;
  57. const uint32_t CARLA_URI_MAP_ID_ATOM_INT = 3;
  58. const uint32_t CARLA_URI_MAP_ID_ATOM_PATH = 4;
  59. const uint32_t CARLA_URI_MAP_ID_ATOM_SEQUENCE = 5;
  60. const uint32_t CARLA_URI_MAP_ID_ATOM_STRING = 6;
  61. const uint32_t CARLA_URI_MAP_ID_ATOM_WORKER = 7;
  62. const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM = 8;
  63. const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT = 9;
  64. const uint32_t CARLA_URI_MAP_ID_BUF_MAX_LENGTH = 10;
  65. const uint32_t CARLA_URI_MAP_ID_BUF_MIN_LENGTH = 11;
  66. const uint32_t CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE = 12;
  67. const uint32_t CARLA_URI_MAP_ID_LOG_ERROR = 13;
  68. const uint32_t CARLA_URI_MAP_ID_LOG_NOTE = 14;
  69. const uint32_t CARLA_URI_MAP_ID_LOG_TRACE = 15;
  70. const uint32_t CARLA_URI_MAP_ID_LOG_WARNING = 16;
  71. const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 17;
  72. const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 18;
  73. const uint32_t CARLA_URI_MAP_ID_COUNT = 19;
  74. // -------------------------------------------------------------------------
  75. struct Lv2PluginOptions {
  76. uint32_t eventSize;
  77. uint32_t bufferSize;
  78. double sampleRate;
  79. LV2_Options_Option oNull;
  80. LV2_Options_Option oMaxBlockLenth;
  81. LV2_Options_Option oMinBlockLenth;
  82. LV2_Options_Option oSequenceSize;
  83. LV2_Options_Option oSampleRate;
  84. Lv2PluginOptions()
  85. : eventSize(MAX_EVENT_BUFFER),
  86. bufferSize(0),
  87. sampleRate(0.0) {}
  88. };
  89. Lv2PluginOptions lv2Options;
  90. class CarlaLv2Client : public CarlaBridgeClient
  91. {
  92. public:
  93. CarlaLv2Client(const char* const uiTitle)
  94. : CarlaBridgeClient(uiTitle)
  95. {
  96. handle = nullptr;
  97. widget = nullptr;
  98. descriptor = nullptr;
  99. rdf_descriptor = nullptr;
  100. rdf_ui_descriptor = nullptr;
  101. programs = nullptr;
  102. #ifdef BRIDGE_LV2_X11
  103. m_resizable = false;
  104. #else
  105. m_resizable = true;
  106. #endif
  107. for (uint32_t i=0; i < CARLA_URI_MAP_ID_COUNT; i++)
  108. customURIDs.push_back(nullptr);
  109. for (uint32_t i=0; i < lv2_feature_count+1; i++)
  110. features[i] = nullptr;
  111. // -----------------------------------------------------------------
  112. // initialize options
  113. lv2Options.bufferSize = bufferSize;
  114. lv2Options.sampleRate = sampleRate;
  115. lv2Options.oNull.key = CARLA_URI_MAP_ID_NULL;
  116. lv2Options.oNull.size = 0;
  117. lv2Options.oNull.type = CARLA_URI_MAP_ID_NULL;
  118. lv2Options.oNull.value = nullptr;
  119. lv2Options.oMaxBlockLenth.key = CARLA_URI_MAP_ID_BUF_MAX_LENGTH;
  120. lv2Options.oMaxBlockLenth.size = sizeof(uint32_t);
  121. lv2Options.oMaxBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT;
  122. lv2Options.oMaxBlockLenth.value = &lv2Options.bufferSize;
  123. lv2Options.oMinBlockLenth.key = CARLA_URI_MAP_ID_BUF_MIN_LENGTH;
  124. lv2Options.oMinBlockLenth.size = sizeof(uint32_t);
  125. lv2Options.oMinBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT;
  126. lv2Options.oMinBlockLenth.value = &lv2Options.bufferSize;
  127. lv2Options.oSequenceSize.key = CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE;
  128. lv2Options.oSequenceSize.size = sizeof(uint32_t);
  129. lv2Options.oSequenceSize.type = CARLA_URI_MAP_ID_ATOM_INT;
  130. lv2Options.oSequenceSize.value = &lv2Options.eventSize;
  131. lv2Options.oSampleRate.key = CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE;
  132. lv2Options.oSampleRate.size = sizeof(double);
  133. lv2Options.oSampleRate.type = CARLA_URI_MAP_ID_ATOM_DOUBLE;
  134. lv2Options.oSampleRate.value = &lv2Options.sampleRate;
  135. // -----------------------------------------------------------------
  136. // initialize features
  137. LV2_Event_Feature* const eventFt = new LV2_Event_Feature;
  138. eventFt->callback_data = this;
  139. eventFt->lv2_event_ref = carla_lv2_event_ref;
  140. eventFt->lv2_event_unref = carla_lv2_event_unref;
  141. LV2_Log_Log* const logFt = new LV2_Log_Log;
  142. logFt->handle = this;
  143. logFt->printf = carla_lv2_log_printf;
  144. logFt->vprintf = carla_lv2_log_vprintf;
  145. LV2_Programs_Host* const programsFt = new LV2_Programs_Host;
  146. programsFt->handle = this;
  147. programsFt->program_changed = carla_lv2_program_changed;
  148. LV2_RtMemPool_Pool* const rtMemPoolFt = new LV2_RtMemPool_Pool;
  149. lv2_rtmempool_init(rtMemPoolFt);
  150. LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path;
  151. stateMakePathFt->handle = this;
  152. stateMakePathFt->path = carla_lv2_state_make_path;
  153. LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path;
  154. stateMapPathFt->handle = this;
  155. stateMapPathFt->abstract_path = carla_lv2_state_map_abstract_path;
  156. stateMapPathFt->absolute_path = carla_lv2_state_map_absolute_path;
  157. LV2_URI_Map_Feature* const uriMapFt = new LV2_URI_Map_Feature;
  158. uriMapFt->callback_data = this;
  159. uriMapFt->uri_to_id = carla_lv2_uri_to_id;
  160. LV2_URID_Map* const uridMapFt = new LV2_URID_Map;
  161. uridMapFt->handle = this;
  162. uridMapFt->map = carla_lv2_urid_map;
  163. LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap;
  164. uridUnmapFt->handle = this;
  165. uridUnmapFt->unmap = carla_lv2_urid_unmap;
  166. LV2UI_Port_Map* const uiPortMapFt = new LV2UI_Port_Map;
  167. uiPortMapFt->handle = this;
  168. uiPortMapFt->port_index = carla_lv2_ui_port_map;
  169. LV2UI_Resize* const uiResizeFt = new LV2UI_Resize;
  170. uiResizeFt->handle = this;
  171. uiResizeFt->ui_resize = carla_lv2_ui_resize;
  172. LV2_Options_Option* const optionsFt = new LV2_Options_Option [5];
  173. optionsFt[0] = lv2Options.oMaxBlockLenth;
  174. optionsFt[1] = lv2Options.oMinBlockLenth;
  175. optionsFt[2] = lv2Options.oSequenceSize;
  176. optionsFt[3] = lv2Options.oSampleRate;
  177. optionsFt[4] = lv2Options.oNull;
  178. features[lv2_feature_id_bufsize_bounded] = new LV2_Feature;
  179. features[lv2_feature_id_bufsize_bounded]->URI = LV2_BUF_SIZE__boundedBlockLength;
  180. features[lv2_feature_id_bufsize_bounded]->data = nullptr;
  181. features[lv2_feature_id_bufsize_fixed] = new LV2_Feature;
  182. features[lv2_feature_id_bufsize_fixed]->URI = LV2_BUF_SIZE__fixedBlockLength;
  183. features[lv2_feature_id_bufsize_fixed]->data = nullptr;
  184. features[lv2_feature_id_bufsize_powerof2] = new LV2_Feature;
  185. features[lv2_feature_id_bufsize_powerof2]->URI = LV2_BUF_SIZE__powerOf2BlockLength;
  186. features[lv2_feature_id_bufsize_powerof2]->data = nullptr;
  187. features[lv2_feature_id_event] = new LV2_Feature;
  188. features[lv2_feature_id_event]->URI = LV2_EVENT_URI;
  189. features[lv2_feature_id_event]->data = eventFt;
  190. features[lv2_feature_id_logs] = new LV2_Feature;
  191. features[lv2_feature_id_logs]->URI = LV2_LOG__log;
  192. features[lv2_feature_id_logs]->data = logFt;
  193. features[lv2_feature_id_options] = new LV2_Feature;
  194. features[lv2_feature_id_options]->URI = LV2_OPTIONS__options;
  195. features[lv2_feature_id_options]->data = optionsFt;
  196. features[lv2_feature_id_programs] = new LV2_Feature;
  197. features[lv2_feature_id_programs]->URI = LV2_PROGRAMS__Host;
  198. features[lv2_feature_id_programs]->data = programsFt;
  199. features[lv2_feature_id_rtmempool] = new LV2_Feature;
  200. features[lv2_feature_id_rtmempool]->URI = LV2_RTSAFE_MEMORY_POOL__Pool;
  201. features[lv2_feature_id_rtmempool]->data = rtMemPoolFt;
  202. features[lv2_feature_id_state_make_path] = new LV2_Feature;
  203. features[lv2_feature_id_state_make_path]->URI = LV2_STATE__makePath;
  204. features[lv2_feature_id_state_make_path]->data = stateMakePathFt;
  205. features[lv2_feature_id_state_map_path] = new LV2_Feature;
  206. features[lv2_feature_id_state_map_path]->URI = LV2_STATE__mapPath;
  207. features[lv2_feature_id_state_map_path]->data = stateMapPathFt;
  208. features[lv2_feature_id_strict_bounds] = new LV2_Feature;
  209. features[lv2_feature_id_strict_bounds]->URI = LV2_PORT_PROPS__supportsStrictBounds;
  210. features[lv2_feature_id_strict_bounds]->data = nullptr;
  211. features[lv2_feature_id_uri_map] = new LV2_Feature;
  212. features[lv2_feature_id_uri_map]->URI = LV2_URI_MAP_URI;
  213. features[lv2_feature_id_uri_map]->data = uriMapFt;
  214. features[lv2_feature_id_urid_map] = new LV2_Feature;
  215. features[lv2_feature_id_urid_map]->URI = LV2_URID__map;
  216. features[lv2_feature_id_urid_map]->data = uridMapFt;
  217. features[lv2_feature_id_urid_unmap] = new LV2_Feature;
  218. features[lv2_feature_id_urid_unmap]->URI = LV2_URID__unmap;
  219. features[lv2_feature_id_urid_unmap]->data = uridUnmapFt;
  220. features[lv2_feature_id_ui_parent] = new LV2_Feature;
  221. features[lv2_feature_id_ui_parent]->URI = LV2_UI__parent;
  222. #ifdef BRIDGE_LV2_X11
  223. features[lv2_feature_id_ui_parent]->data = getContainerId();
  224. #else
  225. features[lv2_feature_id_ui_parent]->data = nullptr;
  226. #endif
  227. features[lv2_feature_id_ui_port_map] = new LV2_Feature;
  228. features[lv2_feature_id_ui_port_map]->URI = LV2_UI__portMap;
  229. features[lv2_feature_id_ui_port_map]->data = uiPortMapFt;
  230. features[lv2_feature_id_ui_resize] = new LV2_Feature;
  231. features[lv2_feature_id_ui_resize]->URI = LV2_UI__resize;
  232. features[lv2_feature_id_ui_resize]->data = uiResizeFt;
  233. }
  234. ~CarlaLv2Client()
  235. {
  236. if (rdf_descriptor)
  237. delete rdf_descriptor;
  238. const LV2_Options_Option* const options = (const LV2_Options_Option*)features[lv2_feature_id_options]->data;
  239. delete[] options;
  240. delete (LV2_Event_Feature*)features[lv2_feature_id_event]->data;
  241. delete (LV2_Log_Log*)features[lv2_feature_id_logs]->data;
  242. delete (LV2_Programs_Host*)features[lv2_feature_id_programs]->data;
  243. delete (LV2_RtMemPool_Pool*)features[lv2_feature_id_rtmempool]->data;
  244. delete (LV2_State_Make_Path*)features[lv2_feature_id_state_make_path]->data;
  245. delete (LV2_State_Map_Path*)features[lv2_feature_id_state_map_path]->data;
  246. delete (LV2_URI_Map_Feature*)features[lv2_feature_id_uri_map]->data;
  247. delete (LV2_URID_Map*)features[lv2_feature_id_urid_map]->data;
  248. delete (LV2_URID_Unmap*)features[lv2_feature_id_urid_unmap]->data;
  249. delete (LV2UI_Port_Map*)features[lv2_feature_id_ui_port_map]->data;
  250. delete (LV2UI_Resize*)features[lv2_feature_id_ui_resize]->data;
  251. for (uint32_t i=0; i < lv2_feature_count; i++)
  252. {
  253. if (features[i])
  254. delete features[i];
  255. }
  256. for (size_t i=0; i < customURIDs.size(); i++)
  257. {
  258. if (customURIDs[i])
  259. free((void*)customURIDs[i]);
  260. }
  261. customURIDs.clear();
  262. }
  263. // ---------------------------------------------------------------------
  264. // ui initialization
  265. bool uiInit(const char* pluginURI, const char* uiURI)
  266. {
  267. // -----------------------------------------------------------------
  268. // init
  269. CarlaBridgeClient::uiInit(pluginURI, uiURI);
  270. // -----------------------------------------------------------------
  271. // get plugin from lv2_rdf (lilv)
  272. gLv2World.init();
  273. rdf_descriptor = lv2_rdf_new(pluginURI);
  274. if (! rdf_descriptor)
  275. return false;
  276. // -----------------------------------------------------------------
  277. // find requested UI
  278. for (uint32_t i=0; i < rdf_descriptor->UICount; i++)
  279. {
  280. if (std::strcmp(rdf_descriptor->UIs[i].URI, uiURI) == 0)
  281. {
  282. rdf_ui_descriptor = &rdf_descriptor->UIs[i];
  283. break;
  284. }
  285. }
  286. if (! rdf_ui_descriptor)
  287. return false;
  288. // -----------------------------------------------------------------
  289. // open DLL
  290. if (! uiLibOpen(rdf_ui_descriptor->Binary))
  291. return false;
  292. // -----------------------------------------------------------------
  293. // get DLL main entry
  294. const LV2UI_DescriptorFunction ui_descFn = (LV2UI_DescriptorFunction)uiLibSymbol("lv2ui_descriptor");
  295. if (! ui_descFn)
  296. return false;
  297. // -----------------------------------------------------------
  298. // get descriptor that matches URI
  299. uint32_t i = 0;
  300. while ((descriptor = ui_descFn(i++)))
  301. {
  302. if (std::strcmp(descriptor->URI, uiURI) == 0)
  303. break;
  304. }
  305. if (! descriptor)
  306. return false;
  307. // -----------------------------------------------------------
  308. // initialize UI
  309. handle = descriptor->instantiate(descriptor, pluginURI, rdf_ui_descriptor->Bundle, carla_lv2_ui_write_function, this, &widget, features);
  310. if (! handle)
  311. return false;
  312. // -----------------------------------------------------------
  313. // check if not resizable
  314. #ifndef BRIDGE_LV2_X11
  315. for (uint32_t i=0; i < rdf_ui_descriptor->FeatureCount; i++)
  316. {
  317. if (std::strcmp(rdf_ui_descriptor->Features[i].URI, LV2_UI__fixedSize) == 0 || std::strcmp(rdf_ui_descriptor->Features[i].URI, LV2_UI__noUserResize) == 0)
  318. {
  319. m_resizable = false;
  320. break;
  321. }
  322. }
  323. #endif
  324. // -----------------------------------------------------------
  325. // check for known extensions
  326. for (uint32_t i=0; descriptor->extension_data && i < rdf_ui_descriptor->ExtensionCount; i++)
  327. {
  328. if (std::strcmp(rdf_ui_descriptor->Extensions[i], LV2_PROGRAMS__UIInterface) == 0)
  329. {
  330. programs = (LV2_Programs_UI_Interface*)descriptor->extension_data(LV2_PROGRAMS__UIInterface);
  331. if (programs && ! programs->select_program)
  332. // invalid
  333. programs = nullptr;
  334. break;
  335. }
  336. }
  337. return true;
  338. }
  339. void uiClose()
  340. {
  341. CarlaBridgeClient::uiClose();
  342. if (handle && descriptor && descriptor->cleanup)
  343. descriptor->cleanup(handle);
  344. uiLibClose();
  345. }
  346. // ---------------------------------------------------------------------
  347. // ui management
  348. void* getWidget() const
  349. {
  350. return widget;
  351. }
  352. bool isResizable() const
  353. {
  354. return m_resizable;
  355. }
  356. bool needsReparent() const
  357. {
  358. #ifdef BRIDGE_LV2_X11
  359. return true;
  360. #else
  361. return false;
  362. #endif
  363. }
  364. // ---------------------------------------------------------------------
  365. // processing
  366. void setParameter(const int32_t rindex, const float value)
  367. {
  368. CARLA_ASSERT(handle && descriptor);
  369. if (handle && descriptor && descriptor->port_event)
  370. {
  371. float fvalue = value;
  372. descriptor->port_event(handle, rindex, sizeof(float), 0, &fvalue);
  373. }
  374. }
  375. void setProgram(const uint32_t)
  376. {
  377. }
  378. void setMidiProgram(const uint32_t bank, const uint32_t program)
  379. {
  380. CARLA_ASSERT(handle);
  381. if (handle && programs)
  382. programs->select_program(handle, bank, program);
  383. }
  384. void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)
  385. {
  386. CARLA_ASSERT(handle && descriptor);
  387. if (handle && descriptor && descriptor->port_event)
  388. {
  389. LV2_Atom_MidiEvent midiEv;
  390. midiEv.event.time.frames = 0;
  391. midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
  392. midiEv.event.body.size = 3;
  393. midiEv.data[0] = MIDI_STATUS_NOTE_ON + channel;
  394. midiEv.data[1] = note;
  395. midiEv.data[2] = velo;
  396. descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
  397. }
  398. }
  399. void noteOff(const uint8_t channel, const uint8_t note)
  400. {
  401. CARLA_ASSERT(handle && descriptor);
  402. if (handle && descriptor && descriptor->port_event)
  403. {
  404. LV2_Atom_MidiEvent midiEv;
  405. midiEv.event.time.frames = 0;
  406. midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
  407. midiEv.event.body.size = 3;
  408. midiEv.data[0] = MIDI_STATUS_NOTE_OFF + channel;
  409. midiEv.data[1] = note;
  410. midiEv.data[2] = 0;
  411. descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
  412. }
  413. }
  414. // ---------------------------------------------------------------------
  415. uint32_t getCustomURID(const char* const uri)
  416. {
  417. qDebug("CarlaLv2Client::getCustomURID(%s)", uri);
  418. CARLA_ASSERT(uri);
  419. if (! uri)
  420. return CARLA_URI_MAP_ID_NULL;
  421. for (size_t i=0; i < customURIDs.size(); i++)
  422. {
  423. if (customURIDs[i] && std::strcmp(customURIDs[i], uri) == 0)
  424. return i;
  425. }
  426. customURIDs.push_back(strdup(uri));
  427. return customURIDs.size()-1;
  428. }
  429. const char* getCustomURIString(const LV2_URID urid) const
  430. {
  431. qDebug("CarlaLv2Client::getCustomURIString(%i)", urid);
  432. CARLA_ASSERT(urid > CARLA_URI_MAP_ID_NULL);
  433. if (urid == CARLA_URI_MAP_ID_NULL)
  434. return nullptr;
  435. if (urid < customURIDs.size())
  436. return customURIDs[urid];
  437. return nullptr;
  438. }
  439. // ---------------------------------------------------------------------
  440. void handleTransferAtom(const int32_t portIndex, const LV2_Atom* const atom)
  441. {
  442. qDebug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom);
  443. CARLA_ASSERT(portIndex >= 0);
  444. CARLA_ASSERT(atom);
  445. if (atom && handle && descriptor && descriptor->port_event)
  446. descriptor->port_event(handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, atom);
  447. }
  448. void handleTransferEvent(const int32_t portIndex, const LV2_Atom* const atom)
  449. {
  450. qDebug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom);
  451. CARLA_ASSERT(portIndex >= 0);
  452. CARLA_ASSERT(atom);
  453. if (atom && handle && descriptor && descriptor->port_event)
  454. descriptor->port_event(handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);
  455. #if 0
  456. if (handle && descriptor && descriptor->port_event)
  457. {
  458. LV2_URID_Map* const URID_Map = (LV2_URID_Map*)features[lv2_feature_id_urid_map]->data;
  459. const LV2_URID uridPatchSet = getCustomURID(LV2_PATCH__Set);
  460. const LV2_URID uridPatchBody = getCustomURID(LV2_PATCH__body);
  461. Sratom* sratom = sratom_new(URID_Map);
  462. SerdChunk chunk = { nullptr, 0 };
  463. LV2_Atom_Forge forge;
  464. lv2_atom_forge_init(&forge, URID_Map);
  465. lv2_atom_forge_set_sink(&forge, sratom_forge_sink, sratom_forge_deref, &chunk);
  466. LV2_Atom_Forge_Frame refFrame, bodyFrame;
  467. LV2_Atom_Forge_Ref ref = lv2_atom_forge_blank(&forge, &refFrame, 1, uridPatchSet);
  468. lv2_atom_forge_property_head(&forge, uridPatchBody, CARLA_URI_MAP_ID_NULL);
  469. lv2_atom_forge_blank(&forge, &bodyFrame, 2, CARLA_URI_MAP_ID_NULL);
  470. //lv2_atom_forge_property_head(&forge, getCustomURID(key), CARLA_URI_MAP_ID_NULL);
  471. if (std::strcmp(type, "string") == 0)
  472. lv2_atom_forge_string(&forge, value, std::strlen(value));
  473. else if (std::strcmp(type, "path") == 0)
  474. lv2_atom_forge_path(&forge, value, std::strlen(value));
  475. else if (std::strcmp(type, "chunk") == 0)
  476. lv2_atom_forge_literal(&forge, value, std::strlen(value), CARLA_URI_MAP_ID_ATOM_CHUNK, CARLA_URI_MAP_ID_NULL);
  477. //else
  478. // lv2_atom_forge_literal(&forge, value, std::strlen(value), getCustomURID(key), CARLA_URI_MAP_ID_NULL);
  479. lv2_atom_forge_pop(&forge, &bodyFrame);
  480. lv2_atom_forge_pop(&forge, &refFrame);
  481. const LV2_Atom* const atom = lv2_atom_forge_deref(&forge, ref);
  482. descriptor->port_event(handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);
  483. free((void*)chunk.buf);
  484. sratom_free(sratom);
  485. }
  486. #endif
  487. }
  488. // ---------------------------------------------------------------------
  489. void handleProgramChanged(int32_t /*index*/)
  490. {
  491. if (isOscControlRegistered())
  492. sendOscConfigure("reloadprograms", "");
  493. }
  494. uint32_t handleUiPortMap(const char* const symbol)
  495. {
  496. CARLA_ASSERT(symbol);
  497. if (! symbol)
  498. return LV2UI_INVALID_PORT_INDEX;
  499. for (uint32_t i=0; i < rdf_descriptor->PortCount; i++)
  500. {
  501. if (std::strcmp(rdf_descriptor->Ports[i].Symbol, symbol) == 0)
  502. return i;
  503. }
  504. return LV2UI_INVALID_PORT_INDEX;
  505. }
  506. int handleUiResize(int width, int height)
  507. {
  508. CARLA_ASSERT(width > 0);
  509. CARLA_ASSERT(height > 0);
  510. if (width <= 0 || height <= 0)
  511. return 1;
  512. toolkitResize(width, height);
  513. return 0;
  514. }
  515. void handleUiWrite(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer)
  516. {
  517. if (! (buffer && isOscControlRegistered()))
  518. return;
  519. if (format == 0)
  520. {
  521. CARLA_ASSERT(buffer);
  522. CARLA_ASSERT(bufferSize == sizeof(float));
  523. if (bufferSize != sizeof(float))
  524. return;
  525. float value = *(float*)buffer;
  526. sendOscControl(portIndex, value);
  527. }
  528. else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM)
  529. {
  530. CARLA_ASSERT(buffer);
  531. const LV2_Atom* const atom = (const LV2_Atom*)buffer;
  532. QByteArray chunk((const char*)buffer, bufferSize);
  533. sendOscLv2TransferAtom(portIndex, getCustomURIString(atom->type), chunk.toBase64().constData());
  534. }
  535. else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
  536. {
  537. CARLA_ASSERT(buffer);
  538. const LV2_Atom* const atom = (const LV2_Atom*)buffer;
  539. QByteArray chunk((const char*)buffer, bufferSize);
  540. sendOscLv2TransferEvent(portIndex, getCustomURIString(atom->type), chunk.toBase64().constData());
  541. }
  542. }
  543. // ----------------- Event Feature ---------------------------------------------------
  544. static uint32_t carla_lv2_event_ref(const LV2_Event_Callback_Data callback_data, LV2_Event* const event)
  545. {
  546. qDebug("CarlaLv2Client::carla_lv2_event_ref(%p, %p)", callback_data, event);
  547. CARLA_ASSERT(callback_data);
  548. CARLA_ASSERT(event);
  549. return 0;
  550. }
  551. static uint32_t carla_lv2_event_unref(const LV2_Event_Callback_Data callback_data, LV2_Event* const event)
  552. {
  553. qDebug("CarlaLv2Client::carla_lv2_event_unref(%p, %p)", callback_data, event);
  554. CARLA_ASSERT(callback_data);
  555. CARLA_ASSERT(event);
  556. return 0;
  557. }
  558. // ----------------- Logs Feature ----------------------------------------------------
  559. static int carla_lv2_log_printf(const LV2_Log_Handle handle, const LV2_URID type, const char* const fmt, ...)
  560. {
  561. qDebug("CarlaLv2Client::carla_lv2_log_printf(%p, %i, %s, ...)", handle, type, fmt);
  562. CARLA_ASSERT(handle);
  563. CARLA_ASSERT(type > 0);
  564. #ifndef DEBUG
  565. if (type == CARLA_URI_MAP_ID_LOG_TRACE)
  566. return 0;
  567. #endif
  568. va_list args;
  569. va_start(args, fmt);
  570. const int ret = carla_lv2_log_vprintf(handle, type, fmt, args);
  571. va_end(args);
  572. return ret;
  573. }
  574. static int carla_lv2_log_vprintf(const LV2_Log_Handle handle, const LV2_URID type, const char* const fmt, va_list ap)
  575. {
  576. qDebug("CarlaLv2Client::carla_lv2_log_vprintf(%p, %i, %s, ...)", handle, type, fmt);
  577. CARLA_ASSERT(handle);
  578. CARLA_ASSERT(type > 0);
  579. #ifndef DEBUG
  580. if (type == CARLA_URI_MAP_ID_LOG_TRACE)
  581. return 0;
  582. #endif
  583. char buf[8196];
  584. vsprintf(buf, fmt, ap);
  585. if (*buf == 0)
  586. return 0;
  587. switch (type)
  588. {
  589. case CARLA_URI_MAP_ID_LOG_ERROR:
  590. qCritical("%s", buf);
  591. break;
  592. case CARLA_URI_MAP_ID_LOG_NOTE:
  593. printf("%s\n", buf);
  594. break;
  595. case CARLA_URI_MAP_ID_LOG_TRACE:
  596. qDebug("%s", buf);
  597. break;
  598. case CARLA_URI_MAP_ID_LOG_WARNING:
  599. carla_stderr("%s", buf);
  600. break;
  601. default:
  602. break;
  603. }
  604. return std::strlen(buf);
  605. }
  606. // ----------------- Programs Feature ------------------------------------------------
  607. static void carla_lv2_program_changed(const LV2_Programs_Handle handle, const int32_t index)
  608. {
  609. qDebug("CarlaLv2Client::carla_lv2_program_changed(%p, %i)", handle, index);
  610. CARLA_ASSERT(handle);
  611. if (! handle)
  612. return;
  613. CarlaLv2Client* const client = (CarlaLv2Client*)handle;
  614. client->handleProgramChanged(index);
  615. }
  616. // ----------------- State Feature ---------------------------------------------------
  617. static char* carla_lv2_state_make_path(const LV2_State_Make_Path_Handle handle, const char* const path)
  618. {
  619. qDebug("CarlaLv2Client::carla_lv2_state_make_path(%p, %p)", handle, path);
  620. CARLA_ASSERT(handle);
  621. CARLA_ASSERT(path);
  622. if (! path)
  623. return nullptr;
  624. QDir dir;
  625. dir.mkpath(path);
  626. return strdup(path);
  627. }
  628. static char* carla_lv2_state_map_abstract_path(const LV2_State_Map_Path_Handle handle, const char* const absolute_path)
  629. {
  630. qDebug("CarlaLv2Client::carla_lv2_state_map_abstract_path(%p, %p)", handle, absolute_path);
  631. CARLA_ASSERT(handle);
  632. CARLA_ASSERT(absolute_path);
  633. if (! absolute_path)
  634. return nullptr;
  635. QDir dir(absolute_path);
  636. return strdup(dir.canonicalPath().toUtf8().constData());
  637. }
  638. static char* carla_lv2_state_map_absolute_path(const LV2_State_Map_Path_Handle handle, const char* const abstract_path)
  639. {
  640. qDebug("CarlaLv2Client::carla_lv2_state_map_absolute_path(%p, %p)", handle, abstract_path);
  641. CARLA_ASSERT(handle);
  642. CARLA_ASSERT(abstract_path);
  643. if (! abstract_path)
  644. return nullptr;
  645. QDir dir(abstract_path);
  646. return strdup(dir.absolutePath().toUtf8().constData());
  647. }
  648. // ----------------- URI-Map Feature ---------------------------------------
  649. static uint32_t carla_lv2_uri_to_id(const LV2_URI_Map_Callback_Data data, const char* const map, const char* const uri)
  650. {
  651. qDebug("CarlaLv2Client::carla_lv2_uri_to_id(%p, %s, %s)", data, map, uri);
  652. return carla_lv2_urid_map((LV2_URID_Map_Handle*)data, uri);
  653. }
  654. // ----------------- URID Feature ------------------------------------------
  655. static LV2_URID carla_lv2_urid_map(const LV2_URID_Map_Handle handle, const char* const uri)
  656. {
  657. qDebug("CarlaLv2Client::carla_lv2_urid_map(%p, %s)", handle, uri);
  658. CARLA_ASSERT(handle);
  659. CARLA_ASSERT(uri);
  660. if (! uri)
  661. return CARLA_URI_MAP_ID_NULL;
  662. // Atom types
  663. if (std::strcmp(uri, LV2_ATOM__Chunk) == 0)
  664. return CARLA_URI_MAP_ID_ATOM_CHUNK;
  665. if (std::strcmp(uri, LV2_ATOM__Double) == 0)
  666. return CARLA_URI_MAP_ID_ATOM_DOUBLE;
  667. if (std::strcmp(uri, LV2_ATOM__Int) == 0)
  668. return CARLA_URI_MAP_ID_ATOM_INT;
  669. if (std::strcmp(uri, LV2_ATOM__Path) == 0)
  670. return CARLA_URI_MAP_ID_ATOM_PATH;
  671. if (std::strcmp(uri, LV2_ATOM__Sequence) == 0)
  672. return CARLA_URI_MAP_ID_ATOM_SEQUENCE;
  673. if (std::strcmp(uri, LV2_ATOM__String) == 0)
  674. return CARLA_URI_MAP_ID_ATOM_STRING;
  675. if (std::strcmp(uri, LV2_ATOM__atomTransfer) == 0)
  676. return CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM;
  677. if (std::strcmp(uri, LV2_ATOM__eventTransfer) == 0)
  678. return CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT;
  679. // BufSize types
  680. if (std::strcmp(uri, LV2_BUF_SIZE__maxBlockLength) == 0)
  681. return CARLA_URI_MAP_ID_BUF_MAX_LENGTH;
  682. if (std::strcmp(uri, LV2_BUF_SIZE__minBlockLength) == 0)
  683. return CARLA_URI_MAP_ID_BUF_MIN_LENGTH;
  684. if (std::strcmp(uri, LV2_BUF_SIZE__sequenceSize) == 0)
  685. return CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE;
  686. // Log types
  687. if (std::strcmp(uri, LV2_LOG__Error) == 0)
  688. return CARLA_URI_MAP_ID_LOG_ERROR;
  689. if (std::strcmp(uri, LV2_LOG__Note) == 0)
  690. return CARLA_URI_MAP_ID_LOG_NOTE;
  691. if (std::strcmp(uri, LV2_LOG__Trace) == 0)
  692. return CARLA_URI_MAP_ID_LOG_TRACE;
  693. if (std::strcmp(uri, LV2_LOG__Warning) == 0)
  694. return CARLA_URI_MAP_ID_LOG_WARNING;
  695. // Others
  696. if (std::strcmp(uri, LV2_MIDI__MidiEvent) == 0)
  697. return CARLA_URI_MAP_ID_MIDI_EVENT;
  698. if (std::strcmp(uri, LV2_PARAMETERS__sampleRate) == 0)
  699. return CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE;
  700. if (! handle)
  701. return CARLA_URI_MAP_ID_NULL;
  702. // Custom types
  703. CarlaLv2Client* const client = (CarlaLv2Client*)handle;
  704. return client->getCustomURID(uri);
  705. }
  706. static const char* carla_lv2_urid_unmap(const LV2_URID_Map_Handle handle, const LV2_URID urid)
  707. {
  708. qDebug("CarlaLv2Client::carla_lv2_urid_unmap(%p, %i)", handle, urid);
  709. CARLA_ASSERT(handle);
  710. CARLA_ASSERT(urid > CARLA_URI_MAP_ID_NULL);
  711. if (urid == CARLA_URI_MAP_ID_NULL)
  712. return nullptr;
  713. // Atom types
  714. if (urid == CARLA_URI_MAP_ID_ATOM_CHUNK)
  715. return LV2_ATOM__Chunk;
  716. if (urid == CARLA_URI_MAP_ID_ATOM_DOUBLE)
  717. return LV2_ATOM__Double;
  718. if (urid == CARLA_URI_MAP_ID_ATOM_INT)
  719. return LV2_ATOM__Int;
  720. if (urid == CARLA_URI_MAP_ID_ATOM_PATH)
  721. return LV2_ATOM__Path;
  722. if (urid == CARLA_URI_MAP_ID_ATOM_SEQUENCE)
  723. return LV2_ATOM__Sequence;
  724. if (urid == CARLA_URI_MAP_ID_ATOM_STRING)
  725. return LV2_ATOM__String;
  726. if (urid == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM)
  727. return LV2_ATOM__atomTransfer;
  728. if (urid == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
  729. return LV2_ATOM__eventTransfer;
  730. // BufSize types
  731. if (urid == CARLA_URI_MAP_ID_BUF_MAX_LENGTH)
  732. return LV2_BUF_SIZE__maxBlockLength;
  733. if (urid == CARLA_URI_MAP_ID_BUF_MIN_LENGTH)
  734. return LV2_BUF_SIZE__minBlockLength;
  735. if (urid == CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE)
  736. return LV2_BUF_SIZE__sequenceSize;
  737. // Log types
  738. if (urid == CARLA_URI_MAP_ID_LOG_ERROR)
  739. return LV2_LOG__Error;
  740. if (urid == CARLA_URI_MAP_ID_LOG_NOTE)
  741. return LV2_LOG__Note;
  742. if (urid == CARLA_URI_MAP_ID_LOG_TRACE)
  743. return LV2_LOG__Trace;
  744. if (urid == CARLA_URI_MAP_ID_LOG_WARNING)
  745. return LV2_LOG__Warning;
  746. // Others
  747. if (urid == CARLA_URI_MAP_ID_MIDI_EVENT)
  748. return LV2_MIDI__MidiEvent;
  749. if (urid == CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE)
  750. return LV2_PARAMETERS__sampleRate;
  751. if (! handle)
  752. return nullptr;
  753. // Custom types
  754. CarlaLv2Client* const client = (CarlaLv2Client*)handle;
  755. return client->getCustomURIString(urid);
  756. }
  757. // ----------------- UI Port-Map Feature ---------------------------------------------
  758. static uint32_t carla_lv2_ui_port_map(const LV2UI_Feature_Handle handle, const char* const symbol)
  759. {
  760. qDebug("CarlaLv2Client::carla_lv2_ui_port_map(%p, %s)", handle, symbol);
  761. CARLA_ASSERT(handle);
  762. if (! handle)
  763. return LV2UI_INVALID_PORT_INDEX;
  764. CarlaLv2Client* const client = (CarlaLv2Client*)handle;
  765. return client->handleUiPortMap(symbol);
  766. }
  767. // ----------------- UI Resize Feature -------------------------------------
  768. static int carla_lv2_ui_resize(const LV2UI_Feature_Handle handle, const int width, const int height)
  769. {
  770. qDebug("CarlaLv2Client::carla_lv2_ui_resize(%p, %i, %i)", handle, width, height);
  771. CARLA_ASSERT(handle);
  772. if (! handle)
  773. return 1;
  774. CarlaLv2Client* const client = (CarlaLv2Client*)handle;
  775. return client->handleUiResize(width, height);
  776. }
  777. // ----------------- UI Extension ------------------------------------------
  778. static void carla_lv2_ui_write_function(const LV2UI_Controller controller, const uint32_t port_index, const uint32_t buffer_size, const uint32_t format, const void* const buffer)
  779. {
  780. qDebug("CarlaLv2Client::carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
  781. CARLA_ASSERT(controller);
  782. if (! controller)
  783. return;
  784. CarlaLv2Client* const client = (CarlaLv2Client*)controller;
  785. client->handleUiWrite(port_index, buffer_size, format, buffer);
  786. }
  787. private:
  788. LV2UI_Handle handle;
  789. LV2UI_Widget widget;
  790. const LV2UI_Descriptor* descriptor;
  791. LV2_Feature* features[lv2_feature_count+1];
  792. const LV2_RDF_Descriptor* rdf_descriptor;
  793. const LV2_RDF_UI* rdf_ui_descriptor;
  794. const LV2_Programs_UI_Interface* programs;
  795. bool m_resizable;
  796. std::vector<const char*> customURIDs;
  797. };
  798. int CarlaBridgeOsc::handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
  799. {
  800. qDebug("CarlaBridgeOsc::handleMsgLv2TransferAtom()");
  801. CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "iss");
  802. if (! kClient)
  803. return 1;
  804. const int32_t portIndex = argv[0]->i;
  805. const char* const typeStr = (const char*)&argv[1]->s;
  806. const char* const atomBuf = (const char*)&argv[2]->s;
  807. QByteArray chunk;
  808. chunk = QByteArray::fromBase64(atomBuf);
  809. LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
  810. CarlaLv2Client* const lv2Client = (CarlaLv2Client*)kClient;
  811. atom->type = lv2Client->getCustomURID(typeStr);
  812. lv2Client->handleTransferAtom(portIndex, atom);
  813. return 0;
  814. }
  815. int CarlaBridgeOsc::handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS)
  816. {
  817. qDebug("CarlaBridgeOsc::handleMsgLv2TransferEvent()");
  818. CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "iss");
  819. if (! kClient)
  820. return 1;
  821. const int32_t portIndex = argv[0]->i;
  822. const char* const typeStr = (const char*)&argv[1]->s;
  823. const char* const atomBuf = (const char*)&argv[2]->s;
  824. QByteArray chunk;
  825. chunk = QByteArray::fromBase64(atomBuf);
  826. LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
  827. CarlaLv2Client* const lv2Client = (CarlaLv2Client*)kClient;
  828. atom->type = lv2Client->getCustomURID(typeStr);
  829. lv2Client->handleTransferEvent(portIndex, atom);
  830. return 0;
  831. }
  832. CARLA_BRIDGE_END_NAMESPACE
  833. int main(int argc, char* argv[])
  834. {
  835. CARLA_BRIDGE_USE_NAMESPACE
  836. if (argc != 5)
  837. {
  838. carla_stderr("usage: %s <osc-url|\"null\"> <plugin-uri> <ui-uri> <ui-title>", argv[0]);
  839. return 1;
  840. }
  841. const char* oscUrl = argv[1];
  842. const char* pluginURI = argv[2];
  843. const char* uiURI = argv[3];
  844. const char* uiTitle = argv[4];
  845. const bool useOsc = std::strcmp(oscUrl, "null");
  846. // try to get sampleRate value
  847. const char* const sampleRateStr = getenv("CARLA_SAMPLE_RATE");
  848. if (sampleRateStr)
  849. sampleRate = atof(sampleRateStr);
  850. // Init LV2 client
  851. CarlaLv2Client client(uiTitle);
  852. // Init OSC
  853. if (useOsc)
  854. client.oscInit(oscUrl);
  855. // Load UI
  856. int ret;
  857. if (client.uiInit(pluginURI, uiURI))
  858. {
  859. client.toolkitExec(!useOsc);
  860. ret = 0;
  861. }
  862. else
  863. {
  864. qCritical("Failed to load LV2 UI");
  865. ret = 1;
  866. }
  867. // Close OSC
  868. if (useOsc)
  869. client.oscClose();
  870. // Close LV2 client
  871. client.uiClose();
  872. return ret;
  873. }
  874. #endif // BRIDGE_LV2