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.

CarlaEngine.cpp 105KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047
  1. /*
  2. * Carla Engine
  3. * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. /* TODO:
  18. * - add more checks to oscSend_* stuff
  19. * - complete processRack(): carefully add to input, sorted events
  20. * - implement processPatchbay()
  21. * - implement oscSend_control_switch_plugins()
  22. * - proper find&load plugins
  23. * - uncomment CarlaPlugin::newAU and newCSOUND
  24. * - something about the peaks?
  25. * - patchbayDisconnect should return false sometimes
  26. */
  27. #include "CarlaEngineInternal.hpp"
  28. #include "CarlaBackendUtils.hpp"
  29. #include "CarlaStateUtils.hpp"
  30. #include "CarlaMIDI.h"
  31. #include <cmath>
  32. #include <QtCore/QFile>
  33. #include <QtCore/QFileInfo>
  34. #include <QtCore/QTextStream>
  35. CARLA_BACKEND_START_NAMESPACE
  36. #if 0
  37. } // Fix editor indentation
  38. #endif
  39. // -----------------------------------------------------------------------
  40. // Fallback data
  41. static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, { kEngineControlEventTypeNull, 0, 0.0f } };
  42. // -----------------------------------------------------------------------
  43. void EngineControlEvent::dumpToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept
  44. {
  45. switch (type)
  46. {
  47. case kEngineControlEventTypeNull:
  48. break;
  49. case kEngineControlEventTypeParameter:
  50. if (MIDI_IS_CONTROL_BANK_SELECT(param))
  51. {
  52. size = 3;
  53. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel);
  54. data[1] = MIDI_CONTROL_BANK_SELECT;
  55. data[2] = static_cast<uint8_t>(value);
  56. }
  57. else
  58. {
  59. size = 3;
  60. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel);
  61. data[1] = static_cast<uint8_t>(param);
  62. data[2] = uint8_t(value * 127.0f);
  63. }
  64. break;
  65. case kEngineControlEventTypeMidiBank:
  66. size = 3;
  67. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel);
  68. data[1] = MIDI_CONTROL_BANK_SELECT;
  69. data[2] = static_cast<uint8_t>(param);
  70. break;
  71. case kEngineControlEventTypeMidiProgram:
  72. size = 2;
  73. data[0] = static_cast<uint8_t>(MIDI_STATUS_PROGRAM_CHANGE + channel);
  74. data[1] = static_cast<uint8_t>(param);
  75. break;
  76. case kEngineControlEventTypeAllSoundOff:
  77. size = 2;
  78. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel);
  79. data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  80. break;
  81. case kEngineControlEventTypeAllNotesOff:
  82. size = 2;
  83. data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel);
  84. data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  85. break;
  86. }
  87. }
  88. void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data)
  89. {
  90. // get channel
  91. channel = MIDI_GET_CHANNEL_FROM_DATA(data);
  92. // get status
  93. const uint8_t midiStatus(MIDI_GET_STATUS_FROM_DATA(data));
  94. if (midiStatus == MIDI_STATUS_CONTROL_CHANGE)
  95. {
  96. type = kEngineEventTypeControl;
  97. const uint8_t midiControl(data[1]);
  98. if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
  99. {
  100. CARLA_SAFE_ASSERT_INT(size == 3, size);
  101. const uint8_t midiBank(data[2]);
  102. ctrl.type = kEngineControlEventTypeMidiBank;
  103. ctrl.param = midiBank;
  104. ctrl.value = 0.0f;
  105. }
  106. else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF)
  107. {
  108. CARLA_SAFE_ASSERT_INT(size == 2, size);
  109. ctrl.type = kEngineControlEventTypeAllSoundOff;
  110. ctrl.param = 0;
  111. ctrl.value = 0.0f;
  112. }
  113. else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF)
  114. {
  115. CARLA_SAFE_ASSERT_INT(size == 2, size);
  116. ctrl.type = kEngineControlEventTypeAllNotesOff;
  117. ctrl.param = 0;
  118. ctrl.value = 0.0f;
  119. }
  120. else
  121. {
  122. CARLA_SAFE_ASSERT_INT2(size == 3, size, midiControl);
  123. const uint8_t midiValue(data[2]);
  124. ctrl.type = kEngineControlEventTypeParameter;
  125. ctrl.param = midiControl;
  126. ctrl.value = float(midiValue)/127.0f;
  127. }
  128. }
  129. else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE)
  130. {
  131. CARLA_SAFE_ASSERT_INT2(size == 2, size, data[1]);
  132. type = kEngineEventTypeControl;
  133. const uint8_t midiProgram(data[1]);
  134. ctrl.type = kEngineControlEventTypeMidiProgram;
  135. ctrl.param = midiProgram;
  136. ctrl.value = 0.0f;
  137. }
  138. else
  139. {
  140. type = kEngineEventTypeMidi;
  141. midi.port = 0;
  142. midi.size = size;
  143. if (size > EngineMidiEvent::kDataSize)
  144. {
  145. midi.dataExt = data;
  146. std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize);
  147. }
  148. else
  149. {
  150. midi.data[0] = midiStatus;
  151. uint8_t i=1;
  152. for (; i < midi.size; ++i)
  153. midi.data[i] = data[i];
  154. for (; i < EngineMidiEvent::kDataSize; ++i)
  155. midi.data[i] = 0;
  156. midi.dataExt = nullptr;
  157. }
  158. }
  159. }
  160. // -----------------------------------------------------------------------
  161. #ifndef BUILD_BRIDGE
  162. void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2], const uint32_t frames, const bool isOffline)
  163. {
  164. CARLA_SAFE_ASSERT_RETURN(bufEvents.in != nullptr,);
  165. CARLA_SAFE_ASSERT_RETURN(bufEvents.out != nullptr,);
  166. // safe copy
  167. float inBuf0[frames];
  168. float inBuf1[frames];
  169. float* inBuf[2] = { inBuf0, inBuf1 };
  170. // initialize audio inputs
  171. FLOAT_COPY(inBuf0, inBufReal[0], frames);
  172. FLOAT_COPY(inBuf1, inBufReal[1], frames);
  173. // initialize audio outputs (zero)
  174. FLOAT_CLEAR(outBuf[0], frames);
  175. FLOAT_CLEAR(outBuf[1], frames);
  176. // initialize event outputs (zero)
  177. carla_zeroStruct<EngineEvent>(bufEvents.out, kEngineMaxInternalEventCount);
  178. bool processed = false;
  179. uint32_t oldAudioInCount = 0;
  180. uint32_t oldMidiOutCount = 0;
  181. // process plugins
  182. for (unsigned int i=0; i < curPluginCount; ++i)
  183. {
  184. CarlaPlugin* const plugin = plugins[i].plugin;
  185. if (plugin == nullptr || ! plugin->isEnabled() || ! plugin->tryLock(isOffline))
  186. continue;
  187. if (processed)
  188. {
  189. // initialize audio inputs (from previous outputs)
  190. FLOAT_COPY(inBuf0, outBuf[0], frames);
  191. FLOAT_COPY(inBuf1, outBuf[1], frames);
  192. // initialize audio outputs (zero)
  193. FLOAT_CLEAR(outBuf[0], frames);
  194. FLOAT_CLEAR(outBuf[1], frames);
  195. // if plugin has no midi out, add previous events
  196. if (oldMidiOutCount == 0 && bufEvents.in[0].type != kEngineEventTypeNull)
  197. {
  198. if (bufEvents.out[0].type != kEngineEventTypeNull)
  199. {
  200. // TODO: carefully add to input, sorted events
  201. }
  202. // else nothing needed
  203. }
  204. else
  205. {
  206. // initialize event inputs from previous outputs
  207. carla_copyStruct<EngineEvent>(bufEvents.in, bufEvents.out, kEngineMaxInternalEventCount);
  208. // initialize event outputs (zero)
  209. carla_zeroStruct<EngineEvent>(bufEvents.out, kEngineMaxInternalEventCount);
  210. }
  211. }
  212. oldAudioInCount = plugin->getAudioInCount();
  213. oldMidiOutCount = plugin->getMidiOutCount();
  214. // process
  215. plugin->initBuffers();
  216. plugin->process(inBuf, outBuf, frames);
  217. plugin->unlock();
  218. // if plugin has no audio inputs, add input buffer
  219. if (oldAudioInCount == 0)
  220. {
  221. FLOAT_ADD(outBuf[0], inBuf0, frames);
  222. FLOAT_ADD(outBuf[1], inBuf1, frames);
  223. }
  224. // set peaks
  225. {
  226. EnginePluginData& pluginData(plugins[i]);
  227. #ifdef HAVE_JUCE
  228. float tmpMin, tmpMax;
  229. if (oldAudioInCount > 0)
  230. {
  231. FloatVectorOperations::findMinAndMax(inBuf0, frames, tmpMin, tmpMax);
  232. pluginData.insPeak[0] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
  233. FloatVectorOperations::findMinAndMax(inBuf1, frames, tmpMin, tmpMax);
  234. pluginData.insPeak[1] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
  235. }
  236. else
  237. {
  238. pluginData.insPeak[0] = 0.0f;
  239. pluginData.insPeak[1] = 0.0f;
  240. }
  241. if (plugin->getAudioOutCount() > 0)
  242. {
  243. FloatVectorOperations::findMinAndMax(outBuf[0], frames, tmpMin, tmpMax);
  244. pluginData.outsPeak[0] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
  245. FloatVectorOperations::findMinAndMax(outBuf[1], frames, tmpMin, tmpMax);
  246. pluginData.outsPeak[1] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
  247. }
  248. else
  249. {
  250. pluginData.outsPeak[0] = 0.0f;
  251. pluginData.outsPeak[1] = 0.0f;
  252. }
  253. #else
  254. float peak1, peak2;
  255. if (oldAudioInCount > 0)
  256. {
  257. peak1 = peak2 = 0.0f;
  258. for (uint32_t k=0; k < frames; ++k)
  259. {
  260. peak1 = carla_max<float>(peak1, std::fabs(inBuf0[k]), 1.0f);
  261. peak2 = carla_max<float>(peak2, std::fabs(inBuf1[k]), 1.0f);
  262. }
  263. pluginData.insPeak[0] = peak1;
  264. pluginData.insPeak[1] = peak2;
  265. }
  266. else
  267. {
  268. pluginData.insPeak[0] = 0.0f;
  269. pluginData.insPeak[1] = 0.0f;
  270. }
  271. if (plugin->getAudioOutCount() > 0)
  272. {
  273. peak1 = peak2 = 0.0f;
  274. for (uint32_t k=0; k < frames; ++k)
  275. {
  276. peak1 = carla_max<float>(peak1, std::fabs(outBuf[0][k]), 1.0f);
  277. peak2 = carla_max<float>(peak2, std::fabs(outBuf[1][k]), 1.0f);
  278. }
  279. pluginData.outsPeak[0] = peak1;
  280. pluginData.outsPeak[1] = peak2;
  281. }
  282. else
  283. {
  284. pluginData.outsPeak[0] = 0.0f;
  285. pluginData.outsPeak[1] = 0.0f;
  286. }
  287. #endif
  288. }
  289. processed = true;
  290. }
  291. }
  292. void CarlaEngineProtectedData::processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline)
  293. {
  294. EngineRackBuffers* const rack(bufAudio.rack);
  295. const CarlaMutex::ScopedLocker sl(rack->connectLock);
  296. // connect input buffers
  297. if (rack->connectedIns[0].count() == 0)
  298. {
  299. FLOAT_CLEAR(rack->in[0], nframes);
  300. }
  301. else
  302. {
  303. bool first = true;
  304. for (List<uint>::Itenerator it = rack->connectedIns[0].begin(); it.valid(); it.next())
  305. {
  306. const uint& port(it.getConstValue());
  307. CARLA_SAFE_ASSERT_CONTINUE(port < inCount);
  308. if (first)
  309. {
  310. FLOAT_COPY(rack->in[0], inBuf[port], nframes);
  311. first = false;
  312. }
  313. else
  314. {
  315. FLOAT_ADD(rack->in[0], inBuf[port], nframes);
  316. }
  317. }
  318. if (first)
  319. FLOAT_CLEAR(rack->in[0], nframes);
  320. }
  321. if (rack->connectedIns[1].count() == 0)
  322. {
  323. FLOAT_CLEAR(rack->in[1], nframes);
  324. }
  325. else
  326. {
  327. bool first = true;
  328. for (List<uint>::Itenerator it = rack->connectedIns[1].begin(); it.valid(); it.next())
  329. {
  330. const uint& port(it.getConstValue());
  331. CARLA_SAFE_ASSERT_CONTINUE(port < inCount);
  332. if (first)
  333. {
  334. FLOAT_COPY(rack->in[1], inBuf[port], nframes);
  335. first = false;
  336. }
  337. else
  338. {
  339. FLOAT_ADD(rack->in[1], inBuf[port], nframes);
  340. }
  341. }
  342. if (first)
  343. FLOAT_CLEAR(rack->in[1], nframes);
  344. }
  345. FLOAT_CLEAR(rack->out[0], nframes);
  346. FLOAT_CLEAR(rack->out[1], nframes);
  347. // process
  348. processRack(rack->in, rack->out, nframes, isOffline);
  349. // connect output buffers
  350. if (rack->connectedOuts[0].count() != 0)
  351. {
  352. for (List<uint>::Itenerator it = rack->connectedOuts[0].begin(); it.valid(); it.next())
  353. {
  354. const uint& port(it.getConstValue());
  355. CARLA_SAFE_ASSERT_CONTINUE(port < outCount);
  356. FLOAT_ADD(outBuf[port], rack->out[0], nframes);
  357. }
  358. }
  359. if (rack->connectedOuts[1].count() != 0)
  360. {
  361. for (List<uint>::Itenerator it = rack->connectedOuts[1].begin(); it.valid(); it.next())
  362. {
  363. const uint& port(it.getConstValue());
  364. CARLA_SAFE_ASSERT_CONTINUE(port < outCount);
  365. FLOAT_ADD(outBuf[port], rack->out[1], nframes);
  366. }
  367. }
  368. }
  369. #endif
  370. // -----------------------------------------------------------------------
  371. // Carla Engine port (Abstract)
  372. CarlaEnginePort::CarlaEnginePort(const CarlaEngine& engine, const bool isInput)
  373. : fEngine(engine),
  374. fIsInput(isInput)
  375. {
  376. carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInput));
  377. }
  378. CarlaEnginePort::~CarlaEnginePort()
  379. {
  380. carla_debug("CarlaEnginePort::~CarlaEnginePort()");
  381. }
  382. // -----------------------------------------------------------------------
  383. // Carla Engine Audio port
  384. CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngine& engine, const bool isInput)
  385. : CarlaEnginePort(engine, isInput),
  386. fBuffer(nullptr)
  387. {
  388. carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInput));
  389. }
  390. CarlaEngineAudioPort::~CarlaEngineAudioPort()
  391. {
  392. carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()");
  393. }
  394. void CarlaEngineAudioPort::initBuffer()
  395. {
  396. }
  397. // -----------------------------------------------------------------------
  398. // Carla Engine CV port
  399. CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInput)
  400. : CarlaEnginePort(engine, isInput),
  401. fBuffer(nullptr),
  402. fProcessMode(engine.getProccessMode())
  403. {
  404. carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInput));
  405. if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  406. fBuffer = new float[engine.getBufferSize()];
  407. }
  408. CarlaEngineCVPort::~CarlaEngineCVPort()
  409. {
  410. carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()");
  411. if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
  412. {
  413. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);
  414. delete[] fBuffer;
  415. fBuffer = nullptr;
  416. }
  417. }
  418. void CarlaEngineCVPort::initBuffer()
  419. {
  420. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);
  421. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,);
  422. FLOAT_CLEAR(fBuffer, fEngine.getBufferSize());
  423. }
  424. void CarlaEngineCVPort::setBufferSize(const uint32_t bufferSize)
  425. {
  426. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);
  427. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,);
  428. delete[] fBuffer;
  429. fBuffer = new float[bufferSize];
  430. }
  431. // -----------------------------------------------------------------------
  432. // Carla Engine Event port
  433. CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInput)
  434. : CarlaEnginePort(engine, isInput),
  435. fBuffer(nullptr),
  436. fProcessMode(engine.getProccessMode())
  437. {
  438. carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput));
  439. if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
  440. fBuffer = new EngineEvent[kEngineMaxInternalEventCount];
  441. }
  442. CarlaEngineEventPort::~CarlaEngineEventPort()
  443. {
  444. carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()");
  445. if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
  446. {
  447. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);
  448. delete[] fBuffer;
  449. fBuffer = nullptr;
  450. }
  451. }
  452. void CarlaEngineEventPort::initBuffer()
  453. {
  454. if (fProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fProcessMode == ENGINE_PROCESS_MODE_BRIDGE)
  455. fBuffer = fEngine.getInternalEventBuffer(fIsInput);
  456. else if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput)
  457. carla_zeroStruct<EngineEvent>(fBuffer, kEngineMaxInternalEventCount);
  458. }
  459. uint32_t CarlaEngineEventPort::getEventCount() const
  460. {
  461. CARLA_SAFE_ASSERT_RETURN(fIsInput, 0);
  462. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0);
  463. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0);
  464. uint32_t i=0;
  465. for (; i < kEngineMaxInternalEventCount; ++i)
  466. {
  467. if (fBuffer[i].type == kEngineEventTypeNull)
  468. break;
  469. }
  470. return i;
  471. }
  472. const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index)
  473. {
  474. CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent);
  475. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent);
  476. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent);
  477. CARLA_SAFE_ASSERT_RETURN(index < kEngineMaxInternalEventCount, kFallbackEngineEvent);
  478. return fBuffer[index];
  479. }
  480. const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index)
  481. {
  482. return fBuffer[index];
  483. }
  484. bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value)
  485. {
  486. CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
  487. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
  488. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
  489. CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false);
  490. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  491. CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);
  492. if (type == kEngineControlEventTypeParameter)
  493. {
  494. CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
  495. }
  496. const float fixedValue(carla_fixValue<float>(0.0f, 1.0f, value));
  497. for (uint32_t i=0; i < kEngineMaxInternalEventCount; ++i)
  498. {
  499. if (fBuffer[i].type != kEngineEventTypeNull)
  500. continue;
  501. EngineEvent& event(fBuffer[i]);
  502. event.type = kEngineEventTypeControl;
  503. event.time = time;
  504. event.channel = channel;
  505. event.ctrl.type = type;
  506. event.ctrl.param = param;
  507. event.ctrl.value = fixedValue;
  508. return true;
  509. }
  510. carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full");
  511. return false;
  512. }
  513. bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data)
  514. {
  515. CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
  516. CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
  517. CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
  518. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
  519. CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false);
  520. CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);
  521. for (uint32_t i=0; i < kEngineMaxInternalEventCount; ++i)
  522. {
  523. if (fBuffer[i].type != kEngineEventTypeNull)
  524. continue;
  525. EngineEvent& event(fBuffer[i]);
  526. event.type = kEngineEventTypeMidi;
  527. event.time = time;
  528. event.channel = channel;
  529. event.midi.port = port;
  530. event.midi.size = size;
  531. event.midi.data[0] = MIDI_GET_STATUS_FROM_DATA(data);
  532. uint8_t j=1;
  533. for (; j < size; ++j)
  534. event.midi.data[j] = data[j];
  535. for (; j < EngineMidiEvent::kDataSize; ++j)
  536. event.midi.data[j] = 0;
  537. return true;
  538. }
  539. carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full");
  540. return false;
  541. }
  542. // -----------------------------------------------------------------------
  543. // Carla Engine client (Abstract)
  544. CarlaEngineClient::CarlaEngineClient(const CarlaEngine& engine)
  545. : fEngine(engine),
  546. fActive(false),
  547. fLatency(0)
  548. {
  549. carla_debug("CarlaEngineClient::CarlaEngineClient()");
  550. }
  551. CarlaEngineClient::~CarlaEngineClient()
  552. {
  553. CARLA_ASSERT(! fActive);
  554. carla_debug("CarlaEngineClient::~CarlaEngineClient()");
  555. }
  556. void CarlaEngineClient::activate()
  557. {
  558. CARLA_ASSERT(! fActive);
  559. carla_debug("CarlaEngineClient::activate()");
  560. fActive = true;
  561. }
  562. void CarlaEngineClient::deactivate()
  563. {
  564. CARLA_ASSERT(fActive);
  565. carla_debug("CarlaEngineClient::deactivate()");
  566. fActive = false;
  567. }
  568. bool CarlaEngineClient::isActive() const noexcept
  569. {
  570. return fActive;
  571. }
  572. bool CarlaEngineClient::isOk() const noexcept
  573. {
  574. return true;
  575. }
  576. uint32_t CarlaEngineClient::getLatency() const noexcept
  577. {
  578. return fLatency;
  579. }
  580. void CarlaEngineClient::setLatency(const uint32_t samples) noexcept
  581. {
  582. fLatency = samples;
  583. }
  584. CarlaEnginePort* CarlaEngineClient::addPort(const EnginePortType portType, const char* const name, const bool isInput)
  585. {
  586. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr);
  587. carla_debug("CarlaEngineClient::addPort(%i:%s, \"%s\", %s)", portType, EnginePortType2Str(portType), name, bool2str(isInput));
  588. switch (portType)
  589. {
  590. case kEnginePortTypeNull:
  591. break;
  592. case kEnginePortTypeAudio:
  593. return new CarlaEngineAudioPort(fEngine, isInput);
  594. case kEnginePortTypeCV:
  595. return new CarlaEngineCVPort(fEngine, isInput);
  596. case kEnginePortTypeEvent:
  597. return new CarlaEngineEventPort(fEngine, isInput);
  598. }
  599. carla_stderr("CarlaEngineClient::addPort(%i, \"%s\", %s) - invalid type", portType, name, bool2str(isInput));
  600. return nullptr;
  601. }
  602. // -----------------------------------------------------------------------
  603. // Carla Engine
  604. CarlaEngine::CarlaEngine()
  605. : pData(new CarlaEngineProtectedData(this))
  606. {
  607. carla_debug("CarlaEngine::CarlaEngine()");
  608. }
  609. CarlaEngine::~CarlaEngine()
  610. {
  611. carla_debug("CarlaEngine::~CarlaEngine()");
  612. delete pData;
  613. }
  614. // -----------------------------------------------------------------------
  615. // Static calls
  616. unsigned int CarlaEngine::getDriverCount()
  617. {
  618. carla_debug("CarlaEngine::getDriverCount()");
  619. unsigned int count = 1; // JACK
  620. #ifndef BUILD_BRIDGE
  621. count += getRtAudioApiCount();
  622. # ifdef HAVE_JUCE
  623. count += getJuceApiCount();
  624. # endif
  625. #endif
  626. return count;
  627. }
  628. const char* CarlaEngine::getDriverName(const unsigned int index)
  629. {
  630. carla_debug("CarlaEngine::getDriverName(%i)", index);
  631. if (index == 0)
  632. return "JACK";
  633. #ifndef BUILD_BRIDGE
  634. const unsigned int rtAudioIndex(index-1);
  635. if (rtAudioIndex < getRtAudioApiCount())
  636. return getRtAudioApiName(rtAudioIndex);
  637. # ifdef HAVE_JUCE
  638. const unsigned int juceIndex(index-rtAudioIndex-1);
  639. if (juceIndex < getJuceApiCount())
  640. return getJuceApiName(juceIndex);
  641. # endif
  642. #endif
  643. carla_stderr("CarlaEngine::getDriverName(%i) - invalid index", index);
  644. return nullptr;
  645. }
  646. const char* const* CarlaEngine::getDriverDeviceNames(const unsigned int index)
  647. {
  648. carla_debug("CarlaEngine::getDriverDeviceNames(%i)", index);
  649. if (index == 0) // JACK
  650. {
  651. static const char* ret[3] = { "Auto-Connect OFF", "Auto-Connect ON", nullptr };
  652. return ret;
  653. }
  654. #ifndef BUILD_BRIDGE
  655. const unsigned int rtAudioIndex(index-1);
  656. if (rtAudioIndex < getRtAudioApiCount())
  657. return getRtAudioApiDeviceNames(rtAudioIndex);
  658. # ifdef HAVE_JUCE
  659. const unsigned int juceIndex(index-rtAudioIndex-1);
  660. if (juceIndex < getJuceApiCount())
  661. return getJuceApiDeviceNames(juceIndex);
  662. # endif
  663. #endif
  664. carla_stderr("CarlaEngine::getDriverDeviceNames(%i) - invalid index", index);
  665. return nullptr;
  666. }
  667. const EngineDriverDeviceInfo* CarlaEngine::getDriverDeviceInfo(const unsigned int index, const char* const deviceName)
  668. {
  669. carla_debug("CarlaEngine::getDriverDeviceInfo(%i, \"%s\")", index, deviceName);
  670. if (index == 0) // JACK
  671. {
  672. static uint32_t bufSizes[11] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 0 };
  673. static EngineDriverDeviceInfo devInfo;
  674. devInfo.hints = ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE;
  675. devInfo.bufferSizes = bufSizes;
  676. devInfo.sampleRates = nullptr;
  677. return &devInfo;
  678. }
  679. #ifndef BUILD_BRIDGE
  680. const unsigned int rtAudioIndex(index-1);
  681. if (rtAudioIndex < getRtAudioApiCount())
  682. return getRtAudioDeviceInfo(rtAudioIndex, deviceName);
  683. # ifdef HAVE_JUCE
  684. const unsigned int juceIndex(index-rtAudioIndex-1);
  685. if (juceIndex < getJuceApiCount())
  686. return getJuceDeviceInfo(juceIndex, deviceName);
  687. # endif
  688. #endif
  689. carla_stderr("CarlaEngine::getDriverDeviceNames(%i, \"%s\") - invalid index", index, deviceName);
  690. return nullptr;
  691. }
  692. CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName)
  693. {
  694. CARLA_SAFE_ASSERT_RETURN(driverName != nullptr && driverName[0] != '\0', nullptr);
  695. carla_debug("CarlaEngine::newDriverByName(\"%s\")", driverName);
  696. if (std::strcmp(driverName, "JACK") == 0)
  697. return newJack();
  698. // common
  699. if (std::strncmp(driverName, "JACK ", 5) == 0)
  700. return newRtAudio(AUDIO_API_JACK);
  701. // linux
  702. #ifdef HAVE_JUCE
  703. if (std::strcmp(driverName, "ALSA") == 0)
  704. return newJuce(AUDIO_API_ALSA);
  705. #else
  706. if (std::strcmp(driverName, "ALSA") == 0)
  707. return newRtAudio(AUDIO_API_ALSA);
  708. #endif
  709. if (std::strcmp(driverName, "OSS") == 0)
  710. return newRtAudio(AUDIO_API_OSS);
  711. if (std::strcmp(driverName, "PulseAudio") == 0)
  712. return newRtAudio(AUDIO_API_PULSE);
  713. // macos
  714. #ifdef HAVE_JUCE
  715. if (std::strcmp(driverName, "CoreAudio") == 0)
  716. return newJuce(AUDIO_API_CORE);
  717. #else
  718. if (std::strcmp(driverName, "CoreAudio") == 0)
  719. return newRtAudio(AUDIO_API_CORE);
  720. #endif
  721. // windows
  722. #ifdef HAVE_JUCE
  723. if (std::strcmp(driverName, "ASIO") == 0)
  724. return newJuce(AUDIO_API_ASIO);
  725. if (std::strcmp(driverName, "DirectSound") == 0)
  726. return newJuce(AUDIO_API_DS);
  727. #else
  728. if (std::strcmp(driverName, "ASIO") == 0)
  729. return newRtAudio(AUDIO_API_ASIO);
  730. if (std::strcmp(driverName, "DirectSound") == 0)
  731. return newRtAudio(AUDIO_API_DS);
  732. #endif
  733. carla_stderr("CarlaEngine::newDriverByName(\"%s\") - invalid driver name", driverName);
  734. return nullptr;
  735. }
  736. // -----------------------------------------------------------------------
  737. // Maximum values
  738. unsigned int CarlaEngine::getMaxClientNameSize() const noexcept
  739. {
  740. return STR_MAX/2;
  741. }
  742. unsigned int CarlaEngine::getMaxPortNameSize() const noexcept
  743. {
  744. return STR_MAX;
  745. }
  746. unsigned int CarlaEngine::getCurrentPluginCount() const noexcept
  747. {
  748. return pData->curPluginCount;
  749. }
  750. unsigned int CarlaEngine::getMaxPluginNumber() const noexcept
  751. {
  752. return pData->maxPluginNumber;
  753. }
  754. // -----------------------------------------------------------------------
  755. // Virtual, per-engine type calls
  756. bool CarlaEngine::init(const char* const clientName)
  757. {
  758. CARLA_SAFE_ASSERT_RETURN_ERR(pData->name.isEmpty(), "Invalid engine internal data (err #1)");
  759. CARLA_SAFE_ASSERT_RETURN_ERR(pData->oscData == nullptr, "Invalid engine internal data (err #2)");
  760. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins == nullptr, "Invalid engine internal data (err #3)");
  761. CARLA_SAFE_ASSERT_RETURN_ERR(pData->bufEvents.in == nullptr, "Invalid engine internal data (err #4)");
  762. CARLA_SAFE_ASSERT_RETURN_ERR(pData->bufEvents.out == nullptr, "Invalid engine internal data (err #5)");
  763. CARLA_SAFE_ASSERT_RETURN_ERR(clientName != nullptr && clientName[0] != '\0', "Invalid client name");
  764. carla_debug("CarlaEngine::init(\"%s\")", clientName);
  765. pData->aboutToClose = false;
  766. pData->curPluginCount = 0;
  767. pData->maxPluginNumber = 0;
  768. pData->nextPluginId = 0;
  769. switch (pData->options.processMode)
  770. {
  771. case ENGINE_PROCESS_MODE_SINGLE_CLIENT:
  772. case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS:
  773. pData->maxPluginNumber = MAX_DEFAULT_PLUGINS;
  774. break;
  775. case ENGINE_PROCESS_MODE_CONTINUOUS_RACK:
  776. pData->maxPluginNumber = MAX_RACK_PLUGINS;
  777. pData->bufEvents.in = new EngineEvent[kEngineMaxInternalEventCount];
  778. pData->bufEvents.out = new EngineEvent[kEngineMaxInternalEventCount];
  779. break;
  780. case ENGINE_PROCESS_MODE_PATCHBAY:
  781. pData->maxPluginNumber = MAX_PATCHBAY_PLUGINS;
  782. break;
  783. case ENGINE_PROCESS_MODE_BRIDGE:
  784. pData->maxPluginNumber = 1;
  785. pData->bufEvents.in = new EngineEvent[kEngineMaxInternalEventCount];
  786. pData->bufEvents.out = new EngineEvent[kEngineMaxInternalEventCount];
  787. break;
  788. }
  789. CARLA_SAFE_ASSERT_RETURN_ERR(pData->maxPluginNumber != 0, "Invalid engine process mode");
  790. pData->nextPluginId = pData->maxPluginNumber;
  791. pData->name = clientName;
  792. pData->name.toBasic();
  793. pData->timeInfo.clear();
  794. pData->plugins = new EnginePluginData[pData->maxPluginNumber];
  795. for (uint i=0; i < pData->maxPluginNumber; ++i)
  796. pData->plugins[i].clear();
  797. pData->osc.init(clientName);
  798. #ifndef BUILD_BRIDGE
  799. pData->oscData = pData->osc.getControlData();
  800. #endif
  801. pData->nextAction.ready();
  802. pData->thread.start();
  803. callback(ENGINE_CALLBACK_ENGINE_STARTED, 0, 0, 0, 0.0f, getCurrentDriverName());
  804. return true;
  805. }
  806. bool CarlaEngine::close()
  807. {
  808. CARLA_SAFE_ASSERT_RETURN_ERR(pData->name.isNotEmpty(), "Invalid engine internal data (err #6)");
  809. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data (err #7)");
  810. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId == pData->maxPluginNumber, "Invalid engine internal data (err #8)");
  811. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #9)");
  812. carla_debug("CarlaEngine::close()");
  813. pData->thread.stop(500);
  814. pData->nextAction.ready();
  815. #ifndef BUILD_BRIDGE
  816. oscSend_control_exit();
  817. #endif
  818. pData->osc.close();
  819. pData->oscData = nullptr;
  820. pData->aboutToClose = true;
  821. pData->curPluginCount = 0;
  822. pData->maxPluginNumber = 0;
  823. pData->nextPluginId = 0;
  824. if (pData->plugins != nullptr)
  825. {
  826. delete[] pData->plugins;
  827. pData->plugins = nullptr;
  828. }
  829. if (pData->bufEvents.in != nullptr)
  830. {
  831. delete[] pData->bufEvents.in;
  832. pData->bufEvents.in = nullptr;
  833. }
  834. if (pData->bufEvents.out != nullptr)
  835. {
  836. delete[] pData->bufEvents.out;
  837. pData->bufEvents.out = nullptr;
  838. }
  839. pData->name.clear();
  840. callback(ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr);
  841. return true;
  842. }
  843. void CarlaEngine::idle()
  844. {
  845. CARLA_ASSERT(pData->nextAction.opcode == kEnginePostActionNull); // TESTING, remove later
  846. CARLA_ASSERT(pData->nextPluginId == pData->maxPluginNumber); // TESTING, remove later
  847. CARLA_ASSERT(pData->plugins != nullptr); // this one too maybe
  848. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  849. {
  850. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  851. if (plugin != nullptr && plugin->isEnabled())
  852. plugin->idle();
  853. }
  854. }
  855. CarlaEngineClient* CarlaEngine::addClient(CarlaPlugin* const)
  856. {
  857. return new CarlaEngineClient(*this);
  858. }
  859. // -----------------------------------------------------------------------
  860. // Plugin management
  861. bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, const void* const extra)
  862. {
  863. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data (err #10)");
  864. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId <= pData->maxPluginNumber, "Invalid engine internal data (err #11)");
  865. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #12)");
  866. CARLA_SAFE_ASSERT_RETURN_ERR(btype != BINARY_NONE, "Invalid plugin params (err #1)");
  867. CARLA_SAFE_ASSERT_RETURN_ERR(ptype != PLUGIN_NONE, "Invalid plugin params (err #2)");
  868. CARLA_SAFE_ASSERT_RETURN_ERR((filename != nullptr && filename[0] != '\0') || (label != nullptr && label[0] != '\0'), "Invalid plugin params (err #3)");
  869. carla_debug("CarlaEngine::addPlugin(%i:%s, %i:%s, \"%s\", \"%s\", \"%s\", %p)", btype, BinaryType2Str(btype), ptype, PluginType2Str(ptype), filename, name, label, extra);
  870. unsigned int id;
  871. CarlaPlugin* oldPlugin = nullptr;
  872. if (pData->nextPluginId < pData->curPluginCount)
  873. {
  874. id = pData->nextPluginId;
  875. pData->nextPluginId = pData->maxPluginNumber;
  876. oldPlugin = pData->plugins[id].plugin;
  877. CARLA_SAFE_ASSERT_RETURN_ERR(oldPlugin != nullptr, "Invalid replace plugin Id");
  878. }
  879. else
  880. {
  881. id = pData->curPluginCount;
  882. if (id == pData->maxPluginNumber)
  883. {
  884. setLastError("Maximum number of plugins reached");
  885. return false;
  886. }
  887. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins[id].plugin == nullptr, "Invalid engine internal data (err #13)");
  888. }
  889. CarlaPlugin::Initializer init = {
  890. this,
  891. id,
  892. filename,
  893. name,
  894. label
  895. };
  896. CarlaPlugin* plugin = nullptr;
  897. #if 0 //ndef BUILD_BRIDGE
  898. const char* bridgeBinary;
  899. switch (btype)
  900. {
  901. case BINARY_POSIX32:
  902. bridgeBinary = pData->options.bridge_posix32.isNotEmpty() ? (const char*)pData->options.bridge_posix32 : nullptr;
  903. break;
  904. case BINARY_POSIX64:
  905. bridgeBinary = pData->options.bridge_posix64.isNotEmpty() ? (const char*)pData->options.bridge_posix64 : nullptr;
  906. break;
  907. case BINARY_WIN32:
  908. bridgeBinary = pData->options.bridge_win32.isNotEmpty() ? (const char*)pData->options.bridge_win32 : nullptr;
  909. break;
  910. case BINARY_WIN64:
  911. bridgeBinary = pData->options.bridge_win64.isNotEmpty() ? (const char*)pData->options.bridge_win64 : nullptr;
  912. break;
  913. default:
  914. bridgeBinary = nullptr;
  915. break;
  916. }
  917. # ifndef CARLA_OS_WIN
  918. if (btype == BINARY_NATIVE && pData->options.bridge_native.isNotEmpty())
  919. bridgeBinary = (const char*)pData->options.bridge_native;
  920. # endif
  921. if (btype != BINARY_NATIVE || (pData->options.preferPluginBridges && bridgeBinary != nullptr))
  922. {
  923. if (bridgeBinary != nullptr)
  924. {
  925. plugin = CarlaPlugin::newBridge(init, btype, ptype, bridgeBinary);
  926. }
  927. # ifdef CARLA_OS_LINUX
  928. else if (btype == BINARY_WIN32)
  929. {
  930. // fallback to dssi-vst
  931. QFileInfo fileInfo(filename);
  932. CarlaString label2(fileInfo.fileName().toUtf8().constData());
  933. label2.replace(' ', '*');
  934. CarlaPlugin::Initializer init2 = {
  935. this,
  936. id,
  937. "/usr/lib/dssi/dssi-vst.so",
  938. name,
  939. (const char*)label2
  940. };
  941. char* const oldVstPath(getenv("VST_PATH"));
  942. carla_setenv("VST_PATH", fileInfo.absoluteDir().absolutePath().toUtf8().constData());
  943. plugin = CarlaPlugin::newDSSI(init2);
  944. if (oldVstPath != nullptr)
  945. carla_setenv("VST_PATH", oldVstPath);
  946. }
  947. # endif
  948. else
  949. {
  950. setLastError("This Carla build cannot handle this binary");
  951. return false;
  952. }
  953. }
  954. else
  955. #endif // BUILD_BRIDGE
  956. {
  957. setLastError("Invalid or unsupported plugin type");
  958. switch (ptype)
  959. {
  960. case PLUGIN_NONE:
  961. break;
  962. case PLUGIN_INTERNAL:
  963. plugin = CarlaPlugin::newNative(init);
  964. break;
  965. case PLUGIN_LADSPA:
  966. plugin = CarlaPlugin::newLADSPA(init, (const LADSPA_RDF_Descriptor*)extra);
  967. break;
  968. case PLUGIN_DSSI:
  969. plugin = CarlaPlugin::newDSSI(init);
  970. break;
  971. case PLUGIN_LV2:
  972. plugin = CarlaPlugin::newLV2(init);
  973. break;
  974. case PLUGIN_VST:
  975. plugin = CarlaPlugin::newVST(init);
  976. break;
  977. case PLUGIN_AU:
  978. //plugin = CarlaPlugin::newAU(init);
  979. break;
  980. case PLUGIN_CSOUND:
  981. //plugin = CarlaPlugin::newCSOUND(init);
  982. break;
  983. case PLUGIN_GIG:
  984. plugin = CarlaPlugin::newGIG(init, (extra != nullptr));
  985. break;
  986. case PLUGIN_SF2:
  987. plugin = CarlaPlugin::newSF2(init, (extra != nullptr));
  988. break;
  989. case PLUGIN_SFZ:
  990. plugin = CarlaPlugin::newSFZ(init, (extra != nullptr));
  991. break;
  992. }
  993. }
  994. if (plugin == nullptr)
  995. return false;
  996. plugin->registerToOscClient();
  997. EnginePluginData& pluginData(pData->plugins[id]);
  998. pluginData.plugin = plugin;
  999. pluginData.insPeak[0] = 0.0f;
  1000. pluginData.insPeak[1] = 0.0f;
  1001. pluginData.outsPeak[0] = 0.0f;
  1002. pluginData.outsPeak[1] = 0.0f;
  1003. if (oldPlugin != nullptr)
  1004. {
  1005. delete oldPlugin;
  1006. callback(ENGINE_CALLBACK_RELOAD_ALL, id, 0, 0, 0.0f, plugin->getName());
  1007. }
  1008. else
  1009. {
  1010. ++pData->curPluginCount;
  1011. callback(ENGINE_CALLBACK_PLUGIN_ADDED, id, 0, 0, 0.0f, plugin->getName());
  1012. }
  1013. return true;
  1014. }
  1015. bool CarlaEngine::removePlugin(const unsigned int id)
  1016. {
  1017. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data (err #14)");
  1018. CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data (err #15)");
  1019. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #16)");
  1020. CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id (err #1)");
  1021. carla_debug("CarlaEngine::removePlugin(%i)", id);
  1022. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  1023. CARLA_SAFE_ASSERT_RETURN_ERR(plugin != nullptr, "Could not find plugin to remove");
  1024. CARLA_SAFE_ASSERT_RETURN_ERR(plugin->getId() == id, "Invalid engine internal data (err #17)");
  1025. pData->thread.stop(500);
  1026. const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS);
  1027. const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait);
  1028. #ifndef BUILD_BRIDGE
  1029. if (isOscControlRegistered())
  1030. oscSend_control_remove_plugin(id);
  1031. #endif
  1032. delete plugin;
  1033. if (isRunning() && ! pData->aboutToClose)
  1034. pData->thread.start();
  1035. callback(ENGINE_CALLBACK_PLUGIN_REMOVED, id, 0, 0, 0.0f, nullptr);
  1036. return true;
  1037. }
  1038. bool CarlaEngine::removeAllPlugins()
  1039. {
  1040. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data (err #18)");
  1041. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId == pData->maxPluginNumber, "Invalid engine internal data (err #19)");
  1042. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #20)");
  1043. carla_debug("CarlaEngine::removeAllPlugins()");
  1044. if (pData->curPluginCount == 0)
  1045. return true;
  1046. pData->thread.stop(500);
  1047. const bool lockWait(isRunning());
  1048. const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, lockWait);
  1049. for (unsigned int i=0; i < pData->maxPluginNumber; ++i)
  1050. {
  1051. EnginePluginData& pluginData(pData->plugins[i]);
  1052. if (pluginData.plugin != nullptr)
  1053. {
  1054. delete pluginData.plugin;
  1055. pluginData.plugin = nullptr;
  1056. }
  1057. pluginData.insPeak[0] = 0.0f;
  1058. pluginData.insPeak[1] = 0.0f;
  1059. pluginData.outsPeak[0] = 0.0f;
  1060. pluginData.outsPeak[1] = 0.0f;
  1061. }
  1062. if (isRunning() && ! pData->aboutToClose)
  1063. pData->thread.start();
  1064. return true;
  1065. }
  1066. const char* CarlaEngine::renamePlugin(const unsigned int id, const char* const newName)
  1067. {
  1068. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data (err #21)");
  1069. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data (err #22)");
  1070. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #23)");
  1071. CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id (err #2)");
  1072. CARLA_SAFE_ASSERT_RETURN_ERRN(newName != nullptr && newName[0] != '\0', "Invalid plugin name");
  1073. carla_debug("CarlaEngine::renamePlugin(%i, \"%s\")", id, newName);
  1074. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  1075. CARLA_SAFE_ASSERT_RETURN_ERRN(plugin != nullptr, "Could not find plugin to rename");
  1076. CARLA_SAFE_ASSERT_RETURN_ERRN(plugin->getId() == id, "Invalid engine internal data (err #24)");
  1077. if (const char* const name = getUniquePluginName(newName))
  1078. {
  1079. plugin->setName(name);
  1080. return name;
  1081. }
  1082. setLastError("Unable to get new unique plugin name");
  1083. return nullptr;
  1084. }
  1085. bool CarlaEngine::clonePlugin(const unsigned int id)
  1086. {
  1087. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data (err #25)");
  1088. CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data (err #26)");
  1089. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #27)");
  1090. CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id (err #3)");
  1091. carla_debug("CarlaEngine::clonePlugin(%i)", id);
  1092. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  1093. CARLA_SAFE_ASSERT_RETURN_ERR(plugin != nullptr, "Could not find plugin to clone");
  1094. CARLA_SAFE_ASSERT_RETURN_ERR(plugin->getId() == id, "Invalid engine internal data (err #28)");
  1095. char label[STR_MAX+1];
  1096. carla_zeroChar(label, STR_MAX+1);
  1097. plugin->getLabel(label);
  1098. const unsigned int pluginCountBefore(pData->curPluginCount);
  1099. if (! addPlugin(plugin->getBinaryType(), plugin->getType(), plugin->getFilename(), plugin->getName(), label, plugin->getExtraStuff()))
  1100. return false;
  1101. CARLA_ASSERT(pluginCountBefore+1 == pData->curPluginCount);
  1102. if (CarlaPlugin* const newPlugin = pData->plugins[pluginCountBefore].plugin)
  1103. newPlugin->loadSaveState(plugin->getSaveState());
  1104. return true;
  1105. }
  1106. bool CarlaEngine::replacePlugin(const unsigned int id)
  1107. {
  1108. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data (err #29)");
  1109. CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data (err #30)");
  1110. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #31)");
  1111. CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id (err #4)");
  1112. carla_debug("CarlaEngine::replacePlugin(%i)", id);
  1113. CarlaPlugin* const plugin(pData->plugins[id].plugin);
  1114. CARLA_SAFE_ASSERT_RETURN_ERR(plugin != nullptr, "Could not find plugin to replace");
  1115. CARLA_SAFE_ASSERT_RETURN_ERR(plugin->getId() == id, "Invalid engine internal data (err #32)");
  1116. pData->nextPluginId = id;
  1117. return true;
  1118. }
  1119. bool CarlaEngine::switchPlugins(const unsigned int idA, const unsigned int idB)
  1120. {
  1121. CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data (err #33)");
  1122. CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount >= 2, "Invalid engine internal data (err #34)");
  1123. CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #35)");
  1124. CARLA_SAFE_ASSERT_RETURN_ERR(idA != idB, "Invalid operation, cannot switch plugin with itself");
  1125. CARLA_SAFE_ASSERT_RETURN_ERR(idA < pData->curPluginCount, "Invalid plugin Id (err #5)");
  1126. CARLA_SAFE_ASSERT_RETURN_ERR(idB < pData->curPluginCount, "Invalid plugin Id (err #6)");
  1127. carla_debug("CarlaEngine::switchPlugins(%i)", idA, idB);
  1128. CarlaPlugin* const pluginA(pData->plugins[idA].plugin);
  1129. CarlaPlugin* const pluginB(pData->plugins[idB].plugin);
  1130. CARLA_SAFE_ASSERT_RETURN_ERR(pluginA != nullptr, "Could not find plugin to switch (err #1)");
  1131. CARLA_SAFE_ASSERT_RETURN_ERR(pluginA != nullptr, "Could not find plugin to switch (err #2)");
  1132. CARLA_SAFE_ASSERT_RETURN_ERR(pluginA->getId() == idA, "Invalid engine internal data (err #36)");
  1133. CARLA_SAFE_ASSERT_RETURN_ERR(pluginB->getId() == idB, "Invalid engine internal data (err #37)");
  1134. pData->thread.stop(500);
  1135. const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS);
  1136. const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait);
  1137. #ifndef BUILD_BRIDGE // TODO
  1138. //if (isOscControlRegistered())
  1139. // oscSend_control_switch_plugins(idA, idB);
  1140. #endif
  1141. if (isRunning() && ! pData->aboutToClose)
  1142. pData->thread.start();
  1143. return true;
  1144. }
  1145. CarlaPlugin* CarlaEngine::getPlugin(const unsigned int id) const
  1146. {
  1147. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data (err #38)");
  1148. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data (err #39)");
  1149. CARLA_SAFE_ASSERT_RETURN_ERRN(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #40)");
  1150. CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id (err #7)");
  1151. carla_debug("CarlaEngine::getPlugin(%i) [count:%i]", id, pData->curPluginCount);
  1152. return pData->plugins[id].plugin;
  1153. }
  1154. CarlaPlugin* CarlaEngine::getPluginUnchecked(const unsigned int id) const noexcept
  1155. {
  1156. return pData->plugins[id].plugin;
  1157. }
  1158. const char* CarlaEngine::getUniquePluginName(const char* const name) const
  1159. {
  1160. CARLA_SAFE_ASSERT_RETURN(pData->plugins != nullptr, nullptr);
  1161. CARLA_SAFE_ASSERT_RETURN(pData->maxPluginNumber != 0, nullptr);
  1162. CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode == kEnginePostActionNull, nullptr);
  1163. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr);
  1164. carla_debug("CarlaEngine::getUniquePluginName(\"%s\")", name);
  1165. CarlaString sname;
  1166. sname = name;
  1167. if (sname.isEmpty())
  1168. {
  1169. sname = "(No name)";
  1170. return sname.dup();
  1171. }
  1172. sname.truncate(getMaxClientNameSize()-5-1); // 5 = strlen(" (10)")
  1173. sname.replace(':', '.'); // ':' is used in JACK1 to split client/port names
  1174. for (unsigned short i=0; i < pData->curPluginCount; ++i)
  1175. {
  1176. CARLA_SAFE_ASSERT_BREAK(pData->plugins[i].plugin != nullptr);
  1177. // Check if unique name doesn't exist
  1178. if (const char* const pluginName = pData->plugins[i].plugin->getName())
  1179. {
  1180. if (sname != pluginName)
  1181. continue;
  1182. }
  1183. // Check if string has already been modified
  1184. {
  1185. const size_t len(sname.length());
  1186. // 1 digit, ex: " (2)"
  1187. if (sname[len-4] == ' ' && sname[len-3] == '(' && sname.isDigit(len-2) && sname[len-1] == ')')
  1188. {
  1189. int number = sname[len-2] - '0';
  1190. if (number == 9)
  1191. {
  1192. // next number is 10, 2 digits
  1193. sname.truncate(len-4);
  1194. sname += " (10)";
  1195. //sname.replace(" (9)", " (10)");
  1196. }
  1197. else
  1198. sname[len-2] = char('0' + number + 1);
  1199. continue;
  1200. }
  1201. // 2 digits, ex: " (11)"
  1202. if (sname[len-5] == ' ' && sname[len-4] == '(' && sname.isDigit(len-3) && sname.isDigit(len-2) && sname[len-1] == ')')
  1203. {
  1204. char n2 = sname[len-2];
  1205. char n3 = sname[len-3];
  1206. if (n2 == '9')
  1207. {
  1208. n2 = '0';
  1209. n3 = static_cast<char>(n3 + 1);
  1210. }
  1211. else
  1212. n2 = static_cast<char>(n2 + 1);
  1213. sname[len-2] = n2;
  1214. sname[len-3] = n3;
  1215. continue;
  1216. }
  1217. }
  1218. // Modify string if not
  1219. sname += " (2)";
  1220. }
  1221. return sname.dup();
  1222. }
  1223. // -----------------------------------------------------------------------
  1224. // Project management
  1225. bool CarlaEngine::loadFile(const char* const filename)
  1226. {
  1227. CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename (err #1)");
  1228. carla_debug("CarlaEngine::loadFile(\"%s\")", filename);
  1229. QFileInfo fileInfo(filename);
  1230. if (! fileInfo.exists())
  1231. {
  1232. setLastError("File does not exist");
  1233. return false;
  1234. }
  1235. if (! fileInfo.isFile())
  1236. {
  1237. setLastError("Not a file");
  1238. return false;
  1239. }
  1240. if (! fileInfo.isReadable())
  1241. {
  1242. setLastError("File is not readable");
  1243. return false;
  1244. }
  1245. CarlaString baseName(fileInfo.baseName().toUtf8().constData());
  1246. CarlaString extension(fileInfo.suffix().toLower().toUtf8().constData());
  1247. extension.toLower();
  1248. // -------------------------------------------------------------------
  1249. if (extension == "carxp" || extension == "carxs")
  1250. return loadProject(filename);
  1251. // -------------------------------------------------------------------
  1252. if (extension == "csd")
  1253. return addPlugin(PLUGIN_CSOUND, filename, baseName, baseName);
  1254. if (extension == "gig")
  1255. return addPlugin(PLUGIN_GIG, filename, baseName, baseName);
  1256. if (extension == "sf2")
  1257. return addPlugin(PLUGIN_SF2, filename, baseName, baseName);
  1258. if (extension == "sfz")
  1259. return addPlugin(PLUGIN_SFZ, filename, baseName, baseName);
  1260. // -------------------------------------------------------------------
  1261. if (extension == "aiff" || extension == "flac" || extension == "oga" || extension == "ogg" || extension == "w64" || extension == "wav")
  1262. {
  1263. #ifdef WANT_AUDIOFILE
  1264. if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "audiofile"))
  1265. {
  1266. if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1))
  1267. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "file", filename, true);
  1268. return true;
  1269. }
  1270. return false;
  1271. #else
  1272. setLastError("This Carla build does not have Audio file support");
  1273. return false;
  1274. #endif
  1275. }
  1276. if (extension == "3g2" || extension == "3gp" || extension == "aac" || extension == "ac3" || extension == "amr" || extension == "ape" ||
  1277. extension == "mp2" || extension == "mp3" || extension == "mpc" || extension == "wma")
  1278. {
  1279. #ifdef WANT_AUDIOFILE
  1280. # ifdef HAVE_FFMPEG
  1281. if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "audiofile"))
  1282. {
  1283. if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1))
  1284. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "file", filename, true);
  1285. return true;
  1286. }
  1287. return false;
  1288. # else
  1289. setLastError("This Carla build has Audio file support, but not libav/ffmpeg");
  1290. return false;
  1291. # endif
  1292. #else
  1293. setLastError("This Carla build does not have Audio file support");
  1294. return false;
  1295. #endif
  1296. }
  1297. // -------------------------------------------------------------------
  1298. if (extension == "mid" || extension == "midi")
  1299. {
  1300. #ifdef WANT_MIDIFILE
  1301. if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "midifile"))
  1302. {
  1303. if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1))
  1304. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, "file", filename, true);
  1305. return true;
  1306. }
  1307. return false;
  1308. #else
  1309. setLastError("This Carla build does not have MIDI file support");
  1310. return false;
  1311. #endif
  1312. }
  1313. // -------------------------------------------------------------------
  1314. // ZynAddSubFX
  1315. if (extension == "xmz" || extension == "xiz")
  1316. {
  1317. #ifdef WANT_ZYNADDSUBFX
  1318. if (addPlugin(PLUGIN_INTERNAL, nullptr, baseName, "zynaddsubfx"))
  1319. {
  1320. if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1))
  1321. plugin->setCustomData(CUSTOM_DATA_TYPE_STRING, (extension == "xmz") ? "CarlaAlternateFile1" : "CarlaAlternateFile2", filename, true);
  1322. return true;
  1323. }
  1324. return false;
  1325. #else
  1326. setLastError("This Carla build does not have ZynAddSubFX support");
  1327. return false;
  1328. #endif
  1329. }
  1330. // -------------------------------------------------------------------
  1331. setLastError("Unknown file extension");
  1332. return false;
  1333. }
  1334. bool CarlaEngine::loadProject(const char* const filename)
  1335. {
  1336. CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename (err #2)");
  1337. carla_debug("CarlaEngine::loadProject(\"%s\")", filename);
  1338. QFile file(filename);
  1339. if (! file.open(QIODevice::ReadOnly | QIODevice::Text))
  1340. return false;
  1341. QDomDocument xml;
  1342. xml.setContent(file.readAll());
  1343. file.close();
  1344. QDomNode xmlNode(xml.documentElement());
  1345. const bool isPreset(xmlNode.toElement().tagName().compare("carla-preset", Qt::CaseInsensitive) == 0);
  1346. if (xmlNode.toElement().tagName().compare("carla-project", Qt::CaseInsensitive) != 0 && ! isPreset)
  1347. {
  1348. setLastError("Not a valid Carla project or preset file");
  1349. return false;
  1350. }
  1351. for (QDomNode node = xmlNode.firstChild(); ! node.isNull(); node = node.nextSibling())
  1352. {
  1353. if (isPreset || node.toElement().tagName().compare("plugin", Qt::CaseInsensitive) == 0)
  1354. {
  1355. SaveState saveState;
  1356. fillSaveStateFromXmlNode(saveState, isPreset ? xmlNode : node);
  1357. CARLA_SAFE_ASSERT_CONTINUE(saveState.type != nullptr);
  1358. const void* extraStuff = nullptr;
  1359. // check if using GIG, SF2 or SFZ 16outs
  1360. static const char kUse16OutsSuffix[] = " (16 outs)";
  1361. if (CarlaString(saveState.label).endsWith(kUse16OutsSuffix))
  1362. {
  1363. if (std::strcmp(saveState.type, "GIG") == 0 || std::strcmp(saveState.type, "SF2") == 0 || std::strcmp(saveState.type, "SFZ") == 0)
  1364. extraStuff = (void*)0x1; // non-null
  1365. }
  1366. // TODO - proper find&load plugins
  1367. if (addPlugin(getPluginTypeFromString(saveState.type), saveState.binary, saveState.name, saveState.label, extraStuff))
  1368. {
  1369. if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1))
  1370. plugin->loadSaveState(saveState);
  1371. }
  1372. }
  1373. if (isPreset)
  1374. break;
  1375. }
  1376. return true;
  1377. }
  1378. bool CarlaEngine::saveProject(const char* const filename)
  1379. {
  1380. CARLA_SAFE_ASSERT_RETURN_ERR(filename != nullptr && filename[0] != '\0', "Invalid filename (err #3)");
  1381. carla_debug("CarlaEngine::saveProject(\"%s\")", filename);
  1382. QFile file(filename);
  1383. if (! file.open(QIODevice::WriteOnly | QIODevice::Text))
  1384. return false;
  1385. QTextStream out(&file);
  1386. out << "<?xml version='1.0' encoding='UTF-8'?>\n";
  1387. out << "<!DOCTYPE CARLA-PROJECT>\n";
  1388. out << "<CARLA-PROJECT VERSION='2.0'>\n";
  1389. bool firstPlugin = true;
  1390. char strBuf[STR_MAX+1];
  1391. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  1392. {
  1393. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1394. if (plugin != nullptr && plugin->isEnabled())
  1395. {
  1396. if (! firstPlugin)
  1397. out << "\n";
  1398. strBuf[0] = '\0';
  1399. plugin->getRealName(strBuf);
  1400. if (strBuf[0] != '\0')
  1401. out << QString(" <!-- %1 -->\n").arg(xmlSafeString(strBuf, true));
  1402. QString content;
  1403. fillXmlStringFromSaveState(content, plugin->getSaveState());
  1404. out << " <Plugin>\n";
  1405. out << content;
  1406. out << " </Plugin>\n";
  1407. firstPlugin = false;
  1408. }
  1409. }
  1410. out << "</CARLA-PROJECT>\n";
  1411. file.close();
  1412. return true;
  1413. }
  1414. // -----------------------------------------------------------------------
  1415. // Information (base)
  1416. /*!
  1417. * Get the current engine driver hints.
  1418. */
  1419. unsigned int CarlaEngine::getHints() const noexcept
  1420. {
  1421. return pData->hints;
  1422. }
  1423. /*!
  1424. * Get the current buffer size.
  1425. */
  1426. uint32_t CarlaEngine::getBufferSize() const noexcept
  1427. {
  1428. return pData->bufferSize;
  1429. }
  1430. /*!
  1431. * Get the current sample rate.
  1432. */
  1433. double CarlaEngine::getSampleRate() const noexcept
  1434. {
  1435. return pData->sampleRate;
  1436. }
  1437. /*!
  1438. * Get the current engine name.
  1439. */
  1440. const char* CarlaEngine::getName() const noexcept
  1441. {
  1442. return (const char*)pData->name;
  1443. }
  1444. /*!
  1445. * Get the current engine proccess mode.
  1446. */
  1447. EngineProcessMode CarlaEngine::getProccessMode() const noexcept
  1448. {
  1449. return pData->options.processMode;
  1450. }
  1451. /*!
  1452. * Get the current engine options (read-only).
  1453. */
  1454. const EngineOptions& CarlaEngine::getOptions() const noexcept
  1455. {
  1456. return pData->options;
  1457. }
  1458. /*!
  1459. * Get the current Time information (read-only).
  1460. */
  1461. const EngineTimeInfo& CarlaEngine::getTimeInfo() const noexcept
  1462. {
  1463. return pData->timeInfo;
  1464. }
  1465. // -----------------------------------------------------------------------
  1466. // Information (peaks)
  1467. float CarlaEngine::getInputPeak(const unsigned int pluginId, const bool isLeft) const
  1468. {
  1469. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount, 0.0f);
  1470. return pData->plugins[pluginId].insPeak[isLeft ? 0 : 1];
  1471. }
  1472. float CarlaEngine::getOutputPeak(const unsigned int pluginId, const bool isLeft) const
  1473. {
  1474. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount, 0.0f);
  1475. return pData->plugins[pluginId].outsPeak[isLeft ? 0 : 1];
  1476. }
  1477. // -----------------------------------------------------------------------
  1478. // Callback
  1479. void CarlaEngine::callback(const EngineCallbackOpcode action, const unsigned int pluginId, const int value1, const int value2, const float value3, const char* const valueStr)
  1480. {
  1481. carla_debug("CarlaEngine::callback(%s, %i, %i, %i, %f, \"%s\")", EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valueStr);
  1482. if (pData->callback != nullptr)
  1483. pData->callback(pData->callbackPtr, action, pluginId, value1, value2, value3, valueStr);
  1484. }
  1485. void CarlaEngine::setCallback(const EngineCallbackFunc func, void* const ptr)
  1486. {
  1487. carla_debug("CarlaEngine::setCallback(%p, %p)", func, ptr);
  1488. pData->callback = func;
  1489. pData->callbackPtr = ptr;
  1490. }
  1491. #ifndef BUILD_BRIDGE
  1492. // -----------------------------------------------------------------------
  1493. // Patchbay
  1494. bool CarlaEngine::patchbayConnect(const int portA, const int portB)
  1495. {
  1496. CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false);
  1497. CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false);
  1498. carla_debug("CarlaEngineRtAudio::patchbayConnect(%i, %i)", portA, portB);
  1499. if (pData->bufAudio.usePatchbay)
  1500. {
  1501. // not implemented yet
  1502. return false;
  1503. }
  1504. EngineRackBuffers* const rack(pData->bufAudio.rack);
  1505. CARLA_SAFE_ASSERT_RETURN_ERR(portA > RACK_PATCHBAY_PORT_MAX, "Invalid output port");
  1506. CARLA_SAFE_ASSERT_RETURN_ERR(portB > RACK_PATCHBAY_PORT_MAX, "Invalid input port");
  1507. // only allow connections between Carla and other ports
  1508. if (portA < 0 && portB < 0)
  1509. {
  1510. setLastError("Invalid connection (1)");
  1511. return false;
  1512. }
  1513. if (portA >= 0 && portB >= 0)
  1514. {
  1515. setLastError("Invalid connection (2)");
  1516. return false;
  1517. }
  1518. const int carlaPort = (portA < 0) ? portA : portB;
  1519. const int targetPort = (carlaPort == portA) ? portB : portA;
  1520. bool makeConnection = false;
  1521. switch (carlaPort)
  1522. {
  1523. case RACK_PATCHBAY_PORT_AUDIO_IN1:
  1524. CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
  1525. CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999);
  1526. rack->connectLock.lock();
  1527. rack->connectedIns[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
  1528. rack->connectLock.unlock();
  1529. makeConnection = true;
  1530. break;
  1531. case RACK_PATCHBAY_PORT_AUDIO_IN2:
  1532. CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
  1533. CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999);
  1534. rack->connectLock.lock();
  1535. rack->connectedIns[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
  1536. rack->connectLock.unlock();
  1537. makeConnection = true;
  1538. break;
  1539. case RACK_PATCHBAY_PORT_AUDIO_OUT1:
  1540. CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
  1541. CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999);
  1542. rack->connectLock.lock();
  1543. rack->connectedOuts[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
  1544. rack->connectLock.unlock();
  1545. makeConnection = true;
  1546. break;
  1547. case RACK_PATCHBAY_PORT_AUDIO_OUT2:
  1548. CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
  1549. CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999);
  1550. rack->connectLock.lock();
  1551. rack->connectedOuts[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
  1552. rack->connectLock.unlock();
  1553. makeConnection = true;
  1554. break;
  1555. case RACK_PATCHBAY_PORT_MIDI_IN:
  1556. CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000);
  1557. CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_IN*1000+999);
  1558. makeConnection = connectRackMidiInPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_IN*1000);
  1559. break;
  1560. case RACK_PATCHBAY_PORT_MIDI_OUT:
  1561. CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000);
  1562. CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_OUT*1000+999);
  1563. makeConnection = connectRackMidiOutPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_OUT*1000);
  1564. break;
  1565. }
  1566. if (! makeConnection)
  1567. {
  1568. setLastError("Invalid connection (3)");
  1569. return false;
  1570. }
  1571. ConnectionToId connectionToId;
  1572. connectionToId.id = rack->lastConnectionId;
  1573. connectionToId.portOut = portA;
  1574. connectionToId.portIn = portB;
  1575. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, portA, portB, 0.0f, nullptr);
  1576. rack->usedConnections.append(connectionToId);
  1577. rack->lastConnectionId++;
  1578. return true;
  1579. }
  1580. bool CarlaEngine::patchbayDisconnect(const int connectionId)
  1581. {
  1582. CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false);
  1583. CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false);
  1584. carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId);
  1585. if (pData->bufAudio.usePatchbay)
  1586. {
  1587. // not implemented yet
  1588. return false;
  1589. }
  1590. EngineRackBuffers* const rack(pData->bufAudio.rack);
  1591. CARLA_SAFE_ASSERT_RETURN_ERR(rack->usedConnections.count() > 0, "No connections available");
  1592. for (List<ConnectionToId>::Itenerator it=rack->usedConnections.begin(); it.valid(); it.next())
  1593. {
  1594. const ConnectionToId& connection(it.getConstValue());
  1595. if (connection.id == connectionId)
  1596. {
  1597. const int targetPort((connection.portOut >= 0) ? connection.portOut : connection.portIn);
  1598. const int carlaPort((targetPort == connection.portOut) ? connection.portIn : connection.portOut);
  1599. if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000)
  1600. {
  1601. const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000);
  1602. disconnectRackMidiInPort(portId);
  1603. }
  1604. else if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000)
  1605. {
  1606. const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000);
  1607. disconnectRackMidiOutPort(portId);
  1608. }
  1609. else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000)
  1610. {
  1611. CARLA_ASSERT(carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT2);
  1612. const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
  1613. rack->connectLock.lock();
  1614. if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1)
  1615. rack->connectedOuts[0].removeAll(portId);
  1616. else
  1617. rack->connectedOuts[1].removeAll(portId);
  1618. rack->connectLock.unlock();
  1619. }
  1620. else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000)
  1621. {
  1622. CARLA_ASSERT(carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN2);
  1623. const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
  1624. rack->connectLock.lock();
  1625. if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1)
  1626. rack->connectedIns[0].removeAll(portId);
  1627. else
  1628. rack->connectedIns[1].removeAll(portId);
  1629. rack->connectLock.unlock();
  1630. }
  1631. else
  1632. {
  1633. CARLA_ASSERT(false);
  1634. }
  1635. callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, connection.portOut, connection.portIn, 0.0f, nullptr);
  1636. rack->usedConnections.remove(it);
  1637. break;
  1638. }
  1639. }
  1640. return true;
  1641. }
  1642. bool CarlaEngine::patchbayRefresh()
  1643. {
  1644. setLastError("Unsupported operation");
  1645. return false;
  1646. }
  1647. #endif
  1648. // -----------------------------------------------------------------------
  1649. // Transport
  1650. void CarlaEngine::transportPlay()
  1651. {
  1652. pData->time.playing = true;
  1653. }
  1654. void CarlaEngine::transportPause()
  1655. {
  1656. pData->time.playing = false;
  1657. }
  1658. void CarlaEngine::transportRelocate(const uint64_t frame)
  1659. {
  1660. pData->time.frame = frame;
  1661. }
  1662. // -----------------------------------------------------------------------
  1663. // Error handling
  1664. const char* CarlaEngine::getLastError() const noexcept
  1665. {
  1666. return (const char*)pData->lastError;
  1667. }
  1668. void CarlaEngine::setLastError(const char* const error) const
  1669. {
  1670. pData->lastError = error;
  1671. }
  1672. void CarlaEngine::setAboutToClose()
  1673. {
  1674. carla_debug("CarlaEngine::setAboutToClose()");
  1675. pData->aboutToClose = true;
  1676. }
  1677. // -----------------------------------------------------------------------
  1678. // Global options
  1679. void CarlaEngine::setOption(const EngineOption option, const int value, const char* const valueStr)
  1680. {
  1681. carla_debug("CarlaEngine::setOption(%i:%s, %i, \"%s\")", option, EngineOption2Str(option), value, valueStr);
  1682. if (isRunning() && (option == ENGINE_OPTION_PROCESS_MODE || option == ENGINE_OPTION_AUDIO_NUM_PERIODS || option == ENGINE_OPTION_AUDIO_DEVICE))
  1683. return carla_stderr("CarlaEngine::setOption(%i:%s, %i, \"%s\") - Cannot set this option while engine is running!", option, EngineOption2Str(option), value, valueStr);
  1684. switch (option)
  1685. {
  1686. case ENGINE_OPTION_DEBUG:
  1687. break;
  1688. case ENGINE_OPTION_PROCESS_MODE:
  1689. CARLA_SAFE_ASSERT_RETURN(value >= ENGINE_PROCESS_MODE_SINGLE_CLIENT && value <= ENGINE_PROCESS_MODE_BRIDGE,);
  1690. pData->options.processMode = static_cast<EngineProcessMode>(value);
  1691. break;
  1692. case ENGINE_OPTION_TRANSPORT_MODE:
  1693. CARLA_SAFE_ASSERT_RETURN(value >= ENGINE_TRANSPORT_MODE_INTERNAL && value <= ENGINE_TRANSPORT_MODE_BRIDGE,);
  1694. pData->options.transportMode = static_cast<EngineTransportMode>(value);
  1695. break;
  1696. case ENGINE_OPTION_FORCE_STEREO:
  1697. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1698. pData->options.forceStereo = (value != 0);
  1699. break;
  1700. case ENGINE_OPTION_PREFER_PLUGIN_BRIDGES:
  1701. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1702. pData->options.preferPluginBridges = (value != 0);
  1703. break;
  1704. case ENGINE_OPTION_PREFER_UI_BRIDGES:
  1705. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1706. pData->options.preferUiBridges = (value != 0);
  1707. break;
  1708. case ENGINE_OPTION_UIS_ALWAYS_ON_TOP:
  1709. CARLA_SAFE_ASSERT_RETURN(value == 0 || value == 1,);
  1710. pData->options.uisAlwaysOnTop = (value != 0);
  1711. break;
  1712. case ENGINE_OPTION_MAX_PARAMETERS:
  1713. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  1714. pData->options.maxParameters = static_cast<uint>(value);
  1715. break;
  1716. case ENGINE_OPTION_UI_BRIDGES_TIMEOUT:
  1717. CARLA_SAFE_ASSERT_RETURN(value >= 0,);
  1718. pData->options.uiBridgesTimeout = static_cast<uint>(value);
  1719. break;
  1720. case ENGINE_OPTION_AUDIO_NUM_PERIODS:
  1721. CARLA_SAFE_ASSERT_RETURN(value >= 2 && value <= 3,);
  1722. pData->options.audioNumPeriods = static_cast<uint>(value);
  1723. break;
  1724. case ENGINE_OPTION_AUDIO_BUFFER_SIZE:
  1725. CARLA_SAFE_ASSERT_RETURN(value >= 8,);
  1726. pData->options.audioBufferSize = static_cast<uint>(value);
  1727. break;
  1728. case ENGINE_OPTION_AUDIO_SAMPLE_RATE:
  1729. CARLA_SAFE_ASSERT_RETURN(value >= 22050,);
  1730. pData->options.audioSampleRate = static_cast<uint>(value);
  1731. break;
  1732. case ENGINE_OPTION_AUDIO_DEVICE:
  1733. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  1734. if (pData->options.audioDevice != nullptr)
  1735. delete[] pData->options.audioDevice;
  1736. pData->options.audioDevice = carla_strdup(valueStr);
  1737. break;
  1738. case ENGINE_OPTION_PATH_BINARIES:
  1739. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  1740. if (pData->options.binaryDir != nullptr)
  1741. delete[] pData->options.binaryDir;
  1742. pData->options.binaryDir = carla_strdup(valueStr);
  1743. break;
  1744. case ENGINE_OPTION_PATH_RESOURCES:
  1745. CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr && valueStr[0] != '\0',);
  1746. if (pData->options.resourceDir != nullptr)
  1747. delete[] pData->options.resourceDir;
  1748. pData->options.resourceDir = carla_strdup(valueStr);
  1749. break;
  1750. }
  1751. }
  1752. // -----------------------------------------------------------------------
  1753. // OSC Stuff
  1754. #ifdef BUILD_BRIDGE
  1755. bool CarlaEngine::isOscBridgeRegistered() const noexcept
  1756. {
  1757. return (pData->oscData != nullptr);
  1758. }
  1759. #else
  1760. bool CarlaEngine::isOscControlRegistered() const noexcept
  1761. {
  1762. return pData->osc.isControlRegistered();
  1763. }
  1764. #endif
  1765. void CarlaEngine::idleOsc()
  1766. {
  1767. pData->osc.idle();
  1768. }
  1769. const char* CarlaEngine::getOscServerPathTCP() const noexcept
  1770. {
  1771. return pData->osc.getServerPathTCP();
  1772. }
  1773. const char* CarlaEngine::getOscServerPathUDP() const noexcept
  1774. {
  1775. return pData->osc.getServerPathUDP();
  1776. }
  1777. #ifdef BUILD_BRIDGE
  1778. void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData) const noexcept
  1779. {
  1780. pData->oscData = oscData;
  1781. }
  1782. #endif
  1783. // -----------------------------------------------------------------------
  1784. // Helper functions
  1785. EngineEvent* CarlaEngine::getInternalEventBuffer(const bool isInput) const noexcept
  1786. {
  1787. return isInput ? pData->bufEvents.in : pData->bufEvents.out;
  1788. }
  1789. void CarlaEngine::registerEnginePlugin(const unsigned int id, CarlaPlugin* const plugin)
  1790. {
  1791. CARLA_SAFE_ASSERT_RETURN(id == pData->curPluginCount,);
  1792. carla_debug("CarlaEngine::registerEnginePlugin(%i, %p)", id, plugin);
  1793. pData->plugins[id].plugin = plugin;
  1794. }
  1795. // -----------------------------------------------------------------------
  1796. // Internal stuff
  1797. void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize)
  1798. {
  1799. carla_debug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize);
  1800. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  1801. {
  1802. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1803. if (plugin != nullptr && plugin->isEnabled())
  1804. plugin->bufferSizeChanged(newBufferSize);
  1805. }
  1806. callback(ENGINE_CALLBACK_BUFFER_SIZE_CHANGED, 0, newBufferSize, 0, 0.0f, nullptr);
  1807. }
  1808. void CarlaEngine::sampleRateChanged(const double newSampleRate)
  1809. {
  1810. carla_debug("CarlaEngine::sampleRateChanged(%g)", newSampleRate);
  1811. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  1812. {
  1813. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1814. if (plugin != nullptr && plugin->isEnabled())
  1815. plugin->sampleRateChanged(newSampleRate);
  1816. }
  1817. callback(ENGINE_CALLBACK_SAMPLE_RATE_CHANGED, 0, 0, 0, static_cast<float>(newSampleRate), nullptr);
  1818. }
  1819. void CarlaEngine::offlineModeChanged(const bool isOffline)
  1820. {
  1821. carla_debug("CarlaEngine::offlineModeChanged(%s)", bool2str(isOffline));
  1822. for (unsigned int i=0; i < pData->curPluginCount; ++i)
  1823. {
  1824. CarlaPlugin* const plugin(pData->plugins[i].plugin);
  1825. if (plugin != nullptr && plugin->isEnabled())
  1826. plugin->offlineModeChanged(isOffline);
  1827. }
  1828. }
  1829. void CarlaEngine::runPendingRtEvents()
  1830. {
  1831. pData->doNextPluginAction(true);
  1832. if (pData->time.playing)
  1833. pData->time.frame += pData->bufferSize;
  1834. if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
  1835. {
  1836. pData->timeInfo.playing = pData->time.playing;
  1837. pData->timeInfo.frame = pData->time.frame;
  1838. }
  1839. }
  1840. void CarlaEngine::setPluginPeaks(const unsigned int pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept
  1841. {
  1842. EnginePluginData& pluginData(pData->plugins[pluginId]);
  1843. pluginData.insPeak[0] = inPeaks[0];
  1844. pluginData.insPeak[1] = inPeaks[1];
  1845. pluginData.outsPeak[0] = outPeaks[0];
  1846. pluginData.outsPeak[1] = outPeaks[1];
  1847. }
  1848. // -----------------------------------------------------------------------
  1849. // Bridge/Controller OSC stuff
  1850. #ifdef BUILD_BRIDGE
  1851. void CarlaEngine::oscSend_bridge_plugin_info1(const PluginCategory category, const uint hints, const long uniqueId) const
  1852. {
  1853. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1854. carla_debug("CarlaEngine::oscSend_bridge_plugin_info1(%i:%s, %X, %l)", category, PluginCategory2Str(category), hints, uniqueId);
  1855. if (pData->oscData->target != nullptr)
  1856. {
  1857. char targetPath[std::strlen(pData->oscData->path)+21];
  1858. std::strcpy(targetPath, pData->oscData->path);
  1859. std::strcat(targetPath, "/bridge_plugin_info1");
  1860. lo_send(pData->oscData->target, targetPath, "iih", static_cast<int32_t>(category), static_cast<int32_t>(hints), static_cast<int64_t>(uniqueId));
  1861. }
  1862. }
  1863. void CarlaEngine::oscSend_bridge_plugin_info2(const char* const realName, const char* const label, const char* const maker, const char* const copyright) const
  1864. {
  1865. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1866. CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',);
  1867. CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',);
  1868. CARLA_SAFE_ASSERT_RETURN(maker != nullptr,);
  1869. CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,);
  1870. carla_debug("CarlaEngine::oscSend_bridge_plugin_info2(\"%s\", \"%s\", \"%s\", \"%s\")", realName, label, maker, copyright);
  1871. if (pData->oscData->target != nullptr)
  1872. {
  1873. char targetPath[std::strlen(pData->oscData->path)+21];
  1874. std::strcpy(targetPath, pData->oscData->path);
  1875. std::strcat(targetPath, "/bridge_plugin_info2");
  1876. lo_send(pData->oscData->target, targetPath, "ssss", realName, label, maker, copyright);
  1877. }
  1878. }
  1879. void CarlaEngine::oscSend_bridge_audio_count(const uint32_t ins, const uint32_t outs) const
  1880. {
  1881. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1882. carla_debug("CarlaEngine::oscSend_bridge_audio_count(%i, %i)", ins, outs);
  1883. if (pData->oscData->target != nullptr)
  1884. {
  1885. char targetPath[std::strlen(pData->oscData->path)+20];
  1886. std::strcpy(targetPath, pData->oscData->path);
  1887. std::strcat(targetPath, "/bridge_audio_count");
  1888. lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(ins), static_cast<int32_t>(outs));
  1889. }
  1890. }
  1891. void CarlaEngine::oscSend_bridge_midi_count(const uint32_t ins, const uint32_t outs) const
  1892. {
  1893. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1894. carla_debug("CarlaEngine::oscSend_bridge_midi_count(%i, %i)", ins, outs);
  1895. if (pData->oscData->target != nullptr)
  1896. {
  1897. char targetPath[std::strlen(pData->oscData->path)+19];
  1898. std::strcpy(targetPath, pData->oscData->path);
  1899. std::strcat(targetPath, "/bridge_midi_count");
  1900. lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(ins), static_cast<int32_t>(outs));
  1901. }
  1902. }
  1903. void CarlaEngine::oscSend_bridge_parameter_count(const uint32_t ins, const uint32_t outs) const
  1904. {
  1905. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1906. carla_debug("CarlaEngine::oscSend_bridge_parameter_count(%i, %i)", ins, outs);
  1907. if (pData->oscData->target != nullptr)
  1908. {
  1909. char targetPath[std::strlen(pData->oscData->path)+24];
  1910. std::strcpy(targetPath, pData->oscData->path);
  1911. std::strcat(targetPath, "/bridge_parameter_count");
  1912. lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(ins), static_cast<int32_t>(outs));
  1913. }
  1914. }
  1915. void CarlaEngine::oscSend_bridge_program_count(const uint32_t count) const
  1916. {
  1917. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1918. carla_debug("CarlaEngine::oscSend_bridge_program_count(%i)", count);
  1919. if (pData->oscData->target != nullptr)
  1920. {
  1921. char targetPath[std::strlen(pData->oscData->path)+22];
  1922. std::strcpy(targetPath, pData->oscData->path);
  1923. std::strcat(targetPath, "/bridge_program_count");
  1924. lo_send(pData->oscData->target, targetPath, "i", static_cast<int32_t>(count));
  1925. }
  1926. }
  1927. void CarlaEngine::oscSend_bridge_midi_program_count(const uint32_t count) const
  1928. {
  1929. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1930. carla_debug("CarlaEngine::oscSend_bridge_midi_program_count(%i)", count);
  1931. if (pData->oscData->target != nullptr)
  1932. {
  1933. char targetPath[std::strlen(pData->oscData->path)+27];
  1934. std::strcpy(targetPath, pData->oscData->path);
  1935. std::strcat(targetPath, "/bridge_midi_program_count");
  1936. lo_send(pData->oscData->target, targetPath, "i", static_cast<int32_t>(count));
  1937. }
  1938. }
  1939. void CarlaEngine::oscSend_bridge_parameter_data(const uint32_t index, const int32_t rindex, const ParameterType type, const uint hints, const char* const name, const char* const unit) const
  1940. {
  1941. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1942. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
  1943. CARLA_SAFE_ASSERT_RETURN(unit != nullptr,);
  1944. carla_debug("CarlaEngine::oscSend_bridge_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", index, rindex, type, ParameterType2Str(type), hints, name, unit);
  1945. if (pData->oscData->target != nullptr)
  1946. {
  1947. char targetPath[std::strlen(pData->oscData->path)+23];
  1948. std::strcpy(targetPath, pData->oscData->path);
  1949. std::strcat(targetPath, "/bridge_parameter_data");
  1950. lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast<int32_t>(index), static_cast<int32_t>(rindex), static_cast<int32_t>(type), static_cast<int32_t>(hints), name, unit);
  1951. }
  1952. }
  1953. void CarlaEngine::oscSend_bridge_parameter_ranges1(const uint32_t index, const float def, const float min, const float max) const
  1954. {
  1955. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1956. carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, def, min, max);
  1957. if (pData->oscData->target != nullptr)
  1958. {
  1959. char targetPath[std::strlen(pData->oscData->path)+26];
  1960. std::strcpy(targetPath, pData->oscData->path);
  1961. std::strcat(targetPath, "/bridge_parameter_ranges1");
  1962. lo_send(pData->oscData->target, targetPath, "ifff", static_cast<int32_t>(index), def, min, max);
  1963. }
  1964. }
  1965. void CarlaEngine::oscSend_bridge_parameter_ranges2(const uint32_t index, const float step, const float stepSmall, const float stepLarge) const
  1966. {
  1967. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1968. carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, step, stepSmall, stepLarge);
  1969. if (pData->oscData->target != nullptr)
  1970. {
  1971. char targetPath[std::strlen(pData->oscData->path)+26];
  1972. std::strcpy(targetPath, pData->oscData->path);
  1973. std::strcat(targetPath, "/bridge_parameter_ranges2");
  1974. lo_send(pData->oscData->target, targetPath, "ifff", static_cast<int32_t>(index), step, stepSmall, stepLarge);
  1975. }
  1976. }
  1977. void CarlaEngine::oscSend_bridge_parameter_midi_cc(const uint32_t index, const int16_t cc) const
  1978. {
  1979. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1980. carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_cc(%i, %i)", index, cc);
  1981. if (pData->oscData->target != nullptr)
  1982. {
  1983. char targetPath[std::strlen(pData->oscData->path)+26];
  1984. std::strcpy(targetPath, pData->oscData->path);
  1985. std::strcat(targetPath, "/bridge_parameter_midi_cc");
  1986. lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(index), static_cast<int32_t>(cc));
  1987. }
  1988. }
  1989. void CarlaEngine::oscSend_bridge_parameter_midi_channel(const uint32_t index, const uint8_t channel) const
  1990. {
  1991. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  1992. carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_channel(%i, %i)", index, channel);
  1993. if (pData->oscData->target != nullptr)
  1994. {
  1995. char targetPath[std::strlen(pData->oscData->path)+31];
  1996. std::strcpy(targetPath, pData->oscData->path);
  1997. std::strcat(targetPath, "/bridge_parameter_midi_channel");
  1998. lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(index), static_cast<int32_t>(channel));
  1999. }
  2000. }
  2001. void CarlaEngine::oscSend_bridge_parameter_value(const int32_t index, const float value) const
  2002. {
  2003. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2004. CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,);
  2005. carla_debug("CarlaEngine::oscSend_bridge_parameter_value(%i, %f)", index, value);
  2006. if (pData->oscData->target != nullptr)
  2007. {
  2008. char targetPath[std::strlen(pData->oscData->path)+24];
  2009. std::strcpy(targetPath, pData->oscData->path);
  2010. std::strcat(targetPath, "/bridge_parameter_value");
  2011. lo_send(pData->oscData->target, targetPath, "if", index, value);
  2012. }
  2013. }
  2014. void CarlaEngine::oscSend_bridge_default_value(const uint32_t index, const float value) const
  2015. {
  2016. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2017. carla_debug("CarlaEngine::oscSend_bridge_default_value(%i, %f)", index, value);
  2018. if (pData->oscData->target != nullptr)
  2019. {
  2020. char targetPath[std::strlen(pData->oscData->path)+22];
  2021. std::strcpy(targetPath, pData->oscData->path);
  2022. std::strcat(targetPath, "/bridge_default_value");
  2023. lo_send(pData->oscData->target, targetPath, "if", static_cast<int32_t>(index), value);
  2024. }
  2025. }
  2026. void CarlaEngine::oscSend_bridge_current_program(const int32_t index) const
  2027. {
  2028. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2029. carla_debug("CarlaEngine::oscSend_bridge_current_program(%i)", index);
  2030. if (pData->oscData->target != nullptr)
  2031. {
  2032. char targetPath[std::strlen(pData->oscData->path)+20];
  2033. std::strcpy(targetPath, pData->oscData->path);
  2034. std::strcat(targetPath, "/bridge_current_program");
  2035. lo_send(pData->oscData->target, targetPath, "i", index);
  2036. }
  2037. }
  2038. void CarlaEngine::oscSend_bridge_current_midi_program(const int32_t index) const
  2039. {
  2040. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2041. carla_debug("CarlaEngine::oscSend_bridge_current_midi_program(%i)", index);
  2042. if (pData->oscData->target != nullptr)
  2043. {
  2044. char targetPath[std::strlen(pData->oscData->path)+25];
  2045. std::strcpy(targetPath, pData->oscData->path);
  2046. std::strcat(targetPath, "/bridge_current_midi_program");
  2047. lo_send(pData->oscData->target, targetPath, "i", index);
  2048. }
  2049. }
  2050. void CarlaEngine::oscSend_bridge_program_name(const uint32_t index, const char* const name) const
  2051. {
  2052. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2053. carla_debug("CarlaEngine::oscSend_bridge_program_name(%i, \"%s\")", index, name);
  2054. if (pData->oscData->target != nullptr)
  2055. {
  2056. char targetPath[std::strlen(pData->oscData->path)+21];
  2057. std::strcpy(targetPath, pData->oscData->path);
  2058. std::strcat(targetPath, "/bridge_program_name");
  2059. lo_send(pData->oscData->target, targetPath, "is", static_cast<int32_t>(index), name);
  2060. }
  2061. }
  2062. void CarlaEngine::oscSend_bridge_midi_program_data(const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const
  2063. {
  2064. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2065. CARLA_SAFE_ASSERT_RETURN(name != nullptr,);
  2066. carla_debug("CarlaEngine::oscSend_bridge_midi_program_data(%i, %i, %i, \"%s\")", index, bank, program, name);
  2067. if (pData->oscData->target != nullptr)
  2068. {
  2069. char targetPath[std::strlen(pData->oscData->path)+26];
  2070. std::strcpy(targetPath, pData->oscData->path);
  2071. std::strcat(targetPath, "/bridge_midi_program_data");
  2072. lo_send(pData->oscData->target, targetPath, "iiis", static_cast<int32_t>(index), static_cast<int32_t>(bank), static_cast<int32_t>(program), name);
  2073. }
  2074. }
  2075. void CarlaEngine::oscSend_bridge_configure(const char* const key, const char* const value) const
  2076. {
  2077. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2078. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  2079. CARLA_SAFE_ASSERT_RETURN(value != nullptr,);
  2080. carla_debug("CarlaEngine::oscSend_bridge_configure(\"%s\", \"%s\")", key, value);
  2081. if (pData->oscData->target != nullptr)
  2082. {
  2083. char targetPath[std::strlen(pData->oscData->path)+18];
  2084. std::strcpy(targetPath, pData->oscData->path);
  2085. std::strcat(targetPath, "/bridge_configure");
  2086. lo_send(pData->oscData->target, targetPath, "ss", key, value);
  2087. }
  2088. }
  2089. void CarlaEngine::oscSend_bridge_set_custom_data(const char* const type, const char* const key, const char* const value) const
  2090. {
  2091. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2092. carla_debug("CarlaEngine::oscSend_bridge_set_custom_data(\"%s\", \"%s\", \"%s\")", type, key, value);
  2093. if (pData->oscData->target != nullptr)
  2094. {
  2095. char targetPath[std::strlen(pData->oscData->path)+24];
  2096. std::strcpy(targetPath, pData->oscData->path);
  2097. std::strcat(targetPath, "/bridge_set_custom_data");
  2098. lo_send(pData->oscData->target, targetPath, "sss", type, key, value);
  2099. }
  2100. }
  2101. void CarlaEngine::oscSend_bridge_set_chunk_data(const char* const chunkFile) const
  2102. {
  2103. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2104. carla_debug("CarlaEngine::oscSend_bridge_set_chunk_data(\"%s\")", chunkFile);
  2105. if (pData->oscData->target != nullptr)
  2106. {
  2107. char targetPath[std::strlen(pData->oscData->path)+23];
  2108. std::strcpy(targetPath, pData->oscData->path);
  2109. std::strcat(targetPath, "/bridge_set_chunk_data");
  2110. lo_send(pData->oscData->target, targetPath, "s", chunkFile);
  2111. }
  2112. }
  2113. // TODO?
  2114. //void oscSend_bridge_set_peaks() const;
  2115. #else
  2116. void CarlaEngine::oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const
  2117. {
  2118. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2119. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2120. CARLA_SAFE_ASSERT_RETURN(pluginName != nullptr && pluginName[0] != '\0',);
  2121. carla_debug("CarlaEngine::oscSend_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName);
  2122. if (pData->oscData->target != nullptr)
  2123. {
  2124. char targetPath[std::strlen(pData->oscData->path)+18];
  2125. std::strcpy(targetPath, pData->oscData->path);
  2126. std::strcat(targetPath, "/add_plugin_start");
  2127. lo_send(pData->oscData->target, targetPath, "is", static_cast<int32_t>(pluginId), pluginName);
  2128. }
  2129. }
  2130. void CarlaEngine::oscSend_control_add_plugin_end(const uint pluginId) const
  2131. {
  2132. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2133. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2134. carla_debug("CarlaEngine::oscSend_control_add_plugin_end(%i)", pluginId);
  2135. if (pData->oscData->target != nullptr)
  2136. {
  2137. char targetPath[std::strlen(pData->oscData->path)+16];
  2138. std::strcpy(targetPath, pData->oscData->path);
  2139. std::strcat(targetPath, "/add_plugin_end");
  2140. lo_send(pData->oscData->target, targetPath, "i", static_cast<int32_t>(pluginId));
  2141. }
  2142. }
  2143. void CarlaEngine::oscSend_control_remove_plugin(const uint pluginId) const
  2144. {
  2145. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2146. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2147. carla_debug("CarlaEngine::oscSend_control_remove_plugin(%i)", pluginId);
  2148. if (pData->oscData->target != nullptr)
  2149. {
  2150. char targetPath[std::strlen(pData->oscData->path)+15];
  2151. std::strcpy(targetPath, pData->oscData->path);
  2152. std::strcat(targetPath, "/remove_plugin");
  2153. lo_send(pData->oscData->target, targetPath, "i", static_cast<int32_t>(pluginId));
  2154. }
  2155. }
  2156. void CarlaEngine::oscSend_control_set_plugin_info1(const uint pluginId, const PluginType type, const PluginCategory category, const uint hints, const long uniqueId) const
  2157. {
  2158. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2159. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2160. CARLA_SAFE_ASSERT_RETURN(type != PLUGIN_NONE,);
  2161. carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, %i:%s, %i:%s, %X, %l)", pluginId, type, PluginType2Str(type), category, PluginCategory2Str(category), hints, uniqueId);
  2162. if (pData->oscData->target != nullptr)
  2163. {
  2164. char targetPath[std::strlen(pData->oscData->path)+18];
  2165. std::strcpy(targetPath, pData->oscData->path);
  2166. std::strcat(targetPath, "/set_plugin_info1");
  2167. lo_send(pData->oscData->target, targetPath, "iiiih", static_cast<int32_t>(pluginId), static_cast<int32_t>(type), static_cast<int32_t>(category), static_cast<int32_t>(hints), static_cast<int64_t>(uniqueId));
  2168. }
  2169. }
  2170. void CarlaEngine::oscSend_control_set_plugin_info2(const uint pluginId, const char* const realName, const char* const label, const char* const maker, const char* const copyright) const
  2171. {
  2172. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2173. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2174. CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',);
  2175. CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',);
  2176. CARLA_SAFE_ASSERT_RETURN(maker != nullptr,);
  2177. CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,);
  2178. carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, \"%s\", \"%s\", \"%s\", \"%s\")", pluginId, realName, label, maker, copyright);
  2179. if (pData->oscData->target != nullptr)
  2180. {
  2181. char targetPath[std::strlen(pData->oscData->path)+18];
  2182. std::strcpy(targetPath, pData->oscData->path);
  2183. std::strcat(targetPath, "/set_plugin_info2");
  2184. lo_send(pData->oscData->target, targetPath, "issss", static_cast<int32_t>(pluginId), realName, label, maker, copyright);
  2185. }
  2186. }
  2187. void CarlaEngine::oscSend_control_set_audio_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const
  2188. {
  2189. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2190. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2191. carla_debug("CarlaEngine::oscSend_control_set_audio_count(%i, %i, %i)", pluginId, ins, outs);
  2192. if (pData->oscData->target != nullptr)
  2193. {
  2194. char targetPath[std::strlen(pData->oscData->path)+18];
  2195. std::strcpy(targetPath, pData->oscData->path);
  2196. std::strcat(targetPath, "/set_audio_count");
  2197. lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(outs));
  2198. }
  2199. }
  2200. void CarlaEngine::oscSend_control_set_midi_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const
  2201. {
  2202. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2203. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2204. carla_debug("CarlaEngine::oscSend_control_set_midi_count(%i, %i, %i)", pluginId, ins, outs);
  2205. if (pData->oscData->target != nullptr)
  2206. {
  2207. char targetPath[std::strlen(pData->oscData->path)+18];
  2208. std::strcpy(targetPath, pData->oscData->path);
  2209. std::strcat(targetPath, "/set_midi_count");
  2210. lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(outs));
  2211. }
  2212. }
  2213. void CarlaEngine::oscSend_control_set_parameter_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const
  2214. {
  2215. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2216. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2217. carla_debug("CarlaEngine::oscSend_control_set_parameter_count(%i, %i, %i)", pluginId, ins, outs);
  2218. if (pData->oscData->target != nullptr)
  2219. {
  2220. char targetPath[std::strlen(pData->oscData->path)+18];
  2221. std::strcpy(targetPath, pData->oscData->path);
  2222. std::strcat(targetPath, "/set_parameter_count");
  2223. lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(outs));
  2224. }
  2225. }
  2226. void CarlaEngine::oscSend_control_set_program_count(const uint pluginId, const uint32_t count) const
  2227. {
  2228. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2229. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2230. carla_debug("CarlaEngine::oscSend_control_set_program_count(%i, %i)", pluginId, count);
  2231. if (pData->oscData->target != nullptr)
  2232. {
  2233. char targetPath[std::strlen(pData->oscData->path)+19];
  2234. std::strcpy(targetPath, pData->oscData->path);
  2235. std::strcat(targetPath, "/set_program_count");
  2236. lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(pluginId), static_cast<int32_t>(count));
  2237. }
  2238. }
  2239. void CarlaEngine::oscSend_control_set_midi_program_count(const uint pluginId, const uint32_t count) const
  2240. {
  2241. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2242. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2243. carla_debug("CarlaEngine::oscSend_control_set_midi_program_count(%i, %i)", pluginId, count);
  2244. if (pData->oscData->target != nullptr)
  2245. {
  2246. char targetPath[std::strlen(pData->oscData->path)+24];
  2247. std::strcpy(targetPath, pData->oscData->path);
  2248. std::strcat(targetPath, "/set_midi_program_count");
  2249. lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(pluginId), static_cast<int32_t>(count));
  2250. }
  2251. }
  2252. void CarlaEngine::oscSend_control_set_parameter_data(const uint pluginId, const uint32_t index, const ParameterType type, const uint hints, const char* const name, const char* const unit) const
  2253. {
  2254. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2255. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2256. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',);
  2257. CARLA_SAFE_ASSERT_RETURN(unit != nullptr,);
  2258. carla_debug("CarlaEngine::oscSend_control_set_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", pluginId, index, type, ParameterType2Str(type), hints, name, unit);
  2259. if (pData->oscData->target != nullptr)
  2260. {
  2261. char targetPath[std::strlen(pData->oscData->path)+20];
  2262. std::strcpy(targetPath, pData->oscData->path);
  2263. std::strcat(targetPath, "/set_parameter_data");
  2264. lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(type), static_cast<int32_t>(hints), name, unit);
  2265. }
  2266. }
  2267. void CarlaEngine::oscSend_control_set_parameter_ranges1(const uint pluginId, const uint32_t index, const float def, const float min, const float max) const
  2268. {
  2269. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2270. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2271. CARLA_SAFE_ASSERT_RETURN(def <= min && def >= max,);
  2272. CARLA_SAFE_ASSERT_RETURN(min < max,);
  2273. carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges1(%i, %i, %f, %f, %f)", pluginId, index, def, min, max, def);
  2274. if (pData->oscData->target != nullptr)
  2275. {
  2276. char targetPath[std::strlen(pData->oscData->path)+23];
  2277. std::strcpy(targetPath, pData->oscData->path);
  2278. std::strcat(targetPath, "/set_parameter_ranges1");
  2279. lo_send(pData->oscData->target, targetPath, "iifff", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), def, min, max);
  2280. }
  2281. }
  2282. void CarlaEngine::oscSend_control_set_parameter_ranges2(const uint pluginId, const uint32_t index, const float step, const float stepSmall, const float stepLarge) const
  2283. {
  2284. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2285. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2286. CARLA_SAFE_ASSERT_RETURN(step <= stepSmall && step >= stepLarge,);
  2287. CARLA_SAFE_ASSERT_RETURN(stepSmall <= stepLarge,);
  2288. carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges2(%i, %i, %f, %f, %f)", pluginId, index, step, stepSmall, stepLarge);
  2289. if (pData->oscData->target != nullptr)
  2290. {
  2291. char targetPath[std::strlen(pData->oscData->path)+23];
  2292. std::strcpy(targetPath, pData->oscData->path);
  2293. std::strcat(targetPath, "/set_parameter_ranges");
  2294. lo_send(pData->oscData->target, targetPath, "iifff", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), step, stepSmall, stepLarge);
  2295. }
  2296. }
  2297. void CarlaEngine::oscSend_control_set_parameter_midi_cc(const uint pluginId, const uint32_t index, const int16_t cc) const
  2298. {
  2299. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2300. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2301. CARLA_SAFE_ASSERT_RETURN(cc <= 0x5F,);
  2302. carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc);
  2303. if (pData->oscData->target != nullptr)
  2304. {
  2305. char targetPath[std::strlen(pData->oscData->path)+23];
  2306. std::strcpy(targetPath, pData->oscData->path);
  2307. std::strcat(targetPath, "/set_parameter_midi_cc");
  2308. lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(cc));
  2309. }
  2310. }
  2311. void CarlaEngine::oscSend_control_set_parameter_midi_channel(const uint pluginId, const uint32_t index, const uint8_t channel) const
  2312. {
  2313. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2314. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2315. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  2316. carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel);
  2317. if (pData->oscData->target != nullptr)
  2318. {
  2319. char targetPath[std::strlen(pData->oscData->path)+28];
  2320. std::strcpy(targetPath, pData->oscData->path);
  2321. std::strcat(targetPath, "/set_parameter_midi_channel");
  2322. lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(channel));
  2323. }
  2324. }
  2325. void CarlaEngine::oscSend_control_set_parameter_value(const uint pluginId, const int32_t index, const float value) const
  2326. {
  2327. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2328. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2329. CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,);
  2330. carla_debug("CarlaEngine::oscSend_control_set_parameter_value(%i, %i:%s, %f)", pluginId, index, (index < 0) ? InternalParameterIndex2Str(static_cast<InternalParameterIndex>(index)) : "(none)", value);
  2331. if (pData->oscData->target != nullptr)
  2332. {
  2333. char targetPath[std::strlen(pData->oscData->path)+21];
  2334. std::strcpy(targetPath, pData->oscData->path);
  2335. std::strcat(targetPath, "/set_parameter_value");
  2336. lo_send(pData->oscData->target, targetPath, "iif", static_cast<int32_t>(pluginId), index, value);
  2337. }
  2338. }
  2339. void CarlaEngine::oscSend_control_set_default_value(const uint pluginId, const uint32_t index, const float value) const
  2340. {
  2341. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2342. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2343. carla_debug("CarlaEngine::oscSend_control_set_default_value(%i, %i, %f)", pluginId, index, value);
  2344. if (pData->oscData->target != nullptr)
  2345. {
  2346. char targetPath[std::strlen(pData->oscData->path)+19];
  2347. std::strcpy(targetPath, pData->oscData->path);
  2348. std::strcat(targetPath, "/set_default_value");
  2349. lo_send(pData->oscData->target, targetPath, "iif", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), value);
  2350. }
  2351. }
  2352. void CarlaEngine::oscSend_control_set_current_program(const uint pluginId, const int32_t index) const
  2353. {
  2354. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2355. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2356. carla_debug("CarlaEngine::oscSend_control_set_current_program(%i, %i)", pluginId, index);
  2357. if (pData->oscData->target != nullptr)
  2358. {
  2359. char targetPath[std::strlen(pData->oscData->path)+21];
  2360. std::strcpy(targetPath, pData->oscData->path);
  2361. std::strcat(targetPath, "/set_current_program");
  2362. lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(pluginId), index);
  2363. }
  2364. }
  2365. void CarlaEngine::oscSend_control_set_current_midi_program(const uint pluginId, const int32_t index) const
  2366. {
  2367. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2368. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2369. carla_debug("CarlaEngine::oscSend_control_set_current_midi_program(%i, %i)", pluginId, index);
  2370. if (pData->oscData->target != nullptr)
  2371. {
  2372. char targetPath[std::strlen(pData->oscData->path)+26];
  2373. std::strcpy(targetPath, pData->oscData->path);
  2374. std::strcat(targetPath, "/set_current_midi_program");
  2375. lo_send(pData->oscData->target, targetPath, "ii", static_cast<int32_t>(pluginId), index);
  2376. }
  2377. }
  2378. void CarlaEngine::oscSend_control_set_program_name(const uint pluginId, const uint32_t index, const char* const name) const
  2379. {
  2380. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2381. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2382. CARLA_SAFE_ASSERT_RETURN(name != nullptr,);
  2383. carla_debug("CarlaEngine::oscSend_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name);
  2384. if (pData->oscData->target != nullptr)
  2385. {
  2386. char targetPath[std::strlen(pData->oscData->path)+18];
  2387. std::strcpy(targetPath, pData->oscData->path);
  2388. std::strcat(targetPath, "/set_program_name");
  2389. lo_send(pData->oscData->target, targetPath, "iis", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), name);
  2390. }
  2391. }
  2392. void CarlaEngine::oscSend_control_set_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const
  2393. {
  2394. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2395. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2396. CARLA_SAFE_ASSERT_RETURN(name != nullptr,);
  2397. carla_debug("CarlaEngine::oscSend_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name);
  2398. if (pData->oscData->target != nullptr)
  2399. {
  2400. char targetPath[std::strlen(pData->oscData->path)+23];
  2401. std::strcpy(targetPath, pData->oscData->path);
  2402. std::strcat(targetPath, "/set_midi_program_data");
  2403. lo_send(pData->oscData->target, targetPath, "iiiis", static_cast<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(bank), static_cast<int32_t>(program), name);
  2404. }
  2405. }
  2406. void CarlaEngine::oscSend_control_note_on(const uint pluginId, const uint8_t channel, const uint8_t note, const uint8_t velo) const
  2407. {
  2408. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2409. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2410. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  2411. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  2412. CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,);
  2413. carla_debug("CarlaEngine::oscSend_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo);
  2414. if (pData->oscData->target != nullptr)
  2415. {
  2416. char targetPath[std::strlen(pData->oscData->path)+9];
  2417. std::strcpy(targetPath, pData->oscData->path);
  2418. std::strcat(targetPath, "/note_on");
  2419. lo_send(pData->oscData->target, targetPath, "iiii", static_cast<int32_t>(pluginId), static_cast<int32_t>(channel), static_cast<int32_t>(note), static_cast<int32_t>(velo));
  2420. }
  2421. }
  2422. void CarlaEngine::oscSend_control_note_off(const uint pluginId, const uint8_t channel, const uint8_t note) const
  2423. {
  2424. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2425. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2426. CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,);
  2427. CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
  2428. carla_debug("CarlaEngine::oscSend_control_note_off(%i, %i, %i)", pluginId, channel, note);
  2429. if (pData->oscData->target != nullptr)
  2430. {
  2431. char targetPath[std::strlen(pData->oscData->path)+10];
  2432. std::strcpy(targetPath, pData->oscData->path);
  2433. std::strcat(targetPath, "/note_off");
  2434. lo_send(pData->oscData->target, targetPath, "iii", static_cast<int32_t>(pluginId), static_cast<int32_t>(channel), static_cast<int32_t>(note));
  2435. }
  2436. }
  2437. void CarlaEngine::oscSend_control_set_peaks(const uint pluginId) const
  2438. {
  2439. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2440. CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,);
  2441. // TODO - try and see if we can get peaks[4] ref
  2442. const EnginePluginData& epData(pData->plugins[pluginId]);
  2443. if (pData->oscData->target != nullptr)
  2444. {
  2445. char targetPath[std::strlen(pData->oscData->path)+11];
  2446. std::strcpy(targetPath, pData->oscData->path);
  2447. std::strcat(targetPath, "/set_peaks");
  2448. lo_send(pData->oscData->target, targetPath, "iffff", static_cast<int32_t>(pluginId), epData.insPeak[0], epData.insPeak[1], epData.outsPeak[0], epData.outsPeak[1]);
  2449. }
  2450. }
  2451. void CarlaEngine::oscSend_control_exit() const
  2452. {
  2453. CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,);
  2454. carla_debug("CarlaEngine::oscSend_control_exit()");
  2455. if (pData->oscData->target != nullptr)
  2456. {
  2457. char targetPath[std::strlen(pData->oscData->path)+6];
  2458. std::strcpy(targetPath, pData->oscData->path);
  2459. std::strcat(targetPath, "/exit");
  2460. lo_send(pData->oscData->target, targetPath, "");
  2461. }
  2462. }
  2463. #endif
  2464. // -----------------------------------------------------------------------
  2465. #undef CARLA_SAFE_ASSERT_RETURN_ERR
  2466. CARLA_BACKEND_END_NAMESPACE