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.

1553 lines
49KB

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