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.

1608 lines
50KB

  1. /*
  2. * Carla Backend
  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. #include "carla_backend_standalone.h"
  18. #include "carla_plugin.h"
  19. #include "plugins/carla_native.h"
  20. // -------------------------------------------------------------------------------------------------------------------
  21. // Single, standalone engine
  22. static CarlaBackend::CarlaEngine* carlaEngine = nullptr;
  23. static CarlaBackend::CallbackFunc carlaFunc = nullptr;
  24. static const char* extendedLicenseText = nullptr;
  25. // -------------------------------------------------------------------------------------------------------------------
  26. const char* get_extended_license_text()
  27. {
  28. qDebug("CarlaBackendStandalone::get_extended_license_text()");
  29. QString text("<p>This current Carla build is using the following features and 3rd-party code:</p>");
  30. text += "<ul>";
  31. #ifdef WANT_LADSPA
  32. text += "<li>LADSPA plugin support, http://www.ladspa.org/</li>";
  33. #endif
  34. #ifdef WANT_DSSI
  35. text += "<li>DSSI plugin support, http://dssi.sourceforge.net/</li>";
  36. #endif
  37. #ifdef WANT_LV2
  38. text += "<li>LV2 plugin support, http://lv2plug.in/</li>";
  39. #endif
  40. #ifdef WANT_VST
  41. # ifdef VESTIGE_HEADER
  42. text += "<li>VST plugin support, using VeSTige header by Javier Serrano Polo</li>";
  43. # else
  44. text += "<li>VST plugin support, using official VST SDK 2.4 trademark of Steinberg Media Technologies GmbH</li>";
  45. # endif
  46. #endif
  47. #ifdef WANT_FLUIDSYNTH
  48. text += "<li>FluidSynth library for SF2 support, http://www.fluidsynth.org/</li>";
  49. #endif
  50. #ifdef WANT_LINUXSAMPLER
  51. text += "<li>LinuxSampler library for GIG and SFZ support*, http://www.linuxsampler.org/</li>";
  52. #endif
  53. text += "<li>liblo library for OSC support, http://liblo.sourceforge.net/</li>";
  54. #ifdef WANT_LV2
  55. text += "<li>serd, sord, sratom and lilv libraries for LV2 discovery, http://drobilla.net/software/lilv/</li>";
  56. #endif
  57. #ifdef CARLA_ENGINE_RTAUDIO
  58. text += "<li>RtAudio and RtMidi libraries for extra Audio and MIDI support, http://www.music.mcgill.ca/~gary/rtaudio/</li>";
  59. #endif
  60. text += "</ul>";
  61. #ifdef WANT_LINUXSAMPLER
  62. text += "<p>(*) Using LinuxSampler code in commercial hardware or software products is not allowed without prior written authorization by the authors.</p>";
  63. #endif
  64. if (! extendedLicenseText)
  65. extendedLicenseText = strdup(text.toUtf8().constData());
  66. return extendedLicenseText;
  67. }
  68. unsigned int get_engine_driver_count()
  69. {
  70. qDebug("CarlaBackendStandalone::get_engine_driver_count()");
  71. unsigned int count = 0;
  72. #ifdef CARLA_ENGINE_JACK
  73. count += 1;
  74. #endif
  75. #ifdef CARLA_ENGINE_RTAUDIO
  76. std::vector<RtAudio::Api> apis;
  77. RtAudio::getCompiledApi(apis);
  78. count += apis.size();
  79. #endif
  80. return count;
  81. }
  82. const char* get_engine_driver_name(unsigned int index)
  83. {
  84. qDebug("CarlaBackendStandalone::get_engine_driver_name(%i)", index);
  85. #ifdef CARLA_ENGINE_JACK
  86. if (index == 0)
  87. return "JACK";
  88. index -= 1;
  89. #endif
  90. #ifdef CARLA_ENGINE_RTAUDIO
  91. std::vector<RtAudio::Api> apis;
  92. RtAudio::getCompiledApi(apis);
  93. if (index < apis.size())
  94. {
  95. RtAudio::Api api = apis[index];
  96. switch (api)
  97. {
  98. case RtAudio::UNSPECIFIED:
  99. return "Unspecified";
  100. case RtAudio::LINUX_ALSA:
  101. return "ALSA";
  102. case RtAudio::LINUX_PULSE:
  103. return "PulseAudio";
  104. case RtAudio::LINUX_OSS:
  105. return "OSS";
  106. case RtAudio::UNIX_JACK:
  107. return "JACK (RtAudio)";
  108. case RtAudio::MACOSX_CORE:
  109. return "CoreAudio";
  110. case RtAudio::WINDOWS_ASIO:
  111. return "ASIO";
  112. case RtAudio::WINDOWS_DS:
  113. return "DirectSound";
  114. case RtAudio::RTAUDIO_DUMMY:
  115. return "Dummy";
  116. }
  117. }
  118. #endif
  119. qDebug("CarlaBackendStandalone::get_engine_driver_name(%i) - invalid index", index);
  120. return nullptr;
  121. }
  122. // -------------------------------------------------------------------------------------------------------------------
  123. unsigned int get_internal_plugin_count()
  124. {
  125. qDebug("CarlaBackendStandalone::get_internal_plugin_count()");
  126. return CarlaBackend::CarlaPlugin::getNativePluginCount();
  127. }
  128. const PluginInfo* get_internal_plugin_info(unsigned int plugin_id)
  129. {
  130. qDebug("CarlaBackendStandalone::get_internal_plugin_info(%i)", plugin_id);
  131. static PluginInfo info;
  132. const PluginDescriptor* const nativePlugin = CarlaBackend::CarlaPlugin::getNativePlugin(plugin_id);
  133. CARLA_ASSERT(nativePlugin);
  134. if (! nativePlugin)
  135. return nullptr;
  136. info.type = CarlaBackend::PLUGIN_NONE;
  137. info.category = (CarlaBackend::PluginCategory)nativePlugin->category;
  138. info.hints = CarlaBackend::getPluginHintsFromNative(nativePlugin->hints);
  139. info.name = nativePlugin->name;
  140. info.label = nativePlugin->label;
  141. info.maker = nativePlugin->maker;
  142. info.copyright = nativePlugin->copyright;
  143. return &info;
  144. }
  145. // -------------------------------------------------------------------------------------------------------------------
  146. bool engine_init(const char* driver_name, const char* client_name)
  147. {
  148. qDebug("CarlaBackendStandalone::engine_init(\"%s\", \"%s\")", driver_name, client_name);
  149. #ifdef CARLA_ENGINE_JACK
  150. if (strcmp(driver_name, "JACK") == 0)
  151. carlaEngine = new CarlaBackend::CarlaEngineJack;
  152. #else
  153. if (false)
  154. pass();
  155. #endif
  156. #ifdef CARLA_ENGINE_RTAUDIO
  157. #ifdef __LINUX_ALSA__
  158. else if (strcmp(driver_name, "ALSA") == 0)
  159. carlaEngine = new CarlaBackend::CarlaEngineRtAudio(RtAudio::LINUX_ALSA);
  160. #endif
  161. #ifdef __LINUX_PULSE__
  162. else if (strcmp(driver_name, "PulseAudio") == 0)
  163. carlaEngine = new CarlaBackend::CarlaEngineRtAudio(RtAudio::LINUX_PULSE);
  164. #endif
  165. #ifdef __LINUX_OSS__
  166. else if (strcmp(driver_name, "OSS") == 0)
  167. carlaEngine = new CarlaBackend::CarlaEngineRtAudio(RtAudio::LINUX_OSS);
  168. #endif
  169. #ifdef __UNIX_JACK__
  170. else if (strcmp(driver_name, "JACK (RtAudio)") == 0)
  171. carlaEngine = new CarlaBackend::CarlaEngineRtAudio(RtAudio::UNIX_JACK);
  172. #endif
  173. #ifdef __MACOSX_CORE__
  174. else if (strcmp(driver_name, "CoreAudio") == 0)
  175. carlaEngine = new CarlaBackend::CarlaEngineRtAudio(RtAudio::MACOSX_CORE);
  176. #endif
  177. #ifdef __WINDOWS_ASIO__
  178. else if (strcmp(driver_name, "ASIO") == 0)
  179. carlaEngine = new CarlaBackend::CarlaEngineRtAudio(RtAudio::WINDOWS_ASIO);
  180. #endif
  181. #ifdef __WINDOWS_DS__
  182. else if (strcmp(driver_name, "DirectSound") == 0)
  183. carlaEngine = new CarlaBackend::CarlaEngineRtAudio(RtAudio::WINDOWS_DS);
  184. #endif
  185. #ifdef __RTAUDIO_DUMMY__
  186. else if (strcmp(driver_name, "Dummy") == 0)
  187. carlaEngine = new CarlaBackend::CarlaEngineRtAudio(RtAudio::RTAUDIO_DUMMY);
  188. #endif
  189. #endif
  190. else
  191. {
  192. CarlaBackend::setLastError("The seleted audio driver is not available!");
  193. return false;
  194. }
  195. #ifndef Q_OS_WIN
  196. // TODO: make this an option, put somewhere else
  197. if (! getenv("WINE_RT"))
  198. {
  199. carla_setenv("WINE_RT", "15");
  200. carla_setenv("WINE_SVR_RT", "10");
  201. }
  202. #endif
  203. carlaEngine->setCallback(carlaFunc, nullptr);
  204. bool started = carlaEngine->init(client_name);
  205. if (started)
  206. CarlaBackend::setLastError("no error");
  207. return started;
  208. }
  209. bool engine_close()
  210. {
  211. qDebug("CarlaBackendStandalone::engine_close()");
  212. if (! carlaEngine)
  213. {
  214. CarlaBackend::setLastError("Engine is not started");
  215. return false;
  216. }
  217. bool closed = carlaEngine->close();
  218. carlaEngine->removeAllPlugins();
  219. // cleanup static data
  220. get_plugin_info(0);
  221. get_parameter_info(0, 0);
  222. get_parameter_scalepoint_info(0, 0, 0);
  223. get_chunk_data(0);
  224. //get_parameter_text(0, 0);
  225. get_program_name(0, 0);
  226. get_midi_program_name(0, 0);
  227. get_real_plugin_name(0);
  228. CarlaBackend::resetOptions();
  229. CarlaBackend::setLastError(nullptr);
  230. delete carlaEngine;
  231. carlaEngine = nullptr;
  232. if (extendedLicenseText)
  233. {
  234. free((void*)extendedLicenseText);
  235. extendedLicenseText = nullptr;
  236. }
  237. return closed;
  238. }
  239. bool is_engine_running()
  240. {
  241. qDebug("CarlaBackendStandalone::is_engine_running()");
  242. return carlaEngine && carlaEngine->isRunning();
  243. }
  244. // -------------------------------------------------------------------------------------------------------------------
  245. short add_plugin(CarlaBackend::BinaryType btype, CarlaBackend::PluginType ptype, const char* filename, const char* const name, const char* label, void* extra_stuff)
  246. {
  247. qDebug("CarlaBackendStandalone::add_plugin(%s, %s, \"%s\", \"%s\", \"%s\", %p)", CarlaBackend::BinaryType2str(btype), CarlaBackend::PluginType2str(ptype), filename, name, label, extra_stuff);
  248. return carlaEngine->addPlugin(btype, ptype, filename, name, label, extra_stuff);
  249. }
  250. bool remove_plugin(unsigned short plugin_id)
  251. {
  252. qDebug("CarlaBackendStandalone::remove_plugin(%i)", plugin_id);
  253. return carlaEngine->removePlugin(plugin_id);
  254. }
  255. // -------------------------------------------------------------------------------------------------------------------
  256. const PluginInfo* get_plugin_info(unsigned short plugin_id)
  257. {
  258. qDebug("CarlaBackendStandalone::get_plugin_info(%i)", plugin_id);
  259. static PluginInfo info;
  260. if (info.label)
  261. {
  262. free((void*)info.label);
  263. info.label = nullptr;
  264. }
  265. if (info.maker)
  266. {
  267. free((void*)info.maker);
  268. info.maker = nullptr;
  269. }
  270. if (info.copyright)
  271. {
  272. free((void*)info.copyright);
  273. info.copyright = nullptr;
  274. }
  275. if (! carlaEngine->isRunning())
  276. return &info;
  277. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  278. if (plugin)
  279. {
  280. char buf_str[STR_MAX] = { 0 };
  281. info.type = plugin->type();
  282. info.category = plugin->category();
  283. info.hints = plugin->hints();
  284. info.binary = plugin->filename();
  285. info.name = plugin->name();
  286. info.uniqueId = plugin->uniqueId();
  287. plugin->getLabel(buf_str);
  288. info.label = strdup(buf_str);
  289. plugin->getMaker(buf_str);
  290. info.maker = strdup(buf_str);
  291. plugin->getCopyright(buf_str);
  292. info.copyright = strdup(buf_str);
  293. return &info;
  294. }
  295. qCritical("CarlaBackendStandalone::get_plugin_info(%i) - could not find plugin", plugin_id);
  296. return &info;
  297. }
  298. const PortCountInfo* get_audio_port_count_info(unsigned short plugin_id)
  299. {
  300. qDebug("CarlaBackendStandalone::get_audio_port_count_info(%i)", plugin_id);
  301. static PortCountInfo info;
  302. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  303. if (plugin)
  304. {
  305. info.ins = plugin->audioInCount();
  306. info.outs = plugin->audioOutCount();
  307. info.total = info.ins + info.outs;
  308. return &info;
  309. }
  310. qCritical("CarlaBackendStandalone::get_audio_port_count_info(%i) - could not find plugin", plugin_id);
  311. return &info;
  312. }
  313. const PortCountInfo* get_midi_port_count_info(unsigned short plugin_id)
  314. {
  315. qDebug("CarlaBackendStandalone::get_midi_port_count_info(%i)", plugin_id);
  316. static PortCountInfo info;
  317. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  318. if (plugin)
  319. {
  320. info.ins = plugin->midiInCount();
  321. info.outs = plugin->midiOutCount();
  322. info.total = info.ins + info.outs;
  323. return &info;
  324. }
  325. qCritical("CarlaBackendStandalone::get_midi_port_count_info(%i) - could not find plugin", plugin_id);
  326. return &info;
  327. }
  328. const PortCountInfo* get_parameter_count_info(unsigned short plugin_id)
  329. {
  330. qDebug("CarlaBackendStandalone::get_parameter_port_count_info(%i)", plugin_id);
  331. static PortCountInfo info;
  332. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  333. if (plugin)
  334. {
  335. plugin->getParameterCountInfo(&info.ins, &info.outs, &info.total);
  336. return &info;
  337. }
  338. qCritical("CarlaBackendStandalone::get_parameter_port_count_info(%i) - could not find plugin", plugin_id);
  339. return &info;
  340. }
  341. const ParameterInfo* get_parameter_info(unsigned short plugin_id, uint32_t parameter_id)
  342. {
  343. qDebug("CarlaBackendStandalone::get_parameter_info(%i, %i)", plugin_id, parameter_id);
  344. static ParameterInfo info;
  345. if (info.name)
  346. {
  347. free((void*)info.name);
  348. info.name = nullptr;
  349. }
  350. if (info.symbol)
  351. {
  352. free((void*)info.symbol);
  353. info.symbol = nullptr;
  354. }
  355. if (info.unit)
  356. {
  357. free((void*)info.unit);
  358. info.unit = nullptr;
  359. }
  360. if (! carlaEngine->isRunning())
  361. return &info;
  362. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  363. if (plugin)
  364. {
  365. if (parameter_id < plugin->parameterCount())
  366. {
  367. char buf_str[STR_MAX] = { 0 };
  368. info.scalePointCount = plugin->parameterScalePointCount(parameter_id);
  369. plugin->getParameterName(parameter_id, buf_str);
  370. info.name = strdup(buf_str);
  371. plugin->getParameterSymbol(parameter_id, buf_str);
  372. info.symbol = strdup(buf_str);
  373. plugin->getParameterUnit(parameter_id, buf_str);
  374. info.unit = strdup(buf_str);
  375. }
  376. else
  377. qCritical("CarlaBackendStandalone::get_parameter_info(%i, %i) - parameter_id out of bounds", plugin_id, parameter_id);
  378. return &info;
  379. }
  380. if (carlaEngine->isRunning())
  381. qCritical("CarlaBackendStandalone::get_parameter_info(%i, %i) - could not find plugin", plugin_id, parameter_id);
  382. return &info;
  383. }
  384. const ScalePointInfo* get_parameter_scalepoint_info(unsigned short plugin_id, uint32_t parameter_id, uint32_t scalepoint_id)
  385. {
  386. qDebug("CarlaBackendStandalone::get_parameter_scalepoint_info(%i, %i, %i)", plugin_id, parameter_id, scalepoint_id);
  387. static ScalePointInfo info;
  388. if (info.label)
  389. {
  390. free((void*)info.label);
  391. info.label = nullptr;
  392. }
  393. if (! carlaEngine->isRunning())
  394. return &info;
  395. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  396. if (plugin)
  397. {
  398. if (parameter_id < plugin->parameterCount())
  399. {
  400. if (scalepoint_id < plugin->parameterScalePointCount(parameter_id))
  401. {
  402. char buf_str[STR_MAX] = { 0 };
  403. info.value = plugin->getParameterScalePointValue(parameter_id, scalepoint_id);
  404. plugin->getParameterScalePointLabel(parameter_id, scalepoint_id, buf_str);
  405. info.label = strdup(buf_str);
  406. }
  407. else
  408. qCritical("CarlaBackendStandalone::get_parameter_scalepoint_info(%i, %i, %i) - scalepoint_id out of bounds", plugin_id, parameter_id, scalepoint_id);
  409. }
  410. else
  411. qCritical("CarlaBackendStandalone::get_parameter_scalepoint_info(%i, %i, %i) - parameter_id out of bounds", plugin_id, parameter_id, parameter_id);
  412. return &info;
  413. }
  414. if (carlaEngine->isRunning())
  415. qCritical("CarlaBackendStandalone::get_parameter_scalepoint_info(%i, %i, %i) - could not find plugin", plugin_id, parameter_id, scalepoint_id);
  416. return &info;
  417. }
  418. const GuiInfo* get_gui_info(unsigned short plugin_id)
  419. {
  420. qDebug("CarlaBackendStandalone::get_gui_info(%i)", plugin_id);
  421. static GuiInfo info;
  422. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  423. if (plugin)
  424. {
  425. plugin->getGuiInfo(&info.type, &info.resizable);
  426. return &info;
  427. }
  428. qCritical("CarlaBackendStandalone::get_gui_info(%i) - could not find plugin", plugin_id);
  429. return &info;
  430. }
  431. // -------------------------------------------------------------------------------------------------------------------
  432. const CarlaBackend::ParameterData* get_parameter_data(unsigned short plugin_id, uint32_t parameter_id)
  433. {
  434. qDebug("CarlaBackendStandalone::get_parameter_data(%i, %i)", plugin_id, parameter_id);
  435. static CarlaBackend::ParameterData data;
  436. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  437. if (plugin)
  438. {
  439. if (parameter_id < plugin->parameterCount())
  440. return plugin->parameterData(parameter_id);
  441. qCritical("CarlaBackendStandalone::get_parameter_data(%i, %i) - parameter_id out of bounds", plugin_id, parameter_id);
  442. return &data;
  443. }
  444. qCritical("CarlaBackendStandalone::get_parameter_data(%i, %i) - could not find plugin", plugin_id, parameter_id);
  445. return &data;
  446. }
  447. const CarlaBackend::ParameterRanges* get_parameter_ranges(unsigned short plugin_id, uint32_t parameter_id)
  448. {
  449. qDebug("CarlaBackendStandalone::get_parameter_ranges(%i, %i)", plugin_id, parameter_id);
  450. static CarlaBackend::ParameterRanges ranges;
  451. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  452. if (plugin)
  453. {
  454. if (parameter_id < plugin->parameterCount())
  455. return plugin->parameterRanges(parameter_id);
  456. qCritical("CarlaBackendStandalone::get_parameter_ranges(%i, %i) - parameter_id out of bounds", plugin_id, parameter_id);
  457. return &ranges;
  458. }
  459. qCritical("CarlaBackendStandalone::get_parameter_ranges(%i, %i) - could not find plugin", plugin_id, parameter_id);
  460. return &ranges;
  461. }
  462. const CarlaBackend::midi_program_t* get_midi_program_data(unsigned short plugin_id, uint32_t midi_program_id)
  463. {
  464. qDebug("CarlaBackendStandalone::get_midi_program_data(%i, %i)", plugin_id, midi_program_id);
  465. static CarlaBackend::midi_program_t data;
  466. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  467. if (plugin)
  468. {
  469. if (midi_program_id < plugin->midiProgramCount())
  470. return plugin->midiProgramData(midi_program_id);
  471. qCritical("CarlaBackendStandalone::get_midi_program_data(%i, %i) - midi_program_id out of bounds", plugin_id, midi_program_id);
  472. return &data;
  473. }
  474. qCritical("CarlaBackendStandalone::get_midi_program_data(%i, %i) - could not find plugin", plugin_id, midi_program_id);
  475. return &data;
  476. }
  477. const CarlaBackend::CustomData* get_custom_data(unsigned short plugin_id, uint32_t custom_data_id)
  478. {
  479. qDebug("CarlaBackendStandalone::get_custom_data(%i, %i)", plugin_id, custom_data_id);
  480. static CarlaBackend::CustomData data;
  481. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  482. if (plugin)
  483. {
  484. if (custom_data_id < plugin->customDataCount())
  485. return plugin->customData(custom_data_id);
  486. qCritical("CarlaBackendStandalone::get_custom_data(%i, %i) - custom_data_id out of bounds", plugin_id, custom_data_id);
  487. return &data;
  488. }
  489. qCritical("CarlaBackendStandalone::get_custom_data(%i, %i) - could not find plugin", plugin_id, custom_data_id);
  490. return &data;
  491. }
  492. const char* get_chunk_data(unsigned short plugin_id)
  493. {
  494. qDebug("CarlaBackendStandalone::get_chunk_data(%i)", plugin_id);
  495. static const char* chunk_data = nullptr;
  496. if (chunk_data)
  497. {
  498. free((void*)chunk_data);
  499. chunk_data = nullptr;
  500. }
  501. if (! carlaEngine->isRunning())
  502. return nullptr;
  503. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  504. if (plugin)
  505. {
  506. if (plugin->hints() & CarlaBackend::PLUGIN_USES_CHUNKS)
  507. {
  508. void* data = nullptr;
  509. int32_t data_size = plugin->chunkData(&data);
  510. if (data && data_size >= 4)
  511. {
  512. QByteArray chunk((const char*)data, data_size);
  513. chunk_data = strdup(chunk.toBase64().data());
  514. }
  515. else
  516. qCritical("CarlaBackendStandalone::get_chunk_data(%i) - got invalid chunk data", plugin_id);
  517. }
  518. else
  519. qCritical("CarlaBackendStandalone::get_chunk_data(%i) - plugin does not support chunks", plugin_id);
  520. return chunk_data;
  521. }
  522. if (carlaEngine->isRunning())
  523. qCritical("CarlaBackendStandalone::get_chunk_data(%i) - could not find plugin", plugin_id);
  524. return nullptr;
  525. }
  526. // -------------------------------------------------------------------------------------------------------------------
  527. uint32_t get_parameter_count(unsigned short plugin_id)
  528. {
  529. qDebug("CarlaBackendStandalone::get_parameter_count(%i)", plugin_id);
  530. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  531. if (plugin)
  532. return plugin->parameterCount();
  533. qCritical("CarlaBackendStandalone::get_parameter_count(%i) - could not find plugin", plugin_id);
  534. return 0;
  535. }
  536. uint32_t get_program_count(unsigned short plugin_id)
  537. {
  538. qDebug("CarlaBackendStandalone::get_program_count(%i)", plugin_id);
  539. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  540. if (plugin)
  541. return plugin->programCount();
  542. qCritical("CarlaBackendStandalone::get_program_count(%i) - could not find plugin", plugin_id);
  543. return 0;
  544. }
  545. uint32_t get_midi_program_count(unsigned short plugin_id)
  546. {
  547. qDebug("CarlaBackendStandalone::get_midi_program_count(%i)", plugin_id);
  548. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  549. if (plugin)
  550. return plugin->midiProgramCount();
  551. qCritical("CarlaBackendStandalone::get_midi_program_count(%i) - could not find plugin", plugin_id);
  552. return 0;
  553. }
  554. uint32_t get_custom_data_count(unsigned short plugin_id)
  555. {
  556. qDebug("CarlaBackendStandalone::get_custom_data_count(%i)", plugin_id);
  557. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  558. if (plugin)
  559. return plugin->customDataCount();
  560. qCritical("CarlaBackendStandalone::get_custom_data_count(%i) - could not find plugin", plugin_id);
  561. return 0;
  562. }
  563. // -------------------------------------------------------------------------------------------------------------------
  564. const char* get_parameter_text(unsigned short plugin_id, uint32_t parameter_id)
  565. {
  566. qDebug("CarlaBackendStandalone::get_parameter_text(%i, %i)", plugin_id, parameter_id);
  567. static char buf_text[STR_MAX] = { 0 };
  568. memset(buf_text, 0, sizeof(char)*STR_MAX);
  569. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  570. if (plugin)
  571. {
  572. if (parameter_id < plugin->parameterCount())
  573. {
  574. plugin->getParameterText(parameter_id, buf_text);
  575. return buf_text;
  576. }
  577. qCritical("CarlaBackendStandalone::get_parameter_text(%i, %i) - parameter_id out of bounds", plugin_id, parameter_id);
  578. return nullptr;
  579. }
  580. if (carlaEngine->isRunning())
  581. qCritical("CarlaBackendStandalone::get_parameter_text(%i, %i) - could not find plugin", plugin_id, parameter_id);
  582. return nullptr;
  583. }
  584. const char* get_program_name(unsigned short plugin_id, uint32_t program_id)
  585. {
  586. qDebug("CarlaBackendStandalone::get_program_name(%i, %i)", plugin_id, program_id);
  587. static const char* program_name = nullptr;
  588. if (program_name)
  589. {
  590. free((void*)program_name);
  591. program_name = nullptr;
  592. }
  593. if (! carlaEngine->isRunning())
  594. return nullptr;
  595. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  596. if (plugin)
  597. {
  598. if (program_id < plugin->programCount())
  599. {
  600. char buf_str[STR_MAX] = { 0 };
  601. plugin->getProgramName(program_id, buf_str);
  602. program_name = strdup(buf_str);
  603. return program_name;
  604. }
  605. qCritical("CarlaBackendStandalone::get_program_name(%i, %i) - program_id out of bounds", plugin_id, program_id);
  606. return nullptr;
  607. }
  608. if (carlaEngine->isRunning())
  609. qCritical("CarlaBackendStandalone::get_program_name(%i, %i) - could not find plugin", plugin_id, program_id);
  610. return nullptr;
  611. }
  612. const char* get_midi_program_name(unsigned short plugin_id, uint32_t midi_program_id)
  613. {
  614. qDebug("CarlaBackendStandalone::get_midi_program_name(%i, %i)", plugin_id, midi_program_id);
  615. static const char* midi_program_name = nullptr;
  616. if (midi_program_name)
  617. free((void*)midi_program_name);
  618. midi_program_name = nullptr;
  619. if (! carlaEngine->isRunning())
  620. return nullptr;
  621. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  622. if (plugin)
  623. {
  624. if (midi_program_id < plugin->midiProgramCount())
  625. {
  626. char buf_str[STR_MAX] = { 0 };
  627. plugin->getMidiProgramName(midi_program_id, buf_str);
  628. midi_program_name = strdup(buf_str);
  629. return midi_program_name;
  630. }
  631. qCritical("CarlaBackendStandalone::get_midi_program_name(%i, %i) - program_id out of bounds", plugin_id, midi_program_id);
  632. return nullptr;
  633. }
  634. if (carlaEngine->isRunning())
  635. qCritical("CarlaBackendStandalone::get_midi_program_name(%i, %i) - could not find plugin", plugin_id, midi_program_id);
  636. return nullptr;
  637. }
  638. const char* get_real_plugin_name(unsigned short plugin_id)
  639. {
  640. qDebug("CarlaBackendStandalone::get_real_plugin_name(%i)", plugin_id);
  641. static const char* real_plugin_name = nullptr;
  642. if (real_plugin_name)
  643. {
  644. free((void*)real_plugin_name);
  645. real_plugin_name = nullptr;
  646. }
  647. if (! carlaEngine->isRunning())
  648. return nullptr;
  649. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  650. if (plugin)
  651. {
  652. char buf_str[STR_MAX] = { 0 };
  653. plugin->getRealName(buf_str);
  654. real_plugin_name = strdup(buf_str);
  655. return real_plugin_name;
  656. }
  657. if (carlaEngine->isRunning())
  658. qCritical("CarlaBackendStandalone::get_real_plugin_name(%i) - could not find plugin", plugin_id);
  659. return real_plugin_name;
  660. }
  661. // -------------------------------------------------------------------------------------------------------------------
  662. int32_t get_current_program_index(unsigned short plugin_id)
  663. {
  664. qDebug("CarlaBackendStandalone::get_current_program_index(%i)", plugin_id);
  665. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  666. if (plugin)
  667. return plugin->currentProgram();
  668. qCritical("CarlaBackendStandalone::get_current_program_index(%i) - could not find plugin", plugin_id);
  669. return -1;
  670. }
  671. int32_t get_current_midi_program_index(unsigned short plugin_id)
  672. {
  673. qDebug("CarlaBackendStandalone::get_current_midi_program_index(%i)", plugin_id);
  674. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  675. if (plugin)
  676. return plugin->currentMidiProgram();
  677. qCritical("CarlaBackendStandalone::get_current_midi_program_index(%i) - could not find plugin", plugin_id);
  678. return -1;
  679. }
  680. // -------------------------------------------------------------------------------------------------------------------
  681. double get_default_parameter_value(unsigned short plugin_id, uint32_t parameter_id)
  682. {
  683. qDebug("CarlaBackendStandalone::get_default_parameter_value(%i, %i)", plugin_id, parameter_id);
  684. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  685. if (plugin)
  686. {
  687. if (parameter_id < plugin->parameterCount())
  688. return plugin->parameterRanges(parameter_id)->def;
  689. qCritical("CarlaBackendStandalone::get_default_parameter_value(%i, %i) - parameter_id out of bounds", plugin_id, parameter_id);
  690. return 0.0;
  691. }
  692. qCritical("CarlaBackendStandalone::get_default_parameter_value(%i, %i) - could not find plugin", plugin_id, parameter_id);
  693. return 0.0;
  694. }
  695. double get_current_parameter_value(unsigned short plugin_id, uint32_t parameter_id)
  696. {
  697. qDebug("CarlaBackendStandalone::get_current_parameter_value(%i, %i)", plugin_id, parameter_id);
  698. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  699. if (plugin)
  700. {
  701. if (parameter_id < plugin->parameterCount())
  702. return plugin->getParameterValue(parameter_id);
  703. qCritical("CarlaBackendStandalone::get_current_parameter_value(%i, %i) - parameter_id out of bounds", plugin_id, parameter_id);
  704. return 0.0;
  705. }
  706. qCritical("CarlaBackendStandalone::get_current_parameter_value(%i, %i) - could not find plugin", plugin_id, parameter_id);
  707. return 0.0;
  708. }
  709. // -------------------------------------------------------------------------------------------------------------------
  710. double get_input_peak_value(unsigned short plugin_id, unsigned short port_id)
  711. {
  712. if (plugin_id < CarlaBackend::CarlaEngine::maxPluginNumber() && (port_id == 1 || port_id == 2))
  713. return carlaEngine->getInputPeak(plugin_id, port_id-1);
  714. qCritical("CarlaBackendStandalone::get_input_peak_value(%i, %i) - invalid plugin or port value", plugin_id, port_id);
  715. return 0.0;
  716. }
  717. double get_output_peak_value(unsigned short plugin_id, unsigned short port_id)
  718. {
  719. if (plugin_id < CarlaBackend::CarlaEngine::maxPluginNumber() && (port_id == 1 || port_id == 2))
  720. return carlaEngine->getOutputPeak(plugin_id, port_id-1);
  721. qCritical("CarlaBackendStandalone::get_output_peak_value(%i, %i) - invalid plugin or port value", plugin_id, port_id);
  722. return 0.0;
  723. }
  724. // -------------------------------------------------------------------------------------------------------------------
  725. void set_active(unsigned short plugin_id, bool onoff)
  726. {
  727. qDebug("CarlaBackendStandalone::set_active(%i, %s)", plugin_id, bool2str(onoff));
  728. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  729. if (plugin)
  730. return plugin->setActive(onoff, true, false);
  731. qCritical("CarlaBackendStandalone::set_active(%i, %s) - could not find plugin", plugin_id, bool2str(onoff));
  732. }
  733. void set_drywet(unsigned short plugin_id, double value)
  734. {
  735. qDebug("CarlaBackendStandalone::set_drywet(%i, %g)", plugin_id, value);
  736. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  737. if (plugin)
  738. return plugin->setDryWet(value, true, false);
  739. qCritical("CarlaBackendStandalone::set_drywet(%i, %g) - could not find plugin", plugin_id, value);
  740. }
  741. void set_volume(unsigned short plugin_id, double value)
  742. {
  743. qDebug("CarlaBackendStandalone::set_volume(%i, %g)", plugin_id, value);
  744. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  745. if (plugin)
  746. return plugin->setVolume(value, true, false);
  747. qCritical("CarlaBackendStandalone::set_volume(%i, %g) - could not find plugin", plugin_id, value);
  748. }
  749. void set_balance_left(unsigned short plugin_id, double value)
  750. {
  751. qDebug("CarlaBackendStandalone::set_balance_left(%i, %g)", plugin_id, value);
  752. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  753. if (plugin)
  754. return plugin->setBalanceLeft(value, true, false);
  755. qCritical("CarlaBackendStandalone::set_balance_left(%i, %g) - could not find plugin", plugin_id, value);
  756. }
  757. void set_balance_right(unsigned short plugin_id, double value)
  758. {
  759. qDebug("CarlaBackendStandalone::set_balance_right(%i, %g)", plugin_id, value);
  760. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  761. if (plugin)
  762. return plugin->setBalanceRight(value, true, false);
  763. qCritical("CarlaBackendStandalone::set_balance_right(%i, %g) - could not find plugin", plugin_id, value);
  764. }
  765. // -------------------------------------------------------------------------------------------------------------------
  766. void set_parameter_value(unsigned short plugin_id, uint32_t parameter_id, double value)
  767. {
  768. qDebug("CarlaBackendStandalone::set_parameter_value(%i, %i, %g)", plugin_id, parameter_id, value);
  769. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  770. if (plugin)
  771. {
  772. if (parameter_id < plugin->parameterCount())
  773. return plugin->setParameterValue(parameter_id, value, true, true, false);
  774. qCritical("CarlaBackendStandalone::set_parameter_value(%i, %i, %g) - parameter_id out of bounds", plugin_id, parameter_id, value);
  775. return;
  776. }
  777. qCritical("CarlaBackendStandalone::set_parameter_value(%i, %i, %g) - could not find plugin", plugin_id, parameter_id, value);
  778. }
  779. void set_parameter_midi_channel(unsigned short plugin_id, uint32_t parameter_id, uint8_t channel)
  780. {
  781. qDebug("CarlaBackendStandalone::set_parameter_midi_channel(%i, %i, %i)", plugin_id, parameter_id, channel);
  782. if (channel > 15)
  783. {
  784. qCritical("CarlaBackendStandalone::set_parameter_midi_channel(%i, %i, %i) - invalid channel number", plugin_id, parameter_id, channel);
  785. return;
  786. }
  787. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  788. if (plugin)
  789. {
  790. if (parameter_id < plugin->parameterCount())
  791. return plugin->setParameterMidiChannel(parameter_id, channel, true, false);
  792. qCritical("CarlaBackendStandalone::set_parameter_midi_channel(%i, %i, %i) - parameter_id out of bounds", plugin_id, parameter_id, channel);
  793. return;
  794. }
  795. qCritical("CarlaBackendStandalone::set_parameter_midi_channel(%i, %i, %i) - could not find plugin", plugin_id, parameter_id, channel);
  796. }
  797. void set_parameter_midi_cc(unsigned short plugin_id, uint32_t parameter_id, int16_t cc)
  798. {
  799. qDebug("CarlaBackendStandalone::set_parameter_midi_cc(%i, %i, %i)", plugin_id, parameter_id, cc);
  800. if (cc < -1)
  801. {
  802. cc = -1;
  803. }
  804. else if (cc > 0x5F) // 95
  805. {
  806. qCritical("CarlaBackendStandalone::set_parameter_midi_cc(%i, %i, %i) - invalid cc number", plugin_id, parameter_id, cc);
  807. return;
  808. }
  809. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  810. if (plugin)
  811. {
  812. if (parameter_id < plugin->parameterCount())
  813. return plugin->setParameterMidiCC(parameter_id, cc, true, false);
  814. qCritical("CarlaBackendStandalone::set_parameter_midi_cc(%i, %i, %i) - parameter_id out of bounds", plugin_id, parameter_id, cc);
  815. return;
  816. }
  817. qCritical("CarlaBackendStandalone::set_parameter_midi_cc(%i, %i, %i) - could not find plugin", plugin_id, parameter_id, cc);
  818. }
  819. void set_program(unsigned short plugin_id, uint32_t program_id)
  820. {
  821. qDebug("CarlaBackendStandalone::set_program(%i, %i)", plugin_id, program_id);
  822. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  823. if (plugin)
  824. {
  825. if (program_id < plugin->programCount())
  826. return plugin->setProgram(program_id, true, true, false, true);
  827. qCritical("CarlaBackendStandalone::set_program(%i, %i) - program_id out of bounds", plugin_id, program_id);
  828. return;
  829. }
  830. qCritical("CarlaBackendStandalone::set_program(%i, %i) - could not find plugin", plugin_id, program_id);
  831. }
  832. void set_midi_program(unsigned short plugin_id, uint32_t midi_program_id)
  833. {
  834. qDebug("CarlaBackendStandalone::set_midi_program(%i, %i)", plugin_id, midi_program_id);
  835. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  836. if (plugin)
  837. {
  838. if (midi_program_id < plugin->midiProgramCount())
  839. return plugin->setMidiProgram(midi_program_id, true, true, false, true);
  840. qCritical("CarlaBackendStandalone::set_midi_program(%i, %i) - midi_program_id out of bounds", plugin_id, midi_program_id);
  841. return;
  842. }
  843. qCritical("CarlaBackendStandalone::set_midi_program(%i, %i) - could not find plugin", plugin_id, midi_program_id);
  844. }
  845. // -------------------------------------------------------------------------------------------------------------------
  846. void set_custom_data(unsigned short plugin_id, CarlaBackend::CustomDataType type, const char* key, const char* value)
  847. {
  848. qDebug("CarlaBackendStandalone::set_custom_data(%i, %i, \"%s\", \"%s\")", plugin_id, type, key, value);
  849. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  850. if (plugin)
  851. return plugin->setCustomData(type, key, value, true);
  852. qCritical("CarlaBackendStandalone::set_custom_data(%i, %i, \"%s\", \"%s\") - could not find plugin", plugin_id, type, key, value);
  853. }
  854. void set_chunk_data(unsigned short plugin_id, const char* chunk_data)
  855. {
  856. qDebug("CarlaBackendStandalone::set_chunk_data(%i, \"%s\")", plugin_id, chunk_data);
  857. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  858. if (plugin)
  859. {
  860. if (plugin->hints() & CarlaBackend::PLUGIN_USES_CHUNKS)
  861. return plugin->setChunkData(chunk_data);
  862. qCritical("CarlaBackendStandalone::set_chunk_data(%i, \"%s\") - plugin does not support chunks", plugin_id, chunk_data);
  863. return;
  864. }
  865. qCritical("CarlaBackendStandalone::set_chunk_data(%i, \"%s\") - could not find plugin", plugin_id, chunk_data);
  866. }
  867. void set_gui_container(unsigned short plugin_id, uintptr_t gui_addr)
  868. {
  869. qDebug("CarlaBackendStandalone::set_gui_container(%i, " P_UINTPTR ")", plugin_id, gui_addr);
  870. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  871. if (plugin)
  872. return plugin->setGuiContainer((GuiContainer*)CarlaBackend::getPointer(gui_addr));
  873. qCritical("CarlaBackendStandalone::set_gui_container(%i, " P_UINTPTR ") - could not find plugin", plugin_id, gui_addr);
  874. }
  875. // -------------------------------------------------------------------------------------------------------------------
  876. void show_gui(unsigned short plugin_id, bool yesno)
  877. {
  878. qDebug("CarlaBackendStandalone::show_gui(%i, %s)", plugin_id, bool2str(yesno));
  879. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  880. if (plugin)
  881. return plugin->showGui(yesno);
  882. qCritical("CarlaBackendStandalone::show_gui(%i, %s) - could not find plugin", plugin_id, bool2str(yesno));
  883. }
  884. void idle_guis()
  885. {
  886. carlaEngine->idlePluginGuis();
  887. }
  888. // -------------------------------------------------------------------------------------------------------------------
  889. void send_midi_note(unsigned short plugin_id, uint8_t channel, uint8_t note, uint8_t velocity)
  890. {
  891. qDebug("CarlaBackendStandalone::send_midi_note(%i, %i, %i, %i)", plugin_id, channel, note, velocity);
  892. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  893. if (plugin)
  894. return plugin->sendMidiSingleNote(channel, note, velocity, true, true, false);
  895. qCritical("CarlaBackendStandalone::send_midi_note(%i, %i, %i, %i) - could not find plugin", plugin_id, channel, note, velocity);
  896. }
  897. void prepare_for_save(unsigned short plugin_id)
  898. {
  899. qDebug("CarlaBackendStandalone::prepare_for_save(%i)", plugin_id);
  900. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  901. if (plugin)
  902. return plugin->prepareForSave();
  903. qCritical("CarlaBackendStandalone::prepare_for_save(%i) - could not find plugin", plugin_id);
  904. }
  905. // -------------------------------------------------------------------------------------------------------------------
  906. uint32_t get_buffer_size()
  907. {
  908. qDebug("CarlaBackendStandalone::get_buffer_size()");
  909. return carlaEngine->getBufferSize();
  910. }
  911. double get_sample_rate()
  912. {
  913. qDebug("CarlaBackendStandalone::get_sample_rate()");
  914. return carlaEngine->getSampleRate();
  915. }
  916. // -------------------------------------------------------------------------------------------------------------------
  917. const char* get_last_error()
  918. {
  919. return CarlaBackend::getLastError();
  920. }
  921. const char* get_host_osc_url()
  922. {
  923. qDebug("CarlaBackendStandalone::get_host_osc_url()");
  924. return carlaEngine->getOscServerPathTCP();
  925. }
  926. // -------------------------------------------------------------------------------------------------------------------
  927. void set_callback_function(CarlaBackend::CallbackFunc func)
  928. {
  929. qDebug("CarlaBackendStandalone::set_callback_function(%p)", func);
  930. carlaFunc = func;
  931. if (carlaEngine)
  932. carlaEngine->setCallback(func, nullptr);
  933. }
  934. void set_option(CarlaBackend::OptionsType option, int value, const char* valueStr)
  935. {
  936. qDebug("CarlaBackendStandalone::set_option(%s, %i, \"%s\")", CarlaBackend::OptionsType2str(option), value, valueStr);
  937. CarlaBackend::setOption(option, value, valueStr);
  938. }
  939. // -------------------------------------------------------------------------------------------------------------------
  940. #define NSM_API_VERSION_MAJOR 1
  941. #define NSM_API_VERSION_MINOR 0
  942. class CarlaNSM
  943. {
  944. public:
  945. CarlaNSM()
  946. {
  947. m_controlAddr = nullptr;
  948. m_serverThread = nullptr;
  949. m_isOpened = false;
  950. m_isSaved = false;
  951. }
  952. ~CarlaNSM()
  953. {
  954. if (m_controlAddr)
  955. lo_address_free(m_controlAddr);
  956. if (m_serverThread)
  957. {
  958. lo_server_thread_stop(m_serverThread);
  959. lo_server_thread_del_method(m_serverThread, nullptr, nullptr);
  960. lo_server_thread_free(m_serverThread);
  961. }
  962. }
  963. void announce(const char* const url, const int pid)
  964. {
  965. lo_address addr = lo_address_new_from_url(url);
  966. int proto = lo_address_get_protocol(addr);
  967. if (! m_serverThread)
  968. {
  969. // create new OSC thread
  970. m_serverThread = lo_server_thread_new_with_proto(nullptr, proto, error_handler);
  971. // register message handlers and start OSC thread
  972. lo_server_thread_add_method(m_serverThread, "/reply", "ssss", _announce_handler, this);
  973. lo_server_thread_add_method(m_serverThread, "/nsm/client/open", "sss", _nsm_open_handler, this);
  974. lo_server_thread_add_method(m_serverThread, "/nsm/client/save", "", _nsm_save_handler, this);
  975. lo_server_thread_start(m_serverThread);
  976. }
  977. lo_send_from(addr, lo_server_thread_get_server(m_serverThread), LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
  978. "Carla", ":switch:", "carla", NSM_API_VERSION_MAJOR, NSM_API_VERSION_MINOR, pid);
  979. lo_address_free(addr);
  980. }
  981. void replyOpen()
  982. {
  983. m_isOpened = true;
  984. }
  985. void replySave()
  986. {
  987. m_isSaved = true;
  988. }
  989. protected:
  990. int announce_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
  991. {
  992. qDebug("CarlaNSM::announce_handler(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
  993. m_controlAddr = lo_address_new_from_url(lo_address_get_url(lo_message_get_source(msg)));
  994. const char* const method = &argv[0]->s;
  995. if (strcmp(method, "/nsm/server/announce") == 0 && carlaFunc)
  996. carlaFunc(nullptr, CarlaBackend::CALLBACK_NSM_ANNOUNCE, 0, 0, 0, 0.0);
  997. return 0;
  998. }
  999. int nsm_open_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
  1000. {
  1001. qDebug("CarlaNSM::nsm_open_handler(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
  1002. if (! carlaFunc)
  1003. return 1;
  1004. const char* const projectPath = &argv[0]->s;
  1005. const char* const clientId = &argv[2]->s;
  1006. CarlaBackend::setLastError(clientId);
  1007. carlaFunc(nullptr, CarlaBackend::CALLBACK_NSM_OPEN1, 0, 0, 0, 0.0);
  1008. CarlaBackend::setLastError(projectPath);
  1009. carlaFunc(nullptr, CarlaBackend::CALLBACK_NSM_OPEN2, 0, 0, 0, 0.0);
  1010. for (int i=0; i < 30 && ! m_isOpened; i++)
  1011. carla_msleep(100);
  1012. if (m_controlAddr)
  1013. lo_send_from(m_controlAddr, lo_server_thread_get_server(m_serverThread), LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/open", "OK");
  1014. return 0;
  1015. }
  1016. int nsm_save_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
  1017. {
  1018. qDebug("CarlaNSM::nsm_save_handler(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
  1019. if (! carlaFunc)
  1020. return 1;
  1021. carlaFunc(nullptr, CarlaBackend::CALLBACK_NSM_SAVE, 0, 0, 0, 0.0);
  1022. for (int i=0; i < 30 && ! m_isSaved; i++)
  1023. carla_msleep(100);
  1024. if (m_controlAddr)
  1025. lo_send_from(m_controlAddr, lo_server_thread_get_server(m_serverThread), LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/save", "OK");
  1026. return 0;
  1027. }
  1028. private:
  1029. lo_address m_controlAddr;
  1030. lo_server_thread m_serverThread;
  1031. bool m_isOpened, m_isSaved;
  1032. static int _announce_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg, void* const data)
  1033. {
  1034. CarlaNSM* const _this_ = (CarlaNSM*)data;
  1035. return _this_->announce_handler(path, types, argv, argc, msg);
  1036. }
  1037. static int _nsm_open_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg, void* const data)
  1038. {
  1039. CarlaNSM* const _this_ = (CarlaNSM*)data;
  1040. return _this_->nsm_open_handler(path, types, argv, argc, msg);
  1041. }
  1042. static int _nsm_save_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg, void* const data)
  1043. {
  1044. CarlaNSM* const _this_ = (CarlaNSM*)data;
  1045. return _this_->nsm_save_handler(path, types, argv, argc, msg);
  1046. }
  1047. static void error_handler(const int num, const char* const msg, const char* const path)
  1048. {
  1049. qCritical("CarlaNSM::error_handler(%i, %s, %s)", num, msg, path);
  1050. }
  1051. };
  1052. static CarlaNSM carlaNSM;
  1053. void nsm_announce(const char* url, int pid)
  1054. {
  1055. carlaNSM.announce(url, pid);
  1056. }
  1057. void nsm_reply_open()
  1058. {
  1059. carlaNSM.replyOpen();
  1060. }
  1061. void nsm_reply_save()
  1062. {
  1063. carlaNSM.replySave();
  1064. }
  1065. // -------------------------------------------------------------------------------------------------------------------
  1066. #ifdef QTCREATOR_TEST
  1067. #include <QtGui/QApplication>
  1068. #include <QtGui/QDialog>
  1069. QDialog* vstGui = nullptr;
  1070. void main_callback(void* ptr, CarlaBackend::CallbackType action, unsigned short pluginId, int value1, int value2, double value3)
  1071. {
  1072. switch (action)
  1073. {
  1074. case CarlaBackend::CALLBACK_SHOW_GUI:
  1075. if (vstGui && ! value1)
  1076. vstGui->close();
  1077. break;
  1078. case CarlaBackend::CALLBACK_RESIZE_GUI:
  1079. vstGui->setFixedSize(value1, value2);
  1080. break;
  1081. default:
  1082. break;
  1083. }
  1084. Q_UNUSED(ptr);
  1085. Q_UNUSED(pluginId);
  1086. Q_UNUSED(value3);
  1087. }
  1088. void run_tests_standalone(short idMax)
  1089. {
  1090. for (short id = 0; id <= idMax; id++)
  1091. {
  1092. qDebug("------------------- TEST @%i: non-parameter calls --------------------", id);
  1093. get_plugin_info(id);
  1094. get_audio_port_count_info(id);
  1095. get_midi_port_count_info(id);
  1096. get_parameter_count_info(id);
  1097. get_gui_info(id);
  1098. get_chunk_data(id);
  1099. get_parameter_count(id);
  1100. get_program_count(id);
  1101. get_midi_program_count(id);
  1102. get_custom_data_count(id);
  1103. get_real_plugin_name(id);
  1104. get_current_program_index(id);
  1105. get_current_midi_program_index(id);
  1106. qDebug("------------------- TEST @%i: parameter calls [-1] --------------------", id);
  1107. get_parameter_info(id, -1);
  1108. get_parameter_scalepoint_info(id, -1, -1);
  1109. get_parameter_data(id, -1);
  1110. get_parameter_ranges(id, -1);
  1111. get_midi_program_data(id, -1);
  1112. get_custom_data(id, -1);
  1113. get_parameter_text(id, -1);
  1114. get_program_name(id, -1);
  1115. get_midi_program_name(id, -1);
  1116. get_default_parameter_value(id, -1);
  1117. get_current_parameter_value(id, -1);
  1118. get_input_peak_value(id, -1);
  1119. get_output_peak_value(id, -1);
  1120. qDebug("------------------- TEST @%i: parameter calls [0] --------------------", id);
  1121. get_parameter_info(id, 0);
  1122. get_parameter_scalepoint_info(id, 0, -1);
  1123. get_parameter_scalepoint_info(id, 0, 0);
  1124. get_parameter_data(id, 0);
  1125. get_parameter_ranges(id, 0);
  1126. get_midi_program_data(id, 0);
  1127. get_custom_data(id, 0);
  1128. get_parameter_text(id, 0);
  1129. get_program_name(id, 0);
  1130. get_midi_program_name(id, 0);
  1131. get_default_parameter_value(id, 0);
  1132. get_current_parameter_value(id, 0);
  1133. get_input_peak_value(id, 0);
  1134. get_input_peak_value(id, 1);
  1135. get_input_peak_value(id, 2);
  1136. get_output_peak_value(id, 0);
  1137. get_output_peak_value(id, 1);
  1138. get_output_peak_value(id, 2);
  1139. qDebug("------------------- TEST @%i: set extra data --------------------", id);
  1140. set_custom_data(id, CarlaBackend::CUSTOM_DATA_STRING, "", "");
  1141. set_chunk_data(id, nullptr);
  1142. set_gui_container(id, (uintptr_t)1);
  1143. qDebug("------------------- TEST @%i: gui stuff --------------------", id);
  1144. show_gui(id, false);
  1145. show_gui(id, true);
  1146. show_gui(id, true);
  1147. idle_guis();
  1148. idle_guis();
  1149. idle_guis();
  1150. qDebug("------------------- TEST @%i: other --------------------", id);
  1151. send_midi_note(id, 15, 127, 127);
  1152. send_midi_note(id, 0, 0, 0);
  1153. prepare_for_save(id);
  1154. prepare_for_save(id);
  1155. prepare_for_save(id);
  1156. }
  1157. }
  1158. int main(int argc, char* argv[])
  1159. {
  1160. using namespace CarlaBackend;
  1161. // Qt app
  1162. QApplication app(argc, argv);
  1163. // Qt gui (for vst)
  1164. vstGui = new QDialog(nullptr);
  1165. // set callback and options
  1166. set_callback_function(main_callback);
  1167. set_option(OPTION_PREFER_UI_BRIDGES, 0, nullptr);
  1168. //set_option(OPTION_PROCESS_MODE, PROCESS_MODE_CONTINUOUS_RACK, nullptr);
  1169. // start engine
  1170. if (! engine_init("JACK", "carla_demo"))
  1171. {
  1172. qCritical("failed to start backend engine, reason:\n%s", get_last_error());
  1173. delete vstGui;
  1174. return 1;
  1175. }
  1176. short id_ladspa = add_plugin(BINARY_NATIVE, PLUGIN_LADSPA, "/usr/lib/ladspa/LEET_eqbw2x2.so", "LADSPA plug name, test long name - "
  1177. "------- name ------------ name2 ----------- name3 ------------ name4 ------------ name5 ---------- name6", "leet_equalizer_bw2x2", nullptr);
  1178. short id_dssi = add_plugin(BINARY_NATIVE, PLUGIN_DSSI, "/usr/lib/dssi/fluidsynth-dssi.so", "DSSI pname, short-utf8 _ \xAE", "FluidSynth-DSSI", (void*)"/usr/lib/dssi/fluidsynth-dssi/FluidSynth-DSSI_gtk");
  1179. //short id_lv2 = add_plugin(BINARY_NATIVE, PLUGIN_LV2, "FILENAME", "HAHA name!!!", "http://studionumbersix.com/foo/lv2/yc20", nullptr);
  1180. //short id_vst = add_plugin(BINARY_NATIVE, PLUGIN_LV2, "FILENAME", "HAHA name!!!", "http://studionumbersix.com/foo/lv2/yc20", nullptr);
  1181. if (id_ladspa < 0 || id_dssi < 0)
  1182. {
  1183. qCritical("failed to start load plugins, reason:\n%s", get_last_error());
  1184. delete vstGui;
  1185. return 1;
  1186. }
  1187. //const GuiInfo* const guiInfo = get_gui_info(id);
  1188. //if (guiInfo->type == CarlaBackend::GUI_INTERNAL_QT4 || guiInfo->type == CarlaBackend::GUI_INTERNAL_X11)
  1189. //{
  1190. // set_gui_data(id, 0, (uintptr_t)gui);
  1191. //gui->show();
  1192. //}
  1193. // activate
  1194. set_active(id_ladspa, true);
  1195. set_active(id_dssi, true);
  1196. // start guis
  1197. show_gui(id_dssi, true);
  1198. carla_sleep(1);
  1199. // do tests
  1200. run_tests_standalone(id_dssi+1);
  1201. // lock
  1202. app.exec();
  1203. delete vstGui;
  1204. vstGui = nullptr;
  1205. remove_plugin(id_ladspa);
  1206. remove_plugin(id_dssi);
  1207. engine_close();
  1208. return 0;
  1209. }
  1210. #endif