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

6 years ago
10 years ago
6 years ago
6 years ago
6 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
6 years ago
11 years ago
6 years ago
6 years ago
6 years ago
11 years ago
6 years ago
11 years ago
11 years ago
11 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
11 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 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
6 years ago
11 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 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
6 years ago
11 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
6 years ago
10 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413
  1. /*
  2. * Carla Standalone
  3. * Copyright (C) 2011-2022 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 "CarlaHostImpl.hpp"
  20. #include "CarlaMIDI.h"
  21. #include "CarlaEngineInit.hpp"
  22. #include "CarlaPlugin.hpp"
  23. #include "CarlaBackendUtils.hpp"
  24. #include "CarlaBase64Utils.hpp"
  25. #include "ThreadSafeFFTW.hpp"
  26. #if !(defined(BUILD_BRIDGE) || defined(CARLA_OS_WASM))
  27. # define CARLA_CAN_USE_LOG_THREAD
  28. # include "CarlaLogThread.hpp"
  29. #endif
  30. #include "water/files/File.h"
  31. #ifdef USING_JUCE
  32. # include "carla_juce/carla_juce.h"
  33. #endif
  34. #define CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(cond, msg, ret) \
  35. if (! (cond)) { \
  36. carla_stderr2("%s: " msg, __FUNCTION__); \
  37. if (handle->isStandalone) \
  38. ((CarlaHostStandalone*)handle)->lastError = msg; \
  39. return ret; \
  40. }
  41. // -------------------------------------------------------------------------------------------------------------------
  42. // Always return a valid string ptr for standalone functions
  43. static const char* const gNullCharPtr = "";
  44. static void checkStringPtr(const char*& charPtr) noexcept
  45. {
  46. if (charPtr == nullptr)
  47. charPtr = gNullCharPtr;
  48. }
  49. // -------------------------------------------------------------------------------------------------------------------
  50. // Constructors
  51. _CarlaPluginInfo::_CarlaPluginInfo() noexcept
  52. : type(CB::PLUGIN_NONE),
  53. category(CB::PLUGIN_CATEGORY_NONE),
  54. hints(0x0),
  55. optionsAvailable(0x0),
  56. optionsEnabled(0x0),
  57. filename(gNullCharPtr),
  58. name(gNullCharPtr),
  59. label(gNullCharPtr),
  60. maker(gNullCharPtr),
  61. copyright(gNullCharPtr),
  62. iconName(gNullCharPtr),
  63. uniqueId(0) {}
  64. _CarlaPluginInfo::~_CarlaPluginInfo() noexcept
  65. {
  66. if (label != gNullCharPtr)
  67. delete[] label;
  68. if (maker != gNullCharPtr)
  69. delete[] maker;
  70. if (copyright != gNullCharPtr)
  71. delete[] copyright;
  72. }
  73. _CarlaParameterInfo::_CarlaParameterInfo() noexcept
  74. : name(gNullCharPtr),
  75. symbol(gNullCharPtr),
  76. unit(gNullCharPtr),
  77. comment(gNullCharPtr),
  78. groupName(gNullCharPtr),
  79. scalePointCount(0) {}
  80. _CarlaParameterInfo::~_CarlaParameterInfo() noexcept
  81. {
  82. if (name != gNullCharPtr)
  83. delete[] name;
  84. if (symbol != gNullCharPtr)
  85. delete[] symbol;
  86. if (unit != gNullCharPtr)
  87. delete[] unit;
  88. if (comment != gNullCharPtr)
  89. delete[] comment;
  90. if (groupName != gNullCharPtr)
  91. delete[] groupName;
  92. }
  93. _CarlaScalePointInfo::_CarlaScalePointInfo() noexcept
  94. : value(0.0f),
  95. label(gNullCharPtr) {}
  96. _CarlaScalePointInfo::~_CarlaScalePointInfo() noexcept
  97. {
  98. if (label != gNullCharPtr)
  99. delete[] label;
  100. }
  101. _CarlaTransportInfo::_CarlaTransportInfo() noexcept
  102. : playing(false),
  103. frame(0),
  104. bar(0),
  105. beat(0),
  106. tick(0),
  107. bpm(0.0) {}
  108. void _CarlaTransportInfo::clear() noexcept
  109. {
  110. playing = false;
  111. frame = 0;
  112. bar = 0;
  113. beat = 0;
  114. tick = 0;
  115. bpm = 0.0;
  116. }
  117. // --------------------------------------------------------------------------------------------------------------------
  118. using CARLA_BACKEND_NAMESPACE::CarlaPluginPtr;
  119. // --------------------------------------------------------------------------------------------------------------------
  120. uint carla_get_engine_driver_count()
  121. {
  122. carla_debug("carla_get_engine_driver_count()");
  123. return CarlaEngine::getDriverCount();
  124. }
  125. const char* carla_get_engine_driver_name(uint index)
  126. {
  127. carla_debug("carla_get_engine_driver_name(%i)", index);
  128. return CarlaEngine::getDriverName(index);
  129. }
  130. const char* const* carla_get_engine_driver_device_names(uint index)
  131. {
  132. carla_debug("carla_get_engine_driver_device_names(%i)", index);
  133. return CarlaEngine::getDriverDeviceNames(index);
  134. }
  135. const EngineDriverDeviceInfo* carla_get_engine_driver_device_info(uint index, const char* name)
  136. {
  137. CARLA_SAFE_ASSERT_RETURN(name != nullptr, nullptr);
  138. static EngineDriverDeviceInfo retDevInfo;
  139. static const uint32_t nullBufferSizes[] = { 0 };
  140. static const double nullSampleRates[] = { 0.0 };
  141. carla_debug("carla_get_engine_driver_device_info(%i, \"%s\")", index, name);
  142. if (const EngineDriverDeviceInfo* const devInfo = CarlaEngine::getDriverDeviceInfo(index, name))
  143. {
  144. retDevInfo.hints = devInfo->hints;
  145. retDevInfo.bufferSizes = (devInfo->bufferSizes != nullptr) ? devInfo->bufferSizes : nullBufferSizes;
  146. retDevInfo.sampleRates = (devInfo->sampleRates != nullptr) ? devInfo->sampleRates : nullSampleRates;
  147. }
  148. else
  149. {
  150. retDevInfo.hints = 0x0;
  151. retDevInfo.bufferSizes = nullBufferSizes;
  152. retDevInfo.sampleRates = nullSampleRates;
  153. }
  154. return &retDevInfo;
  155. }
  156. bool carla_show_engine_driver_device_control_panel(uint index, const char* name)
  157. {
  158. return CarlaEngine::showDriverDeviceControlPanel(index, name);
  159. }
  160. // --------------------------------------------------------------------------------------------------------------------
  161. CarlaHostHandle carla_standalone_host_init(void)
  162. {
  163. #ifdef CARLA_OS_UNIX
  164. static const ThreadSafeFFTW sThreadSafeFFTW;
  165. #endif
  166. static CarlaHostStandalone gStandalone;
  167. return &gStandalone;
  168. }
  169. CarlaEngine* carla_get_engine_from_handle(CarlaHostHandle handle)
  170. {
  171. carla_debug("carla_get_engine(%p)", handle);
  172. return handle->engine;
  173. }
  174. // --------------------------------------------------------------------------------------------------------------------
  175. static void carla_engine_init_common(const CarlaHostStandalone& standalone, CarlaEngine* const engine)
  176. {
  177. engine->setCallback(standalone.engineCallback, standalone.engineCallbackPtr);
  178. engine->setFileCallback(standalone.fileCallback, standalone.fileCallbackPtr);
  179. using water::File;
  180. const File waterBinaryDir(File::getSpecialLocation(File::currentExecutableFile).getParentDirectory());
  181. #ifdef BUILD_BRIDGE
  182. /*
  183. if (const char* const forceStereo = std::getenv("ENGINE_OPTION_FORCE_STEREO"))
  184. engine->setOption(CB::ENGINE_OPTION_FORCE_STEREO, (std::strcmp(forceStereo, "true") == 0) ? 1 : 0, nullptr);
  185. if (const char* const preferPluginBridges = std::getenv("ENGINE_OPTION_PREFER_PLUGIN_BRIDGES"))
  186. engine->setOption(CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, (std::strcmp(preferPluginBridges, "true") == 0) ? 1 : 0, nullptr);
  187. if (const char* const preferUiBridges = std::getenv("ENGINE_OPTION_PREFER_UI_BRIDGES"))
  188. engine->setOption(CB::ENGINE_OPTION_PREFER_UI_BRIDGES, (std::strcmp(preferUiBridges, "true") == 0) ? 1 : 0, nullptr);
  189. */
  190. if (const char* const uisAlwaysOnTop = std::getenv("ENGINE_OPTION_UIS_ALWAYS_ON_TOP"))
  191. engine->setOption(CB::ENGINE_OPTION_UIS_ALWAYS_ON_TOP, (std::strcmp(uisAlwaysOnTop, "true") == 0) ? 1 : 0, nullptr);
  192. if (const char* const maxParameters = std::getenv("ENGINE_OPTION_MAX_PARAMETERS"))
  193. engine->setOption(CB::ENGINE_OPTION_MAX_PARAMETERS, std::atoi(maxParameters), nullptr);
  194. if (const char* const resetXruns = std::getenv("ENGINE_OPTION_RESET_XRUNS"))
  195. engine->setOption(CB::ENGINE_OPTION_RESET_XRUNS, (std::strcmp(resetXruns, "true") == 0) ? 1 : 0, nullptr);
  196. if (const char* const uiBridgesTimeout = std::getenv("ENGINE_OPTION_UI_BRIDGES_TIMEOUT"))
  197. engine->setOption(CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT, std::atoi(uiBridgesTimeout), nullptr);
  198. if (const char* const pathAudio = std::getenv("ENGINE_OPTION_FILE_PATH_AUDIO"))
  199. engine->setOption(CB::ENGINE_OPTION_FILE_PATH, CB::FILE_AUDIO, pathAudio);
  200. if (const char* const pathMIDI = std::getenv("ENGINE_OPTION_FILE_PATH_MIDI"))
  201. engine->setOption(CB::ENGINE_OPTION_FILE_PATH, CB::FILE_MIDI, pathMIDI);
  202. if (const char* const pathLADSPA = std::getenv("ENGINE_OPTION_PLUGIN_PATH_LADSPA"))
  203. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_LADSPA, pathLADSPA);
  204. if (const char* const pathDSSI = std::getenv("ENGINE_OPTION_PLUGIN_PATH_DSSI"))
  205. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_DSSI, pathDSSI);
  206. if (const char* const pathLV2 = std::getenv("ENGINE_OPTION_PLUGIN_PATH_LV2"))
  207. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_LV2, pathLV2);
  208. if (const char* const pathVST2 = std::getenv("ENGINE_OPTION_PLUGIN_PATH_VST2"))
  209. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_VST2, pathVST2);
  210. if (const char* const pathVST3 = std::getenv("ENGINE_OPTION_PLUGIN_PATH_VST3"))
  211. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_VST3, pathVST3);
  212. if (const char* const pathSF2 = std::getenv("ENGINE_OPTION_PLUGIN_PATH_SF2"))
  213. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_SF2, pathSF2);
  214. if (const char* const pathSFZ = std::getenv("ENGINE_OPTION_PLUGIN_PATH_SFZ"))
  215. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_SFZ, pathSFZ);
  216. if (const char* const pathJSFX = std::getenv("ENGINE_OPTION_PLUGIN_PATH_JSFX"))
  217. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_JSFX, pathJSFX);
  218. if (const char* const binaryDir = std::getenv("ENGINE_OPTION_PATH_BINARIES"))
  219. engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, binaryDir);
  220. else
  221. engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, waterBinaryDir.getFullPathName().toRawUTF8());
  222. if (const char* const resourceDir = std::getenv("ENGINE_OPTION_PATH_RESOURCES"))
  223. engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, resourceDir);
  224. else
  225. engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, waterBinaryDir.getChildFile("resources").getFullPathName().toRawUTF8());
  226. if (const char* const preventBadBehaviour = std::getenv("ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR"))
  227. engine->setOption(CB::ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR, (std::strcmp(preventBadBehaviour, "true") == 0) ? 1 : 0, nullptr);
  228. if (const char* const frontendWinId = std::getenv("ENGINE_OPTION_FRONTEND_WIN_ID"))
  229. engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, frontendWinId);
  230. #else
  231. engine->setOption(CB::ENGINE_OPTION_FORCE_STEREO, standalone.engineOptions.forceStereo ? 1 : 0, nullptr);
  232. engine->setOption(CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, standalone.engineOptions.preferPluginBridges ? 1 : 0, nullptr);
  233. engine->setOption(CB::ENGINE_OPTION_PREFER_UI_BRIDGES, standalone.engineOptions.preferUiBridges ? 1 : 0, nullptr);
  234. engine->setOption(CB::ENGINE_OPTION_UIS_ALWAYS_ON_TOP, standalone.engineOptions.uisAlwaysOnTop ? 1 : 0, nullptr);
  235. engine->setOption(CB::ENGINE_OPTION_MAX_PARAMETERS, static_cast<int>(standalone.engineOptions.maxParameters), nullptr);
  236. engine->setOption(CB::ENGINE_OPTION_RESET_XRUNS, standalone.engineOptions.resetXruns ? 1 : 0, nullptr);
  237. engine->setOption(CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT, static_cast<int>(standalone.engineOptions.uiBridgesTimeout), nullptr);
  238. engine->setOption(CB::ENGINE_OPTION_AUDIO_BUFFER_SIZE, static_cast<int>(standalone.engineOptions.audioBufferSize), nullptr);
  239. engine->setOption(CB::ENGINE_OPTION_AUDIO_SAMPLE_RATE, static_cast<int>(standalone.engineOptions.audioSampleRate), nullptr);
  240. engine->setOption(CB::ENGINE_OPTION_AUDIO_TRIPLE_BUFFER, standalone.engineOptions.audioTripleBuffer ? 1 : 0, nullptr);
  241. if (standalone.engineOptions.audioDriver != nullptr)
  242. engine->setOption(CB::ENGINE_OPTION_AUDIO_DRIVER, 0, standalone.engineOptions.audioDriver);
  243. if (standalone.engineOptions.audioDevice != nullptr)
  244. engine->setOption(CB::ENGINE_OPTION_AUDIO_DEVICE, 0, standalone.engineOptions.audioDevice);
  245. engine->setOption(CB::ENGINE_OPTION_OSC_ENABLED, standalone.engineOptions.oscEnabled, nullptr);
  246. engine->setOption(CB::ENGINE_OPTION_OSC_PORT_TCP, standalone.engineOptions.oscPortTCP, nullptr);
  247. engine->setOption(CB::ENGINE_OPTION_OSC_PORT_UDP, standalone.engineOptions.oscPortUDP, nullptr);
  248. if (standalone.engineOptions.pathAudio != nullptr)
  249. engine->setOption(CB::ENGINE_OPTION_FILE_PATH, CB::FILE_AUDIO, standalone.engineOptions.pathAudio);
  250. if (standalone.engineOptions.pathMIDI != nullptr)
  251. engine->setOption(CB::ENGINE_OPTION_FILE_PATH, CB::FILE_MIDI, standalone.engineOptions.pathMIDI);
  252. if (standalone.engineOptions.pathLADSPA != nullptr)
  253. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_LADSPA, standalone.engineOptions.pathLADSPA);
  254. if (standalone.engineOptions.pathDSSI != nullptr)
  255. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_DSSI, standalone.engineOptions.pathDSSI);
  256. if (standalone.engineOptions.pathLV2 != nullptr)
  257. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_LV2, standalone.engineOptions.pathLV2);
  258. if (standalone.engineOptions.pathVST2 != nullptr)
  259. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_VST2, standalone.engineOptions.pathVST2);
  260. if (standalone.engineOptions.pathVST3 != nullptr)
  261. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_VST3, standalone.engineOptions.pathVST3);
  262. if (standalone.engineOptions.pathSF2 != nullptr)
  263. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_SF2, standalone.engineOptions.pathSF2);
  264. if (standalone.engineOptions.pathSFZ != nullptr)
  265. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_SFZ, standalone.engineOptions.pathSFZ);
  266. if (standalone.engineOptions.pathJSFX != nullptr)
  267. engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_JSFX, standalone.engineOptions.pathJSFX);
  268. if (standalone.engineOptions.binaryDir != nullptr && standalone.engineOptions.binaryDir[0] != '\0')
  269. engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, standalone.engineOptions.binaryDir);
  270. else
  271. engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, waterBinaryDir.getFullPathName().toRawUTF8());
  272. if (standalone.engineOptions.resourceDir != nullptr && standalone.engineOptions.resourceDir[0] != '\0')
  273. engine->setOption(CB::ENGINE_OPTION_PATH_RESOURCES, 0, standalone.engineOptions.resourceDir);
  274. engine->setOption(CB::ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR, standalone.engineOptions.preventBadBehaviour ? 1 : 0, nullptr);
  275. engine->setOption(CB::ENGINE_OPTION_FRONTEND_BACKGROUND_COLOR, static_cast<int>(standalone.engineOptions.bgColor), nullptr);
  276. engine->setOption(CB::ENGINE_OPTION_FRONTEND_FOREGROUND_COLOR, static_cast<int>(standalone.engineOptions.fgColor), nullptr);
  277. engine->setOption(CB::ENGINE_OPTION_FRONTEND_UI_SCALE, static_cast<int>(standalone.engineOptions.uiScale * 1000.0f), nullptr);
  278. if (standalone.engineOptions.frontendWinId != 0)
  279. {
  280. char strBuf[STR_MAX+1];
  281. strBuf[STR_MAX] = '\0';
  282. std::snprintf(strBuf, STR_MAX, P_UINTPTR, standalone.engineOptions.frontendWinId);
  283. engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, strBuf);
  284. }
  285. else
  286. {
  287. engine->setOption(CB::ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0");
  288. }
  289. # ifndef CARLA_OS_WIN
  290. if (standalone.engineOptions.wine.executable != nullptr && standalone.engineOptions.wine.executable[0] != '\0')
  291. engine->setOption(CB::ENGINE_OPTION_WINE_EXECUTABLE, 0, standalone.engineOptions.wine.executable);
  292. engine->setOption(CB::ENGINE_OPTION_WINE_AUTO_PREFIX, standalone.engineOptions.wine.autoPrefix ? 1 : 0, nullptr);
  293. if (standalone.engineOptions.wine.fallbackPrefix != nullptr && standalone.engineOptions.wine.fallbackPrefix[0] != '\0')
  294. engine->setOption(CB::ENGINE_OPTION_WINE_FALLBACK_PREFIX, 0, standalone.engineOptions.wine.fallbackPrefix);
  295. engine->setOption(CB::ENGINE_OPTION_WINE_RT_PRIO_ENABLED, standalone.engineOptions.wine.rtPrio ? 1 : 0, nullptr);
  296. engine->setOption(CB::ENGINE_OPTION_WINE_BASE_RT_PRIO, standalone.engineOptions.wine.baseRtPrio, nullptr);
  297. engine->setOption(CB::ENGINE_OPTION_WINE_SERVER_RT_PRIO, standalone.engineOptions.wine.serverRtPrio, nullptr);
  298. # endif
  299. engine->setOption(CB::ENGINE_OPTION_CLIENT_NAME_PREFIX, 0, standalone.engineOptions.clientNamePrefix);
  300. engine->setOption(CB::ENGINE_OPTION_PLUGINS_ARE_STANDALONE, standalone.engineOptions.pluginsAreStandalone, nullptr);
  301. #endif // BUILD_BRIDGE
  302. }
  303. bool carla_engine_init(CarlaHostHandle handle, const char* driverName, const char* clientName)
  304. {
  305. CARLA_SAFE_ASSERT_RETURN(driverName != nullptr && driverName[0] != '\0', false);
  306. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
  307. carla_debug("carla_engine_init(%p, \"%s\", \"%s\")", handle, driverName, clientName);
  308. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->isStandalone, "Must be a standalone host handle", false);
  309. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine == nullptr, "Engine is already initialized", false);
  310. #ifdef CARLA_OS_WIN
  311. carla_setenv("WINEASIO_CLIENT_NAME", clientName);
  312. #endif
  313. #ifdef USING_JUCE
  314. CarlaJUCE::initialiseJuce_GUI();
  315. #endif
  316. CarlaHostStandalone& shandle((CarlaHostStandalone&)*handle);
  317. CarlaEngine* const engine = CarlaEngine::newDriverByName(driverName);
  318. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(engine != nullptr, "The selected audio driver is not available", false);
  319. shandle.engine = engine;
  320. #ifdef BUILD_BRIDGE
  321. if (std::getenv("CARLA_BRIDGE_DUMMY") != nullptr)
  322. {
  323. // engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_PATCHBAY, nullptr);
  324. engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_CONTINUOUS_RACK, nullptr);
  325. engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, CB::ENGINE_TRANSPORT_MODE_INTERNAL, nullptr);
  326. engine->setOption(CB::ENGINE_OPTION_AUDIO_BUFFER_SIZE, 4096, nullptr);
  327. engine->setOption(CB::ENGINE_OPTION_AUDIO_SAMPLE_RATE, 48000, nullptr);
  328. }
  329. else
  330. {
  331. engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, nullptr);
  332. engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, CB::ENGINE_TRANSPORT_MODE_JACK, nullptr);
  333. }
  334. engine->setOption(CB::ENGINE_OPTION_FORCE_STEREO, false, nullptr);
  335. engine->setOption(CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, false, nullptr);
  336. engine->setOption(CB::ENGINE_OPTION_PREFER_UI_BRIDGES, false, nullptr);
  337. #else
  338. engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, static_cast<int>(shandle.engineOptions.processMode), nullptr);
  339. engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, static_cast<int>(shandle.engineOptions.transportMode), shandle.engineOptions.transportExtra);
  340. #endif
  341. carla_engine_init_common(shandle, engine);
  342. if (engine->init(clientName))
  343. {
  344. #ifdef CARLA_CAN_USE_LOG_THREAD
  345. if (shandle.logThreadEnabled && std::getenv("CARLA_LOGS_DISABLED") == nullptr)
  346. shandle.logThread.init();
  347. #endif
  348. shandle.lastError = "No error";
  349. return true;
  350. }
  351. else
  352. {
  353. shandle.lastError = engine->getLastError();
  354. shandle.engine = nullptr;
  355. delete engine;
  356. #ifdef USING_JUCE
  357. CarlaJUCE::shutdownJuce_GUI();
  358. #endif
  359. return false;
  360. }
  361. }
  362. #ifdef BUILD_BRIDGE
  363. bool carla_engine_init_bridge(CarlaHostHandle handle,
  364. const char audioBaseName[6+1],
  365. const char rtClientBaseName[6+1],
  366. const char nonRtClientBaseName[6+1],
  367. const char nonRtServerBaseName[6+1],
  368. const char* const clientName)
  369. {
  370. CARLA_SAFE_ASSERT_RETURN(audioBaseName != nullptr && audioBaseName[0] != '\0', false);
  371. CARLA_SAFE_ASSERT_RETURN(rtClientBaseName != nullptr && rtClientBaseName[0] != '\0', false);
  372. CARLA_SAFE_ASSERT_RETURN(nonRtClientBaseName != nullptr && nonRtClientBaseName[0] != '\0', false);
  373. CARLA_SAFE_ASSERT_RETURN(nonRtServerBaseName != nullptr && nonRtServerBaseName[0] != '\0', false);
  374. CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
  375. carla_debug("carla_engine_init_bridge(%p, \"%s\", \"%s\", \"%s\", \"%s\", \"%s\")",
  376. handle, audioBaseName, rtClientBaseName, nonRtClientBaseName, nonRtServerBaseName, clientName);
  377. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->isStandalone, "Must be a standalone host handle", false);
  378. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine == nullptr, "Engine is already initialized", false);
  379. CarlaScopedPointer<CarlaEngine> engine(CB::EngineInit::newBridge(audioBaseName,
  380. rtClientBaseName,
  381. nonRtClientBaseName,
  382. nonRtServerBaseName));
  383. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(engine != nullptr, "The selected audio driver is not available", false);
  384. engine->setOption(CB::ENGINE_OPTION_PROCESS_MODE, CB::ENGINE_PROCESS_MODE_BRIDGE, nullptr);
  385. engine->setOption(CB::ENGINE_OPTION_TRANSPORT_MODE, CB::ENGINE_TRANSPORT_MODE_BRIDGE, nullptr);
  386. CarlaHostStandalone& shandle((CarlaHostStandalone&)*handle);
  387. carla_engine_init_common(shandle, engine);
  388. if (engine->init(clientName))
  389. {
  390. shandle.lastError = "No error";
  391. shandle.engine = engine.release();
  392. return true;
  393. }
  394. else
  395. {
  396. shandle.lastError = engine->getLastError();
  397. return false;
  398. }
  399. }
  400. #endif
  401. bool carla_engine_close(CarlaHostHandle handle)
  402. {
  403. carla_debug("carla_engine_close(%p)", handle);
  404. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->isStandalone, "Must be a standalone host handle", false);
  405. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  406. CarlaHostStandalone& shandle((CarlaHostStandalone&)*handle);
  407. CarlaEngine* const engine = shandle.engine;
  408. engine->setAboutToClose();
  409. engine->removeAllPlugins();
  410. const bool closed = engine->close();
  411. if (! closed)
  412. shandle.lastError = engine->getLastError();
  413. #ifdef CARLA_CAN_USE_LOG_THREAD
  414. shandle.logThread.stop();
  415. #endif
  416. shandle.engine = nullptr;
  417. delete engine;
  418. #ifdef USING_JUCE
  419. CarlaJUCE::shutdownJuce_GUI();
  420. #endif
  421. return closed;
  422. }
  423. void carla_engine_idle(CarlaHostHandle handle)
  424. {
  425. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->isStandalone,);
  426. handle->engine->idle();
  427. #ifdef USING_JUCE
  428. if (handle->isStandalone)
  429. CarlaJUCE::idleJuce_GUI();
  430. #endif
  431. }
  432. bool carla_is_engine_running(CarlaHostHandle handle)
  433. {
  434. return (handle->engine != nullptr && handle->engine->isRunning());
  435. }
  436. const CarlaRuntimeEngineInfo* carla_get_runtime_engine_info(CarlaHostHandle handle)
  437. {
  438. static CarlaRuntimeEngineInfo retInfo;
  439. // reset
  440. retInfo.load = 0.0f;
  441. retInfo.xruns = 0;
  442. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retInfo);
  443. retInfo.load = handle->engine->getDSPLoad();
  444. retInfo.xruns = handle->engine->getTotalXruns();
  445. return &retInfo;
  446. }
  447. #ifndef BUILD_BRIDGE
  448. const CarlaRuntimeEngineDriverDeviceInfo* carla_get_runtime_engine_driver_device_info(CarlaHostHandle handle)
  449. {
  450. static CarlaRuntimeEngineDriverDeviceInfo retInfo;
  451. // reset
  452. retInfo.name = gNullCharPtr;
  453. retInfo.hints = 0x0;
  454. retInfo.bufferSize = 0;
  455. retInfo.bufferSizes = nullptr;
  456. retInfo.sampleRate = 0.0;
  457. retInfo.sampleRates = nullptr;
  458. const char* audioDriver;
  459. const char* audioDevice;
  460. if (CarlaEngine* const engine = handle->engine)
  461. {
  462. audioDriver = engine->getCurrentDriverName();
  463. audioDevice = engine->getOptions().audioDevice;
  464. retInfo.bufferSize = engine->getBufferSize();
  465. retInfo.sampleRate = engine->getSampleRate();
  466. }
  467. else if (handle->isStandalone)
  468. {
  469. CarlaHostStandalone& shandle((CarlaHostStandalone&)*handle);
  470. audioDriver = shandle.engineOptions.audioDriver;
  471. audioDevice = shandle.engineOptions.audioDevice;
  472. retInfo.bufferSize = shandle.engineOptions.audioBufferSize;
  473. retInfo.sampleRate = shandle.engineOptions.audioSampleRate;
  474. }
  475. else
  476. {
  477. return &retInfo;
  478. }
  479. CARLA_SAFE_ASSERT_RETURN(audioDriver != nullptr, &retInfo);
  480. CARLA_SAFE_ASSERT_RETURN(audioDevice != nullptr, &retInfo);
  481. uint index = 0;
  482. uint count = CarlaEngine::getDriverCount();
  483. for (; index<count; ++index)
  484. {
  485. const char* const testDriverName = CarlaEngine::getDriverName(index);
  486. CARLA_SAFE_ASSERT_CONTINUE(testDriverName != nullptr);
  487. if (std::strcmp(testDriverName, audioDriver) == 0)
  488. break;
  489. }
  490. CARLA_SAFE_ASSERT_RETURN(index != count, &retInfo);
  491. const EngineDriverDeviceInfo* const devInfo = CarlaEngine::getDriverDeviceInfo(index, audioDevice);
  492. CARLA_SAFE_ASSERT_RETURN(devInfo != nullptr, &retInfo);
  493. retInfo.name = audioDevice;
  494. retInfo.hints = devInfo->hints;
  495. retInfo.bufferSizes = devInfo->bufferSizes;
  496. retInfo.sampleRates = devInfo->sampleRates;
  497. return &retInfo;
  498. }
  499. bool carla_set_engine_buffer_size_and_sample_rate(CarlaHostHandle handle, uint bufferSize, double sampleRate)
  500. {
  501. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, false);
  502. carla_debug("carla_set_engine_buffer_size_and_sample_rate(%p, %u, %f)", handle, bufferSize, sampleRate);
  503. return handle->engine->setBufferSizeAndSampleRate(bufferSize, sampleRate);
  504. }
  505. bool carla_show_engine_device_control_panel(CarlaHostHandle handle)
  506. {
  507. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, false);
  508. carla_debug("carla_show_engine_device_control_panel(%p)", handle);
  509. return handle->engine->showDeviceControlPanel();
  510. }
  511. #endif // BUILD_BRIDGE
  512. void carla_clear_engine_xruns(CarlaHostHandle handle)
  513. {
  514. if (handle->engine != nullptr)
  515. handle->engine->clearXruns();
  516. }
  517. void carla_cancel_engine_action(CarlaHostHandle handle)
  518. {
  519. if (handle->engine != nullptr)
  520. handle->engine->setActionCanceled(true);
  521. }
  522. bool carla_set_engine_about_to_close(CarlaHostHandle handle)
  523. {
  524. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, true);
  525. carla_debug("carla_set_engine_about_to_close(%p)", handle);
  526. return handle->engine->setAboutToClose();
  527. }
  528. void carla_set_engine_callback(CarlaHostHandle handle, EngineCallbackFunc func, void* ptr)
  529. {
  530. carla_debug("carla_set_engine_callback(%p, %p, %p)", handle, func, ptr);
  531. if (handle->isStandalone)
  532. {
  533. CarlaHostStandalone& shandle((CarlaHostStandalone&)*handle);
  534. shandle.engineCallback = func;
  535. shandle.engineCallbackPtr = ptr;
  536. #ifdef CARLA_CAN_USE_LOG_THREAD
  537. shandle.logThread.setCallback(func, ptr);
  538. #endif
  539. }
  540. if (handle->engine != nullptr)
  541. handle->engine->setCallback(func, ptr);
  542. }
  543. void carla_set_engine_option(CarlaHostHandle handle, EngineOption option, int value, const char* valueStr)
  544. {
  545. carla_debug("carla_set_engine_option(%p, %i:%s, %i, \"%s\")",
  546. handle, option, CB::EngineOption2Str(option), value, valueStr);
  547. if (handle->isStandalone)
  548. {
  549. CarlaHostStandalone& shandle((CarlaHostStandalone&)*handle);
  550. switch (option)
  551. {
  552. case CB::ENGINE_OPTION_DEBUG:
  553. break;
  554. case CB::ENGINE_OPTION_PROCESS_MODE:
  555. CARLA_SAFE_ASSERT_RETURN(value >= CB::ENGINE_PROCESS_MODE_SINGLE_CLIENT && value < CB::ENGINE_PROCESS_MODE_BRIDGE,);
  556. shandle.engineOptions.processMode = static_cast<CB::EngineProcessMode>(value);
  557. break;
  558. case CB::ENGINE_OPTION_TRANSPORT_MODE:
  559. CARLA_SAFE_ASSERT_RETURN(value >= CB::ENGINE_TRANSPORT_MODE_DISABLED && value <= CB::ENGINE_TRANSPORT_MODE_BRIDGE,);
  560. // jack transport cannot be disabled in multi-client
  561. if (shandle.engineOptions.processMode == CB::ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS
  562. && value != CB::ENGINE_TRANSPORT_MODE_JACK)
  563. {
  564. shandle.engineOptions.transportMode = CB::ENGINE_TRANSPORT_MODE_JACK;
  565. if (shandle.engineCallback != nullptr)
  566. shandle.engineCallback(shandle.engineCallbackPtr,
  567. CB::ENGINE_CALLBACK_TRANSPORT_MODE_CHANGED,
  568. 0,
  569. CB::ENGINE_TRANSPORT_MODE_JACK,
  570. 0, 0, 0.0f,
  571. shandle.engineOptions.transportExtra);
  572. }
  573. else
  574. {
  575. shandle.engineOptions.transportMode = static_cast<CB::EngineTransportMode>(value);
  576. }
  577. delete[] shandle.engineOptions.transportExtra;
  578. if (value != CB::ENGINE_TRANSPORT_MODE_DISABLED && valueStr != nullptr)
  579. shandle.engineOptions.transportExtra = carla_strdup_safe(valueStr);
  580. else
  581. shandle.engineOptions.transportExtra = nullptr;
  582. break;
  583. case CB::ENGINE_OPTION_FORCE_STEREO:
  584. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  585. shandle.engineOptions.forceStereo = (value != 0);
  586. break;
  587. case CB::ENGINE_OPTION_PREFER_PLUGIN_BRIDGES:
  588. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  589. shandle.engineOptions.preferPluginBridges = (value != 0);
  590. break;
  591. case CB::ENGINE_OPTION_PREFER_UI_BRIDGES:
  592. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  593. shandle.engineOptions.preferUiBridges = (value != 0);
  594. break;
  595. case CB::ENGINE_OPTION_UIS_ALWAYS_ON_TOP:
  596. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  597. shandle.engineOptions.uisAlwaysOnTop = (value != 0);
  598. break;
  599. case CB::ENGINE_OPTION_MAX_PARAMETERS:
  600. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  601. shandle.engineOptions.maxParameters = static_cast<uint>(value);
  602. break;
  603. case CB::ENGINE_OPTION_RESET_XRUNS:
  604. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  605. shandle.engineOptions.resetXruns = (value != 0);
  606. break;
  607. case CB::ENGINE_OPTION_UI_BRIDGES_TIMEOUT:
  608. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  609. shandle.engineOptions.uiBridgesTimeout = static_cast<uint>(value);
  610. break;
  611. case CB::ENGINE_OPTION_AUDIO_BUFFER_SIZE:
  612. CARLA_SAFE_ASSERT_RETURN(value >= 8,);
  613. shandle.engineOptions.audioBufferSize = static_cast<uint>(value);
  614. break;
  615. case CB::ENGINE_OPTION_AUDIO_SAMPLE_RATE:
  616. CARLA_SAFE_ASSERT_RETURN(value >= 22050,);
  617. shandle.engineOptions.audioSampleRate = static_cast<uint>(value);
  618. break;
  619. case CB::ENGINE_OPTION_AUDIO_TRIPLE_BUFFER:
  620. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  621. shandle.engineOptions.audioTripleBuffer = (value != 0);
  622. break;
  623. case CB::ENGINE_OPTION_AUDIO_DRIVER:
  624. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr,);
  625. if (shandle.engineOptions.audioDriver != nullptr)
  626. delete[] shandle.engineOptions.audioDriver;
  627. shandle.engineOptions.audioDriver = carla_strdup_safe(valueStr);
  628. break;
  629. case CB::ENGINE_OPTION_AUDIO_DEVICE:
  630. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr,);
  631. if (shandle.engineOptions.audioDevice != nullptr)
  632. delete[] shandle.engineOptions.audioDevice;
  633. shandle.engineOptions.audioDevice = carla_strdup_safe(valueStr);
  634. break;
  635. #ifndef BUILD_BRIDGE
  636. case CB::ENGINE_OPTION_OSC_ENABLED:
  637. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  638. shandle.engineOptions.oscEnabled = (value != 0);
  639. break;
  640. case CB::ENGINE_OPTION_OSC_PORT_TCP:
  641. CARLA_SAFE_ASSERT_RETURN(value <= 0 || value >= 1024,);
  642. shandle.engineOptions.oscPortTCP = value;
  643. break;
  644. case CB::ENGINE_OPTION_OSC_PORT_UDP:
  645. CARLA_SAFE_ASSERT_RETURN(value <= 0 || value >= 1024,);
  646. shandle.engineOptions.oscPortUDP = value;
  647. break;
  648. #endif
  649. case CB::ENGINE_OPTION_FILE_PATH:
  650. CARLA_SAFE_ASSERT_RETURN(value > CB::FILE_NONE,);
  651. CARLA_SAFE_ASSERT_RETURN(value <= CB::FILE_MIDI,);
  652. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr,);
  653. switch (value)
  654. {
  655. case CB::FILE_AUDIO:
  656. if (shandle.engineOptions.pathAudio != nullptr)
  657. delete[] shandle.engineOptions.pathAudio;
  658. shandle.engineOptions.pathAudio = carla_strdup_safe(valueStr);
  659. break;
  660. case CB::FILE_MIDI:
  661. if (shandle.engineOptions.pathMIDI != nullptr)
  662. delete[] shandle.engineOptions.pathMIDI;
  663. shandle.engineOptions.pathMIDI = carla_strdup_safe(valueStr);
  664. break;
  665. }
  666. break;
  667. case CB::ENGINE_OPTION_PLUGIN_PATH:
  668. CARLA_SAFE_ASSERT_RETURN(value > CB::PLUGIN_NONE,);
  669. CARLA_SAFE_ASSERT_RETURN(value <= CB::PLUGIN_JSFX,);
  670. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr,);
  671. switch (value)
  672. {
  673. case CB::PLUGIN_LADSPA:
  674. if (shandle.engineOptions.pathLADSPA != nullptr)
  675. delete[] shandle.engineOptions.pathLADSPA;
  676. shandle.engineOptions.pathLADSPA = carla_strdup_safe(valueStr);
  677. break;
  678. case CB::PLUGIN_DSSI:
  679. if (shandle.engineOptions.pathDSSI != nullptr)
  680. delete[] shandle.engineOptions.pathDSSI;
  681. shandle.engineOptions.pathDSSI = carla_strdup_safe(valueStr);
  682. break;
  683. case CB::PLUGIN_LV2:
  684. if (shandle.engineOptions.pathLV2 != nullptr)
  685. delete[] shandle.engineOptions.pathLV2;
  686. shandle.engineOptions.pathLV2 = carla_strdup_safe(valueStr);
  687. break;
  688. case CB::PLUGIN_VST2:
  689. if (shandle.engineOptions.pathVST2 != nullptr)
  690. delete[] shandle.engineOptions.pathVST2;
  691. shandle.engineOptions.pathVST2 = carla_strdup_safe(valueStr);
  692. break;
  693. case CB::PLUGIN_VST3:
  694. if (shandle.engineOptions.pathVST3 != nullptr)
  695. delete[] shandle.engineOptions.pathVST3;
  696. shandle.engineOptions.pathVST3 = carla_strdup_safe(valueStr);
  697. break;
  698. case CB::PLUGIN_SF2:
  699. if (shandle.engineOptions.pathSF2 != nullptr)
  700. delete[] shandle.engineOptions.pathSF2;
  701. shandle.engineOptions.pathSF2 = carla_strdup_safe(valueStr);
  702. break;
  703. case CB::PLUGIN_SFZ:
  704. if (shandle.engineOptions.pathSFZ != nullptr)
  705. delete[] shandle.engineOptions.pathSFZ;
  706. shandle.engineOptions.pathSFZ = carla_strdup_safe(valueStr);
  707. break;
  708. case CB::PLUGIN_JSFX:
  709. if (shandle.engineOptions.pathJSFX != nullptr)
  710. delete[] shandle.engineOptions.pathJSFX;
  711. shandle.engineOptions.pathJSFX = carla_strdup_safe(valueStr);
  712. break;
  713. }
  714. break;
  715. case CB::ENGINE_OPTION_PATH_BINARIES:
  716. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  717. if (shandle.engineOptions.binaryDir != nullptr)
  718. delete[] shandle.engineOptions.binaryDir;
  719. shandle.engineOptions.binaryDir = carla_strdup_safe(valueStr);
  720. break;
  721. case CB::ENGINE_OPTION_PATH_RESOURCES:
  722. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  723. if (shandle.engineOptions.resourceDir != nullptr)
  724. delete[] shandle.engineOptions.resourceDir;
  725. shandle.engineOptions.resourceDir = carla_strdup_safe(valueStr);
  726. break;
  727. case CB::ENGINE_OPTION_PREVENT_BAD_BEHAVIOUR:
  728. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  729. shandle.engineOptions.preventBadBehaviour = (value != 0);
  730. break;
  731. case CB::ENGINE_OPTION_FRONTEND_BACKGROUND_COLOR:
  732. shandle.engineOptions.bgColor = static_cast<uint>(value);
  733. break;
  734. case CB::ENGINE_OPTION_FRONTEND_FOREGROUND_COLOR:
  735. shandle.engineOptions.fgColor = static_cast<uint>(value);
  736. break;
  737. case CB::ENGINE_OPTION_FRONTEND_UI_SCALE:
  738. CARLA_SAFE_ASSERT_RETURN(value > 0,);
  739. shandle.engineOptions.uiScale = static_cast<float>(value) / 1000;
  740. break;
  741. case CB::ENGINE_OPTION_FRONTEND_WIN_ID: {
  742. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  743. const long long winId(std::strtoll(valueStr, nullptr, 16));
  744. CARLA_SAFE_ASSERT_RETURN(winId >= 0,);
  745. shandle.engineOptions.frontendWinId = static_cast<uintptr_t>(winId);
  746. } break;
  747. #if !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH) && !defined(CARLA_OS_WIN)
  748. case CB::ENGINE_OPTION_WINE_EXECUTABLE:
  749. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  750. if (shandle.engineOptions.wine.executable != nullptr)
  751. delete[] shandle.engineOptions.wine.executable;
  752. shandle.engineOptions.wine.executable = carla_strdup_safe(valueStr);
  753. break;
  754. case CB::ENGINE_OPTION_WINE_AUTO_PREFIX:
  755. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  756. shandle.engineOptions.wine.autoPrefix = (value != 0);
  757. break;
  758. case CB::ENGINE_OPTION_WINE_FALLBACK_PREFIX:
  759. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  760. if (shandle.engineOptions.wine.fallbackPrefix != nullptr)
  761. delete[] shandle.engineOptions.wine.fallbackPrefix;
  762. shandle.engineOptions.wine.fallbackPrefix = carla_strdup_safe(valueStr);
  763. break;
  764. case CB::ENGINE_OPTION_WINE_RT_PRIO_ENABLED:
  765. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  766. shandle.engineOptions.wine.rtPrio = (value != 0);
  767. break;
  768. case CB::ENGINE_OPTION_WINE_BASE_RT_PRIO:
  769. CARLA_SAFE_ASSERT_RETURN(value >= 1 && value <= 89,);
  770. shandle.engineOptions.wine.baseRtPrio = value;
  771. break;
  772. case CB::ENGINE_OPTION_WINE_SERVER_RT_PRIO:
  773. CARLA_SAFE_ASSERT_RETURN(value >= 1 && value <= 99,);
  774. shandle.engineOptions.wine.serverRtPrio = value;
  775. break;
  776. #endif
  777. #ifndef BUILD_BRIDGE
  778. case CB::ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT:
  779. #ifdef CARLA_CAN_USE_LOG_THREAD
  780. shandle.logThreadEnabled = (value != 0);
  781. #endif
  782. break;
  783. #endif
  784. case CB::ENGINE_OPTION_CLIENT_NAME_PREFIX:
  785. if (shandle.engineOptions.clientNamePrefix != nullptr)
  786. delete[] shandle.engineOptions.clientNamePrefix;
  787. shandle.engineOptions.clientNamePrefix = valueStr != nullptr && valueStr[0] != '\0'
  788. ? carla_strdup_safe(valueStr)
  789. : nullptr;
  790. break;
  791. case CB::ENGINE_OPTION_PLUGINS_ARE_STANDALONE:
  792. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  793. shandle.engineOptions.pluginsAreStandalone = (value != 0);
  794. break;
  795. }
  796. }
  797. if (handle->engine != nullptr)
  798. handle->engine->setOption(option, value, valueStr);
  799. }
  800. void carla_set_file_callback(CarlaHostHandle handle, FileCallbackFunc func, void* ptr)
  801. {
  802. carla_debug("carla_set_file_callback(%p, %p, %p)", handle, func, ptr);
  803. if (handle->isStandalone)
  804. {
  805. CarlaHostStandalone& shandle((CarlaHostStandalone&)*handle);
  806. shandle.fileCallback = func;
  807. shandle.fileCallbackPtr = ptr;
  808. }
  809. if (handle->engine != nullptr)
  810. handle->engine->setFileCallback(func, ptr);
  811. }
  812. // --------------------------------------------------------------------------------------------------------------------
  813. bool carla_load_file(CarlaHostHandle handle, const char* filename)
  814. {
  815. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  816. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  817. carla_debug("carla_load_file(%p, \"%s\")", handle, filename);
  818. return handle->engine->loadFile(filename);
  819. }
  820. bool carla_load_project(CarlaHostHandle handle, const char* filename)
  821. {
  822. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  823. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  824. carla_debug("carla_load_project(%p, \"%s\")", handle, filename);
  825. return handle->engine->loadProject(filename, true);
  826. }
  827. bool carla_save_project(CarlaHostHandle handle, const char* filename)
  828. {
  829. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  830. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  831. carla_debug("carla_save_project(%p, \"%s\")", handle, filename);
  832. return handle->engine->saveProject(filename, true);
  833. }
  834. #ifndef BUILD_BRIDGE
  835. const char* carla_get_current_project_folder(CarlaHostHandle handle)
  836. {
  837. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, gNullCharPtr);
  838. carla_debug("carla_get_current_project_folder(%p)", handle);
  839. if (const char* const ret = handle->engine->getCurrentProjectFolder())
  840. return ret;
  841. return gNullCharPtr;
  842. }
  843. const char* carla_get_current_project_filename(CarlaHostHandle handle)
  844. {
  845. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->isStandalone, gNullCharPtr);
  846. carla_debug("carla_get_current_project_filename(%p)", handle);
  847. if (const char* const ret = handle->engine->getCurrentProjectFilename())
  848. return ret;
  849. return gNullCharPtr;
  850. }
  851. void carla_clear_project_filename(CarlaHostHandle handle)
  852. {
  853. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  854. carla_debug("carla_clear_project_filename(%p)", handle);
  855. handle->engine->clearCurrentProjectFilename();
  856. }
  857. // --------------------------------------------------------------------------------------------------------------------
  858. bool carla_patchbay_connect(CarlaHostHandle handle, bool external, uint groupIdA, uint portIdA, uint groupIdB, uint portIdB)
  859. {
  860. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  861. carla_debug("carla_patchbay_connect(%p, %s, %u, %u, %u, %u)",
  862. handle, bool2str(external), groupIdA, portIdA, groupIdB, portIdB);
  863. return handle->engine->patchbayConnect(external, groupIdA, portIdA, groupIdB, portIdB);
  864. }
  865. bool carla_patchbay_disconnect(CarlaHostHandle handle, bool external, uint connectionId)
  866. {
  867. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  868. carla_debug("carla_patchbay_disconnect(%p, %s, %i)", handle, bool2str(external), connectionId);
  869. return handle->engine->patchbayDisconnect(external, connectionId);
  870. }
  871. bool carla_patchbay_set_group_pos(CarlaHostHandle handle, bool external, uint groupId, int x1, int y1, int x2, int y2)
  872. {
  873. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr && handle->engine->isRunning(),
  874. "Engine is not running", false);
  875. carla_debug("carla_patchbay_set_group_pos(%p, %s, %u, %i, %i, %i, %i)",
  876. handle, bool2str(external), groupId, x1, y1, x2, y2);
  877. if (handle->engine->isAboutToClose())
  878. return true;
  879. return handle->engine->patchbaySetGroupPos(false, true, external, groupId, x1, y1, x2, y2);
  880. }
  881. bool carla_patchbay_refresh(CarlaHostHandle handle, bool external)
  882. {
  883. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  884. carla_debug("carla_patchbay_refresh(%p, %s)", handle, bool2str(external));
  885. return handle->engine->patchbayRefresh(true, false, external);
  886. }
  887. // --------------------------------------------------------------------------------------------------------------------
  888. void carla_transport_play(CarlaHostHandle handle)
  889. {
  890. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->engine->isRunning(),);
  891. carla_debug("carla_transport_play(%p)", handle);
  892. handle->engine->transportPlay();
  893. }
  894. void carla_transport_pause(CarlaHostHandle handle)
  895. {
  896. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->engine->isRunning(),);
  897. carla_debug("carla_transport_pause(%p)", handle);
  898. handle->engine->transportPause();
  899. }
  900. void carla_transport_bpm(CarlaHostHandle handle, double bpm)
  901. {
  902. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->engine->isRunning(),);
  903. carla_debug("carla_transport_bpm(%p, %f)", handle, bpm);
  904. handle->engine->transportBPM(bpm);
  905. }
  906. void carla_transport_relocate(CarlaHostHandle handle, uint64_t frame)
  907. {
  908. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->engine->isRunning(),);
  909. carla_debug("carla_transport_relocate(%p, %i)", handle, frame);
  910. handle->engine->transportRelocate(frame);
  911. }
  912. uint64_t carla_get_current_transport_frame(CarlaHostHandle handle)
  913. {
  914. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->engine->isRunning(), 0);
  915. return handle->engine->getTimeInfo().frame;
  916. }
  917. const CarlaTransportInfo* carla_get_transport_info(CarlaHostHandle handle)
  918. {
  919. static CarlaTransportInfo retTransInfo;
  920. retTransInfo.clear();
  921. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->engine->isRunning(), &retTransInfo);
  922. const CB::EngineTimeInfo& timeInfo(handle->engine->getTimeInfo());
  923. retTransInfo.playing = timeInfo.playing;
  924. retTransInfo.frame = timeInfo.frame;
  925. if (timeInfo.bbt.valid)
  926. {
  927. retTransInfo.bar = timeInfo.bbt.bar;
  928. retTransInfo.beat = timeInfo.bbt.beat;
  929. retTransInfo.tick = static_cast<int32_t>(timeInfo.bbt.tick + 0.5);
  930. retTransInfo.bpm = timeInfo.bbt.beatsPerMinute;
  931. }
  932. return &retTransInfo;
  933. }
  934. #endif
  935. // --------------------------------------------------------------------------------------------------------------------
  936. uint32_t carla_get_current_plugin_count(CarlaHostHandle handle)
  937. {
  938. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0);
  939. carla_debug("carla_get_current_plugin_count(%p)", handle);
  940. return handle->engine->getCurrentPluginCount();
  941. }
  942. uint32_t carla_get_max_plugin_number(CarlaHostHandle handle)
  943. {
  944. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0);
  945. carla_debug("carla_get_max_plugin_number(%p)", handle);
  946. return handle->engine->getMaxPluginNumber();
  947. }
  948. // --------------------------------------------------------------------------------------------------------------------
  949. bool carla_add_plugin(CarlaHostHandle handle,
  950. BinaryType btype, PluginType ptype,
  951. const char* filename, const char* name, const char* label, int64_t uniqueId,
  952. const void* extraPtr, uint options)
  953. {
  954. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  955. carla_debug("carla_add_plugin(%p, %i:%s, %i:%s, \"%s\", \"%s\", \"%s\", " P_INT64 ", %p, %u)",
  956. handle,
  957. btype, CB::BinaryType2Str(btype),
  958. ptype, CB::PluginType2Str(ptype),
  959. filename, name, label, uniqueId, extraPtr, options);
  960. return handle->engine->addPlugin(btype, ptype, filename, name, label, uniqueId, extraPtr, options);
  961. }
  962. bool carla_remove_plugin(CarlaHostHandle handle, uint pluginId)
  963. {
  964. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  965. carla_debug("carla_remove_plugin(%p, %i)", handle, pluginId);
  966. return handle->engine->removePlugin(pluginId);
  967. }
  968. bool carla_remove_all_plugins(CarlaHostHandle handle)
  969. {
  970. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  971. carla_debug("carla_remove_all_plugins(%p)", handle);
  972. return handle->engine->removeAllPlugins();
  973. }
  974. #ifndef BUILD_BRIDGE
  975. bool carla_rename_plugin(CarlaHostHandle handle, uint pluginId, const char* newName)
  976. {
  977. CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', false);
  978. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  979. carla_debug("carla_rename_plugin(%p, %i, \"%s\")", handle, pluginId, newName);
  980. return handle->engine->renamePlugin(pluginId, newName);
  981. }
  982. bool carla_clone_plugin(CarlaHostHandle handle, uint pluginId)
  983. {
  984. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  985. carla_debug("carla_clone_plugin(%p, %i)", handle, pluginId);
  986. return handle->engine->clonePlugin(pluginId);
  987. }
  988. bool carla_replace_plugin(CarlaHostHandle handle, uint pluginId)
  989. {
  990. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  991. carla_debug("carla_replace_plugin(%p, %i)", handle, pluginId);
  992. return handle->engine->replacePlugin(pluginId);
  993. }
  994. bool carla_switch_plugins(CarlaHostHandle handle, uint pluginIdA, uint pluginIdB)
  995. {
  996. CARLA_SAFE_ASSERT_RETURN(pluginIdA != pluginIdB, false);
  997. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  998. carla_debug("carla_switch_plugins(%p, %i, %i)", handle, pluginIdA, pluginIdB);
  999. return handle->engine->switchPlugins(pluginIdA, pluginIdB);
  1000. }
  1001. #endif
  1002. // --------------------------------------------------------------------------------------------------------------------
  1003. bool carla_load_plugin_state(CarlaHostHandle handle, uint pluginId, const char* filename)
  1004. {
  1005. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  1006. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr
  1007. && handle->engine->isRunning(), "Engine is not running", false);
  1008. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1009. return plugin->loadStateFromFile(filename);
  1010. return false;
  1011. }
  1012. bool carla_save_plugin_state(CarlaHostHandle handle, uint pluginId, const char* filename)
  1013. {
  1014. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  1015. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  1016. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1017. return plugin->saveStateToFile(filename);
  1018. return false;
  1019. }
  1020. bool carla_export_plugin_lv2(CarlaHostHandle handle, uint pluginId, const char* lv2path)
  1021. {
  1022. CARLA_SAFE_ASSERT_RETURN(lv2path != nullptr && lv2path[0] != '\0', false);
  1023. CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(handle->engine != nullptr, "Engine is not initialized", false);
  1024. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1025. return plugin->exportAsLV2(lv2path);
  1026. return false;
  1027. }
  1028. // --------------------------------------------------------------------------------------------------------------------
  1029. const CarlaPluginInfo* carla_get_plugin_info(CarlaHostHandle handle, uint pluginId)
  1030. {
  1031. static CarlaPluginInfo retInfo;
  1032. // reset
  1033. retInfo.type = CB::PLUGIN_NONE;
  1034. retInfo.category = CB::PLUGIN_CATEGORY_NONE;
  1035. retInfo.hints = 0x0;
  1036. retInfo.optionsAvailable = 0x0;
  1037. retInfo.optionsEnabled = 0x0;
  1038. retInfo.filename = gNullCharPtr;
  1039. retInfo.name = gNullCharPtr;
  1040. retInfo.iconName = gNullCharPtr;
  1041. retInfo.uniqueId = 0;
  1042. // cleanup
  1043. if (retInfo.label != gNullCharPtr)
  1044. {
  1045. delete[] retInfo.label;
  1046. retInfo.label = gNullCharPtr;
  1047. }
  1048. if (retInfo.maker != gNullCharPtr)
  1049. {
  1050. delete[] retInfo.maker;
  1051. retInfo.maker = gNullCharPtr;
  1052. }
  1053. if (retInfo.copyright != gNullCharPtr)
  1054. {
  1055. delete[] retInfo.copyright;
  1056. retInfo.copyright = gNullCharPtr;
  1057. }
  1058. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retInfo);
  1059. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1060. {
  1061. char strBuf[STR_MAX+1];
  1062. carla_zeroChars(strBuf, STR_MAX+1);
  1063. retInfo.type = plugin->getType();
  1064. retInfo.category = plugin->getCategory();
  1065. retInfo.hints = plugin->getHints();
  1066. retInfo.filename = plugin->getFilename();
  1067. retInfo.name = plugin->getName();
  1068. retInfo.iconName = plugin->getIconName();
  1069. retInfo.uniqueId = plugin->getUniqueId();
  1070. retInfo.optionsAvailable = plugin->getOptionsAvailable();
  1071. retInfo.optionsEnabled = plugin->getOptionsEnabled();
  1072. if (plugin->getLabel(strBuf))
  1073. retInfo.label = carla_strdup_safe(strBuf);
  1074. if (plugin->getMaker(strBuf))
  1075. retInfo.maker = carla_strdup_safe(strBuf);
  1076. if (plugin->getCopyright(strBuf))
  1077. retInfo.copyright = carla_strdup_safe(strBuf);
  1078. checkStringPtr(retInfo.filename);
  1079. checkStringPtr(retInfo.name);
  1080. checkStringPtr(retInfo.iconName);
  1081. checkStringPtr(retInfo.label);
  1082. checkStringPtr(retInfo.maker);
  1083. checkStringPtr(retInfo.copyright);
  1084. }
  1085. return &retInfo;
  1086. }
  1087. const CarlaPortCountInfo* carla_get_audio_port_count_info(CarlaHostHandle handle, uint pluginId)
  1088. {
  1089. static CarlaPortCountInfo retInfo;
  1090. carla_zeroStruct(retInfo);
  1091. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retInfo);
  1092. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1093. {
  1094. retInfo.ins = plugin->getAudioInCount();
  1095. retInfo.outs = plugin->getAudioOutCount();
  1096. }
  1097. return &retInfo;
  1098. }
  1099. const CarlaPortCountInfo* carla_get_midi_port_count_info(CarlaHostHandle handle, uint pluginId)
  1100. {
  1101. static CarlaPortCountInfo retInfo;
  1102. carla_zeroStruct(retInfo);
  1103. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retInfo);
  1104. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1105. {
  1106. retInfo.ins = plugin->getMidiInCount();
  1107. retInfo.outs = plugin->getMidiOutCount();
  1108. }
  1109. return &retInfo;
  1110. }
  1111. const CarlaPortCountInfo* carla_get_parameter_count_info(CarlaHostHandle handle, uint pluginId)
  1112. {
  1113. static CarlaPortCountInfo retInfo;
  1114. carla_zeroStruct(retInfo);
  1115. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retInfo);
  1116. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1117. plugin->getParameterCountInfo(retInfo.ins, retInfo.outs);
  1118. return &retInfo;
  1119. }
  1120. const CarlaParameterInfo* carla_get_parameter_info(CarlaHostHandle handle, uint pluginId, uint32_t parameterId)
  1121. {
  1122. static CarlaParameterInfo retInfo;
  1123. // reset
  1124. retInfo.scalePointCount = 0;
  1125. // cleanup
  1126. if (retInfo.name != gNullCharPtr)
  1127. {
  1128. delete[] retInfo.name;
  1129. retInfo.name = gNullCharPtr;
  1130. }
  1131. if (retInfo.symbol != gNullCharPtr)
  1132. {
  1133. delete[] retInfo.symbol;
  1134. retInfo.symbol = gNullCharPtr;
  1135. }
  1136. if (retInfo.unit != gNullCharPtr)
  1137. {
  1138. delete[] retInfo.unit;
  1139. retInfo.unit = gNullCharPtr;
  1140. }
  1141. if (retInfo.comment != gNullCharPtr)
  1142. {
  1143. delete[] retInfo.comment;
  1144. retInfo.comment = gNullCharPtr;
  1145. }
  1146. if (retInfo.groupName != gNullCharPtr)
  1147. {
  1148. delete[] retInfo.groupName;
  1149. retInfo.groupName = gNullCharPtr;
  1150. }
  1151. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retInfo);
  1152. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1153. {
  1154. char strBuf[STR_MAX+1];
  1155. carla_zeroChars(strBuf, STR_MAX+1);
  1156. retInfo.scalePointCount = plugin->getParameterScalePointCount(parameterId);
  1157. if (plugin->getParameterName(parameterId, strBuf))
  1158. {
  1159. retInfo.name = carla_strdup_safe(strBuf);
  1160. carla_zeroChars(strBuf, STR_MAX+1);
  1161. }
  1162. if (plugin->getParameterSymbol(parameterId, strBuf))
  1163. {
  1164. retInfo.symbol = carla_strdup_safe(strBuf);
  1165. carla_zeroChars(strBuf, STR_MAX+1);
  1166. }
  1167. if (plugin->getParameterUnit(parameterId, strBuf))
  1168. {
  1169. retInfo.unit = carla_strdup_safe(strBuf);
  1170. carla_zeroChars(strBuf, STR_MAX+1);
  1171. }
  1172. if (plugin->getParameterComment(parameterId, strBuf))
  1173. {
  1174. retInfo.comment = carla_strdup_safe(strBuf);
  1175. carla_zeroChars(strBuf, STR_MAX+1);
  1176. }
  1177. if (plugin->getParameterGroupName(parameterId, strBuf))
  1178. {
  1179. retInfo.groupName = carla_strdup_safe(strBuf);
  1180. carla_zeroChars(strBuf, STR_MAX+1);
  1181. }
  1182. checkStringPtr(retInfo.name);
  1183. checkStringPtr(retInfo.symbol);
  1184. checkStringPtr(retInfo.unit);
  1185. checkStringPtr(retInfo.comment);
  1186. checkStringPtr(retInfo.groupName);
  1187. }
  1188. return &retInfo;
  1189. }
  1190. const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(CarlaHostHandle handle,
  1191. uint pluginId,
  1192. uint32_t parameterId,
  1193. uint32_t scalePointId)
  1194. {
  1195. CARLA_ASSERT(handle->engine != nullptr);
  1196. static CarlaScalePointInfo retInfo;
  1197. // reset
  1198. retInfo.value = 0.0f;
  1199. // cleanup
  1200. if (retInfo.label != gNullCharPtr)
  1201. {
  1202. delete[] retInfo.label;
  1203. retInfo.label = gNullCharPtr;
  1204. }
  1205. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retInfo);
  1206. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1207. {
  1208. char strBuf[STR_MAX+1];
  1209. retInfo.value = plugin->getParameterScalePointValue(parameterId, scalePointId);
  1210. carla_zeroChars(strBuf, STR_MAX+1);
  1211. if (plugin->getParameterScalePointLabel(parameterId, scalePointId, strBuf))
  1212. retInfo.label = carla_strdup_safe(strBuf);
  1213. checkStringPtr(retInfo.label);
  1214. }
  1215. return &retInfo;
  1216. }
  1217. // --------------------------------------------------------------------------------------------------------------------
  1218. uint carla_get_audio_port_hints(CarlaHostHandle handle, uint pluginId, bool isOutput, uint32_t portIndex)
  1219. {
  1220. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0x0);
  1221. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1222. {
  1223. CARLA_SAFE_ASSERT_RETURN(portIndex < (isOutput ? plugin->getAudioOutCount() : plugin->getAudioInCount()), 0x0);
  1224. return plugin->getAudioPortHints(isOutput, portIndex);
  1225. }
  1226. return 0x0;
  1227. }
  1228. // --------------------------------------------------------------------------------------------------------------------
  1229. const ParameterData* carla_get_parameter_data(CarlaHostHandle handle, uint pluginId, uint32_t parameterId)
  1230. {
  1231. static ParameterData retParamData;
  1232. // reset
  1233. retParamData.type = CB::PARAMETER_UNKNOWN;
  1234. retParamData.hints = 0x0;
  1235. retParamData.index = CB::PARAMETER_NULL;
  1236. retParamData.rindex = -1;
  1237. retParamData.midiChannel = 0;
  1238. retParamData.mappedControlIndex = CB::CONTROL_INDEX_NONE;
  1239. retParamData.mappedMinimum = 0.0f;
  1240. retParamData.mappedMaximum = 0.0f;
  1241. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retParamData);
  1242. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1243. {
  1244. CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(), &retParamData);
  1245. const ParameterData& pluginParamData(plugin->getParameterData(parameterId));
  1246. retParamData.type = pluginParamData.type;
  1247. retParamData.hints = pluginParamData.hints;
  1248. retParamData.index = pluginParamData.index;
  1249. retParamData.rindex = pluginParamData.rindex;
  1250. retParamData.midiChannel = pluginParamData.midiChannel;
  1251. retParamData.mappedControlIndex = pluginParamData.mappedControlIndex;
  1252. retParamData.mappedMinimum = pluginParamData.mappedMinimum;
  1253. retParamData.mappedMaximum = pluginParamData.mappedMaximum;
  1254. }
  1255. return &retParamData;
  1256. }
  1257. const ParameterRanges* carla_get_parameter_ranges(CarlaHostHandle handle, uint pluginId, uint32_t parameterId)
  1258. {
  1259. static ParameterRanges retParamRanges;
  1260. // reset
  1261. retParamRanges.def = 0.0f;
  1262. retParamRanges.min = 0.0f;
  1263. retParamRanges.max = 1.0f;
  1264. retParamRanges.step = 0.01f;
  1265. retParamRanges.stepSmall = 0.0001f;
  1266. retParamRanges.stepLarge = 0.1f;
  1267. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retParamRanges);
  1268. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1269. {
  1270. CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(), &retParamRanges);
  1271. const ParameterRanges& pluginParamRanges(plugin->getParameterRanges(parameterId));
  1272. retParamRanges.def = pluginParamRanges.def;
  1273. retParamRanges.min = pluginParamRanges.min;
  1274. retParamRanges.max = pluginParamRanges.max;
  1275. retParamRanges.step = pluginParamRanges.step;
  1276. retParamRanges.stepSmall = pluginParamRanges.stepSmall;
  1277. retParamRanges.stepLarge = pluginParamRanges.stepLarge;
  1278. }
  1279. return &retParamRanges;
  1280. }
  1281. const MidiProgramData* carla_get_midi_program_data(CarlaHostHandle handle, uint pluginId, uint32_t midiProgramId)
  1282. {
  1283. static MidiProgramData retMidiProgData = { 0, 0, gNullCharPtr };
  1284. // reset
  1285. retMidiProgData.bank = 0;
  1286. retMidiProgData.program = 0;
  1287. if (retMidiProgData.name != gNullCharPtr)
  1288. {
  1289. delete[] retMidiProgData.name;
  1290. retMidiProgData.name = gNullCharPtr;
  1291. }
  1292. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retMidiProgData);
  1293. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1294. {
  1295. CARLA_SAFE_ASSERT_RETURN(midiProgramId < plugin->getMidiProgramCount(), &retMidiProgData);
  1296. const MidiProgramData& pluginMidiProgData(plugin->getMidiProgramData(midiProgramId));
  1297. retMidiProgData.bank = pluginMidiProgData.bank;
  1298. retMidiProgData.program = pluginMidiProgData.program;
  1299. if (pluginMidiProgData.name != nullptr)
  1300. {
  1301. retMidiProgData.name = carla_strdup_safe(pluginMidiProgData.name);
  1302. checkStringPtr(retMidiProgData.name);
  1303. }
  1304. else
  1305. {
  1306. retMidiProgData.name = gNullCharPtr;
  1307. }
  1308. }
  1309. return &retMidiProgData;
  1310. }
  1311. const CustomData* carla_get_custom_data(CarlaHostHandle handle, uint pluginId, uint32_t customDataId)
  1312. {
  1313. static CustomData retCustomData = { gNullCharPtr, gNullCharPtr, gNullCharPtr };
  1314. // reset
  1315. if (retCustomData.type != gNullCharPtr)
  1316. {
  1317. delete[] retCustomData.type;
  1318. retCustomData.type = gNullCharPtr;
  1319. }
  1320. if (retCustomData.key != gNullCharPtr)
  1321. {
  1322. delete[] retCustomData.key;
  1323. retCustomData.key = gNullCharPtr;
  1324. }
  1325. if (retCustomData.value != gNullCharPtr)
  1326. {
  1327. delete[] retCustomData.value;
  1328. retCustomData.value = gNullCharPtr;
  1329. }
  1330. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, &retCustomData);
  1331. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1332. {
  1333. CARLA_SAFE_ASSERT_RETURN(customDataId < plugin->getCustomDataCount(), &retCustomData)
  1334. const CustomData& pluginCustomData(plugin->getCustomData(customDataId));
  1335. retCustomData.type = carla_strdup_safe(pluginCustomData.type);
  1336. retCustomData.key = carla_strdup_safe(pluginCustomData.key);
  1337. retCustomData.value = carla_strdup_safe(pluginCustomData.value);
  1338. checkStringPtr(retCustomData.type);
  1339. checkStringPtr(retCustomData.key);
  1340. checkStringPtr(retCustomData.value);
  1341. }
  1342. return &retCustomData;
  1343. }
  1344. const char* carla_get_custom_data_value(CarlaHostHandle handle, uint pluginId, const char* type, const char* key)
  1345. {
  1346. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0', gNullCharPtr);
  1347. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', gNullCharPtr);
  1348. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, gNullCharPtr);
  1349. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1350. {
  1351. const uint32_t count = plugin->getCustomDataCount();
  1352. if (count == 0)
  1353. return gNullCharPtr;
  1354. static CarlaString customDataValue;
  1355. for (uint32_t i=0; i<count; ++i)
  1356. {
  1357. const CustomData& pluginCustomData(plugin->getCustomData(i));
  1358. if (std::strcmp(pluginCustomData.type, type) != 0)
  1359. continue;
  1360. if (std::strcmp(pluginCustomData.key, key) != 0)
  1361. continue;
  1362. customDataValue = pluginCustomData.value;
  1363. return customDataValue.buffer();
  1364. }
  1365. }
  1366. return gNullCharPtr;
  1367. }
  1368. const char* carla_get_chunk_data(CarlaHostHandle handle, uint pluginId)
  1369. {
  1370. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, gNullCharPtr);
  1371. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1372. {
  1373. CARLA_SAFE_ASSERT_RETURN(plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS, gNullCharPtr);
  1374. void* data = nullptr;
  1375. const std::size_t dataSize(plugin->getChunkData(&data));
  1376. CARLA_SAFE_ASSERT_RETURN(data != nullptr && dataSize > 0, gNullCharPtr);
  1377. static CarlaString chunkData;
  1378. chunkData = CarlaString::asBase64(data, static_cast<std::size_t>(dataSize));
  1379. return chunkData.buffer();
  1380. }
  1381. return gNullCharPtr;
  1382. }
  1383. // --------------------------------------------------------------------------------------------------------------------
  1384. uint32_t carla_get_parameter_count(CarlaHostHandle handle, uint pluginId)
  1385. {
  1386. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0);
  1387. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1388. return plugin->getParameterCount();
  1389. return 0;
  1390. }
  1391. uint32_t carla_get_program_count(CarlaHostHandle handle, uint pluginId)
  1392. {
  1393. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0);
  1394. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1395. return plugin->getProgramCount();
  1396. return 0;
  1397. }
  1398. uint32_t carla_get_midi_program_count(CarlaHostHandle handle, uint pluginId)
  1399. {
  1400. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0);
  1401. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1402. return plugin->getMidiProgramCount();
  1403. return 0;
  1404. }
  1405. uint32_t carla_get_custom_data_count(CarlaHostHandle handle, uint pluginId)
  1406. {
  1407. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0);
  1408. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1409. return plugin->getCustomDataCount();
  1410. return 0;
  1411. }
  1412. // --------------------------------------------------------------------------------------------------------------------
  1413. const char* carla_get_parameter_text(CarlaHostHandle handle, uint pluginId, uint32_t parameterId)
  1414. {
  1415. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, gNullCharPtr);
  1416. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1417. {
  1418. CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(), gNullCharPtr);
  1419. static char textBuf[STR_MAX+1];
  1420. carla_zeroChars(textBuf, STR_MAX+1);
  1421. if (! plugin->getParameterText(parameterId, textBuf))
  1422. textBuf[0] = '\0';
  1423. return textBuf;
  1424. }
  1425. return gNullCharPtr;
  1426. }
  1427. const char* carla_get_program_name(CarlaHostHandle handle, uint pluginId, uint32_t programId)
  1428. {
  1429. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, nullptr);
  1430. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1431. {
  1432. CARLA_SAFE_ASSERT_RETURN(programId < plugin->getProgramCount(), gNullCharPtr);
  1433. static char programName[STR_MAX+1];
  1434. carla_zeroChars(programName, STR_MAX+1);
  1435. if (! plugin->getProgramName(programId, programName))
  1436. programName[0] = '\0';
  1437. return programName;
  1438. }
  1439. return gNullCharPtr;
  1440. }
  1441. const char* carla_get_midi_program_name(CarlaHostHandle handle, uint pluginId, uint32_t midiProgramId)
  1442. {
  1443. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, gNullCharPtr);
  1444. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1445. {
  1446. CARLA_SAFE_ASSERT_RETURN(midiProgramId < plugin->getMidiProgramCount(), gNullCharPtr);
  1447. static char midiProgramName[STR_MAX+1];
  1448. carla_zeroChars(midiProgramName, STR_MAX+1);
  1449. if (! plugin->getMidiProgramName(midiProgramId, midiProgramName))
  1450. midiProgramName[0] = '\0';
  1451. return midiProgramName;
  1452. }
  1453. return gNullCharPtr;
  1454. }
  1455. const char* carla_get_real_plugin_name(CarlaHostHandle handle, uint pluginId)
  1456. {
  1457. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, gNullCharPtr);
  1458. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1459. {
  1460. static char realPluginName[STR_MAX+1];
  1461. carla_zeroChars(realPluginName, STR_MAX+1);
  1462. if (! plugin->getRealName(realPluginName))
  1463. realPluginName[0] = '\0';
  1464. return realPluginName;
  1465. }
  1466. return gNullCharPtr;
  1467. }
  1468. // --------------------------------------------------------------------------------------------------------------------
  1469. int32_t carla_get_current_program_index(CarlaHostHandle handle, uint pluginId)
  1470. {
  1471. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, -1);
  1472. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1473. return plugin->getCurrentProgram();
  1474. return -1;
  1475. }
  1476. int32_t carla_get_current_midi_program_index(CarlaHostHandle handle, uint pluginId)
  1477. {
  1478. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, -1);
  1479. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1480. return plugin->getCurrentMidiProgram();
  1481. return -1;
  1482. }
  1483. // --------------------------------------------------------------------------------------------------------------------
  1484. float carla_get_default_parameter_value(CarlaHostHandle handle, uint pluginId, uint32_t parameterId)
  1485. {
  1486. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0.0f);
  1487. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1488. {
  1489. CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(), 0.0f);
  1490. return plugin->getParameterRanges(parameterId).def;
  1491. }
  1492. return 0.0f;
  1493. }
  1494. float carla_get_current_parameter_value(CarlaHostHandle handle, uint pluginId, uint32_t parameterId)
  1495. {
  1496. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0.0f);
  1497. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1498. {
  1499. CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(), 0.0f);
  1500. return plugin->getParameterValue(parameterId);
  1501. }
  1502. return 0.0f;
  1503. }
  1504. float carla_get_internal_parameter_value(CarlaHostHandle handle, uint pluginId, int32_t parameterId)
  1505. {
  1506. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1507. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, (parameterId == CB::PARAMETER_CTRL_CHANNEL) ? -1.0f : 0.0f);
  1508. #else
  1509. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0.0f);
  1510. #endif
  1511. CARLA_SAFE_ASSERT_RETURN(parameterId != CB::PARAMETER_NULL && parameterId > CB::PARAMETER_MAX, 0.0f);
  1512. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1513. return plugin->getInternalParameterValue(parameterId);
  1514. return 0.0f;
  1515. }
  1516. // --------------------------------------------------------------------------------------------------------------------
  1517. uint32_t carla_get_plugin_latency(CarlaHostHandle handle, uint pluginId)
  1518. {
  1519. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0);
  1520. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1521. return plugin->getLatencyInFrames();
  1522. return 0;
  1523. }
  1524. // --------------------------------------------------------------------------------------------------------------------
  1525. const float* carla_get_peak_values(CarlaHostHandle handle, uint pluginId)
  1526. {
  1527. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, nullptr);
  1528. return handle->engine->getPeaks(pluginId);
  1529. }
  1530. float carla_get_input_peak_value(CarlaHostHandle handle, uint pluginId, bool isLeft)
  1531. {
  1532. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0.0f);
  1533. return handle->engine->getInputPeak(pluginId, isLeft);
  1534. }
  1535. float carla_get_output_peak_value(CarlaHostHandle handle, uint pluginId, bool isLeft)
  1536. {
  1537. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0.0f);
  1538. return handle->engine->getOutputPeak(pluginId, isLeft);
  1539. }
  1540. // --------------------------------------------------------------------------------------------------------------------
  1541. CARLA_BACKEND_START_NAMESPACE
  1542. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1543. // defined in CarlaPluginInternal.cpp
  1544. const void* carla_render_inline_display_internal(const CarlaPluginPtr& plugin, uint32_t width, uint32_t height);
  1545. #endif
  1546. // defined in CarlaPluginLV2.cpp
  1547. const void* carla_render_inline_display_lv2(const CarlaPluginPtr& plugin, uint32_t width, uint32_t height);
  1548. CARLA_BACKEND_END_NAMESPACE
  1549. const CarlaInlineDisplayImageSurface* carla_render_inline_display(CarlaHostHandle handle,
  1550. uint pluginId,
  1551. uint32_t width, uint32_t height)
  1552. {
  1553. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->engine->isRunning(), nullptr);
  1554. if (handle->engine->isAboutToClose())
  1555. return nullptr;
  1556. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1557. {
  1558. switch (plugin->getType())
  1559. {
  1560. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1561. case CB::PLUGIN_INTERNAL:
  1562. return (const CarlaInlineDisplayImageSurface*)CB::carla_render_inline_display_internal(plugin, width, height);
  1563. #endif
  1564. case CB::PLUGIN_LV2:
  1565. return (const CarlaInlineDisplayImageSurface*)CB::carla_render_inline_display_lv2(plugin, width, height);
  1566. default:
  1567. return nullptr;
  1568. }
  1569. }
  1570. return nullptr;
  1571. }
  1572. // --------------------------------------------------------------------------------------------------------------------
  1573. void carla_set_active(CarlaHostHandle handle, uint pluginId, bool onOff)
  1574. {
  1575. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1576. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1577. plugin->setActive(onOff, true, false);
  1578. }
  1579. #ifndef BUILD_BRIDGE
  1580. void carla_set_drywet(CarlaHostHandle handle, uint pluginId, float value)
  1581. {
  1582. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1583. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1584. plugin->setDryWet(value, true, false);
  1585. }
  1586. void carla_set_volume(CarlaHostHandle handle, uint pluginId, float value)
  1587. {
  1588. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1589. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1590. plugin->setVolume(value, true, false);
  1591. }
  1592. void carla_set_balance_left(CarlaHostHandle handle, uint pluginId, float value)
  1593. {
  1594. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1595. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1596. plugin->setBalanceLeft(value, true, false);
  1597. }
  1598. void carla_set_balance_right(CarlaHostHandle handle, uint pluginId, float value)
  1599. {
  1600. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1601. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1602. plugin->setBalanceRight(value, true, false);
  1603. }
  1604. void carla_set_panning(CarlaHostHandle handle, uint pluginId, float value)
  1605. {
  1606. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1607. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1608. plugin->setPanning(value, true, false);
  1609. }
  1610. void carla_set_ctrl_channel(CarlaHostHandle handle, uint pluginId, int8_t channel)
  1611. {
  1612. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1613. CARLA_SAFE_ASSERT_RETURN(channel >= -1 && channel < MAX_MIDI_CHANNELS,);
  1614. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1615. plugin->setCtrlChannel(channel, true, false);
  1616. }
  1617. #endif
  1618. void carla_set_option(CarlaHostHandle handle, uint pluginId, uint option, bool yesNo)
  1619. {
  1620. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1621. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1622. plugin->setOption(option, yesNo, false);
  1623. }
  1624. // --------------------------------------------------------------------------------------------------------------------
  1625. void carla_set_parameter_value(CarlaHostHandle handle, uint pluginId, uint32_t parameterId, float value)
  1626. {
  1627. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1628. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1629. {
  1630. CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),);
  1631. plugin->setParameterValue(parameterId, value, true, true, false);
  1632. }
  1633. }
  1634. #ifndef BUILD_BRIDGE
  1635. void carla_set_parameter_midi_channel(CarlaHostHandle handle, uint pluginId, uint32_t parameterId, uint8_t channel)
  1636. {
  1637. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1638. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  1639. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1640. {
  1641. CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),);
  1642. plugin->setParameterMidiChannel(parameterId, channel, true, false);
  1643. }
  1644. }
  1645. void carla_set_parameter_mapped_control_index(CarlaHostHandle handle, uint pluginId, uint32_t parameterId, int16_t index)
  1646. {
  1647. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1648. CARLA_SAFE_ASSERT_RETURN(index >= CB::CONTROL_INDEX_NONE && index <= CB::CONTROL_INDEX_MAX_ALLOWED,);
  1649. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1650. {
  1651. CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),);
  1652. plugin->setParameterMappedControlIndex(parameterId, index, true, false, true);
  1653. }
  1654. }
  1655. void carla_set_parameter_mapped_range(CarlaHostHandle handle, uint pluginId, uint32_t parameterId, float minimum, float maximum)
  1656. {
  1657. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1658. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1659. {
  1660. CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),);
  1661. plugin->setParameterMappedRange(parameterId, minimum, maximum, true, false);
  1662. }
  1663. }
  1664. void carla_set_parameter_touch(CarlaHostHandle handle, uint pluginId, uint32_t parameterId, bool touch)
  1665. {
  1666. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1667. carla_debug("carla_set_parameter_touch(%p, %i, %i, %s)", handle, pluginId, parameterId, bool2str(touch));
  1668. return handle->engine->touchPluginParameter(pluginId, parameterId, touch);
  1669. }
  1670. #endif
  1671. // --------------------------------------------------------------------------------------------------------------------
  1672. void carla_set_program(CarlaHostHandle handle, uint pluginId, uint32_t programId)
  1673. {
  1674. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1675. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1676. {
  1677. CARLA_SAFE_ASSERT_RETURN(programId < plugin->getProgramCount(),);
  1678. plugin->setProgram(static_cast<int32_t>(programId), true, true, false);
  1679. }
  1680. }
  1681. void carla_set_midi_program(CarlaHostHandle handle, uint pluginId, uint32_t midiProgramId)
  1682. {
  1683. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1684. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1685. {
  1686. CARLA_SAFE_ASSERT_RETURN(midiProgramId < plugin->getMidiProgramCount(),);
  1687. plugin->setMidiProgram(static_cast<int32_t>(midiProgramId), true, true, false);
  1688. }
  1689. }
  1690. // --------------------------------------------------------------------------------------------------------------------
  1691. void carla_set_custom_data(CarlaHostHandle handle, uint pluginId, const char* type, const char* key, const char* value)
  1692. {
  1693. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1694. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
  1695. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  1696. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  1697. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1698. plugin->setCustomData(type, key, value, true);
  1699. }
  1700. void carla_set_chunk_data(CarlaHostHandle handle, uint pluginId, const char* chunkData)
  1701. {
  1702. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1703. CARLA_SAFE_ASSERT_RETURN(chunkData != nullptr && chunkData[0] != '\0',);
  1704. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1705. {
  1706. CARLA_SAFE_ASSERT_RETURN(plugin->getOptionsEnabled() & CB::PLUGIN_OPTION_USE_CHUNKS,);
  1707. std::vector<uint8_t> chunk(carla_getChunkFromBase64String(chunkData));
  1708. #ifdef CARLA_PROPER_CPP11_SUPPORT
  1709. plugin->setChunkData(chunk.data(), chunk.size());
  1710. #else
  1711. plugin->setChunkData(&chunk.front(), chunk.size());
  1712. #endif
  1713. }
  1714. }
  1715. // --------------------------------------------------------------------------------------------------------------------
  1716. void carla_prepare_for_save(CarlaHostHandle handle, uint pluginId)
  1717. {
  1718. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1719. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1720. plugin->prepareForSave(false);
  1721. }
  1722. void carla_reset_parameters(CarlaHostHandle handle, uint pluginId)
  1723. {
  1724. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1725. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1726. plugin->resetParameters();
  1727. }
  1728. void carla_randomize_parameters(CarlaHostHandle handle, uint pluginId)
  1729. {
  1730. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1731. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1732. plugin->randomizeParameters();
  1733. }
  1734. #ifndef BUILD_BRIDGE
  1735. void carla_send_midi_note(CarlaHostHandle handle, uint pluginId, uint8_t channel, uint8_t note, uint8_t velocity)
  1736. {
  1737. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr && handle->engine->isRunning(),);
  1738. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1739. plugin->sendMidiSingleNote(channel, note, velocity, true, true, false);
  1740. }
  1741. #endif
  1742. void carla_set_custom_ui_title(CarlaHostHandle handle, uint pluginId, const char* title)
  1743. {
  1744. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1745. CARLA_SAFE_ASSERT_RETURN(title != nullptr,);
  1746. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1747. plugin->setCustomUITitle(title);
  1748. }
  1749. void carla_show_custom_ui(CarlaHostHandle handle, uint pluginId, bool yesNo)
  1750. {
  1751. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr,);
  1752. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1753. plugin->showCustomUI(yesNo);
  1754. }
  1755. void* carla_embed_custom_ui(CarlaHostHandle handle, uint pluginId, void* ptr)
  1756. {
  1757. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, nullptr);
  1758. if (const CarlaPluginPtr plugin = handle->engine->getPlugin(pluginId))
  1759. return plugin->embedCustomUI(ptr);
  1760. return nullptr;
  1761. }
  1762. // --------------------------------------------------------------------------------------------------------------------
  1763. uint32_t carla_get_buffer_size(CarlaHostHandle handle)
  1764. {
  1765. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0);
  1766. carla_debug("carla_get_buffer_size(%p)", handle);
  1767. return handle->engine->getBufferSize();
  1768. }
  1769. double carla_get_sample_rate(CarlaHostHandle handle)
  1770. {
  1771. CARLA_SAFE_ASSERT_RETURN(handle->engine != nullptr, 0.0);
  1772. carla_debug("carla_get_sample_rate(%p)", handle);
  1773. return handle->engine->getSampleRate();
  1774. }
  1775. // --------------------------------------------------------------------------------------------------------------------
  1776. const char* carla_get_last_error(CarlaHostHandle handle)
  1777. {
  1778. carla_debug("carla_get_last_error(%p)", handle);
  1779. if (handle->engine != nullptr)
  1780. return handle->engine->getLastError();
  1781. return handle->isStandalone
  1782. ? ((CarlaHostStandalone*)handle)->lastError.buffer()
  1783. : gNullCharPtr;
  1784. }
  1785. const char* carla_get_host_osc_url_tcp(CarlaHostHandle handle)
  1786. {
  1787. carla_debug("carla_get_host_osc_url_tcp(%p)", handle);
  1788. #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
  1789. if (handle->engine == nullptr)
  1790. {
  1791. carla_stderr2("carla_get_host_osc_url_tcp() failed, engine is not running");
  1792. if (handle->isStandalone)
  1793. ((CarlaHostStandalone*)handle)->lastError = "Engine is not running";
  1794. return gNullCharPtr;
  1795. }
  1796. const char* const path = handle->engine->getOscServerPathTCP();
  1797. if (path != nullptr && path[0] != '\0')
  1798. return path;
  1799. static const char* const notAvailable = "(OSC TCP port not available)";
  1800. return notAvailable;
  1801. #else
  1802. return "(OSC support not available in this build)";
  1803. // unused
  1804. (void)handle;
  1805. #endif
  1806. }
  1807. const char* carla_get_host_osc_url_udp(CarlaHostHandle handle)
  1808. {
  1809. carla_debug("carla_get_host_osc_url_udp(%p)", handle);
  1810. #if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
  1811. if (handle->engine == nullptr)
  1812. {
  1813. carla_stderr2("carla_get_host_osc_url_udp() failed, engine is not running");
  1814. if (handle->isStandalone)
  1815. ((CarlaHostStandalone*)handle)->lastError = "Engine is not running";
  1816. return gNullCharPtr;
  1817. }
  1818. const char* const path = handle->engine->getOscServerPathUDP();
  1819. if (path != nullptr && path[0] != '\0')
  1820. return path;
  1821. static const char* const notAvailable = "(OSC UDP port not available)";
  1822. return notAvailable;
  1823. #else
  1824. return "(OSC support not available in this build)";
  1825. // unused
  1826. (void)handle;
  1827. #endif
  1828. }
  1829. // --------------------------------------------------------------------------------------------------------------------
  1830. #ifndef CARLA_PLUGIN_BUILD
  1831. # define CARLA_PLUGIN_UI_CLASS_PREFIX Standalone
  1832. # include "CarlaPluginUI.cpp"
  1833. # undef CARLA_PLUGIN_UI_CLASS_PREFIX
  1834. # include "CarlaDssiUtils.cpp"
  1835. # include "CarlaMacUtils.cpp"
  1836. # include "CarlaPatchbayUtils.cpp"
  1837. # include "CarlaPipeUtils.cpp"
  1838. # include "CarlaProcessUtils.cpp"
  1839. # include "CarlaStateUtils.cpp"
  1840. # include "utils/Information.cpp"
  1841. # include "utils/Windows.cpp"
  1842. #endif /* CARLA_PLUGIN_BUILD */
  1843. // --------------------------------------------------------------------------------------------------------------------