Audio plugin host https://kx.studio/carla
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.

CarlaStandalone.cpp 78KB

10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305
  1. /*
  2. * Carla Standalone
  3. * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or 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 doc/GPL.txt file.
  16. */
  17. // TODO:
  18. // Check carla_stderr2("Engine is not running"); <= prepend func name and args
  19. #include "CarlaHost.h"
  20. #include "CarlaMIDI.h"
  21. #include "CarlaNative.h"
  22. #include "CarlaEngine.hpp"
  23. #include "CarlaPlugin.hpp"
  24. #include "CarlaBackendUtils.hpp"
  25. #include "CarlaBase64Utils.hpp"
  26. #include "CarlaOscUtils.hpp"
  27. #include "juce_audio_formats.h"
  28. #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
  29. # include "juce_gui_basics.h"
  30. #else
  31. namespace juce {
  32. # include "juce_events/messages/juce_Initialisation.h"
  33. } // namespace juce
  34. #endif
  35. namespace CB = CarlaBackend;
  36. using CB::EngineOptions;
  37. // -------------------------------------------------------------------------------------------------------------------
  38. // Single, standalone engine
  39. struct CarlaBackendStandalone {
  40. CarlaEngine* engine;
  41. EngineCallbackFunc engineCallback;
  42. void* engineCallbackPtr;
  43. EngineOptions engineOptions;
  44. FileCallbackFunc fileCallback;
  45. void* fileCallbackPtr;
  46. CarlaString lastError;
  47. CarlaBackendStandalone()
  48. : engine(nullptr),
  49. engineCallback(nullptr),
  50. engineCallbackPtr(nullptr),
  51. engineOptions(),
  52. fileCallback(nullptr),
  53. fileCallbackPtr(nullptr),
  54. lastError()
  55. {
  56. #ifdef BUILD_BRIDGE
  57. engineOptions.processMode = CB::ENGINE_PROCESS_MODE_BRIDGE;
  58. engineOptions.transportMode = CB::ENGINE_TRANSPORT_MODE_BRIDGE;
  59. engineOptions.forceStereo = false;
  60. engineOptions.preferPluginBridges = false;
  61. engineOptions.preferUiBridges = false;
  62. using juce::File;
  63. File binaryDir(File::getSpecialLocation(File::currentApplicationFile).getParentDirectory());
  64. engineOptions.binaryDir = carla_strdup_safe(binaryDir.getFullPathName().toRawUTF8());
  65. engineOptions.resourceDir = carla_strdup_safe(binaryDir.getChildFile("resources").getFullPathName().toRawUTF8());
  66. #else
  67. if (std::getenv("LADISH_APP_NAME") == nullptr && std::getenv("NSM_URL") == nullptr)
  68. juce::Thread::setCurrentThreadName("Carla");
  69. #endif
  70. }
  71. ~CarlaBackendStandalone()
  72. {
  73. CARLA_SAFE_ASSERT(engine == nullptr);
  74. }
  75. CARLA_PREVENT_HEAP_ALLOCATION
  76. CARLA_DECLARE_NON_COPY_STRUCT(CarlaBackendStandalone)
  77. };
  78. static CarlaBackendStandalone gStandalone;
  79. // -------------------------------------------------------------------------------------------------------------------
  80. // NSM support
  81. #define NSM_API_VERSION_MAJOR 1
  82. #define NSM_API_VERSION_MINOR 2
  83. //#define NSM_CLIENT_FEATURES ":switch:optional-gui:"
  84. #define NSM_CLIENT_FEATURES ":switch:"
  85. class CarlaNSM
  86. {
  87. public:
  88. CarlaNSM() noexcept
  89. : fOscServer(nullptr),
  90. fClientId(),
  91. fProjectPath(),
  92. fHasBroadcast(false),
  93. fHasShowHideUI(false) {}
  94. ~CarlaNSM()
  95. {
  96. if (fOscServer != nullptr)
  97. {
  98. lo_server_del_method(fOscServer, "/reply", "ssss");
  99. lo_server_del_method(fOscServer, "/nsm/client/open", "sss");
  100. lo_server_del_method(fOscServer, "/nsm/client/save", "");
  101. //lo_server_del_method(fOscServer, "/nsm/client/show_optional_gui", "");
  102. //lo_server_del_method(fOscServer, "/nsm/client/hide_optional_gui", "");
  103. lo_server_free(fOscServer);
  104. fOscServer = nullptr;
  105. }
  106. }
  107. void announce(const int pid, const char* const initName)
  108. {
  109. const char* const NSM_URL(std::getenv("NSM_URL"));
  110. if (NSM_URL == nullptr)
  111. return;
  112. const lo_address addr = lo_address_new_from_url(NSM_URL);
  113. if (addr == nullptr)
  114. return;
  115. const int proto = lo_address_get_protocol(addr);
  116. if (fOscServer == nullptr)
  117. {
  118. // create new OSC server
  119. fOscServer = lo_server_new_with_proto(nullptr, proto, _error_handler);
  120. // register message handlers and start OSC thread
  121. lo_server_add_method(fOscServer, "/reply", "ssss", _reply_handler, this);
  122. lo_server_add_method(fOscServer, "/nsm/client/open", "sss", _open_handler, this);
  123. lo_server_add_method(fOscServer, "/nsm/client/save", "", _save_handler, this);
  124. //lo_server_add_method(fOscServer, "/nsm/client/show_optional_gui", "", _show_gui_handler, this);
  125. //lo_server_add_method(fOscServer, "/nsm/client/hide_optional_gui", "", _hide_gui_handler, this);
  126. // /nsm/client/session_is_loaded
  127. }
  128. #ifndef BUILD_ANSI_TEST
  129. lo_send_from(addr, fOscServer, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
  130. "Carla", NSM_CLIENT_FEATURES, initName, NSM_API_VERSION_MAJOR, NSM_API_VERSION_MINOR, pid);
  131. #endif
  132. lo_address_free(addr);
  133. }
  134. void idle() noexcept
  135. {
  136. if (fOscServer == nullptr)
  137. return;
  138. for (;;)
  139. {
  140. try {
  141. if (lo_server_recv_noblock(fOscServer, 0) == 0)
  142. break;
  143. }
  144. CARLA_SAFE_EXCEPTION_CONTINUE("NSM OSC idle")
  145. }
  146. }
  147. protected:
  148. int handleReply(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
  149. {
  150. carla_debug("CarlaNSM::handleReply(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
  151. const char* const method = &argv[0]->s;
  152. const char* const message = &argv[1]->s;
  153. const char* const smName = &argv[2]->s;
  154. const char* const features = &argv[3]->s;
  155. CARLA_SAFE_ASSERT_RETURN(std::strcmp(method, "/nsm/server/announce") == 0, 0);
  156. fHasBroadcast = std::strstr(features, ":broadcast:") != nullptr;
  157. fHasShowHideUI = std::strstr(features, ":optional-gui:") != nullptr;
  158. carla_stdout("'%s' started: %s", smName, message);
  159. // TODO: send callback, disable open+save etc
  160. return 0;
  161. #ifndef DEBUG
  162. // unused
  163. (void)path; (void)types; (void)argc; (void)msg;
  164. #endif
  165. }
  166. int handleOpen(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
  167. {
  168. CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 0);
  169. carla_debug("CarlaNSM::handleOpen(\"%s\", \"%s\", %p, %i, %p)", path, types, argv, argc, msg);
  170. const char* const projectPath = &argv[0]->s;
  171. //const char* const displayName = &argv[1]->s;
  172. const char* const clientId = &argv[2]->s;
  173. if (! carla_is_engine_running())
  174. {
  175. gStandalone.engineOptions.processMode = CB::ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS;
  176. gStandalone.engineOptions.transportMode = CB::ENGINE_TRANSPORT_MODE_JACK;
  177. carla_engine_init("JACK", clientId);
  178. }
  179. else
  180. {
  181. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  182. for (uint i=0, count=gStandalone.engine->getCurrentPluginCount(); i < count; ++i)
  183. gStandalone.engine->removePlugin(i);
  184. }
  185. fClientId = clientId;
  186. fProjectPath = projectPath;
  187. fProjectPath += ".carxp";
  188. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  189. if (juce::File(fProjectPath.buffer()).existsAsFile())
  190. gStandalone.engine->loadProject(fProjectPath);
  191. #ifndef BUILD_ANSI_TEST
  192. lo_send_from(lo_message_get_source(msg), fOscServer, LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/open", "OK");
  193. #endif
  194. #if 0
  195. if (fHasBroadcast)
  196. {
  197. char* const url = lo_server_get_url(fOscServer);
  198. lo_send(lo_message_get_source(msg), "/nsm/server/broadcast", "sssss",
  199. "/non/hello", url, "Carla", CARLA_VERSION_STRING, clientId);
  200. //lo_send_from(lo_message_get_source(msg), fOscServer, LO_TT_IMMEDIATE, "/nsm/server/broadcast", "sssss"
  201. // "/non/hello", url, "Carla", CARLA_VERSION_STRING, clientId);
  202. lo_send(lo_message_get_source(msg), "/signal/created", "ssfff", "/path/somewhere", true ? "in" : "out", 0.0f, 1.0f, 0.5f);
  203. std::free(url);
  204. carla_stdout("Broadcast sent!");
  205. }
  206. else
  207. carla_stdout("Broadcast NOT NOT NOT sent!");
  208. #endif
  209. return 0;
  210. #ifndef DEBUG
  211. // unused
  212. (void)path; (void)types; (void)argc; (void)msg;
  213. #endif
  214. }
  215. int handleSave(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
  216. {
  217. CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 0);
  218. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  219. CARLA_SAFE_ASSERT_RETURN(fProjectPath.isNotEmpty(), 0);
  220. carla_debug("CarlaNSM::handleSave(\"%s\", \"%s\", %p, %i, %p)", path, types, argv, argc, msg);
  221. gStandalone.engine->saveProject(fProjectPath);
  222. #ifndef BUILD_ANSI_TEST
  223. lo_send_from(lo_message_get_source(msg), fOscServer, LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/save", "OK");
  224. #endif
  225. return 0;
  226. #ifndef DEBUG
  227. // unused
  228. (void)path; (void)types; (void)argv; (void)argc; (void)msg;
  229. #endif
  230. }
  231. #if 0
  232. int handleShowHideGui(const lo_message msg, const bool show)
  233. {
  234. CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 0);
  235. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  236. //CARLA_SAFE_ASSERT_RETURN(gStandalone.frontendWinId != 0, 0);
  237. carla_debug("CarlaNSM::handleShowHideGui(%s)", bool2str(show));
  238. #ifndef BUILD_ANSI_TEST
  239. lo_send_from(lo_message_get_source(msg), fOscServer, LO_TT_IMMEDIATE, show ? "/nsm/client/gui_is_shown" : "/nsm/client/gui_is_hidden", "");
  240. #endif
  241. return 0;
  242. }
  243. #endif
  244. private:
  245. lo_server fOscServer;
  246. CarlaString fClientId;
  247. CarlaString fProjectPath;
  248. bool fHasBroadcast;
  249. bool fHasShowHideUI;
  250. #define handlePtr ((CarlaNSM*)data)
  251. static void _error_handler(int num, const char* msg, const char* path)
  252. {
  253. carla_stderr2("CarlaNSM::_error_handler(%i, \"%s\", \"%s\")", num, msg, path);
  254. }
  255. static int _reply_handler(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* data)
  256. {
  257. return handlePtr->handleReply(path, types, argv, argc, msg);
  258. }
  259. static int _open_handler(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* data)
  260. {
  261. return handlePtr->handleOpen(path, types, argv, argc, msg);
  262. }
  263. static int _save_handler(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* data)
  264. {
  265. return handlePtr->handleSave(path, types, argv, argc, msg);
  266. }
  267. #if 0
  268. static int _show_gui_handler(const char*, const char*, lo_arg**, int, lo_message, void* data)
  269. {
  270. return handlePtr->handleShowHideGui(true);
  271. }
  272. static int _hide_gui_handler(const char*, const char*, lo_arg**, int, lo_message, void* data)
  273. {
  274. return handlePtr->handleShowHideGui(false);
  275. }
  276. #endif
  277. #undef handlePtr
  278. CARLA_PREVENT_HEAP_ALLOCATION
  279. CARLA_DECLARE_NON_COPY_CLASS(CarlaNSM)
  280. };
  281. static CarlaNSM gNSM;
  282. // -------------------------------------------------------------------------------------------------------------------
  283. // Always return a valid string ptr
  284. static const char* const gNullCharPtr = "";
  285. static void checkStringPtr(const char*& charPtr) noexcept
  286. {
  287. if (charPtr == nullptr)
  288. charPtr = gNullCharPtr;
  289. }
  290. // -------------------------------------------------------------------------------------------------------------------
  291. // Constructors
  292. _CarlaPluginInfo::_CarlaPluginInfo() noexcept
  293. : type(CB::PLUGIN_NONE),
  294. category(CB::PLUGIN_CATEGORY_NONE),
  295. hints(0x0),
  296. optionsAvailable(0x0),
  297. optionsEnabled(0x0),
  298. filename(gNullCharPtr),
  299. name(gNullCharPtr),
  300. label(gNullCharPtr),
  301. maker(gNullCharPtr),
  302. copyright(gNullCharPtr),
  303. iconName(gNullCharPtr),
  304. uniqueId(0) {}
  305. _CarlaPluginInfo::~_CarlaPluginInfo() noexcept
  306. {
  307. if (label != gNullCharPtr)
  308. delete[] label;
  309. if (maker != gNullCharPtr)
  310. delete[] maker;
  311. if (copyright != gNullCharPtr)
  312. delete[] copyright;
  313. }
  314. _CarlaNativePluginInfo::_CarlaNativePluginInfo() noexcept
  315. : category(CB::PLUGIN_CATEGORY_NONE),
  316. hints(0x0),
  317. audioIns(0),
  318. audioOuts(0),
  319. midiIns(0),
  320. midiOuts(0),
  321. parameterIns(0),
  322. parameterOuts(0),
  323. name(gNullCharPtr),
  324. label(gNullCharPtr),
  325. maker(gNullCharPtr),
  326. copyright(gNullCharPtr) {}
  327. _CarlaParameterInfo::_CarlaParameterInfo() noexcept
  328. : name(gNullCharPtr),
  329. symbol(gNullCharPtr),
  330. unit(gNullCharPtr),
  331. scalePointCount(0) {}
  332. _CarlaParameterInfo::~_CarlaParameterInfo() noexcept
  333. {
  334. if (name != gNullCharPtr)
  335. delete[] name;
  336. if (symbol != gNullCharPtr)
  337. delete[] symbol;
  338. if (unit != gNullCharPtr)
  339. delete[] unit;
  340. }
  341. _CarlaScalePointInfo::_CarlaScalePointInfo() noexcept
  342. : value(0.0f),
  343. label(gNullCharPtr) {}
  344. _CarlaScalePointInfo::~_CarlaScalePointInfo() noexcept
  345. {
  346. if (label != gNullCharPtr)
  347. delete[] label;
  348. }
  349. _CarlaTransportInfo::_CarlaTransportInfo() noexcept
  350. : playing(false),
  351. frame(0),
  352. bar(0),
  353. beat(0),
  354. tick(0),
  355. bpm(0.0) {}
  356. // -------------------------------------------------------------------------------------------------------------------
  357. // API
  358. const char* carla_get_complete_license_text()
  359. {
  360. carla_debug("carla_get_complete_license_text()");
  361. static CarlaString retText;
  362. if (retText.isEmpty())
  363. {
  364. CarlaString text1, text2, text3, text4, text5;
  365. text1 += "<p>This current Carla build is using the following features and 3rd-party code:</p>";
  366. text1 += "<ul>";
  367. // Plugin formats
  368. text2 += "<li>LADSPA plugin support, http://www.ladspa.org/</li>";
  369. text2 += "<li>DSSI plugin support, http://dssi.sourceforge.net/</li>";
  370. text2 += "<li>LV2 plugin support, http://lv2plug.in/</li>";
  371. #ifdef VESTIGE_HEADER
  372. text2 += "<li>VST plugin support, using VeSTige header by Javier Serrano Polo</li>";
  373. #else
  374. text2 += "<li>VST plugin support, using official VST SDK 2.4 (trademark of Steinberg Media Technologies GmbH)</li>";
  375. #endif
  376. #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
  377. text2 += "<li>VST3 plugin support, using official VST SDK 3.6 (trademark of Steinberg Media Technologies GmbH)</li>";
  378. #endif
  379. #ifdef CARLA_OS_MAC
  380. text2 += "<li>AU plugin support</li>";
  381. #endif
  382. // Sample kit libraries
  383. #ifdef HAVE_FLUIDSYNTH
  384. text2 += "<li>FluidSynth library for SF2 support, http://www.fluidsynth.org/</li>";
  385. #endif
  386. #ifdef HAVE_LINUXSAMPLER
  387. text2 += "<li>LinuxSampler library for GIG and SFZ support*, http://www.linuxsampler.org/</li>";
  388. #endif
  389. // Internal plugins
  390. text3 += "<li>NekoFilter plugin code, based on lv2fil by Nedko Arnaudov and Fons Adriaensen</li>";
  391. #ifdef WANT_ZYNADDSUBFX
  392. text3 += "<li>ZynAddSubFX plugin code, http://zynaddsubfx.sf.net/</li>";
  393. # ifdef WANT_ZYNADDSUBFX_UI
  394. text3 += "<li>ZynAddSubFX UI using NTK, http://non.tuxfamily.org/wiki/NTK</li>";
  395. # endif
  396. #endif
  397. // misc libs
  398. text4 += "<li>liblo library for OSC support, http://liblo.sourceforge.net/</li>";
  399. text4 += "<li>serd, sord, sratom and lilv libraries for LV2 discovery, http://drobilla.net/software/lilv/</li>";
  400. #if ! (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN))
  401. text4 += "<li>RtAudio+RtMidi libraries for extra Audio and MIDI support, http://www.music.mcgill.ca/~gary/rtaudio/</li>";
  402. #endif
  403. // end
  404. text5 += "</ul>";
  405. #ifdef HAVE_LINUXSAMPLER
  406. // LinuxSampler GPL exception
  407. text5 += "<p>(*) Using LinuxSampler code in commercial hardware or software products is not allowed without prior written authorization by the authors.</p>";
  408. #endif
  409. retText = text1 + text2 + text3 + text4 + text5;
  410. }
  411. return retText;
  412. }
  413. const char* carla_get_juce_version()
  414. {
  415. carla_debug("carla_get_juce_version()");
  416. static CarlaString retVersion;
  417. if (retVersion.isEmpty())
  418. {
  419. if (const char* const version = juce::SystemStats::getJUCEVersion().toRawUTF8())
  420. retVersion = version+6;
  421. else
  422. retVersion = "3.0";
  423. }
  424. return retVersion;
  425. }
  426. const char* carla_get_supported_file_extensions()
  427. {
  428. carla_debug("carla_get_supported_file_extensions()");
  429. static CarlaString retText;
  430. if (retText.isEmpty())
  431. {
  432. // Base types
  433. retText += "*.carxp;*.carxs";
  434. // Sample kits
  435. #ifdef HAVE_FLUIDSYNTH
  436. retText += ";*.sf2";
  437. #endif
  438. #ifdef HAVE_LINUXSAMPLER
  439. retText += ";*.gig;*.sfz";
  440. #endif
  441. #ifndef BUILD_BRIDGE
  442. // Audio files
  443. {
  444. using namespace juce;
  445. AudioFormatManager afm;
  446. afm.registerBasicFormats();
  447. for (AudioFormat **it=afm.begin(), **end=afm.end(); it != end; ++it)
  448. {
  449. const StringArray& exts((*it)->getFileExtensions());
  450. for (String *eit=exts.begin(), *eend=exts.end(); eit != eend; ++eit)
  451. retText += String(";*" + (*eit)).toRawUTF8();
  452. }
  453. }
  454. #endif
  455. // MIDI files
  456. retText += ";*.mid;*.midi";
  457. // Plugin presets
  458. #ifdef WANT_ZYNADDSUBFX
  459. retText += ";*.xmz;*.xiz";
  460. #endif
  461. }
  462. return retText;
  463. }
  464. // -------------------------------------------------------------------------------------------------------------------
  465. uint carla_get_engine_driver_count()
  466. {
  467. carla_debug("carla_get_engine_driver_count()");
  468. return CarlaEngine::getDriverCount();
  469. }
  470. const char* carla_get_engine_driver_name(uint index)
  471. {
  472. carla_debug("carla_get_engine_driver_name(%i)", index);
  473. return CarlaEngine::getDriverName(index);
  474. }
  475. const char* const* carla_get_engine_driver_device_names(uint index)
  476. {
  477. carla_debug("carla_get_engine_driver_device_names(%i)", index);
  478. return CarlaEngine::getDriverDeviceNames(index);
  479. }
  480. const EngineDriverDeviceInfo* carla_get_engine_driver_device_info(uint index, const char* name)
  481. {
  482. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr);
  483. carla_debug("carla_get_engine_driver_device_info(%i, \"%s\")", index, name);
  484. if (const EngineDriverDeviceInfo* const ret = CarlaEngine::getDriverDeviceInfo(index, name))
  485. {
  486. static EngineDriverDeviceInfo devInfo;
  487. static const uint32_t nullBufferSizes[] = { 0 };
  488. static const double nullSampleRates[] = { 0.0 };
  489. devInfo.hints = ret->hints;
  490. devInfo.bufferSizes = (ret->bufferSizes != nullptr) ? ret->bufferSizes : nullBufferSizes;
  491. devInfo.sampleRates = (ret->sampleRates != nullptr) ? ret->sampleRates : nullSampleRates;
  492. return &devInfo;
  493. }
  494. return nullptr;
  495. }
  496. #ifndef BUILD_BRIDGE
  497. // -------------------------------------------------------------------------------------------------------------------
  498. uint carla_get_internal_plugin_count()
  499. {
  500. carla_debug("carla_get_internal_plugin_count()");
  501. return static_cast<uint>(CarlaPlugin::getNativePluginCount());
  502. }
  503. const CarlaNativePluginInfo* carla_get_internal_plugin_info(uint index)
  504. {
  505. carla_debug("carla_get_internal_plugin_info(%i)", index);
  506. static CarlaNativePluginInfo info;
  507. const NativePluginDescriptor* const nativePlugin(CarlaPlugin::getNativePluginDescriptor(index));
  508. // as internal plugin, this must never fail
  509. CARLA_SAFE_ASSERT_RETURN(nativePlugin != nullptr, nullptr);
  510. info.category = static_cast<CB::PluginCategory>(nativePlugin->category);
  511. info.hints = 0x0;
  512. if (nativePlugin->hints & ::PLUGIN_IS_RTSAFE)
  513. info.hints |= CB::PLUGIN_IS_RTSAFE;
  514. if (nativePlugin->hints & ::PLUGIN_IS_SYNTH)
  515. info.hints |= CB::PLUGIN_IS_SYNTH;
  516. if (nativePlugin->hints & ::PLUGIN_HAS_UI)
  517. info.hints |= CB::PLUGIN_HAS_CUSTOM_UI;
  518. if (nativePlugin->hints & ::PLUGIN_NEEDS_FIXED_BUFFERS)
  519. info.hints |= CB::PLUGIN_NEEDS_FIXED_BUFFERS;
  520. if (nativePlugin->hints & ::PLUGIN_NEEDS_SINGLE_THREAD)
  521. info.hints |= CB::PLUGIN_NEEDS_SINGLE_THREAD;
  522. info.audioIns = nativePlugin->audioIns;
  523. info.audioOuts = nativePlugin->audioOuts;
  524. info.midiIns = nativePlugin->midiIns;
  525. info.midiOuts = nativePlugin->midiOuts;
  526. info.parameterIns = nativePlugin->paramIns;
  527. info.parameterOuts = nativePlugin->paramOuts;
  528. info.name = nativePlugin->name;
  529. info.label = nativePlugin->label;
  530. info.maker = nativePlugin->maker;
  531. info.copyright = nativePlugin->copyright;
  532. checkStringPtr(info.name);
  533. checkStringPtr(info.label);
  534. checkStringPtr(info.maker);
  535. checkStringPtr(info.copyright);
  536. return &info;
  537. }
  538. #endif
  539. // -------------------------------------------------------------------------------------------------------------------
  540. const CarlaEngine* carla_get_engine()
  541. {
  542. carla_debug("carla_get_engine()");
  543. return gStandalone.engine;
  544. }
  545. // -------------------------------------------------------------------------------------------------------------------
  546. bool carla_engine_init(const char* driverName, const char* clientName)
  547. {
  548. CARLA_SAFE_ASSERT_RETURN(driverName != nullptr && driverName[0] != '\0', false);
  549. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
  550. carla_debug("carla_engine_init(\"%s\", \"%s\")", driverName, clientName);
  551. if (gStandalone.engine != nullptr)
  552. {
  553. carla_stderr2("Engine is already running");
  554. gStandalone.lastError = "Engine is already running";
  555. return false;
  556. }
  557. #ifdef CARLA_OS_WIN
  558. carla_setenv("WINEASIO_CLIENT_NAME", clientName);
  559. #endif
  560. // TODO: make this an option, put somewhere else
  561. if (std::getenv("WINE_RT") == nullptr)
  562. {
  563. carla_setenv("WINE_RT", "15");
  564. carla_setenv("WINE_SVR_RT", "10");
  565. }
  566. gStandalone.engine = CarlaEngine::newDriverByName(driverName);
  567. if (gStandalone.engine == nullptr)
  568. {
  569. carla_stderr2("The seleted audio driver is not available");
  570. gStandalone.lastError = "The seleted audio driver is not available";
  571. return false;
  572. }
  573. gStandalone.engine->setCallback(gStandalone.engineCallback, gStandalone.engineCallbackPtr);
  574. gStandalone.engine->setFileCallback(gStandalone.fileCallback, gStandalone.fileCallbackPtr);
  575. #ifdef BUILD_BRIDGE
  576. gStandalone.engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, nullptr);
  577. gStandalone.engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, CB::ENGINE_TRANSPORT_MODE_JACK, nullptr);
  578. #else
  579. gStandalone.engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, static_cast<int>(gStandalone.engineOptions.processMode), nullptr);
  580. gStandalone.engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, static_cast<int>(gStandalone.engineOptions.transportMode), nullptr);
  581. #endif
  582. gStandalone.engine->setOption(CB::ENGINE_OPTION_FORCE_STEREO, gStandalone.engineOptions.forceStereo ? 1 : 0, nullptr);
  583. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, gStandalone.engineOptions.preferPluginBridges ? 1 : 0, nullptr);
  584. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_UI_BRIDGES, gStandalone.engineOptions.preferUiBridges ? 1 : 0, nullptr);
  585. gStandalone.engine->setOption(CB::ENGINE_OPTION_UIS_ALWAYS_ON_TOP, gStandalone.engineOptions.uisAlwaysOnTop ? 1 : 0, nullptr);
  586. gStandalone.engine->setOption(CB::ENGINE_OPTION_MAX_PARAMETERS, static_cast<int>(gStandalone.engineOptions.maxParameters), nullptr);
  587. gStandalone.engine->setOption(CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT, static_cast<int>(gStandalone.engineOptions.uiBridgesTimeout), nullptr);
  588. gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_NUM_PERIODS, static_cast<int>(gStandalone.engineOptions.audioNumPeriods), nullptr);
  589. gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_BUFFER_SIZE, static_cast<int>(gStandalone.engineOptions.audioBufferSize), nullptr);
  590. gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_SAMPLE_RATE, static_cast<int>(gStandalone.engineOptions.audioSampleRate), nullptr);
  591. if (gStandalone.engineOptions.audioDevice != nullptr)
  592. gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_DEVICE, 0, gStandalone.engineOptions.audioDevice);
  593. if (gStandalone.engineOptions.binaryDir != nullptr && gStandalone.engineOptions.binaryDir[0] != '\0')
  594. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, gStandalone.engineOptions.binaryDir);
  595. if (gStandalone.engineOptions.resourceDir != nullptr && gStandalone.engineOptions.resourceDir[0] != '\0')
  596. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, gStandalone.engineOptions.resourceDir);
  597. if (gStandalone.engineOptions.frontendWinId != 0)
  598. {
  599. char strBuf[STR_MAX+1];
  600. std::sprintf(strBuf, P_UINTPTR, gStandalone.engineOptions.frontendWinId);
  601. gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, strBuf);
  602. }
  603. else
  604. gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0");
  605. if (gStandalone.engine->init(clientName))
  606. {
  607. #ifndef BUILD_BRIDGE
  608. juce::initialiseJuce_GUI();
  609. #endif
  610. gStandalone.lastError = "No error";
  611. return true;
  612. }
  613. else
  614. {
  615. gStandalone.lastError = gStandalone.engine->getLastError();
  616. delete gStandalone.engine;
  617. gStandalone.engine = nullptr;
  618. return false;
  619. }
  620. }
  621. #ifdef BUILD_BRIDGE
  622. bool carla_engine_init_bridge(const char audioBaseName[6+1], const char rtBaseName[6+1], const char nonRtBaseName[6+1], const char* clientName)
  623. {
  624. CARLA_SAFE_ASSERT_RETURN(audioBaseName != nullptr && audioBaseName[0] != '\0', false);
  625. CARLA_SAFE_ASSERT_RETURN(rtBaseName != nullptr && rtBaseName[0] != '\0', false);
  626. CARLA_SAFE_ASSERT_RETURN(nonRtBaseName != nullptr && nonRtBaseName[0] != '\0', false);
  627. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
  628. carla_debug("carla_engine_init_bridge(\"%s\", \"%s\", \"%s\", \"%s\")", audioBaseName, rtBaseName, nonRtBaseName, clientName);
  629. if (gStandalone.engine != nullptr)
  630. {
  631. carla_stderr2("Engine is already running");
  632. gStandalone.lastError = "Engine is already running";
  633. return false;
  634. }
  635. gStandalone.engine = CarlaEngine::newBridge(audioBaseName, rtBaseName, nonRtBaseName);
  636. if (gStandalone.engine == nullptr)
  637. {
  638. carla_stderr2("The seleted audio driver is not available!");
  639. gStandalone.lastError = "The seleted audio driver is not available!";
  640. return false;
  641. }
  642. gStandalone.engine->setCallback(gStandalone.engineCallback, gStandalone.engineCallbackPtr);
  643. gStandalone.engine->setFileCallback(gStandalone.fileCallback, gStandalone.fileCallbackPtr);
  644. // forced options for bridge mode
  645. gStandalone.engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_BRIDGE, nullptr);
  646. gStandalone.engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, CB::ENGINE_TRANSPORT_MODE_BRIDGE, nullptr);
  647. gStandalone.engine->setOption(CB::ENGINE_OPTION_FORCE_STEREO, false, nullptr);
  648. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, false, nullptr);
  649. gStandalone.engine->setOption(CB::ENGINE_OPTION_PREFER_UI_BRIDGES, false, nullptr);
  650. if (const char* const uisAlwaysOnTop = std::getenv("ENGINE_OPTION_UIS_ALWAYS_ON_TOP"))
  651. gStandalone.engine->setOption(CB::ENGINE_OPTION_UIS_ALWAYS_ON_TOP, (std::strcmp(uisAlwaysOnTop, "true") == 0) ? 1 : 0, nullptr);
  652. if (const char* const maxParameters = std::getenv("ENGINE_OPTION_MAX_PARAMETERS"))
  653. gStandalone.engine->setOption(CB::ENGINE_OPTION_MAX_PARAMETERS, std::atoi(maxParameters), nullptr);
  654. if (const char* const uiBridgesTimeout = std::getenv("ENGINE_OPTION_UI_BRIDGES_TIMEOUT"))
  655. gStandalone.engine->setOption(CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT, std::atoi(uiBridgesTimeout), nullptr);
  656. if (const char* const binaryDir = std::getenv("ENGINE_OPTION_PATH_BINARIES"))
  657. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, binaryDir);
  658. if (const char* const resourceDir = std::getenv("ENGINE_OPTION_PATH_RESOURCES"))
  659. gStandalone.engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, resourceDir);
  660. if (const char* const frontendWinId = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID"))
  661. gStandalone.engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, frontendWinId);
  662. if (gStandalone.engine->init(clientName))
  663. {
  664. gStandalone.lastError = "No error";
  665. return true;
  666. }
  667. else
  668. {
  669. gStandalone.lastError = gStandalone.engine->getLastError();
  670. delete gStandalone.engine;
  671. gStandalone.engine = nullptr;
  672. return false;
  673. }
  674. }
  675. #endif
  676. bool carla_engine_close()
  677. {
  678. carla_debug("carla_engine_close()");
  679. if (gStandalone.engine == nullptr)
  680. {
  681. carla_stderr2("Engine is not running");
  682. gStandalone.lastError = "Engine is not running";
  683. return false;
  684. }
  685. gStandalone.engine->setAboutToClose();
  686. gStandalone.engine->removeAllPlugins();
  687. const bool closed(gStandalone.engine->close());
  688. if (! closed)
  689. gStandalone.lastError = gStandalone.engine->getLastError();
  690. #ifndef BUILD_BRIDGE
  691. juce::shutdownJuce_GUI();
  692. #endif
  693. delete gStandalone.engine;
  694. gStandalone.engine = nullptr;
  695. return closed;
  696. }
  697. void carla_engine_idle()
  698. {
  699. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  700. gNSM.idle();
  701. gStandalone.engine->idle();
  702. }
  703. bool carla_is_engine_running()
  704. {
  705. return (gStandalone.engine != nullptr && gStandalone.engine->isRunning());
  706. }
  707. void carla_set_engine_about_to_close()
  708. {
  709. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  710. carla_debug("carla_set_engine_about_to_close()");
  711. gStandalone.engine->setAboutToClose();
  712. }
  713. void carla_set_engine_callback(EngineCallbackFunc func, void* ptr)
  714. {
  715. carla_debug("carla_set_engine_callback(%p, %p)", func, ptr);
  716. gStandalone.engineCallback = func;
  717. gStandalone.engineCallbackPtr = ptr;
  718. if (gStandalone.engine != nullptr)
  719. gStandalone.engine->setCallback(func, ptr);
  720. //#ifdef WANT_LOGS
  721. // gLogThread.setCallback(func, ptr);
  722. //#endif
  723. }
  724. #ifndef BUILD_BRIDGE
  725. void carla_set_engine_option(EngineOption option, int value, const char* valueStr)
  726. {
  727. carla_debug("carla_set_engine_option(%i:%s, %i, \"%s\")", option, CB::EngineOption2Str(option), value, valueStr);
  728. switch (option)
  729. {
  730. case CB::ENGINE_OPTION_DEBUG:
  731. break;
  732. case CB::ENGINE_OPTION_PROCESS_MODE:
  733. CARLA_SAFE_ASSERT_RETURN(value >= CB::ENGINE_PROCESS_MODE_SINGLE_CLIENT && value < CB::ENGINE_PROCESS_MODE_BRIDGE,);
  734. gStandalone.engineOptions.processMode = static_cast<CB::EngineProcessMode>(value);
  735. break;
  736. case CB::ENGINE_OPTION_TRANSPORT_MODE:
  737. CARLA_SAFE_ASSERT_RETURN(value >= CB::ENGINE_TRANSPORT_MODE_INTERNAL && value < CB::ENGINE_TRANSPORT_MODE_BRIDGE,);
  738. gStandalone.engineOptions.transportMode = static_cast<CB::EngineTransportMode>(value);
  739. break;
  740. case CB::ENGINE_OPTION_FORCE_STEREO:
  741. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  742. gStandalone.engineOptions.forceStereo = (value != 0);
  743. break;
  744. case CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES:
  745. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  746. gStandalone.engineOptions.preferPluginBridges = (value != 0);
  747. break;
  748. case CB::ENGINE_OPTION_PREFER_UI_BRIDGES:
  749. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  750. gStandalone.engineOptions.preferUiBridges = (value != 0);
  751. break;
  752. case CB::ENGINE_OPTION_UIS_ALWAYS_ON_TOP:
  753. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  754. gStandalone.engineOptions.uisAlwaysOnTop = (value != 0);
  755. break;
  756. case CB::ENGINE_OPTION_MAX_PARAMETERS:
  757. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  758. gStandalone.engineOptions.maxParameters = static_cast<uint>(value);
  759. break;
  760. case CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT:
  761. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  762. gStandalone.engineOptions.uiBridgesTimeout = static_cast<uint>(value);
  763. break;
  764. case CB::ENGINE_OPTION_AUDIO_NUM_PERIODS:
  765. CARLA_SAFE_ASSERT_RETURN(value >= 2 && value <= 3,);
  766. gStandalone.engineOptions.audioNumPeriods = static_cast<uint>(value);
  767. break;
  768. case CB::ENGINE_OPTION_AUDIO_BUFFER_SIZE:
  769. CARLA_SAFE_ASSERT_RETURN(value >= 8,);
  770. gStandalone.engineOptions.audioBufferSize = static_cast<uint>(value);
  771. break;
  772. case CB::ENGINE_OPTION_AUDIO_SAMPLE_RATE:
  773. CARLA_SAFE_ASSERT_RETURN(value >= 22050,);
  774. gStandalone.engineOptions.audioSampleRate = static_cast<uint>(value);
  775. break;
  776. case CB::ENGINE_OPTION_AUDIO_DEVICE:
  777. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr,);
  778. if (gStandalone.engineOptions.audioDevice != nullptr)
  779. delete[] gStandalone.engineOptions.audioDevice;
  780. gStandalone.engineOptions.audioDevice = carla_strdup_safe(valueStr);
  781. break;
  782. case CB:: ENGINE_OPTION_NSM_INIT:
  783. CARLA_SAFE_ASSERT_RETURN(value != 0,);
  784. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  785. gNSM.announce(value, valueStr);
  786. break;
  787. case CB::ENGINE_OPTION_PATH_BINARIES:
  788. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  789. if (gStandalone.engineOptions.binaryDir != nullptr)
  790. delete[] gStandalone.engineOptions.binaryDir;
  791. gStandalone.engineOptions.binaryDir = carla_strdup_safe(valueStr);
  792. break;
  793. case CB::ENGINE_OPTION_PATH_RESOURCES:
  794. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  795. if (gStandalone.engineOptions.resourceDir != nullptr)
  796. delete[] gStandalone.engineOptions.resourceDir;
  797. gStandalone.engineOptions.resourceDir = carla_strdup_safe(valueStr);
  798. break;
  799. case CB::ENGINE_OPTION_FRONTEND_WIN_ID:
  800. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  801. const long long winId(std::strtoll(valueStr, nullptr, 16));
  802. CARLA_SAFE_ASSERT_RETURN(winId >= 0,);
  803. gStandalone.engineOptions.frontendWinId = static_cast<uintptr_t>(winId);
  804. break;
  805. }
  806. if (gStandalone.engine != nullptr)
  807. gStandalone.engine->setOption(option, value, valueStr);
  808. }
  809. #endif
  810. void carla_set_file_callback(FileCallbackFunc func, void* ptr)
  811. {
  812. carla_debug("carla_set_file_callback(%p, %p)", func, ptr);
  813. gStandalone.fileCallback = func;
  814. gStandalone.fileCallbackPtr = ptr;
  815. if (gStandalone.engine != nullptr)
  816. gStandalone.engine->setFileCallback(func, ptr);
  817. }
  818. // -------------------------------------------------------------------------------------------------------------------
  819. bool carla_load_file(const char* filename)
  820. {
  821. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  822. carla_debug("carla_load_file(\"%s\")", filename);
  823. if (gStandalone.engine != nullptr)
  824. return gStandalone.engine->loadFile(filename);
  825. carla_stderr2("Engine is not running");
  826. gStandalone.lastError = "Engine is not running";
  827. return false;
  828. }
  829. bool carla_load_project(const char* filename)
  830. {
  831. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  832. carla_debug("carla_load_project(\"%s\")", filename);
  833. if (gStandalone.engine != nullptr)
  834. return gStandalone.engine->loadProject(filename);
  835. carla_stderr2("Engine is not running");
  836. gStandalone.lastError = "Engine is not running";
  837. return false;
  838. }
  839. bool carla_save_project(const char* filename)
  840. {
  841. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  842. carla_debug("carla_save_project(\"%s\")", filename);
  843. if (gStandalone.engine != nullptr)
  844. return gStandalone.engine->saveProject(filename);
  845. carla_stderr2("Engine was never initiated");
  846. gStandalone.lastError = "Engine was never initiated";
  847. return false;
  848. }
  849. #ifndef BUILD_BRIDGE
  850. // -------------------------------------------------------------------------------------------------------------------
  851. bool carla_patchbay_connect(uint groupIdA, uint portIdA, uint groupIdB, uint portIdB)
  852. {
  853. carla_debug("carla_patchbay_connect(%u, %u, %u, %u)", groupIdA, portIdA, groupIdB, portIdB);
  854. if (gStandalone.engine != nullptr)
  855. return gStandalone.engine->patchbayConnect(groupIdA, portIdA, groupIdB, portIdB);
  856. carla_stderr2("Engine is not running");
  857. gStandalone.lastError = "Engine is not running";
  858. return false;
  859. }
  860. bool carla_patchbay_disconnect(uint connectionId)
  861. {
  862. carla_debug("carla_patchbay_disconnect(%i)", connectionId);
  863. if (gStandalone.engine != nullptr)
  864. return gStandalone.engine->patchbayDisconnect(connectionId);
  865. carla_stderr2("Engine is not running");
  866. gStandalone.lastError = "Engine is not running";
  867. return false;
  868. }
  869. bool carla_patchbay_refresh(bool external)
  870. {
  871. carla_debug("carla_patchbay_refresh(%s)", bool2str(external));
  872. if (gStandalone.engine != nullptr)
  873. return gStandalone.engine->patchbayRefresh(external);
  874. carla_stderr2("Engine is not running");
  875. gStandalone.lastError = "Engine is not running";
  876. return false;
  877. }
  878. // -------------------------------------------------------------------------------------------------------------------
  879. void carla_transport_play()
  880. {
  881. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);
  882. carla_debug("carla_transport_play()");
  883. gStandalone.engine->transportPlay();
  884. }
  885. void carla_transport_pause()
  886. {
  887. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);
  888. carla_debug("carla_transport_pause()");
  889. gStandalone.engine->transportPause();
  890. }
  891. void carla_transport_relocate(uint64_t frame)
  892. {
  893. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);
  894. carla_debug("carla_transport_relocate(%i)", frame);
  895. gStandalone.engine->transportRelocate(frame);
  896. }
  897. uint64_t carla_get_current_transport_frame()
  898. {
  899. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(), 0);
  900. const CB::EngineTimeInfo& timeInfo(gStandalone.engine->getTimeInfo());
  901. return timeInfo.frame;
  902. }
  903. const CarlaTransportInfo* carla_get_transport_info()
  904. {
  905. static CarlaTransportInfo retInfo;
  906. // reset
  907. retInfo.playing = false;
  908. retInfo.frame = 0;
  909. retInfo.bar = 0;
  910. retInfo.beat = 0;
  911. retInfo.tick = 0;
  912. retInfo.bpm = 0.0;
  913. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(), &retInfo);
  914. const CB::EngineTimeInfo& timeInfo(gStandalone.engine->getTimeInfo());
  915. retInfo.playing = timeInfo.playing;
  916. retInfo.frame = timeInfo.frame;
  917. if (timeInfo.valid & CB::EngineTimeInfo::kValidBBT)
  918. {
  919. retInfo.bar = timeInfo.bbt.bar;
  920. retInfo.beat = timeInfo.bbt.beat;
  921. retInfo.tick = timeInfo.bbt.tick;
  922. retInfo.bpm = timeInfo.bbt.beatsPerMinute;
  923. }
  924. return &retInfo;
  925. }
  926. #endif
  927. // -------------------------------------------------------------------------------------------------------------------
  928. bool carla_add_plugin(BinaryType btype, PluginType ptype, const char* filename, const char* name, const char* label, int64_t uniqueId, const void* extraPtr)
  929. {
  930. CARLA_SAFE_ASSERT_RETURN(label != nullptr /*&& label[0] != '\0'*/, false);
  931. carla_debug("carla_add_plugin(%i:%s, %i:%s, \"%s\", \"%s\", \"%s\", " P_INT64 ", %p)", btype, CB::BinaryType2Str(btype), ptype, CB::PluginType2Str(ptype), filename, name, label, uniqueId, extraPtr);
  932. if (gStandalone.engine != nullptr)
  933. return gStandalone.engine->addPlugin(btype, ptype, filename, name, label, uniqueId, extraPtr);
  934. carla_stderr2("Engine is not running");
  935. gStandalone.lastError = "Engine is not running";
  936. return false;
  937. }
  938. bool carla_remove_plugin(uint pluginId)
  939. {
  940. carla_debug("carla_remove_plugin(%i)", pluginId);
  941. if (gStandalone.engine != nullptr)
  942. return gStandalone.engine->removePlugin(pluginId);
  943. carla_stderr2("Engine is not running");
  944. gStandalone.lastError = "Engine is not running";
  945. return false;
  946. }
  947. bool carla_remove_all_plugins()
  948. {
  949. carla_debug("carla_remove_all_plugins()");
  950. if (gStandalone.engine != nullptr)
  951. return gStandalone.engine->removeAllPlugins();
  952. carla_stderr2("Engine is not running");
  953. gStandalone.lastError = "Engine is not running";
  954. return false;
  955. }
  956. #ifndef BUILD_BRIDGE
  957. const char* carla_rename_plugin(uint pluginId, const char* newName)
  958. {
  959. CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', nullptr);
  960. carla_debug("carla_rename_plugin(%i, \"%s\")", pluginId, newName);
  961. if (gStandalone.engine != nullptr)
  962. return gStandalone.engine->renamePlugin(pluginId, newName);
  963. carla_stderr2("Engine is not running");
  964. gStandalone.lastError = "Engine is not running";
  965. return nullptr;
  966. }
  967. bool carla_clone_plugin(uint pluginId)
  968. {
  969. carla_debug("carla_clone_plugin(%i)", pluginId);
  970. if (gStandalone.engine != nullptr)
  971. return gStandalone.engine->clonePlugin(pluginId);
  972. carla_stderr2("Engine is not running");
  973. gStandalone.lastError = "Engine is not running";
  974. return false;
  975. }
  976. bool carla_replace_plugin(uint pluginId)
  977. {
  978. carla_debug("carla_replace_plugin(%i)", pluginId);
  979. if (gStandalone.engine != nullptr)
  980. return gStandalone.engine->replacePlugin(pluginId);
  981. carla_stderr2("Engine is not running");
  982. gStandalone.lastError = "Engine is not running";
  983. return false;
  984. }
  985. bool carla_switch_plugins(uint pluginIdA, uint pluginIdB)
  986. {
  987. CARLA_SAFE_ASSERT_RETURN(pluginIdA != pluginIdB, false);
  988. carla_debug("carla_switch_plugins(%i, %i)", pluginIdA, pluginIdB);
  989. if (gStandalone.engine != nullptr)
  990. return gStandalone.engine->switchPlugins(pluginIdA, pluginIdB);
  991. carla_stderr2("Engine is not running");
  992. gStandalone.lastError = "Engine is not running";
  993. return false;
  994. }
  995. #endif
  996. // -------------------------------------------------------------------------------------------------------------------
  997. bool carla_load_plugin_state(uint pluginId, const char* filename)
  998. {
  999. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  1000. carla_debug("carla_load_plugin_state(%i, \"%s\")", pluginId, filename);
  1001. if (gStandalone.engine == nullptr || ! gStandalone.engine->isRunning())
  1002. {
  1003. carla_stderr2("Engine is not running");
  1004. gStandalone.lastError = "Engine is not running";
  1005. return false;
  1006. }
  1007. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1008. return plugin->loadStateFromFile(filename);
  1009. carla_stderr2("carla_load_plugin_state(%i, \"%s\") - could not find plugin", pluginId, filename);
  1010. return false;
  1011. }
  1012. bool carla_save_plugin_state(uint pluginId, const char* filename)
  1013. {
  1014. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  1015. carla_debug("carla_save_plugin_state(%i, \"%s\")", pluginId, filename);
  1016. if (gStandalone.engine == nullptr)
  1017. {
  1018. carla_stderr2("Engine is not running");
  1019. gStandalone.lastError = "Engine is not running";
  1020. return false;
  1021. }
  1022. // allow to save even if engine isn't running
  1023. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1024. return plugin->saveStateToFile(filename);
  1025. carla_stderr2("carla_save_plugin_state(%i, \"%s\") - could not find plugin", pluginId, filename);
  1026. return false;
  1027. }
  1028. // -------------------------------------------------------------------------------------------------------------------
  1029. const CarlaPluginInfo* carla_get_plugin_info(uint pluginId)
  1030. {
  1031. carla_debug("carla_get_plugin_info(%i)", pluginId);
  1032. static CarlaPluginInfo info;
  1033. // reset
  1034. info.type = CB::PLUGIN_NONE;
  1035. info.category = CB::PLUGIN_CATEGORY_NONE;
  1036. info.hints = 0x0;
  1037. info.optionsAvailable = 0x0;
  1038. info.optionsEnabled = 0x0;
  1039. info.filename = gNullCharPtr;
  1040. info.name = gNullCharPtr;
  1041. info.iconName = gNullCharPtr;
  1042. info.uniqueId = 0;
  1043. // cleanup
  1044. if (info.label != gNullCharPtr)
  1045. {
  1046. delete[] info.label;
  1047. info.label = gNullCharPtr;
  1048. }
  1049. if (info.maker != gNullCharPtr)
  1050. {
  1051. delete[] info.maker;
  1052. info.maker = gNullCharPtr;
  1053. }
  1054. if (info.copyright != gNullCharPtr)
  1055. {
  1056. delete[] info.copyright;
  1057. info.copyright = gNullCharPtr;
  1058. }
  1059. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1060. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1061. {
  1062. char strBufLabel[STR_MAX+1];
  1063. char strBufMaker[STR_MAX+1];
  1064. char strBufCopyright[STR_MAX+1];
  1065. carla_zeroChar(strBufLabel, STR_MAX+1);
  1066. carla_zeroChar(strBufMaker, STR_MAX+1);
  1067. carla_zeroChar(strBufCopyright, STR_MAX+1);
  1068. info.type = plugin->getType();
  1069. info.category = plugin->getCategory();
  1070. info.hints = plugin->getHints();
  1071. info.filename = plugin->getFilename();
  1072. info.name = plugin->getName();
  1073. info.iconName = plugin->getIconName();
  1074. info.uniqueId = plugin->getUniqueId();
  1075. info.optionsAvailable = plugin->getOptionsAvailable();
  1076. info.optionsEnabled = plugin->getOptionsEnabled();
  1077. plugin->getLabel(strBufLabel);
  1078. info.label = carla_strdup_safe(strBufLabel);
  1079. plugin->getMaker(strBufMaker);
  1080. info.maker = carla_strdup_safe(strBufMaker);
  1081. plugin->getCopyright(strBufCopyright);
  1082. info.copyright = carla_strdup_safe(strBufCopyright);
  1083. checkStringPtr(info.filename);
  1084. checkStringPtr(info.name);
  1085. checkStringPtr(info.iconName);
  1086. checkStringPtr(info.label);
  1087. checkStringPtr(info.maker);
  1088. checkStringPtr(info.copyright);
  1089. return &info;
  1090. }
  1091. carla_stderr2("carla_get_plugin_info(%i) - could not find plugin", pluginId);
  1092. return &info;
  1093. }
  1094. const CarlaPortCountInfo* carla_get_audio_port_count_info(uint pluginId)
  1095. {
  1096. carla_debug("carla_get_audio_port_count_info(%i)", pluginId);
  1097. static CarlaPortCountInfo info;
  1098. // reset
  1099. info.ins = 0;
  1100. info.outs = 0;
  1101. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1102. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1103. {
  1104. info.ins = plugin->getAudioInCount();
  1105. info.outs = plugin->getAudioOutCount();
  1106. return &info;
  1107. }
  1108. carla_stderr2("carla_get_audio_port_count_info(%i) - could not find plugin", pluginId);
  1109. return &info;
  1110. }
  1111. const CarlaPortCountInfo* carla_get_midi_port_count_info(uint pluginId)
  1112. {
  1113. carla_debug("carla_get_midi_port_count_info(%i)", pluginId);
  1114. static CarlaPortCountInfo info;
  1115. // reset
  1116. info.ins = 0;
  1117. info.outs = 0;
  1118. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1119. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1120. {
  1121. info.ins = plugin->getMidiInCount();
  1122. info.outs = plugin->getMidiOutCount();
  1123. return &info;
  1124. }
  1125. carla_stderr2("carla_get_midi_port_count_info(%i) - could not find plugin", pluginId);
  1126. return &info;
  1127. }
  1128. const CarlaPortCountInfo* carla_get_parameter_count_info(uint pluginId)
  1129. {
  1130. carla_debug("carla_get_parameter_count_info(%i)", pluginId);
  1131. static CarlaPortCountInfo info;
  1132. // reset
  1133. info.ins = 0;
  1134. info.outs = 0;
  1135. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1136. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1137. {
  1138. plugin->getParameterCountInfo(info.ins, info.outs);
  1139. return &info;
  1140. }
  1141. carla_stderr2("carla_get_parameter_count_info(%i) - could not find plugin", pluginId);
  1142. return &info;
  1143. }
  1144. const CarlaParameterInfo* carla_get_parameter_info(uint pluginId, uint32_t parameterId)
  1145. {
  1146. carla_debug("carla_get_parameter_info(%i, %i)", pluginId, parameterId);
  1147. static CarlaParameterInfo info;
  1148. // reset
  1149. info.scalePointCount = 0;
  1150. // cleanup
  1151. if (info.name != gNullCharPtr)
  1152. {
  1153. delete[] info.name;
  1154. info.name = gNullCharPtr;
  1155. }
  1156. if (info.symbol != gNullCharPtr)
  1157. {
  1158. delete[] info.symbol;
  1159. info.symbol = gNullCharPtr;
  1160. }
  1161. if (info.unit != gNullCharPtr)
  1162. {
  1163. delete[] info.unit;
  1164. info.unit = gNullCharPtr;
  1165. }
  1166. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1167. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1168. {
  1169. if (parameterId < plugin->getParameterCount())
  1170. {
  1171. char strBufName[STR_MAX+1];
  1172. char strBufSymbol[STR_MAX+1];
  1173. char strBufUnit[STR_MAX+1];
  1174. carla_zeroChar(strBufName, STR_MAX+1);
  1175. carla_zeroChar(strBufSymbol, STR_MAX+1);
  1176. carla_zeroChar(strBufUnit, STR_MAX+1);
  1177. info.scalePointCount = plugin->getParameterScalePointCount(parameterId);
  1178. plugin->getParameterName(parameterId, strBufName);
  1179. info.name = carla_strdup_safe(strBufName);
  1180. plugin->getParameterSymbol(parameterId, strBufSymbol);
  1181. info.symbol = carla_strdup_safe(strBufSymbol);
  1182. plugin->getParameterUnit(parameterId, strBufUnit);
  1183. info.unit = carla_strdup_safe(strBufUnit);
  1184. checkStringPtr(info.name);
  1185. checkStringPtr(info.symbol);
  1186. checkStringPtr(info.unit);
  1187. }
  1188. else
  1189. carla_stderr2("carla_get_parameter_info(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1190. return &info;
  1191. }
  1192. carla_stderr2("carla_get_parameter_info(%i, %i) - could not find plugin", pluginId, parameterId);
  1193. return &info;
  1194. }
  1195. const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(uint pluginId, uint32_t parameterId, uint32_t scalePointId)
  1196. {
  1197. carla_debug("carla_get_parameter_scalepoint_info(%i, %i, %i)", pluginId, parameterId, scalePointId);
  1198. CARLA_ASSERT(gStandalone.engine != nullptr);
  1199. static CarlaScalePointInfo info;
  1200. // reset
  1201. info.value = 0.0f;
  1202. // cleanup
  1203. if (info.label != gNullCharPtr)
  1204. {
  1205. delete[] info.label;
  1206. info.label = gNullCharPtr;
  1207. }
  1208. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &info);
  1209. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1210. {
  1211. if (parameterId < plugin->getParameterCount())
  1212. {
  1213. if (scalePointId < plugin->getParameterScalePointCount(parameterId))
  1214. {
  1215. char strBufLabel[STR_MAX+1];
  1216. carla_zeroChar(strBufLabel, STR_MAX+1);
  1217. info.value = plugin->getParameterScalePointValue(parameterId, scalePointId);
  1218. plugin->getParameterScalePointLabel(parameterId, scalePointId, strBufLabel);
  1219. info.label = carla_strdup_safe(strBufLabel);
  1220. checkStringPtr(info.label);
  1221. }
  1222. else
  1223. carla_stderr2("carla_get_parameter_scalepoint_info(%i, %i, %i) - scalePointId out of bounds", pluginId, parameterId, scalePointId);
  1224. }
  1225. else
  1226. carla_stderr2("carla_get_parameter_scalepoint_info(%i, %i, %i) - parameterId out of bounds", pluginId, parameterId, scalePointId);
  1227. return &info;
  1228. }
  1229. carla_stderr2("carla_get_parameter_scalepoint_info(%i, %i, %i) - could not find plugin", pluginId, parameterId, scalePointId);
  1230. return &info;
  1231. }
  1232. // -------------------------------------------------------------------------------------------------------------------
  1233. const ParameterData* carla_get_parameter_data(uint pluginId, uint32_t parameterId)
  1234. {
  1235. carla_debug("carla_get_parameter_data(%i, %i)", pluginId, parameterId);
  1236. static const ParameterData fallbackParameterData = { CB::PARAMETER_UNKNOWN, 0x0, CB::PARAMETER_NULL, -1, -1, 0 };
  1237. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParameterData);
  1238. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1239. {
  1240. if (parameterId < plugin->getParameterCount())
  1241. return &plugin->getParameterData(parameterId);
  1242. carla_stderr2("carla_get_parameter_data(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1243. return &fallbackParameterData;
  1244. }
  1245. carla_stderr2("carla_get_parameter_data(%i, %i) - could not find plugin", pluginId, parameterId);
  1246. return &fallbackParameterData;
  1247. }
  1248. const ParameterRanges* carla_get_parameter_ranges(uint pluginId, uint32_t parameterId)
  1249. {
  1250. carla_debug("carla_get_parameter_ranges(%i, %i)", pluginId, parameterId);
  1251. static const ParameterRanges fallbackParamRanges = { 0.0f, 0.0f, 1.0f, 0.01f, 0.0001f, 0.1f };
  1252. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &fallbackParamRanges);
  1253. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1254. {
  1255. if (parameterId < plugin->getParameterCount())
  1256. return &plugin->getParameterRanges(parameterId);
  1257. carla_stderr2("carla_get_parameter_ranges(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1258. return &fallbackParamRanges;
  1259. }
  1260. carla_stderr2("carla_get_parameter_ranges(%i, %i) - could not find plugin", pluginId, parameterId);
  1261. return &fallbackParamRanges;
  1262. }
  1263. const MidiProgramData* carla_get_midi_program_data(uint pluginId, uint32_t midiProgramId)
  1264. {
  1265. carla_debug("carla_get_midi_program_data(%i, %i)", pluginId, midiProgramId);
  1266. static MidiProgramData midiProgData;
  1267. // reset
  1268. midiProgData.bank = 0;
  1269. midiProgData.program = 0;
  1270. midiProgData.name = gNullCharPtr;
  1271. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &midiProgData);
  1272. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1273. {
  1274. if (midiProgramId < plugin->getMidiProgramCount())
  1275. {
  1276. const MidiProgramData& ret(plugin->getMidiProgramData(midiProgramId));
  1277. carla_copyStruct<MidiProgramData>(midiProgData, ret);
  1278. checkStringPtr(midiProgData.name);
  1279. return &midiProgData;
  1280. }
  1281. carla_stderr2("carla_get_midi_program_data(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId);
  1282. return &midiProgData;
  1283. }
  1284. carla_stderr2("carla_get_midi_program_data(%i, %i) - could not find plugin", pluginId, midiProgramId);
  1285. return &midiProgData;
  1286. }
  1287. const CustomData* carla_get_custom_data(uint pluginId, uint32_t customDataId)
  1288. {
  1289. carla_debug("carla_get_custom_data(%i, %i)", pluginId, customDataId);
  1290. static CustomData customData;
  1291. // reset
  1292. customData.type = gNullCharPtr;
  1293. customData.key = gNullCharPtr;
  1294. customData.value = gNullCharPtr;
  1295. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, &customData);
  1296. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1297. {
  1298. if (customDataId < plugin->getCustomDataCount())
  1299. {
  1300. const CustomData& ret(plugin->getCustomData(customDataId));
  1301. carla_copyStruct<CustomData>(customData, ret);
  1302. checkStringPtr(customData.type);
  1303. checkStringPtr(customData.key);
  1304. checkStringPtr(customData.value);
  1305. return &customData;
  1306. }
  1307. carla_stderr2("carla_get_custom_data(%i, %i) - customDataId out of bounds", pluginId, customDataId);
  1308. return &customData;
  1309. }
  1310. carla_stderr2("carla_get_custom_data(%i, %i) - could not find plugin", pluginId, customDataId);
  1311. return &customData;
  1312. }
  1313. const char* carla_get_chunk_data(uint pluginId)
  1314. {
  1315. carla_debug("carla_get_chunk_data(%i)", pluginId);
  1316. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1317. static CarlaString chunkData;
  1318. // cleanup
  1319. chunkData.clear();
  1320. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1321. {
  1322. if (plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS)
  1323. {
  1324. void* data = nullptr;
  1325. const std::size_t dataSize(plugin->getChunkData(&data));
  1326. if (data != nullptr && dataSize > 0)
  1327. {
  1328. chunkData = CarlaString::asBase64(data, static_cast<std::size_t>(dataSize));
  1329. return chunkData;
  1330. }
  1331. else
  1332. carla_stderr2("carla_get_chunk_data(%i) - got invalid chunk data", pluginId);
  1333. }
  1334. else
  1335. carla_stderr2("carla_get_chunk_data(%i) - plugin does not use chunks", pluginId);
  1336. return nullptr;
  1337. }
  1338. carla_stderr2("carla_get_chunk_data(%i) - could not find plugin", pluginId);
  1339. return nullptr;
  1340. }
  1341. // -------------------------------------------------------------------------------------------------------------------
  1342. uint32_t carla_get_parameter_count(uint pluginId)
  1343. {
  1344. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1345. carla_debug("carla_get_parameter_count(%i)", pluginId);
  1346. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1347. return plugin->getParameterCount();
  1348. carla_stderr2("carla_get_parameter_count(%i) - could not find plugin", pluginId);
  1349. return 0;
  1350. }
  1351. uint32_t carla_get_program_count(uint pluginId)
  1352. {
  1353. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1354. carla_debug("carla_get_program_count(%i)", pluginId);
  1355. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1356. return plugin->getProgramCount();
  1357. carla_stderr2("carla_get_program_count(%i) - could not find plugin", pluginId);
  1358. return 0;
  1359. }
  1360. uint32_t carla_get_midi_program_count(uint pluginId)
  1361. {
  1362. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1363. carla_debug("carla_get_midi_program_count(%i)", pluginId);
  1364. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1365. return plugin->getMidiProgramCount();
  1366. carla_stderr2("carla_get_midi_program_count(%i) - could not find plugin", pluginId);
  1367. return 0;
  1368. }
  1369. uint32_t carla_get_custom_data_count(uint pluginId)
  1370. {
  1371. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1372. carla_debug("carla_get_custom_data_count(%i)", pluginId);
  1373. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1374. return plugin->getCustomDataCount();
  1375. carla_stderr2("carla_get_custom_data_count(%i) - could not find plugin", pluginId);
  1376. return 0;
  1377. }
  1378. // -------------------------------------------------------------------------------------------------------------------
  1379. const char* carla_get_parameter_text(uint pluginId, uint32_t parameterId)
  1380. {
  1381. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1382. carla_debug("carla_get_parameter_text(%i, %i)", pluginId, parameterId);
  1383. static char textBuf[STR_MAX+1];
  1384. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1385. {
  1386. if (parameterId < plugin->getParameterCount())
  1387. {
  1388. carla_zeroChar(textBuf, STR_MAX+1);
  1389. plugin->getParameterText(parameterId, textBuf);
  1390. return textBuf;
  1391. }
  1392. carla_stderr2("carla_get_parameter_text(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1393. return nullptr;
  1394. }
  1395. carla_stderr2("carla_get_parameter_text(%i, %i) - could not find plugin", pluginId, parameterId);
  1396. return nullptr;
  1397. }
  1398. const char* carla_get_program_name(uint pluginId, uint32_t programId)
  1399. {
  1400. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1401. carla_debug("carla_get_program_name(%i, %i)", pluginId, programId);
  1402. static char programName[STR_MAX+1];
  1403. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1404. {
  1405. if (programId < plugin->getProgramCount())
  1406. {
  1407. carla_zeroChar(programName, STR_MAX+1);
  1408. plugin->getProgramName(programId, programName);
  1409. return programName;
  1410. }
  1411. carla_stderr2("carla_get_program_name(%i, %i) - programId out of bounds", pluginId, programId);
  1412. return nullptr;
  1413. }
  1414. carla_stderr2("carla_get_program_name(%i, %i) - could not find plugin", pluginId, programId);
  1415. return nullptr;
  1416. }
  1417. const char* carla_get_midi_program_name(uint pluginId, uint32_t midiProgramId)
  1418. {
  1419. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1420. carla_debug("carla_get_midi_program_name(%i, %i)", pluginId, midiProgramId);
  1421. static char midiProgramName[STR_MAX+1];
  1422. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1423. {
  1424. if (midiProgramId < plugin->getMidiProgramCount())
  1425. {
  1426. carla_zeroChar(midiProgramName, STR_MAX+1);
  1427. plugin->getMidiProgramName(midiProgramId, midiProgramName);
  1428. return midiProgramName;
  1429. }
  1430. carla_stderr2("carla_get_midi_program_name(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId);
  1431. return nullptr;
  1432. }
  1433. carla_stderr2("carla_get_midi_program_name(%i, %i) - could not find plugin", pluginId, midiProgramId);
  1434. return nullptr;
  1435. }
  1436. const char* carla_get_real_plugin_name(uint pluginId)
  1437. {
  1438. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, nullptr);
  1439. carla_debug("carla_get_real_plugin_name(%i)", pluginId);
  1440. static char realPluginName[STR_MAX+1];
  1441. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1442. {
  1443. carla_zeroChar(realPluginName, STR_MAX+1);
  1444. plugin->getRealName(realPluginName);
  1445. return realPluginName;
  1446. }
  1447. carla_stderr2("carla_get_real_plugin_name(%i) - could not find plugin", pluginId);
  1448. return nullptr;
  1449. }
  1450. // -------------------------------------------------------------------------------------------------------------------
  1451. int32_t carla_get_current_program_index(uint pluginId)
  1452. {
  1453. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, -1);
  1454. carla_debug("carla_get_current_program_index(%i)", pluginId);
  1455. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1456. return plugin->getCurrentProgram();
  1457. carla_stderr2("carla_get_current_program_index(%i) - could not find plugin", pluginId);
  1458. return -1;
  1459. }
  1460. int32_t carla_get_current_midi_program_index(uint pluginId)
  1461. {
  1462. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, -1);
  1463. carla_debug("carla_get_current_midi_program_index(%i)", pluginId);
  1464. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1465. return plugin->getCurrentMidiProgram();
  1466. carla_stderr2("carla_get_current_midi_program_index(%i) - could not find plugin", pluginId);
  1467. return -1;
  1468. }
  1469. // -------------------------------------------------------------------------------------------------------------------
  1470. float carla_get_default_parameter_value(uint pluginId, uint32_t parameterId)
  1471. {
  1472. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1473. carla_debug("carla_get_default_parameter_value(%i, %i)", pluginId, parameterId);
  1474. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1475. {
  1476. if (parameterId < plugin->getParameterCount())
  1477. return plugin->getParameterRanges(parameterId).def;
  1478. carla_stderr2("carla_get_default_parameter_value(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1479. return 0.0f;
  1480. }
  1481. carla_stderr2("carla_get_default_parameter_value(%i, %i) - could not find plugin", pluginId, parameterId);
  1482. return 0.0f;
  1483. }
  1484. float carla_get_current_parameter_value(uint pluginId, uint32_t parameterId)
  1485. {
  1486. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1487. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1488. {
  1489. if (parameterId < plugin->getParameterCount())
  1490. return plugin->getParameterValue(parameterId);
  1491. carla_stderr2("carla_get_current_parameter_value(%i, %i) - parameterId out of bounds", pluginId, parameterId);
  1492. return 0.0f;
  1493. }
  1494. carla_stderr2("carla_get_current_parameter_value(%i, %i) - could not find plugin", pluginId, parameterId);
  1495. return 0.0f;
  1496. }
  1497. float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId)
  1498. {
  1499. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1500. CARLA_SAFE_ASSERT_RETURN(parameterId != CB::PARAMETER_NULL && parameterId > CB::PARAMETER_MAX, 0.0f);
  1501. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1502. return plugin->getInternalParameterValue(parameterId);
  1503. carla_stderr2("carla_get_internal_parameter_value(%i, %i) - could not find plugin", pluginId, parameterId);
  1504. return 0.0f;
  1505. }
  1506. // -------------------------------------------------------------------------------------------------------------------
  1507. float carla_get_input_peak_value(uint pluginId, bool isLeft)
  1508. {
  1509. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1510. return gStandalone.engine->getInputPeak(pluginId, isLeft);
  1511. }
  1512. float carla_get_output_peak_value(uint pluginId, bool isLeft)
  1513. {
  1514. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0f);
  1515. return gStandalone.engine->getOutputPeak(pluginId, isLeft);
  1516. }
  1517. // -------------------------------------------------------------------------------------------------------------------
  1518. void carla_set_active(uint pluginId, bool onOff)
  1519. {
  1520. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1521. carla_debug("carla_set_active(%i, %s)", pluginId, bool2str(onOff));
  1522. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1523. return plugin->setActive(onOff, true, false);
  1524. carla_stderr2("carla_set_active(%i, %s) - could not find plugin", pluginId, bool2str(onOff));
  1525. }
  1526. #ifndef BUILD_BRIDGE
  1527. void carla_set_drywet(uint pluginId, float value)
  1528. {
  1529. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1530. carla_debug("carla_set_drywet(%i, %f)", pluginId, value);
  1531. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1532. return plugin->setDryWet(value, true, false);
  1533. carla_stderr2("carla_set_drywet(%i, %f) - could not find plugin", pluginId, value);
  1534. }
  1535. void carla_set_volume(uint pluginId, float value)
  1536. {
  1537. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1538. carla_debug("carla_set_volume(%i, %f)", pluginId, value);
  1539. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1540. return plugin->setVolume(value, true, false);
  1541. carla_stderr2("carla_set_volume(%i, %f) - could not find plugin", pluginId, value);
  1542. }
  1543. void carla_set_balance_left(uint pluginId, float value)
  1544. {
  1545. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1546. carla_debug("carla_set_balance_left(%i, %f)", pluginId, value);
  1547. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1548. return plugin->setBalanceLeft(value, true, false);
  1549. carla_stderr2("carla_set_balance_left(%i, %f) - could not find plugin", pluginId, value);
  1550. }
  1551. void carla_set_balance_right(uint pluginId, float value)
  1552. {
  1553. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1554. carla_debug("carla_set_balance_right(%i, %f)", pluginId, value);
  1555. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1556. return plugin->setBalanceRight(value, true, false);
  1557. carla_stderr2("carla_set_balance_right(%i, %f) - could not find plugin", pluginId, value);
  1558. }
  1559. void carla_set_panning(uint pluginId, float value)
  1560. {
  1561. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1562. carla_debug("carla_set_panning(%i, %f)", pluginId, value);
  1563. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1564. return plugin->setPanning(value, true, false);
  1565. carla_stderr2("carla_set_panning(%i, %f) - could not find plugin", pluginId, value);
  1566. }
  1567. void carla_set_ctrl_channel(uint pluginId, int8_t channel)
  1568. {
  1569. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1570. CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS,);
  1571. carla_debug("carla_set_ctrl_channel(%i, %i)", pluginId, channel);
  1572. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1573. return plugin->setCtrlChannel(channel, true, false);
  1574. carla_stderr2("carla_set_ctrl_channel(%i, %i) - could not find plugin", pluginId, channel);
  1575. }
  1576. void carla_set_option(uint pluginId, uint option, bool yesNo)
  1577. {
  1578. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1579. carla_debug("carla_set_option(%i, %i, %s)", pluginId, option, bool2str(yesNo));
  1580. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1581. return plugin->setOption(option, yesNo, false);
  1582. carla_stderr2("carla_set_option(%i, %i, %s) - could not find plugin", pluginId, option, bool2str(yesNo));
  1583. }
  1584. #endif
  1585. // -------------------------------------------------------------------------------------------------------------------
  1586. void carla_set_parameter_value(uint pluginId, uint32_t parameterId, float value)
  1587. {
  1588. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1589. carla_debug("carla_set_parameter_value(%i, %i, %f)", pluginId, parameterId, value);
  1590. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1591. {
  1592. if (parameterId < plugin->getParameterCount())
  1593. return plugin->setParameterValue(parameterId, value, true, true, false);
  1594. carla_stderr2("carla_set_parameter_value(%i, %i, %f) - parameterId out of bounds", pluginId, parameterId, value);
  1595. return;
  1596. }
  1597. carla_stderr2("carla_set_parameter_value(%i, %i, %f) - could not find plugin", pluginId, parameterId, value);
  1598. }
  1599. #ifndef BUILD_BRIDGE
  1600. void carla_set_parameter_midi_channel(uint pluginId, uint32_t parameterId, uint8_t channel)
  1601. {
  1602. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1603. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1604. carla_debug("carla_set_parameter_midi_channel(%i, %i, %i)", pluginId, parameterId, channel);
  1605. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1606. {
  1607. if (parameterId < plugin->getParameterCount())
  1608. return plugin->setParameterMidiChannel(parameterId, channel, true, false);
  1609. carla_stderr2("carla_set_parameter_midi_channel(%i, %i, %i) - parameterId out of bounds", pluginId, parameterId, channel);
  1610. return;
  1611. }
  1612. carla_stderr2("carla_set_parameter_midi_channel(%i, %i, %i) - could not find plugin", pluginId, parameterId, channel);
  1613. }
  1614. void carla_set_parameter_midi_cc(uint pluginId, uint32_t parameterId, int16_t cc)
  1615. {
  1616. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1617. CARLA_SAFE_ASSERT_RETURN(cc >= -1 && cc <= 0x5F,);
  1618. carla_debug("carla_set_parameter_midi_cc(%i, %i, %i)", pluginId, parameterId, cc);
  1619. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1620. {
  1621. if (parameterId < plugin->getParameterCount())
  1622. return plugin->setParameterMidiCC(parameterId, cc, true, false);
  1623. carla_stderr2("carla_set_parameter_midi_cc(%i, %i, %i) - parameterId out of bounds", pluginId, parameterId, cc);
  1624. return;
  1625. }
  1626. carla_stderr2("carla_set_parameter_midi_cc(%i, %i, %i) - could not find plugin", pluginId, parameterId, cc);
  1627. }
  1628. #endif
  1629. // -------------------------------------------------------------------------------------------------------------------
  1630. void carla_set_program(uint pluginId, uint32_t programId)
  1631. {
  1632. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1633. carla_debug("carla_set_program(%i, %i)", pluginId, programId);
  1634. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1635. {
  1636. if (programId < plugin->getProgramCount())
  1637. return plugin->setProgram(static_cast<int32_t>(programId), true, true, false);
  1638. carla_stderr2("carla_set_program(%i, %i) - programId out of bounds", pluginId, programId);
  1639. return;
  1640. }
  1641. carla_stderr2("carla_set_program(%i, %i) - could not find plugin", pluginId, programId);
  1642. }
  1643. void carla_set_midi_program(uint pluginId, uint32_t midiProgramId)
  1644. {
  1645. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1646. carla_debug("carla_set_midi_program(%i, %i)", pluginId, midiProgramId);
  1647. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1648. {
  1649. if (midiProgramId < plugin->getMidiProgramCount())
  1650. return plugin->setMidiProgram(static_cast<int32_t>(midiProgramId), true, true, false);
  1651. carla_stderr2("carla_set_midi_program(%i, %i) - midiProgramId out of bounds", pluginId, midiProgramId);
  1652. return;
  1653. }
  1654. carla_stderr2("carla_set_midi_program(%i, %i) - could not find plugin", pluginId, midiProgramId);
  1655. }
  1656. // -------------------------------------------------------------------------------------------------------------------
  1657. void carla_set_custom_data(uint pluginId, const char* type, const char* key, const char* value)
  1658. {
  1659. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1660. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
  1661. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  1662. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  1663. carla_debug("carla_set_custom_data(%i, \"%s\", \"%s\", \"%s\")", pluginId, type, key, value);
  1664. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1665. return plugin->setCustomData(type, key, value, true);
  1666. carla_stderr2("carla_set_custom_data(%i, \"%s\", \"%s\", \"%s\") - could not find plugin", pluginId, type, key, value);
  1667. }
  1668. void carla_set_chunk_data(uint pluginId, const char* chunkData)
  1669. {
  1670. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1671. CARLA_SAFE_ASSERT_RETURN(chunkData != nullptr && chunkData[0] != '\0',);
  1672. carla_debug("carla_set_chunk_data(%i, \"%s\")", pluginId, chunkData);
  1673. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1674. {
  1675. if (plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS)
  1676. {
  1677. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(chunkData));
  1678. return plugin->setChunkData(chunk.data(), chunk.size());
  1679. }
  1680. carla_stderr2("carla_set_chunk_data(%i, \"%s\") - plugin does not use chunks", pluginId, chunkData);
  1681. return;
  1682. }
  1683. carla_stderr2("carla_set_chunk_data(%i, \"%s\") - could not find plugin", pluginId, chunkData);
  1684. }
  1685. // -------------------------------------------------------------------------------------------------------------------
  1686. void carla_prepare_for_save(uint pluginId)
  1687. {
  1688. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1689. carla_debug("carla_prepare_for_save(%i)", pluginId);
  1690. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1691. return plugin->prepareForSave();
  1692. carla_stderr2("carla_prepare_for_save(%i) - could not find plugin", pluginId);
  1693. }
  1694. void carla_reset_parameters(uint pluginId)
  1695. {
  1696. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1697. carla_debug("carla_reset_parameters(%i)", pluginId);
  1698. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1699. return plugin->resetParameters();
  1700. carla_stderr2("carla_reset_parameters(%i) - could not find plugin", pluginId);
  1701. }
  1702. void carla_randomize_parameters(uint pluginId)
  1703. {
  1704. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1705. carla_debug("carla_randomize_parameters(%i)", pluginId);
  1706. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1707. return plugin->randomizeParameters();
  1708. carla_stderr2("carla_randomize_parameters(%i) - could not find plugin", pluginId);
  1709. }
  1710. #ifndef BUILD_BRIDGE
  1711. void carla_send_midi_note(uint pluginId, uint8_t channel, uint8_t note, uint8_t velocity)
  1712. {
  1713. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);
  1714. carla_debug("carla_send_midi_note(%i, %i, %i, %i)", pluginId, channel, note, velocity);
  1715. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1716. return plugin->sendMidiSingleNote(channel, note, velocity, true, true, false);
  1717. carla_stderr2("carla_send_midi_note(%i, %i, %i, %i) - could not find plugin", pluginId, channel, note, velocity);
  1718. }
  1719. #endif
  1720. void carla_show_custom_ui(uint pluginId, bool yesNo)
  1721. {
  1722. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,);
  1723. carla_debug("carla_show_custom_ui(%i, %s)", pluginId, bool2str(yesNo));
  1724. if (CarlaPlugin* const plugin = gStandalone.engine->getPlugin(pluginId))
  1725. return plugin->showCustomUI(yesNo);
  1726. carla_stderr2("carla_show_custom_ui(%i, %s) - could not find plugin", pluginId, bool2str(yesNo));
  1727. }
  1728. // -------------------------------------------------------------------------------------------------------------------
  1729. uint32_t carla_get_buffer_size()
  1730. {
  1731. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0);
  1732. carla_debug("carla_get_buffer_size()");
  1733. return gStandalone.engine->getBufferSize();
  1734. }
  1735. double carla_get_sample_rate()
  1736. {
  1737. CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0.0);
  1738. carla_debug("carla_get_sample_rate()");
  1739. return gStandalone.engine->getSampleRate();
  1740. }
  1741. // -------------------------------------------------------------------------------------------------------------------
  1742. const char* carla_get_last_error()
  1743. {
  1744. carla_debug("carla_get_last_error()");
  1745. if (gStandalone.engine != nullptr)
  1746. return gStandalone.engine->getLastError();
  1747. return gStandalone.lastError;
  1748. }
  1749. const char* carla_get_host_osc_url_tcp()
  1750. {
  1751. carla_debug("carla_get_host_osc_url_tcp()");
  1752. if (gStandalone.engine == nullptr)
  1753. {
  1754. carla_stderr2("Engine is not running");
  1755. gStandalone.lastError = "Engine is not running";
  1756. return nullptr;
  1757. }
  1758. return gStandalone.engine->getOscServerPathTCP();
  1759. }
  1760. const char* carla_get_host_osc_url_udp()
  1761. {
  1762. carla_debug("carla_get_host_osc_url_udp()");
  1763. if (gStandalone.engine == nullptr)
  1764. {
  1765. carla_stderr2("Engine is not running");
  1766. gStandalone.lastError = "Engine is not running";
  1767. return nullptr;
  1768. }
  1769. return gStandalone.engine->getOscServerPathUDP();
  1770. }
  1771. // -------------------------------------------------------------------------------------------------------------------
  1772. #include "CarlaPluginUI.cpp"
  1773. #include "CarlaDssiUtils.cpp"
  1774. #include "CarlaStateUtils.cpp"
  1775. #include "CarlaJuceEvents.cpp"
  1776. // -------------------------------------------------------------------------------------------------------------------