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.

1524 lines
47KB

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