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

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