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.

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