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.

1526 lines
48KB

  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. // -------------------------------------------------------------------------------------------------------------------
  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_data(unsigned short plugin_id, uintptr_t gui_addr)
  796. {
  797. qDebug("CarlaBackendStandalone::set_gui_data(%i, " P_UINTPTR ")", plugin_id, gui_addr);
  798. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  799. if (plugin)
  800. {
  801. #ifdef __WINE__
  802. plugin->setGuiData((HWND)gui_addr);
  803. #else
  804. plugin->setGuiData((QDialog*)CarlaBackend::getPointer(gui_addr));
  805. #endif
  806. return;
  807. }
  808. qCritical("CarlaBackendStandalone::set_gui_data(%i, " P_UINTPTR ") - could not find plugin", plugin_id, gui_addr);
  809. }
  810. // -------------------------------------------------------------------------------------------------------------------
  811. void show_gui(unsigned short plugin_id, bool yesno)
  812. {
  813. qDebug("CarlaBackendStandalone::show_gui(%i, %s)", plugin_id, bool2str(yesno));
  814. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  815. if (plugin)
  816. return plugin->showGui(yesno);
  817. qCritical("CarlaBackendStandalone::show_gui(%i, %s) - could not find plugin", plugin_id, bool2str(yesno));
  818. }
  819. void idle_guis()
  820. {
  821. carlaEngine->idlePluginGuis();
  822. }
  823. // -------------------------------------------------------------------------------------------------------------------
  824. void send_midi_note(unsigned short plugin_id, uint8_t channel, uint8_t note, uint8_t velocity)
  825. {
  826. qDebug("CarlaBackendStandalone::send_midi_note(%i, %i, %i, %i)", plugin_id, channel, note, velocity);
  827. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  828. if (plugin)
  829. return plugin->sendMidiSingleNote(channel, note, velocity, true, true, false);
  830. qCritical("CarlaBackendStandalone::send_midi_note(%i, %i, %i, %i) - could not find plugin", plugin_id, channel, note, velocity);
  831. }
  832. void prepare_for_save(unsigned short plugin_id)
  833. {
  834. qDebug("CarlaBackendStandalone::prepare_for_save(%i)", plugin_id);
  835. CarlaBackend::CarlaPlugin* const plugin = carlaEngine->getPlugin(plugin_id);
  836. if (plugin)
  837. return plugin->prepareForSave();
  838. qCritical("CarlaBackendStandalone::prepare_for_save(%i) - could not find plugin", plugin_id);
  839. }
  840. // -------------------------------------------------------------------------------------------------------------------
  841. uint32_t get_buffer_size()
  842. {
  843. qDebug("CarlaBackendStandalone::get_buffer_size()");
  844. return carlaEngine->getBufferSize();
  845. }
  846. double get_sample_rate()
  847. {
  848. qDebug("CarlaBackendStandalone::get_sample_rate()");
  849. return carlaEngine->getSampleRate();
  850. }
  851. // -------------------------------------------------------------------------------------------------------------------
  852. const char* get_last_error()
  853. {
  854. return CarlaBackend::getLastError();
  855. }
  856. const char* get_host_osc_url()
  857. {
  858. qDebug("CarlaBackendStandalone::get_host_osc_url()");
  859. return carlaEngine->getOscServerPath();
  860. }
  861. // -------------------------------------------------------------------------------------------------------------------
  862. void set_callback_function(CarlaBackend::CallbackFunc func)
  863. {
  864. qDebug("CarlaBackendStandalone::set_callback_function(%p)", func);
  865. carlaFunc = func;
  866. if (carlaEngine)
  867. carlaEngine->setCallback(func, nullptr);
  868. }
  869. void set_option(CarlaBackend::OptionsType option, int value, const char* valueStr)
  870. {
  871. qDebug("CarlaBackendStandalone::set_option(%s, %i, \"%s\")", CarlaBackend::OptionsType2str(option), value, valueStr);
  872. CarlaBackend::setOption(option, value, valueStr);
  873. }
  874. // -------------------------------------------------------------------------------------------------------------------
  875. #define NSM_API_VERSION_MAJOR 1
  876. #define NSM_API_VERSION_MINOR 0
  877. class CarlaNSM
  878. {
  879. public:
  880. CarlaNSM()
  881. {
  882. m_controlAddr = nullptr;
  883. m_serverThread = nullptr;
  884. m_isOpened = false;
  885. m_isSaved = false;
  886. }
  887. ~CarlaNSM()
  888. {
  889. if (m_controlAddr)
  890. lo_address_free(m_controlAddr);
  891. if (m_serverThread)
  892. {
  893. lo_server_thread_stop(m_serverThread);
  894. lo_server_thread_del_method(m_serverThread, nullptr, nullptr);
  895. lo_server_thread_free(m_serverThread);
  896. }
  897. }
  898. void announce(const char* const url, const int pid)
  899. {
  900. lo_address addr = lo_address_new_from_url(url);
  901. int proto = lo_address_get_protocol(addr);
  902. if (! m_serverThread)
  903. {
  904. // create new OSC thread
  905. m_serverThread = lo_server_thread_new_with_proto(nullptr, proto, error_handler);
  906. // register message handlers and start OSC thread
  907. lo_server_thread_add_method(m_serverThread, "/reply", "ssss", _announce_handler, this);
  908. lo_server_thread_add_method(m_serverThread, "/nsm/client/open", "sss", _nsm_open_handler, this);
  909. lo_server_thread_add_method(m_serverThread, "/nsm/client/save", "", _nsm_save_handler, this);
  910. lo_server_thread_start(m_serverThread);
  911. }
  912. lo_send_from(addr, lo_server_thread_get_server(m_serverThread), LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
  913. "Carla", ":switch:", "carla", NSM_API_VERSION_MAJOR, NSM_API_VERSION_MINOR, pid);
  914. lo_address_free(addr);
  915. }
  916. void replyOpen()
  917. {
  918. m_isOpened = true;
  919. }
  920. void replySave()
  921. {
  922. m_isSaved = true;
  923. }
  924. protected:
  925. int announce_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
  926. {
  927. qDebug("CarlaNSM::announce_handler(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
  928. m_controlAddr = lo_address_new_from_url(lo_address_get_url(lo_message_get_source(msg)));
  929. const char* const method = &argv[0]->s;
  930. if (strcmp(method, "/nsm/server/announce") == 0 && carlaFunc)
  931. carlaFunc(nullptr, CarlaBackend::CALLBACK_NSM_ANNOUNCE, 0, 0, 0, 0.0);
  932. return 0;
  933. }
  934. int nsm_open_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
  935. {
  936. qDebug("CarlaNSM::nsm_open_handler(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
  937. if (! carlaFunc)
  938. return 1;
  939. const char* const projectPath = &argv[0]->s;
  940. const char* const clientId = &argv[2]->s;
  941. CarlaBackend::setLastError(clientId);
  942. carlaFunc(nullptr, CarlaBackend::CALLBACK_NSM_OPEN1, 0, 0, 0, 0.0);
  943. CarlaBackend::setLastError(projectPath);
  944. carlaFunc(nullptr, CarlaBackend::CALLBACK_NSM_OPEN2, 0, 0, 0, 0.0);
  945. for (int i=0; i < 30 && ! m_isOpened; i++)
  946. carla_msleep(100);
  947. if (m_controlAddr)
  948. lo_send_from(m_controlAddr, lo_server_thread_get_server(m_serverThread), LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/open", "OK");
  949. return 0;
  950. }
  951. int nsm_save_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
  952. {
  953. qDebug("CarlaNSM::nsm_save_handler(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
  954. if (! carlaFunc)
  955. return 1;
  956. carlaFunc(nullptr, CarlaBackend::CALLBACK_NSM_SAVE, 0, 0, 0, 0.0);
  957. for (int i=0; i < 30 && ! m_isSaved; i++)
  958. carla_msleep(100);
  959. if (m_controlAddr)
  960. lo_send_from(m_controlAddr, lo_server_thread_get_server(m_serverThread), LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/save", "OK");
  961. return 0;
  962. }
  963. private:
  964. lo_address m_controlAddr;
  965. lo_server_thread m_serverThread;
  966. bool m_isOpened, m_isSaved;
  967. 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)
  968. {
  969. CarlaNSM* const _this_ = (CarlaNSM*)data;
  970. return _this_->announce_handler(path, types, argv, argc, msg);
  971. }
  972. 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)
  973. {
  974. CarlaNSM* const _this_ = (CarlaNSM*)data;
  975. return _this_->nsm_open_handler(path, types, argv, argc, msg);
  976. }
  977. 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)
  978. {
  979. CarlaNSM* const _this_ = (CarlaNSM*)data;
  980. return _this_->nsm_save_handler(path, types, argv, argc, msg);
  981. }
  982. static void error_handler(const int num, const char* const msg, const char* const path)
  983. {
  984. qCritical("CarlaNSM::error_handler(%i, %s, %s)", num, msg, path);
  985. }
  986. };
  987. static CarlaNSM carlaNSM;
  988. void nsm_announce(const char* url, int pid)
  989. {
  990. carlaNSM.announce(url, pid);
  991. }
  992. void nsm_reply_open()
  993. {
  994. carlaNSM.replyOpen();
  995. }
  996. void nsm_reply_save()
  997. {
  998. carlaNSM.replySave();
  999. }
  1000. // -------------------------------------------------------------------------------------------------------------------
  1001. #ifdef QTCREATOR_TEST
  1002. #include <QtGui/QApplication>
  1003. #include <QtGui/QDialog>
  1004. QDialog* vstGui = nullptr;
  1005. void main_callback(void* ptr, CarlaBackend::CallbackType action, unsigned short pluginId, int value1, int value2, double value3)
  1006. {
  1007. switch (action)
  1008. {
  1009. case CarlaBackend::CALLBACK_SHOW_GUI:
  1010. if (vstGui && ! value1)
  1011. vstGui->close();
  1012. break;
  1013. case CarlaBackend::CALLBACK_RESIZE_GUI:
  1014. vstGui->setFixedSize(value1, value2);
  1015. break;
  1016. default:
  1017. break;
  1018. }
  1019. Q_UNUSED(ptr);
  1020. Q_UNUSED(pluginId);
  1021. Q_UNUSED(value3);
  1022. }
  1023. void run_tests_standalone(short idMax)
  1024. {
  1025. for (short id = 0; id <= idMax; id++)
  1026. {
  1027. qDebug("------------------- TEST @%i: non-parameter calls --------------------", id);
  1028. get_plugin_info(id);
  1029. get_audio_port_count_info(id);
  1030. get_midi_port_count_info(id);
  1031. get_parameter_count_info(id);
  1032. get_gui_info(id);
  1033. get_chunk_data(id);
  1034. get_parameter_count(id);
  1035. get_program_count(id);
  1036. get_midi_program_count(id);
  1037. get_custom_data_count(id);
  1038. get_real_plugin_name(id);
  1039. get_current_program_index(id);
  1040. get_current_midi_program_index(id);
  1041. qDebug("------------------- TEST @%i: parameter calls [-1] --------------------", id);
  1042. get_parameter_info(id, -1);
  1043. get_parameter_scalepoint_info(id, -1, -1);
  1044. get_parameter_data(id, -1);
  1045. get_parameter_ranges(id, -1);
  1046. get_midi_program_data(id, -1);
  1047. get_custom_data(id, -1);
  1048. get_parameter_text(id, -1);
  1049. get_program_name(id, -1);
  1050. get_midi_program_name(id, -1);
  1051. get_default_parameter_value(id, -1);
  1052. get_current_parameter_value(id, -1);
  1053. get_input_peak_value(id, -1);
  1054. get_output_peak_value(id, -1);
  1055. qDebug("------------------- TEST @%i: parameter calls [0] --------------------", id);
  1056. get_parameter_info(id, 0);
  1057. get_parameter_scalepoint_info(id, 0, -1);
  1058. get_parameter_scalepoint_info(id, 0, 0);
  1059. get_parameter_data(id, 0);
  1060. get_parameter_ranges(id, 0);
  1061. get_midi_program_data(id, 0);
  1062. get_custom_data(id, 0);
  1063. get_parameter_text(id, 0);
  1064. get_program_name(id, 0);
  1065. get_midi_program_name(id, 0);
  1066. get_default_parameter_value(id, 0);
  1067. get_current_parameter_value(id, 0);
  1068. get_input_peak_value(id, 0);
  1069. get_input_peak_value(id, 1);
  1070. get_input_peak_value(id, 2);
  1071. get_output_peak_value(id, 0);
  1072. get_output_peak_value(id, 1);
  1073. get_output_peak_value(id, 2);
  1074. qDebug("------------------- TEST @%i: set extra data --------------------", id);
  1075. set_custom_data(id, CarlaBackend::CUSTOM_DATA_STRING, "", "");
  1076. set_chunk_data(id, nullptr);
  1077. set_gui_data(id, (uintptr_t)1);
  1078. qDebug("------------------- TEST @%i: gui stuff --------------------", id);
  1079. show_gui(id, false);
  1080. show_gui(id, true);
  1081. show_gui(id, true);
  1082. idle_guis();
  1083. idle_guis();
  1084. idle_guis();
  1085. qDebug("------------------- TEST @%i: other --------------------", id);
  1086. send_midi_note(id, 15, 127, 127);
  1087. send_midi_note(id, 0, 0, 0);
  1088. prepare_for_save(id);
  1089. prepare_for_save(id);
  1090. prepare_for_save(id);
  1091. }
  1092. }
  1093. int main(int argc, char* argv[])
  1094. {
  1095. using namespace CarlaBackend;
  1096. // Qt app
  1097. QApplication app(argc, argv);
  1098. // Qt gui (for vst)
  1099. vstGui = new QDialog(nullptr);
  1100. // set callback and options
  1101. set_callback_function(main_callback);
  1102. set_option(OPTION_PREFER_UI_BRIDGES, 0, nullptr);
  1103. //set_option(OPTION_PROCESS_MODE, PROCESS_MODE_CONTINUOUS_RACK, nullptr);
  1104. // start engine
  1105. if (! engine_init("JACK", "carla_demo"))
  1106. {
  1107. qCritical("failed to start backend engine, reason:\n%s", get_last_error());
  1108. delete vstGui;
  1109. return 1;
  1110. }
  1111. short id_ladspa = add_plugin(BINARY_NATIVE, PLUGIN_LADSPA, "/usr/lib/ladspa/LEET_eqbw2x2.so", "LADSPA plug name, test long name - "
  1112. "------- name ------------ name2 ----------- name3 ------------ name4 ------------ name5 ---------- name6", "leet_equalizer_bw2x2", nullptr);
  1113. 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");
  1114. //short id_lv2 = add_plugin(BINARY_NATIVE, PLUGIN_LV2, "FILENAME", "HAHA name!!!", "http://studionumbersix.com/foo/lv2/yc20", nullptr);
  1115. //short id_vst = add_plugin(BINARY_NATIVE, PLUGIN_LV2, "FILENAME", "HAHA name!!!", "http://studionumbersix.com/foo/lv2/yc20", nullptr);
  1116. if (id_ladspa < 0 || id_dssi < 0)
  1117. {
  1118. qCritical("failed to start load plugins, reason:\n%s", get_last_error());
  1119. delete vstGui;
  1120. return 1;
  1121. }
  1122. //const GuiInfo* const guiInfo = get_gui_info(id);
  1123. //if (guiInfo->type == CarlaBackend::GUI_INTERNAL_QT4 || guiInfo->type == CarlaBackend::GUI_INTERNAL_X11)
  1124. //{
  1125. // set_gui_data(id, 0, (uintptr_t)gui);
  1126. //gui->show();
  1127. //}
  1128. // activate
  1129. set_active(id_ladspa, true);
  1130. set_active(id_dssi, true);
  1131. // start guis
  1132. show_gui(id_dssi, true);
  1133. carla_sleep(1);
  1134. // do tests
  1135. run_tests_standalone(id_dssi+1);
  1136. // lock
  1137. app.exec();
  1138. delete vstGui;
  1139. vstGui = nullptr;
  1140. remove_plugin(id_ladspa);
  1141. remove_plugin(id_dssi);
  1142. engine_close();
  1143. return 0;
  1144. }
  1145. #endif