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.

1246 lines
43KB

  1. /*
  2. * Carla Bridge UI, LV2 version
  3. * Copyright (C) 2011-2014 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 "LinkedList.hpp"
  21. #include <QtCore/QDir>
  22. #define URI_CARLA_WORKER "http://kxstudio.sf.net/ns/carla/worker"
  23. // -----------------------------------------------------
  24. CARLA_BRIDGE_START_NAMESPACE
  25. #if 0
  26. }
  27. #endif
  28. static uint32_t gBufferSize = 1024;
  29. static double gSampleRate = 44100.0;
  30. // Maximum default buffer size
  31. const unsigned int MAX_DEFAULT_BUFFER_SIZE = 8192; // 0x2000
  32. // LV2 URI Map Ids
  33. const uint32_t CARLA_URI_MAP_ID_NULL = 0;
  34. const uint32_t CARLA_URI_MAP_ID_ATOM_BLANK = 1;
  35. const uint32_t CARLA_URI_MAP_ID_ATOM_BOOL = 2;
  36. const uint32_t CARLA_URI_MAP_ID_ATOM_CHUNK = 3;
  37. const uint32_t CARLA_URI_MAP_ID_ATOM_DOUBLE = 4;
  38. const uint32_t CARLA_URI_MAP_ID_ATOM_EVENT = 5;
  39. const uint32_t CARLA_URI_MAP_ID_ATOM_FLOAT = 6;
  40. const uint32_t CARLA_URI_MAP_ID_ATOM_INT = 7;
  41. const uint32_t CARLA_URI_MAP_ID_ATOM_LITERAL = 8;
  42. const uint32_t CARLA_URI_MAP_ID_ATOM_LONG = 9;
  43. const uint32_t CARLA_URI_MAP_ID_ATOM_NUMBER = 10;
  44. const uint32_t CARLA_URI_MAP_ID_ATOM_OBJECT = 11;
  45. const uint32_t CARLA_URI_MAP_ID_ATOM_PATH = 12;
  46. const uint32_t CARLA_URI_MAP_ID_ATOM_PROPERTY = 13;
  47. const uint32_t CARLA_URI_MAP_ID_ATOM_RESOURCE = 14;
  48. const uint32_t CARLA_URI_MAP_ID_ATOM_SEQUENCE = 15;
  49. const uint32_t CARLA_URI_MAP_ID_ATOM_SOUND = 16;
  50. const uint32_t CARLA_URI_MAP_ID_ATOM_STRING = 17;
  51. const uint32_t CARLA_URI_MAP_ID_ATOM_TUPLE = 18;
  52. const uint32_t CARLA_URI_MAP_ID_ATOM_URI = 19;
  53. const uint32_t CARLA_URI_MAP_ID_ATOM_URID = 20;
  54. const uint32_t CARLA_URI_MAP_ID_ATOM_VECTOR = 21;
  55. const uint32_t CARLA_URI_MAP_ID_ATOM_WORKER = 22; // custom
  56. const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM = 23;
  57. const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT = 24;
  58. const uint32_t CARLA_URI_MAP_ID_BUF_MAX_LENGTH = 25;
  59. const uint32_t CARLA_URI_MAP_ID_BUF_MIN_LENGTH = 26;
  60. const uint32_t CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE = 27;
  61. const uint32_t CARLA_URI_MAP_ID_LOG_ERROR = 28;
  62. const uint32_t CARLA_URI_MAP_ID_LOG_NOTE = 29;
  63. const uint32_t CARLA_URI_MAP_ID_LOG_TRACE = 30;
  64. const uint32_t CARLA_URI_MAP_ID_LOG_WARNING = 31;
  65. const uint32_t CARLA_URI_MAP_ID_TIME_POSITION = 32; // base type
  66. const uint32_t CARLA_URI_MAP_ID_TIME_BAR = 33; // values
  67. const uint32_t CARLA_URI_MAP_ID_TIME_BAR_BEAT = 34;
  68. const uint32_t CARLA_URI_MAP_ID_TIME_BEAT = 35;
  69. const uint32_t CARLA_URI_MAP_ID_TIME_BEAT_UNIT = 36;
  70. const uint32_t CARLA_URI_MAP_ID_TIME_BEATS_PER_BAR = 37;
  71. const uint32_t CARLA_URI_MAP_ID_TIME_BEATS_PER_MINUTE = 38;
  72. const uint32_t CARLA_URI_MAP_ID_TIME_FRAME = 39;
  73. const uint32_t CARLA_URI_MAP_ID_TIME_FRAMES_PER_SECOND = 40;
  74. const uint32_t CARLA_URI_MAP_ID_TIME_SPEED = 41;
  75. const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 42;
  76. const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 43;
  77. const uint32_t CARLA_URI_MAP_ID_COUNT = 44;
  78. // LV2 Feature Ids
  79. const uint32_t kFeatureIdLogs = 0;
  80. const uint32_t kFeatureIdOptions = 1;
  81. const uint32_t kFeatureIdPrograms = 2;
  82. const uint32_t kFeatureIdStateMakePath = 3;
  83. const uint32_t kFeatureIdStateMapPath = 4;
  84. const uint32_t kFeatureIdUriMap = 5;
  85. const uint32_t kFeatureIdUridMap = 6;
  86. const uint32_t kFeatureIdUridUnmap = 7;
  87. const uint32_t kFeatureIdUiIdleInterface = 8;
  88. const uint32_t kFeatureIdUiFixedSize = 9;
  89. const uint32_t kFeatureIdUiMakeResident = 10;
  90. const uint32_t kFeatureIdUiNoUserResize = 11;
  91. const uint32_t kFeatureIdUiParent = 12;
  92. const uint32_t kFeatureIdUiPortMap = 13;
  93. const uint32_t kFeatureIdUiPortSubscribe = 14;
  94. const uint32_t kFeatureIdUiResize = 15;
  95. const uint32_t kFeatureIdUiTouch = 16;
  96. const uint32_t kFeatureCount = 17;
  97. // -------------------------------------------------------------------------
  98. struct Lv2PluginOptions {
  99. enum OptIndex {
  100. MaxBlockLenth = 0,
  101. MinBlockLenth,
  102. SequenceSize,
  103. SampleRate,
  104. Null
  105. };
  106. int maxBufferSize;
  107. int minBufferSize;
  108. int sequenceSize;
  109. double sampleRate;
  110. LV2_Options_Option opts[5];
  111. Lv2PluginOptions()
  112. : maxBufferSize(0),
  113. minBufferSize(0),
  114. sequenceSize(MAX_DEFAULT_BUFFER_SIZE),
  115. sampleRate(0.0)
  116. {
  117. LV2_Options_Option& optMaxBlockLenth(opts[MaxBlockLenth]);
  118. optMaxBlockLenth.context = LV2_OPTIONS_INSTANCE;
  119. optMaxBlockLenth.subject = 0;
  120. optMaxBlockLenth.key = CARLA_URI_MAP_ID_BUF_MAX_LENGTH;
  121. optMaxBlockLenth.size = sizeof(int);
  122. optMaxBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT;
  123. optMaxBlockLenth.value = &maxBufferSize;
  124. LV2_Options_Option& optMinBlockLenth(opts[MinBlockLenth]);
  125. optMinBlockLenth.context = LV2_OPTIONS_INSTANCE;
  126. optMinBlockLenth.subject = 0;
  127. optMinBlockLenth.key = CARLA_URI_MAP_ID_BUF_MIN_LENGTH;
  128. optMinBlockLenth.size = sizeof(int);
  129. optMinBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT;
  130. optMinBlockLenth.value = &minBufferSize;
  131. LV2_Options_Option& optSequenceSize(opts[SequenceSize]);
  132. optSequenceSize.context = LV2_OPTIONS_INSTANCE;
  133. optSequenceSize.subject = 0;
  134. optSequenceSize.key = CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE;
  135. optSequenceSize.size = sizeof(int);
  136. optSequenceSize.type = CARLA_URI_MAP_ID_ATOM_INT;
  137. optSequenceSize.value = &sequenceSize;
  138. LV2_Options_Option& optSampleRate(opts[SampleRate]);
  139. optSampleRate.context = LV2_OPTIONS_INSTANCE;
  140. optSampleRate.subject = 0;
  141. optSampleRate.key = CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE;
  142. optSampleRate.size = sizeof(double);
  143. optSampleRate.type = CARLA_URI_MAP_ID_ATOM_DOUBLE;
  144. optSampleRate.value = &sampleRate;
  145. LV2_Options_Option& optNull(opts[Null]);
  146. optNull.context = LV2_OPTIONS_INSTANCE;
  147. optNull.subject = 0;
  148. optNull.key = CARLA_URI_MAP_ID_NULL;
  149. optNull.size = 0;
  150. optNull.type = CARLA_URI_MAP_ID_NULL;
  151. optNull.value = nullptr;
  152. }
  153. };
  154. // -------------------------------------------------------------------------
  155. class CarlaLv2Client : public CarlaBridgeClient
  156. {
  157. public:
  158. CarlaLv2Client(const char* const uiTitle)
  159. : CarlaBridgeClient(uiTitle),
  160. fHandle(nullptr),
  161. fWidget(nullptr),
  162. fDescriptor(nullptr),
  163. fRdfDescriptor(nullptr),
  164. fRdfUiDescriptor(nullptr),
  165. fIsReady(false),
  166. #if defined(BRIDGE_COCOA) || defined(BRIDGE_HWND) || defined(BRIDGE_X11)
  167. fIsResizable(false)
  168. #else
  169. fIsResizable(true)
  170. #endif
  171. {
  172. carla_fill<LV2_Feature*>(fFeatures, kFeatureCount+1, nullptr);
  173. for (uint32_t i=0; i < CARLA_URI_MAP_ID_COUNT; ++i)
  174. fCustomURIDs.append(nullptr);
  175. // ---------------------------------------------------------------
  176. // initialize options
  177. fOptions.minBufferSize = gBufferSize;
  178. fOptions.maxBufferSize = gBufferSize;
  179. fOptions.sampleRate = gSampleRate;
  180. // ---------------------------------------------------------------
  181. // initialize features (part 1)
  182. LV2_Log_Log* const logFt = new LV2_Log_Log;
  183. logFt->handle = this;
  184. logFt->printf = carla_lv2_log_printf;
  185. logFt->vprintf = carla_lv2_log_vprintf;
  186. LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path;
  187. stateMakePathFt->handle = this;
  188. stateMakePathFt->path = carla_lv2_state_make_path;
  189. LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path;
  190. stateMapPathFt->handle = this;
  191. stateMapPathFt->abstract_path = carla_lv2_state_map_abstract_path;
  192. stateMapPathFt->absolute_path = carla_lv2_state_map_absolute_path;
  193. LV2_Programs_Host* const programsFt = new LV2_Programs_Host;
  194. programsFt->handle = this;
  195. programsFt->program_changed = carla_lv2_program_changed;
  196. LV2_URI_Map_Feature* const uriMapFt = new LV2_URI_Map_Feature;
  197. uriMapFt->callback_data = this;
  198. uriMapFt->uri_to_id = carla_lv2_uri_to_id;
  199. LV2_URID_Map* const uridMapFt = new LV2_URID_Map;
  200. uridMapFt->handle = this;
  201. uridMapFt->map = carla_lv2_urid_map;
  202. LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap;
  203. uridUnmapFt->handle = this;
  204. uridUnmapFt->unmap = carla_lv2_urid_unmap;
  205. LV2UI_Port_Map* const uiPortMapFt = new LV2UI_Port_Map;
  206. uiPortMapFt->handle = this;
  207. uiPortMapFt->port_index = carla_lv2_ui_port_map;
  208. LV2UI_Resize* const uiResizeFt = new LV2UI_Resize;
  209. uiResizeFt->handle = this;
  210. uiResizeFt->ui_resize = carla_lv2_ui_resize;
  211. // ---------------------------------------------------------------
  212. // initialize features (part 2)
  213. for (uint32_t i=0; i < kFeatureCount; ++i)
  214. fFeatures[i] = new LV2_Feature;
  215. fFeatures[kFeatureIdLogs]->URI = LV2_LOG__log;
  216. fFeatures[kFeatureIdLogs]->data = logFt;
  217. fFeatures[kFeatureIdOptions]->URI = LV2_OPTIONS__options;
  218. fFeatures[kFeatureIdOptions]->data = fOptions.opts;
  219. fFeatures[kFeatureIdPrograms]->URI = LV2_PROGRAMS__Host;
  220. fFeatures[kFeatureIdPrograms]->data = programsFt;
  221. fFeatures[kFeatureIdStateMakePath]->URI = LV2_STATE__makePath;
  222. fFeatures[kFeatureIdStateMakePath]->data = stateMakePathFt;
  223. fFeatures[kFeatureIdStateMapPath]->URI = LV2_STATE__mapPath;
  224. fFeatures[kFeatureIdStateMapPath]->data = stateMapPathFt;
  225. fFeatures[kFeatureIdUriMap]->URI = LV2_URI_MAP_URI;
  226. fFeatures[kFeatureIdUriMap]->data = uriMapFt;
  227. fFeatures[kFeatureIdUridMap]->URI = LV2_URID__map;
  228. fFeatures[kFeatureIdUridMap]->data = uridMapFt;
  229. fFeatures[kFeatureIdUridUnmap]->URI = LV2_URID__unmap;
  230. fFeatures[kFeatureIdUridUnmap]->data = uridUnmapFt;
  231. fFeatures[kFeatureIdUiIdleInterface]->URI = LV2_UI__idleInterface;
  232. fFeatures[kFeatureIdUiIdleInterface]->data = nullptr;
  233. fFeatures[kFeatureIdUiFixedSize]->URI = LV2_UI__fixedSize;
  234. fFeatures[kFeatureIdUiFixedSize]->data = nullptr;
  235. fFeatures[kFeatureIdUiMakeResident]->URI = LV2_UI__makeResident;
  236. fFeatures[kFeatureIdUiMakeResident]->data = nullptr;
  237. fFeatures[kFeatureIdUiNoUserResize]->URI = LV2_UI__noUserResize;
  238. fFeatures[kFeatureIdUiNoUserResize]->data = nullptr;
  239. fFeatures[kFeatureIdUiParent]->URI = LV2_UI__parent;
  240. fFeatures[kFeatureIdUiParent]->data = nullptr;
  241. fFeatures[kFeatureIdUiPortMap]->URI = LV2_UI__portMap;
  242. fFeatures[kFeatureIdUiPortMap]->data = uiPortMapFt;
  243. fFeatures[kFeatureIdUiPortSubscribe]->URI = LV2_UI__portSubscribe;
  244. fFeatures[kFeatureIdUiPortSubscribe]->data = nullptr;
  245. fFeatures[kFeatureIdUiResize]->URI = LV2_UI__resize;
  246. fFeatures[kFeatureIdUiResize]->data = uiResizeFt;
  247. fFeatures[kFeatureIdUiTouch]->URI = LV2_UI__touch;
  248. fFeatures[kFeatureIdUiTouch]->data = nullptr;
  249. }
  250. ~CarlaLv2Client() override
  251. {
  252. if (fRdfDescriptor != nullptr)
  253. delete fRdfDescriptor;
  254. delete (LV2_Log_Log*)fFeatures[kFeatureIdLogs]->data;
  255. delete (LV2_State_Make_Path*)fFeatures[kFeatureIdStateMakePath]->data;
  256. delete (LV2_State_Map_Path*)fFeatures[kFeatureIdStateMapPath]->data;
  257. delete (LV2_Programs_Host*)fFeatures[kFeatureIdPrograms]->data;
  258. delete (LV2_URI_Map_Feature*)fFeatures[kFeatureIdUriMap]->data;
  259. delete (LV2_URID_Map*)fFeatures[kFeatureIdUridMap]->data;
  260. delete (LV2_URID_Unmap*)fFeatures[kFeatureIdUridUnmap]->data;
  261. delete (LV2UI_Port_Map*)fFeatures[kFeatureIdUiPortMap]->data;
  262. delete (LV2UI_Resize*)fFeatures[kFeatureIdUiResize]->data;
  263. for (uint32_t i=0; i < kFeatureCount; ++i)
  264. {
  265. if (fFeatures[i] != nullptr)
  266. {
  267. delete fFeatures[i];
  268. fFeatures[i] = nullptr;
  269. }
  270. }
  271. for (LinkedList<const char*>::Itenerator it = fCustomURIDs.begin(); it.valid(); it.next())
  272. {
  273. const char* const uri(it.getValue());
  274. if (uri != nullptr)
  275. delete[] uri;
  276. }
  277. fCustomURIDs.clear();
  278. }
  279. // ---------------------------------------------------------------------
  280. // ui initialization
  281. bool uiInit(const char* pluginURI, const char* uiURI) override
  282. {
  283. // -----------------------------------------------------------------
  284. // init
  285. CarlaBridgeClient::uiInit(pluginURI, uiURI);
  286. // -----------------------------------------------------------------
  287. // get plugin from lv2_rdf (lilv)
  288. fRdfDescriptor = lv2_rdf_new(pluginURI, true);
  289. if (fRdfDescriptor == nullptr)
  290. return false;
  291. // -----------------------------------------------------------------
  292. // find requested UI
  293. for (uint32_t i=0; i < fRdfDescriptor->UICount; ++i)
  294. {
  295. if (std::strcmp(fRdfDescriptor->UIs[i].URI, uiURI) == 0)
  296. {
  297. fRdfUiDescriptor = &fRdfDescriptor->UIs[i];
  298. break;
  299. }
  300. }
  301. if (fRdfUiDescriptor == nullptr)
  302. {
  303. carla_stderr("Failed to find requested UI");
  304. return false;
  305. }
  306. // -----------------------------------------------------------------
  307. // open DLL
  308. if (! uiLibOpen(fRdfUiDescriptor->Binary))
  309. {
  310. carla_stderr("Failed to load UI binary, error was:\n%s", uiLibError());
  311. return false;
  312. }
  313. // -----------------------------------------------------------------
  314. // get DLL main entry
  315. const LV2UI_DescriptorFunction ui_descFn = (LV2UI_DescriptorFunction)uiLibSymbol("lv2ui_descriptor");
  316. if (ui_descFn == nullptr)
  317. return false;
  318. // -----------------------------------------------------------
  319. // get descriptor that matches URI
  320. uint32_t i = 0;
  321. while ((fDescriptor = ui_descFn(i++)))
  322. {
  323. if (std::strcmp(fDescriptor->URI, uiURI) == 0)
  324. break;
  325. }
  326. if (fDescriptor == nullptr)
  327. {
  328. carla_stderr("Failed to find UI descriptor");
  329. return false;
  330. }
  331. // -----------------------------------------------------------
  332. // initialize UI
  333. #if defined(BRIDGE_COCOA) || defined(BRIDGE_HWND) || defined(BRIDGE_X11)
  334. fFeatures[kFeatureIdUiParent]->data = getContainerId();
  335. #endif
  336. fHandle = fDescriptor->instantiate(fDescriptor, fRdfDescriptor->URI, fRdfUiDescriptor->Bundle, carla_lv2_ui_write_function, this, &fWidget, fFeatures);
  337. if (fHandle == nullptr)
  338. {
  339. carla_stderr("Failed to init UI");
  340. return false;
  341. }
  342. // -----------------------------------------------------------
  343. // check if not resizable
  344. for (uint32_t i=0; i < fRdfUiDescriptor->FeatureCount && fIsResizable; ++i)
  345. {
  346. if (std::strcmp(fRdfUiDescriptor->Features[i].URI, LV2_UI__fixedSize) == 0 || std::strcmp(fRdfUiDescriptor->Features[i].URI, LV2_UI__noUserResize) == 0)
  347. {
  348. fIsResizable = false;
  349. break;
  350. }
  351. }
  352. // -----------------------------------------------------------
  353. // check for known extensions
  354. if (fDescriptor->extension_data != nullptr)
  355. {
  356. fExt.programs = (const LV2_Programs_UI_Interface*)fDescriptor->extension_data(LV2_PROGRAMS__UIInterface);
  357. fExt.options = (const LV2_Options_Interface*)fDescriptor->extension_data(LV2_OPTIONS__interface);
  358. fExt.idle = (const LV2UI_Idle_Interface*)fDescriptor->extension_data(LV2_UI__idleInterface);
  359. // check if invalid
  360. if (fExt.programs != nullptr && fExt.programs->select_program == nullptr)
  361. fExt.programs = nullptr;
  362. if (fExt.idle != nullptr && fExt.idle->idle == nullptr)
  363. fExt.idle = nullptr;
  364. }
  365. return true;
  366. }
  367. void uiIdle() override
  368. {
  369. if (fHandle != nullptr && fExt.idle != nullptr)
  370. fExt.idle->idle(fHandle);
  371. }
  372. void uiClose() override
  373. {
  374. CarlaBridgeClient::uiClose();
  375. if (fHandle != nullptr && fDescriptor != nullptr && fDescriptor->cleanup != nullptr)
  376. {
  377. fDescriptor->cleanup(fHandle);
  378. fHandle = nullptr;
  379. }
  380. uiLibClose();
  381. }
  382. // ---------------------------------------------------------------------
  383. // ui management
  384. void* getWidget() const override
  385. {
  386. return fWidget;
  387. }
  388. bool isResizable() const override
  389. {
  390. return fIsResizable;
  391. }
  392. bool needsReparent() const override
  393. {
  394. #if defined(BRIDGE_COCOA) || defined(BRIDGE_HWND) || defined(BRIDGE_X11)
  395. return true;
  396. #else
  397. return false;
  398. #endif
  399. }
  400. // ---------------------------------------------------------------------
  401. // ui processing
  402. void setParameter(const int32_t rindex, const float value) override
  403. {
  404. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,)
  405. CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
  406. if (fDescriptor->port_event == nullptr)
  407. return;
  408. fDescriptor->port_event(fHandle, rindex, sizeof(float), 0, &value);
  409. }
  410. void setProgram(const uint32_t) override
  411. {
  412. }
  413. void setMidiProgram(const uint32_t bank, const uint32_t program) override
  414. {
  415. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,)
  416. if (fExt.programs == nullptr)
  417. return;
  418. fExt.programs->select_program(fHandle, bank, program);
  419. }
  420. void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) override
  421. {
  422. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,)
  423. CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
  424. if (fDescriptor->port_event == nullptr)
  425. return;
  426. LV2_Atom_MidiEvent midiEv;
  427. midiEv.event.time.frames = 0;
  428. midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
  429. midiEv.event.body.size = 3;
  430. midiEv.data[0] = MIDI_STATUS_NOTE_ON + channel;
  431. midiEv.data[1] = note;
  432. midiEv.data[2] = velo;
  433. fDescriptor->port_event(fHandle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
  434. }
  435. void noteOff(const uint8_t channel, const uint8_t note) override
  436. {
  437. CARLA_SAFE_ASSERT_RETURN(fHandle != nullptr,)
  438. CARLA_SAFE_ASSERT_RETURN(fDescriptor != nullptr,);
  439. if (fDescriptor->port_event == nullptr)
  440. return;
  441. LV2_Atom_MidiEvent midiEv;
  442. midiEv.event.time.frames = 0;
  443. midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
  444. midiEv.event.body.size = 3;
  445. midiEv.data[0] = MIDI_STATUS_NOTE_OFF + channel;
  446. midiEv.data[1] = note;
  447. midiEv.data[2] = 0;
  448. fDescriptor->port_event(fHandle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
  449. }
  450. // ---------------------------------------------------------------------
  451. void waitForOscURIs()
  452. {
  453. sendOscUpdate();
  454. for (;;)
  455. {
  456. oscWait();
  457. if (fIsReady)
  458. return;
  459. }
  460. }
  461. // ---------------------------------------------------------------------
  462. LV2_URID getCustomURID(const char* const uri)
  463. {
  464. CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', CARLA_URI_MAP_ID_NULL);
  465. carla_debug("CarlaLv2Client::getCustomURID(\"%s\")", uri);
  466. LV2_URID urid = CARLA_URI_MAP_ID_NULL;
  467. for (size_t i=0; i < fCustomURIDs.count(); ++i)
  468. {
  469. const char* const thisUri(fCustomURIDs.getAt(i));
  470. if (thisUri != nullptr && std::strcmp(thisUri, uri) == 0)
  471. {
  472. urid = i;
  473. break;
  474. }
  475. }
  476. if (urid == CARLA_URI_MAP_ID_NULL)
  477. {
  478. urid = fCustomURIDs.count();
  479. fCustomURIDs.append(carla_strdup(uri));
  480. }
  481. if (isOscControlRegistered())
  482. sendOscLv2UridMap(urid, uri);
  483. return urid;
  484. }
  485. const char* getCustomURIString(const LV2_URID urid) const noexcept
  486. {
  487. CARLA_SAFE_ASSERT_RETURN(urid != CARLA_URI_MAP_ID_NULL, nullptr);
  488. CARLA_SAFE_ASSERT_RETURN(urid < fCustomURIDs.count(), nullptr);
  489. carla_debug("CarlaLv2Client::getCustomURIString(%i)", urid);
  490. return fCustomURIDs.getAt(urid);
  491. }
  492. // ---------------------------------------------------------------------
  493. void handleProgramChanged(const int32_t /*index*/)
  494. {
  495. if (isOscControlRegistered())
  496. sendOscConfigure("reloadprograms", "");
  497. }
  498. uint32_t handleUiPortMap(const char* const symbol)
  499. {
  500. CARLA_SAFE_ASSERT_RETURN(symbol != nullptr && symbol[0] != '\0', LV2UI_INVALID_PORT_INDEX);
  501. carla_debug("CarlaLv2Client::handleUiPortMap(\"%s\")", symbol);
  502. for (uint32_t i=0; i < fRdfDescriptor->PortCount; ++i)
  503. {
  504. if (std::strcmp(fRdfDescriptor->Ports[i].Symbol, symbol) == 0)
  505. return i;
  506. }
  507. return LV2UI_INVALID_PORT_INDEX;
  508. }
  509. int handleUiResize(const int width, const int height)
  510. {
  511. CARLA_SAFE_ASSERT_RETURN(width > 0, 1);
  512. CARLA_SAFE_ASSERT_RETURN(height > 0, 1);
  513. carla_debug("CarlaLv2Client::handleUiResize(%i, %i)", width, height);
  514. toolkitResize(width, height);
  515. return 0;
  516. }
  517. void handleUiWrite(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer)
  518. {
  519. CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
  520. CARLA_SAFE_ASSERT_RETURN(bufferSize > 0,);
  521. carla_debug("CarlaLv2Client::handleUiWrite(%i, %i, %i, %p)", rindex, bufferSize, format, buffer);
  522. if (format == 0)
  523. {
  524. CARLA_ASSERT(buffer != nullptr);
  525. CARLA_ASSERT(bufferSize == sizeof(float));
  526. if (bufferSize != sizeof(float))
  527. return;
  528. if (buffer == nullptr || bufferSize != sizeof(float))
  529. return;
  530. const float value(*(const float*)buffer);
  531. if (isOscControlRegistered())
  532. sendOscControl(portIndex, value);
  533. }
  534. else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM || CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
  535. {
  536. CARLA_ASSERT(bufferSize != 0);
  537. CARLA_ASSERT(buffer != nullptr);
  538. if (bufferSize == 0 || buffer == nullptr)
  539. return;
  540. if (isOscControlRegistered())
  541. sendOscLv2AtomTransfer(portIndex, QByteArray((const char*)buffer, bufferSize).toBase64().constData());
  542. }
  543. else
  544. {
  545. carla_stdout("CarlaLv2Client::handleUiWrite(%i, %i, %i:\"%s\", %p) - unknown format", portIndex, bufferSize, format, carla_lv2_urid_unmap(this, format), buffer);
  546. }
  547. }
  548. // ---------------------------------------------------------------------
  549. void handleAtomTransfer(const uint32_t portIndex, const LV2_Atom* const atom)
  550. {
  551. CARLA_ASSERT(atom != nullptr);
  552. carla_debug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom);
  553. if (atom != nullptr && fHandle != nullptr && fDescriptor != nullptr && fDescriptor->port_event != nullptr)
  554. fDescriptor->port_event(fHandle, portIndex, lv2_atom_total_size(atom), CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);
  555. }
  556. void handleUridMap(const LV2_URID urid, const char* const uri)
  557. {
  558. CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0',);
  559. carla_stdout("CarlaLv2Client::handleUridMap(%i, \"%s\")", urid, uri);
  560. if (urid == CARLA_URI_MAP_ID_NULL)
  561. {
  562. CARLA_SAFE_ASSERT_RETURN(std::strcmp(uri, "Complete") == 0,);
  563. carla_stdout("URID map from host complete");
  564. fIsReady = true;
  565. return;
  566. }
  567. const uint32_t uridCount(fCustomURIDs.count());
  568. if (urid < uridCount)
  569. {
  570. if (const char* const ourURI = carla_lv2_urid_unmap(this, urid))
  571. {
  572. if (std::strcmp(ourURI, uri) != 0)
  573. carla_stderr2("UI :: wrong URI '%s' vs '%s'", ourURI, uri);
  574. }
  575. else
  576. {
  577. uint32_t i=0;
  578. for (LinkedList<const char*>::Itenerator it = fCustomURIDs.begin(); it.valid(); it.next())
  579. {
  580. if (i != urid)
  581. continue;
  582. CARLA_SAFE_ASSERT(it.getValue() == nullptr);
  583. it.setValue(carla_strdup(uri));
  584. break;
  585. }
  586. }
  587. }
  588. else if (urid > uridCount)
  589. {
  590. for (uint32_t i=uridCount; i < urid; ++i)
  591. fCustomURIDs.append(nullptr);
  592. }
  593. else
  594. {
  595. fCustomURIDs.append(carla_strdup(uri));
  596. }
  597. }
  598. private:
  599. LV2UI_Handle fHandle;
  600. LV2UI_Widget fWidget;
  601. LV2_Feature* fFeatures[kFeatureCount+1];
  602. const LV2UI_Descriptor* fDescriptor;
  603. const LV2_RDF_Descriptor* fRdfDescriptor;
  604. const LV2_RDF_UI* fRdfUiDescriptor;
  605. Lv2PluginOptions fOptions;
  606. bool fIsReady;
  607. bool fIsResizable;
  608. LinkedList<const char*> fCustomURIDs;
  609. struct Extensions {
  610. const LV2_Options_Interface* options;
  611. const LV2UI_Idle_Interface* idle;
  612. const LV2_Programs_UI_Interface* programs;
  613. Extensions()
  614. : options(nullptr),
  615. idle(nullptr),
  616. programs(nullptr) {}
  617. } fExt;
  618. // -------------------------------------------------------------------
  619. // Logs Feature
  620. static int carla_lv2_log_printf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, ...)
  621. {
  622. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0);
  623. CARLA_SAFE_ASSERT_RETURN(type != CARLA_URI_MAP_ID_NULL, 0);
  624. CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0);
  625. #ifndef DEBUG
  626. if (type == CARLA_URI_MAP_ID_LOG_TRACE)
  627. return 0;
  628. #endif
  629. va_list args;
  630. va_start(args, fmt);
  631. const int ret(carla_lv2_log_vprintf(handle, type, fmt, args));
  632. va_end(args);
  633. return ret;
  634. }
  635. static int carla_lv2_log_vprintf(LV2_Log_Handle handle, LV2_URID type, const char* fmt, va_list ap)
  636. {
  637. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 0);
  638. CARLA_SAFE_ASSERT_RETURN(type != CARLA_URI_MAP_ID_NULL, 0);
  639. CARLA_SAFE_ASSERT_RETURN(fmt != nullptr, 0);
  640. #ifndef DEBUG
  641. if (type == CARLA_URI_MAP_ID_LOG_TRACE)
  642. return 0;
  643. #endif
  644. int ret = 0;
  645. switch (type)
  646. {
  647. case CARLA_URI_MAP_ID_LOG_ERROR:
  648. std::fprintf(stderr, "\x1b[31m");
  649. ret = std::vfprintf(stderr, fmt, ap);
  650. std::fprintf(stderr, "\x1b[0m");
  651. break;
  652. case CARLA_URI_MAP_ID_LOG_NOTE:
  653. ret = std::vfprintf(stdout, fmt, ap);
  654. break;
  655. case CARLA_URI_MAP_ID_LOG_TRACE:
  656. #ifdef DEBUG
  657. std::fprintf(stdout, "\x1b[30;1m");
  658. ret = std::vfprintf(stdout, fmt, ap);
  659. std::fprintf(stdout, "\x1b[0m");
  660. #endif
  661. break;
  662. case CARLA_URI_MAP_ID_LOG_WARNING:
  663. ret = std::vfprintf(stderr, fmt, ap);
  664. break;
  665. default:
  666. break;
  667. }
  668. return ret;
  669. }
  670. // -------------------------------------------------------------------
  671. // Programs Feature
  672. static void carla_lv2_program_changed(LV2_Programs_Handle handle, int32_t index)
  673. {
  674. CARLA_SAFE_ASSERT_RETURN(handle != nullptr,);
  675. carla_debug("carla_lv2_program_changed(%p, %i)", handle, index);
  676. ((CarlaLv2Client*)handle)->handleProgramChanged(index);
  677. }
  678. // -------------------------------------------------------------------
  679. // State Feature
  680. static char* carla_lv2_state_make_path(LV2_State_Make_Path_Handle handle, const char* path)
  681. {
  682. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  683. CARLA_SAFE_ASSERT_RETURN(path != nullptr && path[0] != '\0', nullptr);
  684. carla_debug("carla_lv2_state_make_path(%p, \"%s\")", handle, path);
  685. QDir dir;
  686. dir.mkpath(path);
  687. return strdup(path);
  688. }
  689. static char* carla_lv2_state_map_abstract_path(LV2_State_Map_Path_Handle handle, const char* absolute_path)
  690. {
  691. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  692. CARLA_SAFE_ASSERT_RETURN(absolute_path != nullptr && absolute_path[0] != '\0', nullptr);
  693. carla_debug("carla_lv2_state_map_abstract_path(%p, \"%s\")", handle, absolute_path);
  694. QDir dir(absolute_path);
  695. return strdup(dir.canonicalPath().toUtf8().constData());
  696. }
  697. static char* carla_lv2_state_map_absolute_path(LV2_State_Map_Path_Handle handle, const char* abstract_path)
  698. {
  699. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  700. CARLA_SAFE_ASSERT_RETURN(abstract_path != nullptr && abstract_path[0] != '\0', nullptr);
  701. carla_debug("carla_lv2_state_map_absolute_path(%p, \"%s\")", handle, abstract_path);
  702. QDir dir(abstract_path);
  703. return strdup(dir.absolutePath().toUtf8().constData());
  704. }
  705. // -------------------------------------------------------------------
  706. // URI-Map Feature
  707. static uint32_t carla_lv2_uri_to_id(LV2_URI_Map_Callback_Data data, const char* map, const char* uri)
  708. {
  709. carla_debug("carla_lv2_uri_to_id(%p, \"%s\", \"%s\")", data, map, uri);
  710. return carla_lv2_urid_map((LV2_URID_Map_Handle*)data, uri);
  711. // unused
  712. (void)map;
  713. }
  714. // -------------------------------------------------------------------
  715. // URID Feature
  716. static LV2_URID carla_lv2_urid_map(LV2_URID_Map_Handle handle, const char* uri)
  717. {
  718. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, CARLA_URI_MAP_ID_NULL);
  719. CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', CARLA_URI_MAP_ID_NULL);
  720. carla_debug("carla_lv2_urid_map(%p, \"%s\")", handle, uri);
  721. // Atom types
  722. if (std::strcmp(uri, LV2_ATOM__Blank) == 0)
  723. return CARLA_URI_MAP_ID_ATOM_BLANK;
  724. if (std::strcmp(uri, LV2_ATOM__Bool) == 0)
  725. return CARLA_URI_MAP_ID_ATOM_BOOL;
  726. if (std::strcmp(uri, LV2_ATOM__Chunk) == 0)
  727. return CARLA_URI_MAP_ID_ATOM_CHUNK;
  728. if (std::strcmp(uri, LV2_ATOM__Double) == 0)
  729. return CARLA_URI_MAP_ID_ATOM_DOUBLE;
  730. if (std::strcmp(uri, LV2_ATOM__Event) == 0)
  731. return CARLA_URI_MAP_ID_ATOM_EVENT;
  732. if (std::strcmp(uri, LV2_ATOM__Float) == 0)
  733. return CARLA_URI_MAP_ID_ATOM_FLOAT;
  734. if (std::strcmp(uri, LV2_ATOM__Int) == 0)
  735. return CARLA_URI_MAP_ID_ATOM_INT;
  736. if (std::strcmp(uri, LV2_ATOM__Literal) == 0)
  737. return CARLA_URI_MAP_ID_ATOM_LITERAL;
  738. if (std::strcmp(uri, LV2_ATOM__Long) == 0)
  739. return CARLA_URI_MAP_ID_ATOM_LONG;
  740. if (std::strcmp(uri, LV2_ATOM__Number) == 0)
  741. return CARLA_URI_MAP_ID_ATOM_NUMBER;
  742. if (std::strcmp(uri, LV2_ATOM__Object) == 0)
  743. return CARLA_URI_MAP_ID_ATOM_OBJECT;
  744. if (std::strcmp(uri, LV2_ATOM__Path) == 0)
  745. return CARLA_URI_MAP_ID_ATOM_PATH;
  746. if (std::strcmp(uri, LV2_ATOM__Property) == 0)
  747. return CARLA_URI_MAP_ID_ATOM_PROPERTY;
  748. if (std::strcmp(uri, LV2_ATOM__Resource) == 0)
  749. return CARLA_URI_MAP_ID_ATOM_RESOURCE;
  750. if (std::strcmp(uri, LV2_ATOM__Sequence) == 0)
  751. return CARLA_URI_MAP_ID_ATOM_SEQUENCE;
  752. if (std::strcmp(uri, LV2_ATOM__Sound) == 0)
  753. return CARLA_URI_MAP_ID_ATOM_SOUND;
  754. if (std::strcmp(uri, LV2_ATOM__String) == 0)
  755. return CARLA_URI_MAP_ID_ATOM_STRING;
  756. if (std::strcmp(uri, LV2_ATOM__Tuple) == 0)
  757. return CARLA_URI_MAP_ID_ATOM_TUPLE;
  758. if (std::strcmp(uri, LV2_ATOM__URI) == 0)
  759. return CARLA_URI_MAP_ID_ATOM_URI;
  760. if (std::strcmp(uri, LV2_ATOM__URID) == 0)
  761. return CARLA_URI_MAP_ID_ATOM_URID;
  762. if (std::strcmp(uri, LV2_ATOM__Vector) == 0)
  763. return CARLA_URI_MAP_ID_ATOM_VECTOR;
  764. if (std::strcmp(uri, LV2_ATOM__atomTransfer) == 0)
  765. return CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM;
  766. if (std::strcmp(uri, LV2_ATOM__eventTransfer) == 0)
  767. return CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT;
  768. // BufSize types
  769. if (std::strcmp(uri, LV2_BUF_SIZE__maxBlockLength) == 0)
  770. return CARLA_URI_MAP_ID_BUF_MAX_LENGTH;
  771. if (std::strcmp(uri, LV2_BUF_SIZE__minBlockLength) == 0)
  772. return CARLA_URI_MAP_ID_BUF_MIN_LENGTH;
  773. if (std::strcmp(uri, LV2_BUF_SIZE__sequenceSize) == 0)
  774. return CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE;
  775. // Log types
  776. if (std::strcmp(uri, LV2_LOG__Error) == 0)
  777. return CARLA_URI_MAP_ID_LOG_ERROR;
  778. if (std::strcmp(uri, LV2_LOG__Note) == 0)
  779. return CARLA_URI_MAP_ID_LOG_NOTE;
  780. if (std::strcmp(uri, LV2_LOG__Trace) == 0)
  781. return CARLA_URI_MAP_ID_LOG_TRACE;
  782. if (std::strcmp(uri, LV2_LOG__Warning) == 0)
  783. return CARLA_URI_MAP_ID_LOG_WARNING;
  784. // Time types
  785. if (std::strcmp(uri, LV2_TIME__Position) == 0)
  786. return CARLA_URI_MAP_ID_TIME_POSITION;
  787. if (std::strcmp(uri, LV2_TIME__bar) == 0)
  788. return CARLA_URI_MAP_ID_TIME_BAR;
  789. if (std::strcmp(uri, LV2_TIME__barBeat) == 0)
  790. return CARLA_URI_MAP_ID_TIME_BAR_BEAT;
  791. if (std::strcmp(uri, LV2_TIME__beat) == 0)
  792. return CARLA_URI_MAP_ID_TIME_BEAT;
  793. if (std::strcmp(uri, LV2_TIME__beatUnit) == 0)
  794. return CARLA_URI_MAP_ID_TIME_BEAT_UNIT;
  795. if (std::strcmp(uri, LV2_TIME__beatsPerBar) == 0)
  796. return CARLA_URI_MAP_ID_TIME_BEATS_PER_BAR;
  797. if (std::strcmp(uri, LV2_TIME__beatsPerMinute) == 0)
  798. return CARLA_URI_MAP_ID_TIME_BEATS_PER_MINUTE;
  799. if (std::strcmp(uri, LV2_TIME__frame) == 0)
  800. return CARLA_URI_MAP_ID_TIME_FRAME;
  801. if (std::strcmp(uri, LV2_TIME__framesPerSecond) == 0)
  802. return CARLA_URI_MAP_ID_TIME_FRAMES_PER_SECOND;
  803. if (std::strcmp(uri, LV2_TIME__speed) == 0)
  804. return CARLA_URI_MAP_ID_TIME_SPEED;
  805. // Others
  806. if (std::strcmp(uri, LV2_MIDI__MidiEvent) == 0)
  807. return CARLA_URI_MAP_ID_MIDI_EVENT;
  808. if (std::strcmp(uri, LV2_PARAMETERS__sampleRate) == 0)
  809. return CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE;
  810. // Custom
  811. if (std::strcmp(uri, URI_CARLA_WORKER) == 0)
  812. return CARLA_URI_MAP_ID_ATOM_WORKER;
  813. // Custom types
  814. return ((CarlaLv2Client*)handle)->getCustomURID(uri);
  815. }
  816. static const char* carla_lv2_urid_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
  817. {
  818. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, nullptr);
  819. CARLA_SAFE_ASSERT_RETURN(urid != CARLA_URI_MAP_ID_NULL, nullptr);
  820. carla_debug("carla_lv2_urid_unmap(%p, %i)", handle, urid);
  821. // Atom types
  822. if (urid == CARLA_URI_MAP_ID_ATOM_BLANK)
  823. return LV2_ATOM__Blank;
  824. if (urid == CARLA_URI_MAP_ID_ATOM_BOOL)
  825. return LV2_ATOM__Bool;
  826. if (urid == CARLA_URI_MAP_ID_ATOM_CHUNK)
  827. return LV2_ATOM__Chunk;
  828. if (urid == CARLA_URI_MAP_ID_ATOM_DOUBLE)
  829. return LV2_ATOM__Double;
  830. if (urid == CARLA_URI_MAP_ID_ATOM_EVENT)
  831. return LV2_ATOM__Event;
  832. if (urid == CARLA_URI_MAP_ID_ATOM_FLOAT)
  833. return LV2_ATOM__Float;
  834. if (urid == CARLA_URI_MAP_ID_ATOM_INT)
  835. return LV2_ATOM__Int;
  836. if (urid == CARLA_URI_MAP_ID_ATOM_LITERAL)
  837. return LV2_ATOM__Literal;
  838. if (urid == CARLA_URI_MAP_ID_ATOM_LONG)
  839. return LV2_ATOM__Long;
  840. if (urid == CARLA_URI_MAP_ID_ATOM_NUMBER)
  841. return LV2_ATOM__Number;
  842. if (urid == CARLA_URI_MAP_ID_ATOM_OBJECT)
  843. return LV2_ATOM__Object;
  844. if (urid == CARLA_URI_MAP_ID_ATOM_PATH)
  845. return LV2_ATOM__Path;
  846. if (urid == CARLA_URI_MAP_ID_ATOM_PROPERTY)
  847. return LV2_ATOM__Property;
  848. if (urid == CARLA_URI_MAP_ID_ATOM_RESOURCE)
  849. return LV2_ATOM__Resource;
  850. if (urid == CARLA_URI_MAP_ID_ATOM_SEQUENCE)
  851. return LV2_ATOM__Sequence;
  852. if (urid == CARLA_URI_MAP_ID_ATOM_SOUND)
  853. return LV2_ATOM__Sound;
  854. if (urid == CARLA_URI_MAP_ID_ATOM_STRING)
  855. return LV2_ATOM__String;
  856. if (urid == CARLA_URI_MAP_ID_ATOM_TUPLE)
  857. return LV2_ATOM__Tuple;
  858. if (urid == CARLA_URI_MAP_ID_ATOM_URI)
  859. return LV2_ATOM__URI;
  860. if (urid == CARLA_URI_MAP_ID_ATOM_URID)
  861. return LV2_ATOM__URID;
  862. if (urid == CARLA_URI_MAP_ID_ATOM_VECTOR)
  863. return LV2_ATOM__Vector;
  864. if (urid == CARLA_URI_MAP_ID_ATOM_WORKER)
  865. return URI_CARLA_WORKER; // custom
  866. if (urid == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM)
  867. return LV2_ATOM__atomTransfer;
  868. if (urid == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
  869. return LV2_ATOM__eventTransfer;
  870. // BufSize types
  871. if (urid == CARLA_URI_MAP_ID_BUF_MAX_LENGTH)
  872. return LV2_BUF_SIZE__maxBlockLength;
  873. if (urid == CARLA_URI_MAP_ID_BUF_MIN_LENGTH)
  874. return LV2_BUF_SIZE__minBlockLength;
  875. if (urid == CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE)
  876. return LV2_BUF_SIZE__sequenceSize;
  877. // Log types
  878. if (urid == CARLA_URI_MAP_ID_LOG_ERROR)
  879. return LV2_LOG__Error;
  880. if (urid == CARLA_URI_MAP_ID_LOG_NOTE)
  881. return LV2_LOG__Note;
  882. if (urid == CARLA_URI_MAP_ID_LOG_TRACE)
  883. return LV2_LOG__Trace;
  884. if (urid == CARLA_URI_MAP_ID_LOG_WARNING)
  885. return LV2_LOG__Warning;
  886. // Time types
  887. if (urid == CARLA_URI_MAP_ID_TIME_POSITION)
  888. return LV2_TIME__Position;
  889. if (urid == CARLA_URI_MAP_ID_TIME_BAR)
  890. return LV2_TIME__bar;
  891. if (urid == CARLA_URI_MAP_ID_TIME_BAR_BEAT)
  892. return LV2_TIME__barBeat;
  893. if (urid == CARLA_URI_MAP_ID_TIME_BEAT)
  894. return LV2_TIME__beat;
  895. if (urid == CARLA_URI_MAP_ID_TIME_BEAT_UNIT)
  896. return LV2_TIME__beatUnit;
  897. if (urid == CARLA_URI_MAP_ID_TIME_BEATS_PER_BAR)
  898. return LV2_TIME__beatsPerBar;
  899. if (urid == CARLA_URI_MAP_ID_TIME_BEATS_PER_MINUTE)
  900. return LV2_TIME__beatsPerMinute;
  901. if (urid == CARLA_URI_MAP_ID_TIME_FRAME)
  902. return LV2_TIME__frame;
  903. if (urid == CARLA_URI_MAP_ID_TIME_FRAMES_PER_SECOND)
  904. return LV2_TIME__framesPerSecond;
  905. if (urid == CARLA_URI_MAP_ID_TIME_SPEED)
  906. return LV2_TIME__speed;
  907. // Others
  908. if (urid == CARLA_URI_MAP_ID_MIDI_EVENT)
  909. return LV2_MIDI__MidiEvent;
  910. if (urid == CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE)
  911. return LV2_PARAMETERS__sampleRate;
  912. // Custom types
  913. return ((CarlaLv2Client*)handle)->getCustomURIString(urid);
  914. }
  915. // -------------------------------------------------------------------
  916. // UI Port-Map Feature
  917. static uint32_t carla_lv2_ui_port_map(LV2UI_Feature_Handle handle, const char* symbol)
  918. {
  919. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, LV2UI_INVALID_PORT_INDEX);
  920. carla_debug("carla_lv2_ui_port_map(%p, \"%s\")", handle, symbol);
  921. return ((CarlaLv2Client*)handle)->handleUiPortMap(symbol);
  922. }
  923. // -------------------------------------------------------------------
  924. // UI Resize Feature
  925. static int carla_lv2_ui_resize(LV2UI_Feature_Handle handle, int width, int height)
  926. {
  927. CARLA_SAFE_ASSERT_RETURN(handle != nullptr, 1);
  928. carla_debug("carla_lv2_ui_resize(%p, %i, %i)", handle, width, height);
  929. return ((CarlaLv2Client*)handle)->handleUiResize(width, height);
  930. }
  931. // -------------------------------------------------------------------
  932. // UI Extension
  933. static void carla_lv2_ui_write_function(LV2UI_Controller controller, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void* buffer)
  934. {
  935. CARLA_SAFE_ASSERT_RETURN(controller != nullptr,);
  936. carla_debug("carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
  937. ((CarlaLv2Client*)controller)->handleUiWrite(port_index, buffer_size, format, buffer);
  938. }
  939. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaLv2Client)
  940. };
  941. #define lv2ClientPtr ((CarlaLv2Client*)fClient)
  942. int CarlaBridgeOsc::handleMsgLv2AtomTransfer(CARLA_BRIDGE_OSC_HANDLE_ARGS)
  943. {
  944. CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "is");
  945. carla_debug("CarlaBridgeOsc::handleMsgLv2AtomTransfer()");
  946. if (fClient == nullptr)
  947. return 1;
  948. const int32_t portIndex = argv[0]->i;
  949. const char* const atomBuf = (const char*)&argv[1]->s;
  950. if (portIndex < 0)
  951. return 0;
  952. QByteArray chunk;
  953. chunk = QByteArray::fromBase64(atomBuf);
  954. LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
  955. lv2ClientPtr->handleAtomTransfer(portIndex, atom);
  956. return 0;
  957. }
  958. int CarlaBridgeOsc::handleMsgLv2UridMap(CARLA_BRIDGE_OSC_HANDLE_ARGS)
  959. {
  960. CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "is");
  961. carla_debug("CarlaBridgeOsc::handleMsgLv2UridMap()");
  962. if (fClient == nullptr)
  963. return 1;
  964. const int32_t urid = argv[0]->i;
  965. const char* const uri = (const char*)&argv[1]->s;
  966. if (urid < 0)
  967. return 0;
  968. lv2ClientPtr->handleUridMap(urid, uri);
  969. return 0;
  970. }
  971. #undef lv2ClientPtr
  972. CARLA_BRIDGE_END_NAMESPACE
  973. int main(int argc, char* argv[])
  974. {
  975. CARLA_BRIDGE_USE_NAMESPACE
  976. if (argc != 5)
  977. {
  978. carla_stderr("usage: %s <osc-url|\"null\"> <plugin-uri> <ui-uri> <ui-title>", argv[0]);
  979. return 1;
  980. }
  981. const char* oscUrl = argv[1];
  982. const char* pluginURI = argv[2];
  983. const char* uiURI = argv[3];
  984. const char* uiTitle = argv[4];
  985. const bool useOsc(std::strcmp(oscUrl, "null") != 0);
  986. // try to get sampleRate value
  987. if (const char* const sampleRateStr = getenv("CARLA_SAMPLE_RATE"))
  988. gSampleRate = atof(sampleRateStr);
  989. // Init LV2 client
  990. CarlaLv2Client client(uiTitle);
  991. // Init OSC
  992. if (useOsc)
  993. {
  994. client.oscInit(oscUrl);
  995. client.waitForOscURIs();
  996. }
  997. // Load UI
  998. int ret;
  999. if (client.uiInit(pluginURI, uiURI))
  1000. {
  1001. client.toolkitExec(!useOsc);
  1002. ret = 0;
  1003. }
  1004. else
  1005. {
  1006. ret = 1;
  1007. }
  1008. // Close OSC
  1009. if (useOsc)
  1010. client.oscClose();
  1011. // Close LV2 client
  1012. client.uiClose();
  1013. return ret;
  1014. }