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 77KB

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