Collection of tools useful for audio production
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.

1119 lines
38KB

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