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.

1519 lines
48KB

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