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.

NativePlugin.cpp 74KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297
  1. /*
  2. * Carla Native Plugin
  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 GPL.txt file
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #ifdef WANT_NATIVE
  19. #include "CarlaNative.h"
  20. #include <QtCore/Qt>
  21. # if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
  22. # include <QtWidgets/QFileDialog>
  23. #else
  24. # include <QtGui/QFileDialog>
  25. #endif
  26. void carla_register_all_plugins()
  27. {
  28. // Simple plugins
  29. carla_register_native_plugin_bypass();
  30. carla_register_native_plugin_lfo();
  31. //carla_register_native_plugin_midiSequencer(); // unfinished
  32. carla_register_native_plugin_midiSplit();
  33. carla_register_native_plugin_midiThrough();
  34. carla_register_native_plugin_midiTranspose();
  35. carla_register_native_plugin_nekofilter();
  36. //carla_register_native_plugin_sunvoxfile(); // unfinished
  37. // Carla
  38. //carla_register_native_plugin_carla(); // unfinished
  39. #ifdef WANT_AUDIOFILE
  40. // AudioFile
  41. carla_register_native_plugin_audiofile();
  42. #endif
  43. #ifdef WANT_MIDIFILE
  44. // MidiFile
  45. carla_register_native_plugin_midifile();
  46. #endif
  47. #ifdef WANT_OPENGL
  48. // DISTRHO plugins (OpenGL)
  49. carla_register_native_plugin_3BandEQ();
  50. carla_register_native_plugin_3BandSplitter();
  51. carla_register_native_plugin_PingPongPan();
  52. #endif
  53. // DISTRHO plugins (Qt)
  54. carla_register_native_plugin_Notes();
  55. #ifdef WANT_ZYNADDSUBFX
  56. // ZynAddSubFX
  57. carla_register_native_plugin_zynaddsubfx();
  58. #endif
  59. }
  60. CARLA_BACKEND_START_NAMESPACE
  61. #if 0
  62. }
  63. #endif
  64. struct NativePluginMidiData {
  65. uint32_t count;
  66. uint32_t* indexes;
  67. CarlaEngineEventPort** ports;
  68. NativePluginMidiData()
  69. : count(0),
  70. indexes(nullptr),
  71. ports(nullptr) {}
  72. ~NativePluginMidiData()
  73. {
  74. CARLA_ASSERT_INT(count == 0, count);
  75. CARLA_ASSERT(ports == nullptr);
  76. CARLA_ASSERT(indexes == nullptr);
  77. }
  78. void createNew(const uint32_t newCount)
  79. {
  80. CARLA_ASSERT_INT(count == 0, count);
  81. CARLA_ASSERT(ports == nullptr);
  82. CARLA_ASSERT(indexes == nullptr);
  83. CARLA_ASSERT_INT(newCount > 0, newCount);
  84. if (ports != nullptr || indexes != nullptr || newCount == 0)
  85. return;
  86. ports = new CarlaEngineEventPort*[newCount];
  87. indexes = new uint32_t[newCount];
  88. count = newCount;
  89. for (uint32_t i=0; i < newCount; ++i)
  90. ports[i] = nullptr;
  91. for (uint32_t i=0; i < newCount; ++i)
  92. indexes[i] = 0;
  93. }
  94. void clear()
  95. {
  96. if (ports != nullptr)
  97. {
  98. for (uint32_t i=0; i < count; ++i)
  99. {
  100. if (ports[i] != nullptr)
  101. {
  102. delete ports[i];
  103. ports[i] = nullptr;
  104. }
  105. }
  106. delete[] ports;
  107. ports = nullptr;
  108. }
  109. if (indexes != nullptr)
  110. {
  111. delete[] indexes;
  112. indexes = nullptr;
  113. }
  114. count = 0;
  115. }
  116. void initBuffers(CarlaEngine* const engine)
  117. {
  118. for (uint32_t i=0; i < count; ++i)
  119. {
  120. if (ports[i] != nullptr)
  121. ports[i]->initBuffer(engine);
  122. }
  123. }
  124. CARLA_DECLARE_NON_COPY_STRUCT_WITH_LEAK_DETECTOR(NativePluginMidiData)
  125. };
  126. class NativePlugin : public CarlaPlugin
  127. {
  128. public:
  129. NativePlugin(CarlaEngine* const engine, const unsigned int id)
  130. : CarlaPlugin(engine, id),
  131. fHandle(nullptr),
  132. fHandle2(nullptr),
  133. fDescriptor(nullptr),
  134. fIsProcessing(false),
  135. fIsUiVisible(false),
  136. fAudioInBuffers(nullptr),
  137. fAudioOutBuffers(nullptr),
  138. fMidiEventCount(0)
  139. {
  140. carla_debug("NativePlugin::NativePlugin(%p, %i)", engine, id);
  141. carla_zeroStruct< ::MidiEvent>(fMidiEvents, MAX_MIDI_EVENTS*2);
  142. fHost.handle = this;
  143. fHost.ui_name = nullptr;
  144. fHost.get_buffer_size = carla_host_get_buffer_size;
  145. fHost.get_sample_rate = carla_host_get_sample_rate;
  146. fHost.get_time_info = carla_host_get_time_info;
  147. fHost.write_midi_event = carla_host_write_midi_event;
  148. fHost.ui_parameter_changed = carla_host_ui_parameter_changed;
  149. fHost.ui_custom_data_changed = carla_host_ui_custom_data_changed;
  150. fHost.ui_closed = carla_host_ui_closed;
  151. fHost.ui_open_file = carla_host_ui_open_file;
  152. fHost.ui_save_file = carla_host_ui_save_file;
  153. }
  154. ~NativePlugin() override
  155. {
  156. carla_debug("NativePlugin::~NativePlugin()");
  157. // close UI
  158. if (fHints & PLUGIN_HAS_GUI)
  159. {
  160. if (fIsUiVisible && fDescriptor != nullptr && fDescriptor->ui_show != nullptr && fHandle != nullptr)
  161. fDescriptor->ui_show(fHandle, false);
  162. }
  163. kData->singleMutex.lock();
  164. kData->masterMutex.lock();
  165. CARLA_ASSERT(! fIsProcessing);
  166. if (kData->active)
  167. {
  168. deactivate();
  169. kData->active = false;
  170. }
  171. if (fDescriptor != nullptr)
  172. {
  173. if (fDescriptor->cleanup != nullptr)
  174. {
  175. if (fHandle != nullptr)
  176. fDescriptor->cleanup(fHandle);
  177. if (fHandle2 != nullptr)
  178. fDescriptor->cleanup(fHandle2);
  179. }
  180. fHandle = nullptr;
  181. fHandle2 = nullptr;
  182. fDescriptor = nullptr;
  183. }
  184. if (fHost.ui_name != nullptr)
  185. {
  186. delete[] fHost.ui_name;
  187. fHost.ui_name = nullptr;
  188. }
  189. clearBuffers();
  190. }
  191. // -------------------------------------------------------------------
  192. // Information (base)
  193. PluginType type() const override
  194. {
  195. return PLUGIN_INTERNAL;
  196. }
  197. PluginCategory category() override
  198. {
  199. CARLA_ASSERT(fDescriptor != nullptr);
  200. return static_cast<PluginCategory>(fDescriptor->category);
  201. }
  202. // -------------------------------------------------------------------
  203. // Information (count)
  204. uint32_t midiInCount() const override
  205. {
  206. return fMidiIn.count;
  207. }
  208. uint32_t midiOutCount() const override
  209. {
  210. return fMidiOut.count;
  211. }
  212. uint32_t parameterScalePointCount(const uint32_t parameterId) const override
  213. {
  214. CARLA_ASSERT(fDescriptor != nullptr);
  215. CARLA_ASSERT(fHandle != nullptr);
  216. CARLA_ASSERT(parameterId < kData->param.count);
  217. if (fDescriptor->get_parameter_info != nullptr && parameterId < kData->param.count)
  218. {
  219. if (const Parameter* const param = fDescriptor->get_parameter_info(fHandle, parameterId))
  220. return param->scalePointCount;
  221. }
  222. return 0;
  223. }
  224. // -------------------------------------------------------------------
  225. // Information (current data)
  226. // nothing
  227. // -------------------------------------------------------------------
  228. // Information (per-plugin data)
  229. unsigned int availableOptions() override
  230. {
  231. CARLA_ASSERT(fDescriptor != nullptr);
  232. if (fDescriptor == nullptr)
  233. return 0x0;
  234. unsigned int options = 0x0;
  235. options |= PLUGIN_OPTION_FIXED_BUFFER;
  236. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  237. if (kData->engine->getProccessMode() != PROCESS_MODE_CONTINUOUS_RACK)
  238. {
  239. if (fOptions & PLUGIN_OPTION_FORCE_STEREO)
  240. options |= PLUGIN_OPTION_FORCE_STEREO;
  241. else if (kData->audioIn.count <= 1 && kData->audioOut.count <= 1 && (kData->audioIn.count != 0 || kData->audioOut.count != 0))
  242. options |= PLUGIN_OPTION_FORCE_STEREO;
  243. }
  244. if (fDescriptor->midiIns > 0)
  245. {
  246. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  247. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  248. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  249. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  250. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  251. }
  252. return options;
  253. }
  254. float getParameterValue(const uint32_t parameterId) override
  255. {
  256. CARLA_ASSERT(fDescriptor != nullptr);
  257. CARLA_ASSERT(fHandle != nullptr);
  258. CARLA_ASSERT(parameterId < kData->param.count);
  259. if (fDescriptor->get_parameter_value != nullptr && parameterId < kData->param.count)
  260. return fDescriptor->get_parameter_value(fHandle, parameterId);
  261. return 0.0f;
  262. }
  263. float getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId) override
  264. {
  265. CARLA_ASSERT(fDescriptor != nullptr);
  266. CARLA_ASSERT(fHandle != nullptr);
  267. CARLA_ASSERT(parameterId < kData->param.count);
  268. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  269. if (fDescriptor->get_parameter_info != nullptr && parameterId < kData->param.count)
  270. {
  271. if (const Parameter* const param = fDescriptor->get_parameter_info(fHandle, parameterId))
  272. {
  273. const ParameterScalePoint& scalePoint(param->scalePoints[scalePointId]);
  274. return scalePoint.value;
  275. }
  276. }
  277. return 0.0f;
  278. }
  279. void getLabel(char* const strBuf) override
  280. {
  281. CARLA_ASSERT(fDescriptor != nullptr);
  282. if (fDescriptor->label != nullptr)
  283. std::strncpy(strBuf, fDescriptor->label, STR_MAX);
  284. else
  285. CarlaPlugin::getLabel(strBuf);
  286. }
  287. void getMaker(char* const strBuf) override
  288. {
  289. CARLA_ASSERT(fDescriptor != nullptr);
  290. if (fDescriptor->maker != nullptr)
  291. std::strncpy(strBuf, fDescriptor->maker, STR_MAX);
  292. else
  293. CarlaPlugin::getMaker(strBuf);
  294. }
  295. void getCopyright(char* const strBuf) override
  296. {
  297. CARLA_ASSERT(fDescriptor != nullptr);
  298. if (fDescriptor->copyright != nullptr)
  299. std::strncpy(strBuf, fDescriptor->copyright, STR_MAX);
  300. else
  301. CarlaPlugin::getCopyright(strBuf);
  302. }
  303. void getRealName(char* const strBuf) override
  304. {
  305. CARLA_ASSERT(fDescriptor != nullptr);
  306. if (fDescriptor->name != nullptr)
  307. std::strncpy(strBuf, fDescriptor->name, STR_MAX);
  308. else
  309. CarlaPlugin::getRealName(strBuf);
  310. }
  311. void getParameterName(const uint32_t parameterId, char* const strBuf) override
  312. {
  313. CARLA_ASSERT(fDescriptor != nullptr);
  314. CARLA_ASSERT(fHandle != nullptr);
  315. CARLA_ASSERT(parameterId < kData->param.count);
  316. if (fDescriptor->get_parameter_info != nullptr && parameterId < kData->param.count)
  317. {
  318. const Parameter* const param(fDescriptor->get_parameter_info(fHandle, parameterId));
  319. if (param != nullptr && param->name != nullptr)
  320. {
  321. std::strncpy(strBuf, param->name, STR_MAX);
  322. return;
  323. }
  324. }
  325. CarlaPlugin::getParameterName(parameterId, strBuf);
  326. }
  327. void getParameterText(const uint32_t parameterId, char* const strBuf) override
  328. {
  329. CARLA_ASSERT(fDescriptor != nullptr);
  330. CARLA_ASSERT(fHandle != nullptr);
  331. CARLA_ASSERT(parameterId < kData->param.count);
  332. if (fDescriptor->get_parameter_text != nullptr && parameterId < kData->param.count)
  333. {
  334. if (const char* const text = fDescriptor->get_parameter_text(fHandle, parameterId))
  335. {
  336. std::strncpy(strBuf, text, STR_MAX);
  337. return;
  338. }
  339. }
  340. CarlaPlugin::getParameterText(parameterId, strBuf);
  341. }
  342. void getParameterUnit(const uint32_t parameterId, char* const strBuf) override
  343. {
  344. CARLA_ASSERT(fDescriptor != nullptr);
  345. CARLA_ASSERT(fHandle != nullptr);
  346. CARLA_ASSERT(parameterId < kData->param.count);
  347. if (fDescriptor->get_parameter_info != nullptr && parameterId < kData->param.count)
  348. {
  349. const Parameter* const param(fDescriptor->get_parameter_info(fHandle, parameterId));
  350. if (param != nullptr && param->unit != nullptr)
  351. {
  352. std::strncpy(strBuf, param->unit, STR_MAX);
  353. return;
  354. }
  355. }
  356. CarlaPlugin::getParameterUnit(parameterId, strBuf);
  357. }
  358. void getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf) override
  359. {
  360. CARLA_ASSERT(fDescriptor != nullptr);
  361. CARLA_ASSERT(fHandle != nullptr);
  362. CARLA_ASSERT(parameterId < kData->param.count);
  363. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  364. if (fDescriptor->get_parameter_info != nullptr && parameterId < kData->param.count)
  365. {
  366. if (const Parameter* const param = fDescriptor->get_parameter_info(fHandle, parameterId))
  367. {
  368. const ParameterScalePoint& scalePoint(param->scalePoints[scalePointId]);
  369. if (scalePoint.label != nullptr)
  370. {
  371. std::strncpy(strBuf, scalePoint.label, STR_MAX);
  372. return;
  373. }
  374. }
  375. }
  376. CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf);
  377. }
  378. // -------------------------------------------------------------------
  379. // Set data (state)
  380. void prepareForSave() override
  381. {
  382. CARLA_ASSERT(fDescriptor != nullptr);
  383. CARLA_ASSERT(fHandle != nullptr);
  384. if (fDescriptor->get_state == nullptr)
  385. return;
  386. if ((fDescriptor->hints & ::PLUGIN_USES_STATE) == 0)
  387. return;
  388. if (char* data = fDescriptor->get_state(fHandle))
  389. {
  390. CarlaPlugin::setCustomData(CUSTOM_DATA_CHUNK, "State", data, false);
  391. std::free(data);
  392. }
  393. }
  394. // -------------------------------------------------------------------
  395. // Set data (internal stuff)
  396. void setName(const char* const newName) override
  397. {
  398. char uiName[std::strlen(newName)+6+1];
  399. std::strcpy(uiName, newName);
  400. std::strcat(uiName, " (GUI)");
  401. if (fHost.ui_name != nullptr)
  402. delete[] fHost.ui_name;
  403. fHost.ui_name = carla_strdup(uiName);
  404. CarlaPlugin::setName(newName);
  405. }
  406. // -------------------------------------------------------------------
  407. // Set data (plugin-specific stuff)
  408. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) override
  409. {
  410. CARLA_ASSERT(fDescriptor != nullptr);
  411. CARLA_ASSERT(fHandle != nullptr);
  412. CARLA_ASSERT(parameterId < kData->param.count);
  413. const float fixedValue(kData->param.fixValue(parameterId, value));
  414. if (fDescriptor->set_parameter_value != nullptr && parameterId < kData->param.count)
  415. {
  416. fDescriptor->set_parameter_value(fHandle, parameterId, fixedValue);
  417. if (fHandle2 != nullptr)
  418. fDescriptor->set_parameter_value(fHandle2, parameterId, fixedValue);
  419. }
  420. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  421. }
  422. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
  423. {
  424. CARLA_ASSERT(fDescriptor != nullptr);
  425. CARLA_ASSERT(fHandle != nullptr);
  426. CARLA_ASSERT(type != nullptr);
  427. CARLA_ASSERT(key != nullptr);
  428. CARLA_ASSERT(value != nullptr);
  429. carla_debug("NativePlugin::setCustomData(%s, %s, %s, %s)", type, key, value, bool2str(sendGui));
  430. if (type == nullptr)
  431. return carla_stderr2("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is null", type, key, value, bool2str(sendGui));
  432. if (std::strcmp(type, CUSTOM_DATA_STRING) != 0 && std::strcmp(type, CUSTOM_DATA_CHUNK) != 0)
  433. return carla_stderr2("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is invalid", type, key, value, bool2str(sendGui));
  434. if (key == nullptr)
  435. return carla_stderr2("NativePlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - key is null", type, key, value, bool2str(sendGui));
  436. if (value == nullptr)
  437. return carla_stderr2("Nativelugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - value is null", type, key, value, bool2str(sendGui));
  438. if (std::strcmp(type, CUSTOM_DATA_CHUNK) == 0)
  439. {
  440. if (fDescriptor->set_state != nullptr && (fDescriptor->hints & ::PLUGIN_USES_STATE) != 0)
  441. {
  442. const ScopedSingleProcessLocker spl(this, true);
  443. fDescriptor->set_state(fHandle, value);
  444. if (fHandle2 != nullptr)
  445. fDescriptor->set_state(fHandle2, value);
  446. }
  447. }
  448. else
  449. {
  450. if (fDescriptor->set_custom_data != nullptr)
  451. {
  452. fDescriptor->set_custom_data(fHandle, key, value);
  453. if (fHandle2 != nullptr)
  454. fDescriptor->set_custom_data(fHandle2, key, value);
  455. }
  456. if (sendGui && fIsUiVisible && fDescriptor->ui_set_custom_data != nullptr)
  457. fDescriptor->ui_set_custom_data(fHandle, key, value);
  458. if (std::strlen(key) == 6 && std::strncmp(key, "file", 4) == 0)
  459. {
  460. const ScopedDisabler sd(this);
  461. reloadPrograms(false);
  462. }
  463. }
  464. CarlaPlugin::setCustomData(type, key, value, sendGui);
  465. }
  466. void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) override
  467. {
  468. CARLA_ASSERT(fDescriptor != nullptr);
  469. CARLA_ASSERT(fHandle != nullptr);
  470. CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count));
  471. if (index < -1)
  472. index = -1;
  473. else if (index > static_cast<int32_t>(kData->midiprog.count))
  474. return;
  475. if (index >= 0)
  476. {
  477. const uint32_t bank = kData->midiprog.data[index].bank;
  478. const uint32_t program = kData->midiprog.data[index].program;
  479. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  480. fDescriptor->set_midi_program(fHandle, bank, program);
  481. if (fHandle2 != nullptr)
  482. fDescriptor->set_midi_program(fHandle2, bank, program);
  483. }
  484. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback);
  485. }
  486. // -------------------------------------------------------------------
  487. // Set gui stuff
  488. void showGui(const bool yesNo) override
  489. {
  490. CARLA_ASSERT(fDescriptor != nullptr);
  491. CARLA_ASSERT(fHandle != nullptr);
  492. if (fDescriptor->ui_show == nullptr)
  493. return;
  494. fDescriptor->ui_show(fHandle, yesNo);
  495. fIsUiVisible = yesNo;
  496. if (yesNo)
  497. {
  498. // Update UI values, FIXME? (remove?)
  499. if (fDescriptor->ui_set_custom_data != nullptr)
  500. {
  501. for (auto it = kData->custom.begin(); it.valid(); it.next())
  502. {
  503. const CustomData& cData(*it);
  504. if (std::strcmp(cData.type, CUSTOM_DATA_STRING) == 0)
  505. fDescriptor->ui_set_custom_data(fHandle, cData.key, cData.value);
  506. }
  507. }
  508. if (fDescriptor->ui_set_midi_program != nullptr && kData->midiprog.current >= 0)
  509. {
  510. const MidiProgramData& mpData = kData->midiprog.getCurrent();
  511. fDescriptor->ui_set_midi_program(fHandle, mpData.bank, mpData.program);
  512. }
  513. if (fDescriptor->ui_set_parameter_value != nullptr)
  514. {
  515. for (uint32_t i=0; i < kData->param.count; ++i)
  516. fDescriptor->ui_set_parameter_value(fHandle, i, fDescriptor->get_parameter_value(fHandle, i));
  517. }
  518. }
  519. }
  520. void idleGui() override
  521. {
  522. CARLA_ASSERT(fDescriptor != nullptr);
  523. CARLA_ASSERT(fHandle != nullptr);
  524. if (fIsUiVisible && fDescriptor->ui_idle != nullptr)
  525. fDescriptor->ui_idle(fHandle);
  526. }
  527. // -------------------------------------------------------------------
  528. // Plugin state
  529. void reload() override
  530. {
  531. carla_debug("NativePlugin::reload() - start");
  532. CARLA_ASSERT(kData->engine != nullptr);
  533. CARLA_ASSERT(fDescriptor != nullptr);
  534. CARLA_ASSERT(fHandle != nullptr);
  535. if (kData->engine == nullptr)
  536. return;
  537. if (fDescriptor == nullptr)
  538. return;
  539. if (fHandle == nullptr)
  540. return;
  541. const ProcessMode processMode(kData->engine->getProccessMode());
  542. // Safely disable plugin for reload
  543. const ScopedDisabler sd(this);
  544. if (kData->active)
  545. deactivate();
  546. clearBuffers();
  547. const float sampleRate = (float)kData->engine->getSampleRate();
  548. uint32_t aIns, aOuts, mIns, mOuts, params, j;
  549. bool forcedStereoIn, forcedStereoOut;
  550. forcedStereoIn = forcedStereoOut = false;
  551. bool needsCtrlIn, needsCtrlOut;
  552. needsCtrlIn = needsCtrlOut = false;
  553. aIns = fDescriptor->audioIns;
  554. aOuts = fDescriptor->audioOuts;
  555. mIns = fDescriptor->midiIns;
  556. mOuts = fDescriptor->midiOuts;
  557. params = (fDescriptor->get_parameter_count != nullptr && fDescriptor->get_parameter_info != nullptr) ? fDescriptor->get_parameter_count(fHandle) : 0;
  558. if ((fOptions & PLUGIN_OPTION_FORCE_STEREO) != 0 && (aIns == 1 || aOuts == 1) && mIns <= 1 && mOuts <= 1)
  559. {
  560. if (fHandle2 == nullptr)
  561. fHandle2 = fDescriptor->instantiate(fDescriptor, &fHost);
  562. if (aIns == 1)
  563. {
  564. aIns = 2;
  565. forcedStereoIn = true;
  566. }
  567. if (aOuts == 1)
  568. {
  569. aOuts = 2;
  570. forcedStereoOut = true;
  571. }
  572. }
  573. if (aIns > 0)
  574. {
  575. kData->audioIn.createNew(aIns);
  576. fAudioInBuffers = new float*[aIns];
  577. for (uint32_t i=0; i < aIns; ++i)
  578. fAudioInBuffers[i] = nullptr;
  579. }
  580. if (aOuts > 0)
  581. {
  582. kData->audioOut.createNew(aOuts);
  583. fAudioOutBuffers = new float*[aOuts];
  584. needsCtrlIn = true;
  585. for (uint32_t i=0; i < aOuts; ++i)
  586. fAudioOutBuffers[i] = nullptr;
  587. }
  588. if (mIns > 0)
  589. {
  590. fMidiIn.createNew(mIns);
  591. needsCtrlIn = (mIns == 1);
  592. }
  593. if (mOuts > 0)
  594. {
  595. fMidiOut.createNew(mOuts);
  596. needsCtrlOut = (mOuts == 1);
  597. }
  598. if (params > 0)
  599. {
  600. kData->param.createNew(params);
  601. }
  602. const uint portNameSize(kData->engine->maxPortNameSize());
  603. CarlaString portName;
  604. // Audio Ins
  605. for (j=0; j < aIns; ++j)
  606. {
  607. portName.clear();
  608. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  609. {
  610. portName = fName;
  611. portName += ":";
  612. }
  613. if (aIns > 1 && ! forcedStereoIn)
  614. {
  615. portName += "input_";
  616. portName += CarlaString(j+1);
  617. }
  618. else
  619. portName += "input";
  620. portName.truncate(portNameSize);
  621. kData->audioIn.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, true);
  622. kData->audioIn.ports[j].rindex = j;
  623. if (forcedStereoIn)
  624. {
  625. portName += "_2";
  626. kData->audioIn.ports[1].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, true);
  627. kData->audioIn.ports[1].rindex = j;
  628. break;
  629. }
  630. }
  631. // Audio Outs
  632. for (j=0; j < aOuts; ++j)
  633. {
  634. portName.clear();
  635. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  636. {
  637. portName = fName;
  638. portName += ":";
  639. }
  640. if (aOuts > 1 && ! forcedStereoOut)
  641. {
  642. portName += "output_";
  643. portName += CarlaString(j+1);
  644. }
  645. else
  646. portName += "output";
  647. portName.truncate(portNameSize);
  648. kData->audioOut.ports[j].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, false);
  649. kData->audioOut.ports[j].rindex = j;
  650. if (forcedStereoOut)
  651. {
  652. portName += "_2";
  653. kData->audioOut.ports[1].port = (CarlaEngineAudioPort*)kData->client->addPort(kEnginePortTypeAudio, portName, false);
  654. kData->audioOut.ports[1].rindex = j;
  655. break;
  656. }
  657. }
  658. // MIDI Input (only if multiple)
  659. if (mIns > 1)
  660. {
  661. for (j=0; j < mIns; ++j)
  662. {
  663. portName.clear();
  664. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  665. {
  666. portName = fName;
  667. portName += ":";
  668. }
  669. portName += "midi-in_";
  670. portName += CarlaString(j+1);
  671. portName.truncate(portNameSize);
  672. fMidiIn.ports[j] = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true);
  673. fMidiIn.indexes[j] = j;
  674. }
  675. }
  676. // MIDI Output (only if multiple)
  677. if (mOuts > 1)
  678. {
  679. for (j=0; j < mOuts; ++j)
  680. {
  681. portName.clear();
  682. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  683. {
  684. portName = fName;
  685. portName += ":";
  686. }
  687. portName += "midi-out_";
  688. portName += CarlaString(j+1);
  689. portName.truncate(portNameSize);
  690. fMidiOut.ports[j] = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false);
  691. fMidiOut.indexes[j] = j;
  692. }
  693. }
  694. for (j=0; j < params; ++j)
  695. {
  696. const ::Parameter* const paramInfo = fDescriptor->get_parameter_info(fHandle, j);
  697. CARLA_ASSERT(paramInfo != nullptr);
  698. if (paramInfo == nullptr)
  699. continue;
  700. kData->param.data[j].index = j;
  701. kData->param.data[j].rindex = j;
  702. kData->param.data[j].hints = 0x0;
  703. kData->param.data[j].midiChannel = 0;
  704. kData->param.data[j].midiCC = -1;
  705. float min, max, def, step, stepSmall, stepLarge;
  706. // min value
  707. min = paramInfo->ranges.min;
  708. // max value
  709. max = paramInfo->ranges.max;
  710. if (min > max)
  711. max = min;
  712. else if (max < min)
  713. min = max;
  714. if (max - min == 0.0f)
  715. {
  716. carla_stderr2("WARNING - Broken plugin parameter '%s': max - min == 0.0f", paramInfo->name);
  717. max = min + 0.1f;
  718. }
  719. // default value
  720. def = paramInfo->ranges.def;
  721. if (def < min)
  722. def = min;
  723. else if (def > max)
  724. def = max;
  725. if (paramInfo->hints & ::PARAMETER_USES_SAMPLE_RATE)
  726. {
  727. min *= sampleRate;
  728. max *= sampleRate;
  729. def *= sampleRate;
  730. kData->param.data[j].hints |= PARAMETER_USES_SAMPLERATE;
  731. }
  732. if (paramInfo->hints & ::PARAMETER_IS_BOOLEAN)
  733. {
  734. step = max - min;
  735. stepSmall = step;
  736. stepLarge = step;
  737. kData->param.data[j].hints |= PARAMETER_IS_BOOLEAN;
  738. }
  739. else if (paramInfo->hints & ::PARAMETER_IS_INTEGER)
  740. {
  741. step = 1.0f;
  742. stepSmall = 1.0f;
  743. stepLarge = 10.0f;
  744. kData->param.data[j].hints |= PARAMETER_IS_INTEGER;
  745. }
  746. else
  747. {
  748. float range = max - min;
  749. step = range/100.0f;
  750. stepSmall = range/1000.0f;
  751. stepLarge = range/10.0f;
  752. }
  753. if (paramInfo->hints & ::PARAMETER_IS_OUTPUT)
  754. {
  755. kData->param.data[j].type = PARAMETER_OUTPUT;
  756. needsCtrlOut = true;
  757. }
  758. else
  759. {
  760. kData->param.data[j].type = PARAMETER_INPUT;
  761. needsCtrlIn = true;
  762. }
  763. // extra parameter hints
  764. if (paramInfo->hints & ::PARAMETER_IS_ENABLED)
  765. kData->param.data[j].hints |= PARAMETER_IS_ENABLED;
  766. if (paramInfo->hints & ::PARAMETER_IS_AUTOMABLE)
  767. kData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
  768. if (paramInfo->hints & ::PARAMETER_IS_LOGARITHMIC)
  769. kData->param.data[j].hints |= PARAMETER_IS_LOGARITHMIC;
  770. if (paramInfo->hints & ::PARAMETER_USES_SCALEPOINTS)
  771. kData->param.data[j].hints |= PARAMETER_USES_SCALEPOINTS;
  772. if (paramInfo->hints & ::PARAMETER_USES_CUSTOM_TEXT)
  773. kData->param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT;
  774. kData->param.ranges[j].min = min;
  775. kData->param.ranges[j].max = max;
  776. kData->param.ranges[j].def = def;
  777. kData->param.ranges[j].step = step;
  778. kData->param.ranges[j].stepSmall = stepSmall;
  779. kData->param.ranges[j].stepLarge = stepLarge;
  780. }
  781. if (needsCtrlIn)
  782. {
  783. portName.clear();
  784. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  785. {
  786. portName = fName;
  787. portName += ":";
  788. }
  789. portName += "events-in";
  790. portName.truncate(portNameSize);
  791. kData->event.portIn = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, true);
  792. }
  793. if (needsCtrlOut)
  794. {
  795. portName.clear();
  796. if (processMode == PROCESS_MODE_SINGLE_CLIENT)
  797. {
  798. portName = fName;
  799. portName += ":";
  800. }
  801. portName += "events-out";
  802. portName.truncate(portNameSize);
  803. kData->event.portOut = (CarlaEngineEventPort*)kData->client->addPort(kEnginePortTypeEvent, portName, false);
  804. }
  805. if (forcedStereoIn || forcedStereoOut)
  806. fOptions |= PLUGIN_OPTION_FORCE_STEREO;
  807. else
  808. fOptions &= ~PLUGIN_OPTION_FORCE_STEREO;
  809. // plugin hints
  810. fHints = 0x0;
  811. if (aOuts > 0 && (aIns == aOuts || aIns == 1))
  812. fHints |= PLUGIN_CAN_DRYWET;
  813. if (aOuts > 0)
  814. fHints |= PLUGIN_CAN_VOLUME;
  815. if (aOuts >= 2 && aOuts % 2 == 0)
  816. fHints |= PLUGIN_CAN_BALANCE;
  817. // native plugin hints
  818. if (fDescriptor->hints & ::PLUGIN_IS_RTSAFE)
  819. fHints |= PLUGIN_IS_RTSAFE;
  820. if (fDescriptor->hints & ::PLUGIN_IS_SYNTH)
  821. fHints |= PLUGIN_IS_SYNTH;
  822. if (fDescriptor->hints & ::PLUGIN_HAS_GUI)
  823. fHints |= PLUGIN_HAS_GUI;
  824. if (fDescriptor->hints & ::PLUGIN_USES_SINGLE_THREAD)
  825. fHints |= PLUGIN_HAS_SINGLE_THREAD;
  826. // extra plugin hints
  827. kData->extraHints = 0x0;
  828. if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0) && mIns <= 1 && mOuts <= 1)
  829. kData->extraHints |= PLUGIN_HINT_CAN_RUN_RACK;
  830. bufferSizeChanged(kData->engine->getBufferSize());
  831. reloadPrograms(true);
  832. if (kData->active)
  833. activate();
  834. carla_debug("NativePlugin::reload() - end");
  835. }
  836. void reloadPrograms(const bool init) override
  837. {
  838. carla_debug("NativePlugin::reloadPrograms(%s)", bool2str(init));
  839. uint32_t i, oldCount = kData->midiprog.count;
  840. const int32_t current = kData->midiprog.current;
  841. // Delete old programs
  842. kData->midiprog.clear();
  843. // Query new programs
  844. uint32_t count = 0;
  845. if (fDescriptor->get_midi_program_count != nullptr && fDescriptor->get_midi_program_info != nullptr)
  846. count = fDescriptor->get_midi_program_count(fHandle);
  847. if (count > 0)
  848. {
  849. kData->midiprog.createNew(count);
  850. // Update data
  851. for (i=0; i < count; ++i)
  852. {
  853. const ::MidiProgram* const mpDesc = fDescriptor->get_midi_program_info(fHandle, i);
  854. CARLA_ASSERT(mpDesc != nullptr);
  855. CARLA_ASSERT(mpDesc->name != nullptr);
  856. kData->midiprog.data[i].bank = mpDesc->bank;
  857. kData->midiprog.data[i].program = mpDesc->program;
  858. kData->midiprog.data[i].name = carla_strdup(mpDesc->name);
  859. }
  860. }
  861. #ifndef BUILD_BRIDGE
  862. // Update OSC Names
  863. if (kData->engine->isOscControlRegistered())
  864. {
  865. kData->engine->osc_send_control_set_midi_program_count(fId, count);
  866. for (i=0; i < count; ++i)
  867. kData->engine->osc_send_control_set_midi_program_data(fId, i, kData->midiprog.data[i].bank, kData->midiprog.data[i].program, kData->midiprog.data[i].name);
  868. }
  869. #endif
  870. if (init)
  871. {
  872. if (count > 0)
  873. setMidiProgram(0, false, false, false);
  874. }
  875. else
  876. {
  877. // Check if current program is invalid
  878. bool programChanged = false;
  879. if (count == oldCount+1)
  880. {
  881. // one midi program added, probably created by user
  882. kData->midiprog.current = oldCount;
  883. programChanged = true;
  884. }
  885. else if (current < 0 && count > 0)
  886. {
  887. // programs exist now, but not before
  888. kData->midiprog.current = 0;
  889. programChanged = true;
  890. }
  891. else if (current >= 0 && count == 0)
  892. {
  893. // programs existed before, but not anymore
  894. kData->midiprog.current = -1;
  895. programChanged = true;
  896. }
  897. else if (current >= static_cast<int32_t>(count))
  898. {
  899. // current midi program > count
  900. kData->midiprog.current = 0;
  901. programChanged = true;
  902. }
  903. else
  904. {
  905. // no change
  906. kData->midiprog.current = current;
  907. }
  908. if (programChanged)
  909. setMidiProgram(kData->midiprog.current, true, true, true);
  910. kData->engine->callback(CALLBACK_RELOAD_PROGRAMS, fId, 0, 0, 0.0f, nullptr);
  911. }
  912. }
  913. // -------------------------------------------------------------------
  914. // Plugin processing
  915. void activate() override
  916. {
  917. CARLA_ASSERT(fDescriptor != nullptr);
  918. CARLA_ASSERT(fHandle != nullptr);
  919. if (fDescriptor->activate != nullptr)
  920. {
  921. fDescriptor->activate(fHandle);
  922. if (fHandle2 != nullptr)
  923. fDescriptor->activate(fHandle2);
  924. }
  925. }
  926. void deactivate() override
  927. {
  928. CARLA_ASSERT(fDescriptor != nullptr);
  929. CARLA_ASSERT(fHandle != nullptr);
  930. if (fDescriptor->deactivate != nullptr)
  931. {
  932. fDescriptor->deactivate(fHandle);
  933. if (fHandle2 != nullptr)
  934. fDescriptor->deactivate(fHandle2);
  935. }
  936. }
  937. void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
  938. {
  939. uint32_t i, k;
  940. // --------------------------------------------------------------------------------------------------------
  941. // Check if active
  942. if (! kData->active)
  943. {
  944. // disable any output sound
  945. for (i=0; i < kData->audioOut.count; ++i)
  946. carla_zeroFloat(outBuffer[i], frames);
  947. return;
  948. }
  949. fMidiEventCount = 0;
  950. carla_zeroStruct< ::MidiEvent>(fMidiEvents, MAX_MIDI_EVENTS*2);
  951. // --------------------------------------------------------------------------------------------------------
  952. // Check if needs reset
  953. if (kData->needsReset)
  954. {
  955. // TODO!
  956. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  957. {
  958. for (k=0, i=MAX_MIDI_CHANNELS; k < MAX_MIDI_CHANNELS; ++k)
  959. {
  960. fMidiEvents[k].data[0] = MIDI_STATUS_CONTROL_CHANGE + k;
  961. fMidiEvents[k].data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  962. fMidiEvents[k].size = 2;
  963. fMidiEvents[k+i].data[0] = MIDI_STATUS_CONTROL_CHANGE + k;
  964. fMidiEvents[k+i].data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  965. fMidiEvents[k+i].size = 2;
  966. }
  967. fMidiEventCount = MAX_MIDI_CHANNELS*2;
  968. }
  969. else
  970. {
  971. }
  972. kData->needsReset = false;
  973. }
  974. CARLA_PROCESS_CONTINUE_CHECK;
  975. // --------------------------------------------------------------------------------------------------------
  976. // Set TimeInfo
  977. const EngineTimeInfo& timeInfo(kData->engine->getTimeInfo());
  978. fTimeInfo.playing = timeInfo.playing;
  979. fTimeInfo.frame = timeInfo.frame;
  980. fTimeInfo.usecs = timeInfo.usecs;
  981. if (timeInfo.valid & EngineTimeInfo::ValidBBT)
  982. {
  983. fTimeInfo.bbt.valid = true;
  984. fTimeInfo.bbt.bar = timeInfo.bbt.bar;
  985. fTimeInfo.bbt.beat = timeInfo.bbt.beat;
  986. fTimeInfo.bbt.tick = timeInfo.bbt.tick;
  987. fTimeInfo.bbt.barStartTick = timeInfo.bbt.barStartTick;
  988. fTimeInfo.bbt.beatsPerBar = timeInfo.bbt.beatsPerBar;
  989. fTimeInfo.bbt.beatType = timeInfo.bbt.beatType;
  990. fTimeInfo.bbt.ticksPerBeat = timeInfo.bbt.ticksPerBeat;
  991. fTimeInfo.bbt.beatsPerMinute = timeInfo.bbt.beatsPerMinute;
  992. }
  993. else
  994. fTimeInfo.bbt.valid = false;
  995. CARLA_PROCESS_CONTINUE_CHECK;
  996. // --------------------------------------------------------------------------------------------------------
  997. // Event Input and Processing
  998. if (kData->event.portIn != nullptr)
  999. {
  1000. // ----------------------------------------------------------------------------------------------------
  1001. // MIDI Input (External)
  1002. if (kData->extNotes.mutex.tryLock())
  1003. {
  1004. while (fMidiEventCount < MAX_MIDI_EVENTS*2 && ! kData->extNotes.data.isEmpty())
  1005. {
  1006. const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));
  1007. CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  1008. fMidiEvents[fMidiEventCount].data[0] = (note.velo > 0) ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF;
  1009. fMidiEvents[fMidiEventCount].data[0] += note.channel;
  1010. fMidiEvents[fMidiEventCount].data[1] = note.note;
  1011. fMidiEvents[fMidiEventCount].data[2] = note.velo;
  1012. fMidiEventCount += 1;
  1013. }
  1014. kData->extNotes.mutex.unlock();
  1015. } // End of MIDI Input (External)
  1016. // ----------------------------------------------------------------------------------------------------
  1017. // Event Input (System)
  1018. bool allNotesOffSent = false;
  1019. bool sampleAccurate = (fOptions & PLUGIN_OPTION_FIXED_BUFFER) == 0;
  1020. uint32_t time, nEvents = kData->event.portIn->getEventCount();
  1021. uint32_t startTime = 0;
  1022. uint32_t timeOffset = 0;
  1023. uint32_t nextBankId = 0;
  1024. if (kData->midiprog.current >= 0 && kData->midiprog.count > 0)
  1025. nextBankId = kData->midiprog.data[kData->midiprog.current].bank;
  1026. for (i=0; i < nEvents; ++i)
  1027. {
  1028. const EngineEvent& event(kData->event.portIn->getEvent(i));
  1029. time = event.time;
  1030. if (time >= frames)
  1031. continue;
  1032. CARLA_ASSERT_INT2(time >= timeOffset, time, timeOffset);
  1033. if (time > timeOffset && sampleAccurate)
  1034. {
  1035. if (processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset))
  1036. {
  1037. startTime = 0;
  1038. timeOffset = time;
  1039. nextBankId = 0;
  1040. if (kData->midiprog.current >= 0 && kData->midiprog.count > 0)
  1041. nextBankId = kData->midiprog.data[kData->midiprog.current].bank;
  1042. else
  1043. nextBankId = 0;
  1044. if (fMidiEventCount > 0)
  1045. {
  1046. carla_zeroStruct< ::MidiEvent>(fMidiEvents, fMidiEventCount);
  1047. fMidiEventCount = 0;
  1048. }
  1049. }
  1050. else
  1051. startTime += timeOffset;
  1052. }
  1053. // Control change
  1054. switch (event.type)
  1055. {
  1056. case kEngineEventTypeNull:
  1057. break;
  1058. case kEngineEventTypeControl:
  1059. {
  1060. const EngineControlEvent& ctrlEvent = event.ctrl;
  1061. switch (ctrlEvent.type)
  1062. {
  1063. case kEngineControlEventTypeNull:
  1064. break;
  1065. case kEngineControlEventTypeParameter:
  1066. {
  1067. // Control backend stuff
  1068. if (event.channel == kData->ctrlChannel)
  1069. {
  1070. float value;
  1071. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (fHints & PLUGIN_CAN_DRYWET) > 0)
  1072. {
  1073. value = ctrlEvent.value;
  1074. setDryWet(value, false, false);
  1075. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
  1076. continue;
  1077. }
  1078. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (fHints & PLUGIN_CAN_VOLUME) > 0)
  1079. {
  1080. value = ctrlEvent.value*127.0f/100.0f;
  1081. setVolume(value, false, false);
  1082. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
  1083. continue;
  1084. }
  1085. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (fHints & PLUGIN_CAN_BALANCE) > 0)
  1086. {
  1087. float left, right;
  1088. value = ctrlEvent.value/0.5f - 1.0f;
  1089. if (value < 0.0f)
  1090. {
  1091. left = -1.0f;
  1092. right = (value*2.0f)+1.0f;
  1093. }
  1094. else if (value > 0.0f)
  1095. {
  1096. left = (value*2.0f)-1.0f;
  1097. right = 1.0f;
  1098. }
  1099. else
  1100. {
  1101. left = -1.0f;
  1102. right = 1.0f;
  1103. }
  1104. setBalanceLeft(left, false, false);
  1105. setBalanceRight(right, false, false);
  1106. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  1107. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  1108. continue;
  1109. }
  1110. }
  1111. // Control plugin parameters
  1112. for (k=0; k < kData->param.count; ++k)
  1113. {
  1114. if (kData->param.data[k].midiChannel != event.channel)
  1115. continue;
  1116. if (kData->param.data[k].midiCC != ctrlEvent.param)
  1117. continue;
  1118. if (kData->param.data[k].type != PARAMETER_INPUT)
  1119. continue;
  1120. if ((kData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  1121. continue;
  1122. float value;
  1123. if (kData->param.data[k].hints & PARAMETER_IS_BOOLEAN)
  1124. {
  1125. value = (ctrlEvent.value < 0.5f) ? kData->param.ranges[k].min : kData->param.ranges[k].max;
  1126. }
  1127. else
  1128. {
  1129. value = kData->param.ranges[i].unnormalizeValue(ctrlEvent.value);
  1130. if (kData->param.data[k].hints & PARAMETER_IS_INTEGER)
  1131. value = std::rint(value);
  1132. }
  1133. setParameterValue(k, value, false, false, false);
  1134. postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
  1135. }
  1136. break;
  1137. }
  1138. case kEngineControlEventTypeMidiBank:
  1139. if (event.channel == kData->ctrlChannel && (fOptions & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  1140. nextBankId = ctrlEvent.param;
  1141. break;
  1142. case kEngineControlEventTypeMidiProgram:
  1143. if (event.channel == kData->ctrlChannel && (fOptions & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  1144. {
  1145. const uint32_t nextProgramId = ctrlEvent.param;
  1146. for (k=0; k < kData->midiprog.count; ++k)
  1147. {
  1148. if (kData->midiprog.data[k].bank == nextBankId && kData->midiprog.data[k].program == nextProgramId)
  1149. {
  1150. setMidiProgram(k, false, false, false);
  1151. postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0f);
  1152. break;
  1153. }
  1154. }
  1155. }
  1156. break;
  1157. case kEngineControlEventTypeAllSoundOff:
  1158. if (event.channel == kData->ctrlChannel)
  1159. {
  1160. if (! allNotesOffSent)
  1161. {
  1162. sendMidiAllNotesOff();
  1163. allNotesOffSent = true;
  1164. }
  1165. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 0.0f);
  1166. postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_ACTIVE, 0, 1.0f);
  1167. }
  1168. if (fMidiEventCount >= MAX_MIDI_EVENTS*2)
  1169. continue;
  1170. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1171. {
  1172. fMidiEvents[fMidiEventCount].port = 0;
  1173. fMidiEvents[fMidiEventCount].time = sampleAccurate ? startTime : time;
  1174. fMidiEvents[fMidiEventCount].data[0] = MIDI_STATUS_CONTROL_CHANGE + event.channel;
  1175. fMidiEvents[fMidiEventCount].data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
  1176. fMidiEvents[fMidiEventCount].data[2] = 0;
  1177. fMidiEvents[fMidiEventCount].data[3] = 0;
  1178. fMidiEvents[fMidiEventCount].size = 2;
  1179. fMidiEventCount += 1;
  1180. }
  1181. break;
  1182. case kEngineControlEventTypeAllNotesOff:
  1183. if (event.channel == kData->ctrlChannel)
  1184. {
  1185. if (! allNotesOffSent)
  1186. {
  1187. allNotesOffSent = true;
  1188. sendMidiAllNotesOff();
  1189. }
  1190. }
  1191. if (fMidiEventCount >= MAX_MIDI_EVENTS*2)
  1192. continue;
  1193. if (fOptions & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1194. {
  1195. fMidiEvents[fMidiEventCount].port = 0;
  1196. fMidiEvents[fMidiEventCount].time = sampleAccurate ? startTime : time;
  1197. fMidiEvents[fMidiEventCount].data[0] = MIDI_STATUS_CONTROL_CHANGE + event.channel;
  1198. fMidiEvents[fMidiEventCount].data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
  1199. fMidiEvents[fMidiEventCount].data[2] = 0;
  1200. fMidiEvents[fMidiEventCount].data[3] = 0;
  1201. fMidiEvents[fMidiEventCount].size = 2;
  1202. fMidiEventCount += 1;
  1203. }
  1204. break;
  1205. }
  1206. break;
  1207. }
  1208. case kEngineEventTypeMidi:
  1209. {
  1210. if (fMidiEventCount >= MAX_MIDI_EVENTS*2)
  1211. continue;
  1212. const EngineMidiEvent& midiEvent = event.midi;
  1213. uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent.data);
  1214. uint8_t channel = event.channel;
  1215. if (MIDI_IS_STATUS_AFTERTOUCH(status) && (fOptions & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
  1216. continue;
  1217. if (MIDI_IS_STATUS_CONTROL_CHANGE(status) && (fOptions & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
  1218. continue;
  1219. if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status) && (fOptions & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
  1220. continue;
  1221. if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) && (fOptions & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
  1222. continue;
  1223. // Fix bad note-off
  1224. if (status == MIDI_STATUS_NOTE_ON && midiEvent.data[2] == 0)
  1225. status -= 0x10;
  1226. fMidiEvents[fMidiEventCount].port = 0;
  1227. fMidiEvents[fMidiEventCount].time = sampleAccurate ? startTime : time;
  1228. fMidiEvents[fMidiEventCount].size = midiEvent.size;
  1229. fMidiEvents[fMidiEventCount].data[0] = status + channel;
  1230. fMidiEvents[fMidiEventCount].data[1] = midiEvent.data[1];
  1231. fMidiEvents[fMidiEventCount].data[2] = midiEvent.data[2];
  1232. fMidiEvents[fMidiEventCount].data[3] = midiEvent.data[3];
  1233. fMidiEventCount += 1;
  1234. if (status == MIDI_STATUS_NOTE_ON)
  1235. postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]);
  1236. else if (status == MIDI_STATUS_NOTE_OFF)
  1237. postponeRtEvent(kPluginPostRtEventNoteOff, channel, midiEvent.data[1], 0.0f);
  1238. break;
  1239. }
  1240. }
  1241. }
  1242. kData->postRtEvents.trySplice();
  1243. if (frames > timeOffset)
  1244. processSingle(inBuffer, outBuffer, frames - timeOffset, timeOffset);
  1245. } // End of Event Input and Processing
  1246. // --------------------------------------------------------------------------------------------------------
  1247. // Plugin processing (no events)
  1248. else
  1249. {
  1250. processSingle(inBuffer, outBuffer, frames, 0);
  1251. } // End of Plugin processing (no events)
  1252. CARLA_PROCESS_CONTINUE_CHECK;
  1253. // --------------------------------------------------------------------------------------------------------
  1254. // Control and MIDI Output
  1255. if (fMidiOut.count > 0 || kData->event.portOut != nullptr)
  1256. {
  1257. float value, curValue;
  1258. for (k=0; k < kData->param.count; ++k)
  1259. {
  1260. if (kData->param.data[k].type != PARAMETER_OUTPUT)
  1261. continue;
  1262. curValue = fDescriptor->get_parameter_value(fHandle, k);
  1263. kData->param.ranges[k].fixValue(curValue);
  1264. if (kData->param.data[k].midiCC > 0)
  1265. {
  1266. value = kData->param.ranges[k].normalizeValue(curValue);
  1267. kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
  1268. }
  1269. }
  1270. // reverse lookup MIDI events
  1271. for (k = (MAX_MIDI_EVENTS*2)-1; k >= fMidiEventCount; --k)
  1272. {
  1273. if (fMidiEvents[k].data[0] == 0)
  1274. break;
  1275. const uint8_t channel = MIDI_GET_CHANNEL_FROM_DATA(fMidiEvents[k].data);
  1276. const uint8_t port = fMidiEvents[k].port;
  1277. if (kData->event.portOut != nullptr)
  1278. kData->event.portOut->writeMidiEvent(fMidiEvents[k].time, channel, port, fMidiEvents[k].data, fMidiEvents[k].size);
  1279. else if (port < fMidiOut.count)
  1280. fMidiOut.ports[port]->writeMidiEvent(fMidiEvents[k].time, channel, port, fMidiEvents[k].data, fMidiEvents[k].size);
  1281. }
  1282. } // End of Control and MIDI Output
  1283. }
  1284. bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
  1285. {
  1286. CARLA_ASSERT(frames > 0);
  1287. if (frames == 0)
  1288. return false;
  1289. if (kData->audioIn.count > 0)
  1290. {
  1291. CARLA_ASSERT(inBuffer != nullptr);
  1292. if (inBuffer == nullptr)
  1293. return false;
  1294. }
  1295. if (kData->audioOut.count > 0)
  1296. {
  1297. CARLA_ASSERT(outBuffer != nullptr);
  1298. if (outBuffer == nullptr)
  1299. return false;
  1300. }
  1301. uint32_t i, k;
  1302. // --------------------------------------------------------------------------------------------------------
  1303. // Try lock, silence otherwise
  1304. if (kData->engine->isOffline())
  1305. {
  1306. kData->singleMutex.lock();
  1307. }
  1308. else if (! kData->singleMutex.tryLock())
  1309. {
  1310. for (i=0; i < kData->audioOut.count; ++i)
  1311. {
  1312. for (k=0; k < frames; ++k)
  1313. outBuffer[i][k+timeOffset] = 0.0f;
  1314. }
  1315. return false;
  1316. }
  1317. // --------------------------------------------------------------------------------------------------------
  1318. // Reset audio buffers
  1319. for (i=0; i < kData->audioIn.count; ++i)
  1320. carla_copyFloat(fAudioInBuffers[i], inBuffer[i]+timeOffset, frames);
  1321. for (i=0; i < kData->audioOut.count; ++i)
  1322. carla_zeroFloat(fAudioOutBuffers[i], frames);
  1323. // --------------------------------------------------------------------------------------------------------
  1324. // Run plugin
  1325. fIsProcessing = true;
  1326. if (fHandle2 == nullptr)
  1327. {
  1328. fDescriptor->process(fHandle, fAudioInBuffers, fAudioOutBuffers, frames, fMidiEventCount, fMidiEvents);
  1329. }
  1330. else
  1331. {
  1332. fDescriptor->process(fHandle,
  1333. (kData->audioIn.count > 0) ? &fAudioInBuffers[0] : nullptr,
  1334. (kData->audioOut.count > 0) ? &fAudioOutBuffers[0] : nullptr,
  1335. frames, fMidiEventCount, fMidiEvents);
  1336. fDescriptor->process(fHandle2,
  1337. (kData->audioIn.count > 0) ? &fAudioInBuffers[1] : nullptr,
  1338. (kData->audioOut.count > 0) ? &fAudioOutBuffers[1] : nullptr,
  1339. frames, fMidiEventCount, fMidiEvents);
  1340. }
  1341. fIsProcessing = false;
  1342. fTimeInfo.frame += frames;
  1343. // --------------------------------------------------------------------------------------------------------
  1344. // Post-processing (dry/wet, volume and balance)
  1345. {
  1346. const bool doDryWet = (fHints & PLUGIN_CAN_DRYWET) != 0 && kData->postProc.dryWet != 1.0f;
  1347. const bool doBalance = (fHints & PLUGIN_CAN_BALANCE) != 0 && (kData->postProc.balanceLeft != -1.0f || kData->postProc.balanceRight != 1.0f);
  1348. bool isPair;
  1349. float bufValue, oldBufLeft[doBalance ? frames : 1];
  1350. for (i=0; i < kData->audioOut.count; ++i)
  1351. {
  1352. // Dry/Wet
  1353. if (doDryWet)
  1354. {
  1355. for (k=0; k < frames; ++k)
  1356. {
  1357. bufValue = fAudioInBuffers[(kData->audioIn.count == 1) ? 0 : i][k];
  1358. fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * kData->postProc.dryWet) + (bufValue * (1.0f - kData->postProc.dryWet));
  1359. }
  1360. }
  1361. // Balance
  1362. if (doBalance)
  1363. {
  1364. isPair = (i % 2 == 0);
  1365. if (isPair)
  1366. {
  1367. CARLA_ASSERT(i+1 < kData->audioOut.count);
  1368. carla_copyFloat(oldBufLeft, fAudioOutBuffers[i], frames);
  1369. }
  1370. float balRangeL = (kData->postProc.balanceLeft + 1.0f)/2.0f;
  1371. float balRangeR = (kData->postProc.balanceRight + 1.0f)/2.0f;
  1372. for (k=0; k < frames; ++k)
  1373. {
  1374. if (isPair)
  1375. {
  1376. // left
  1377. fAudioOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
  1378. fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR);
  1379. }
  1380. else
  1381. {
  1382. // right
  1383. fAudioOutBuffers[i][k] = fAudioOutBuffers[i][k] * balRangeR;
  1384. fAudioOutBuffers[i][k] += oldBufLeft[k] * balRangeL;
  1385. }
  1386. }
  1387. }
  1388. // Volume (and buffer copy)
  1389. {
  1390. for (k=0; k < frames; ++k)
  1391. outBuffer[i][k+timeOffset] = fAudioOutBuffers[i][k] * kData->postProc.volume;
  1392. }
  1393. }
  1394. } // End of Post-processing
  1395. // --------------------------------------------------------------------------------------------------------
  1396. kData->singleMutex.unlock();
  1397. return true;
  1398. }
  1399. void bufferSizeChanged(const uint32_t newBufferSize) override
  1400. {
  1401. CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
  1402. carla_debug("NativePlugin::bufferSizeChanged(%i)", newBufferSize);
  1403. for (uint32_t i=0; i < kData->audioIn.count; ++i)
  1404. {
  1405. if (fAudioInBuffers[i] != nullptr)
  1406. delete[] fAudioInBuffers[i];
  1407. fAudioInBuffers[i] = new float[newBufferSize];
  1408. }
  1409. for (uint32_t i=0; i < kData->audioOut.count; ++i)
  1410. {
  1411. if (fAudioOutBuffers[i] != nullptr)
  1412. delete[] fAudioOutBuffers[i];
  1413. fAudioOutBuffers[i] = new float[newBufferSize];
  1414. }
  1415. }
  1416. // -------------------------------------------------------------------
  1417. // Plugin buffers
  1418. void initBuffers() override
  1419. {
  1420. fMidiIn.initBuffers(kData->engine);
  1421. fMidiOut.initBuffers(kData->engine);
  1422. CarlaPlugin::initBuffers();
  1423. }
  1424. void clearBuffers() override
  1425. {
  1426. carla_debug("NativePlugin::clearBuffers() - start");
  1427. if (fAudioInBuffers != nullptr)
  1428. {
  1429. for (uint32_t i=0; i < kData->audioIn.count; ++i)
  1430. {
  1431. if (fAudioInBuffers[i] != nullptr)
  1432. {
  1433. delete[] fAudioInBuffers[i];
  1434. fAudioInBuffers[i] = nullptr;
  1435. }
  1436. }
  1437. delete[] fAudioInBuffers;
  1438. fAudioInBuffers = nullptr;
  1439. }
  1440. if (fAudioOutBuffers != nullptr)
  1441. {
  1442. for (uint32_t i=0; i < kData->audioOut.count; ++i)
  1443. {
  1444. if (fAudioOutBuffers[i] != nullptr)
  1445. {
  1446. delete[] fAudioOutBuffers[i];
  1447. fAudioOutBuffers[i] = nullptr;
  1448. }
  1449. }
  1450. delete[] fAudioOutBuffers;
  1451. fAudioOutBuffers = nullptr;
  1452. }
  1453. fMidiIn.clear();
  1454. fMidiOut.clear();
  1455. CarlaPlugin::clearBuffers();
  1456. carla_debug("NativePlugin::clearBuffers() - end");
  1457. }
  1458. // -------------------------------------------------------------------
  1459. // Post-poned UI Stuff
  1460. void uiParameterChange(const uint32_t index, const float value) override
  1461. {
  1462. CARLA_ASSERT(fDescriptor != nullptr);
  1463. CARLA_ASSERT(fHandle != nullptr);
  1464. CARLA_ASSERT(index < kData->param.count);
  1465. if (! fIsUiVisible)
  1466. return;
  1467. if (fDescriptor == nullptr || fHandle == nullptr)
  1468. return;
  1469. if (index >= kData->param.count)
  1470. return;
  1471. if (fDescriptor->ui_set_parameter_value != nullptr)
  1472. fDescriptor->ui_set_parameter_value(fHandle, index, value);
  1473. }
  1474. void uiMidiProgramChange(const uint32_t index) override
  1475. {
  1476. CARLA_ASSERT(fDescriptor != nullptr);
  1477. CARLA_ASSERT(fHandle != nullptr);
  1478. CARLA_ASSERT(index < kData->midiprog.count);
  1479. if (! fIsUiVisible)
  1480. return;
  1481. if (fDescriptor == nullptr || fHandle == nullptr)
  1482. return;
  1483. if (index >= kData->midiprog.count)
  1484. return;
  1485. if (fDescriptor->ui_set_midi_program != nullptr)
  1486. fDescriptor->ui_set_midi_program(fHandle, kData->midiprog.data[index].bank, kData->midiprog.data[index].program);
  1487. }
  1488. void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) override
  1489. {
  1490. CARLA_ASSERT(fDescriptor != nullptr);
  1491. CARLA_ASSERT(fHandle != nullptr);
  1492. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  1493. CARLA_ASSERT(note < MAX_MIDI_NOTE);
  1494. CARLA_ASSERT(velo > 0 && velo < MAX_MIDI_VALUE);
  1495. if (! fIsUiVisible)
  1496. return;
  1497. if (fDescriptor == nullptr || fHandle == nullptr)
  1498. return;
  1499. if (channel >= MAX_MIDI_CHANNELS)
  1500. return;
  1501. if (note >= MAX_MIDI_NOTE)
  1502. return;
  1503. if (velo >= MAX_MIDI_VALUE)
  1504. return;
  1505. // TODO
  1506. }
  1507. void uiNoteOff(const uint8_t channel, const uint8_t note) override
  1508. {
  1509. CARLA_ASSERT(fDescriptor != nullptr);
  1510. CARLA_ASSERT(fHandle != nullptr);
  1511. CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
  1512. CARLA_ASSERT(note < MAX_MIDI_NOTE);
  1513. if (! fIsUiVisible)
  1514. return;
  1515. if (fDescriptor == nullptr || fHandle == nullptr)
  1516. return;
  1517. if (channel >= MAX_MIDI_CHANNELS)
  1518. return;
  1519. if (note >= MAX_MIDI_NOTE)
  1520. return;
  1521. // TODO
  1522. }
  1523. // -------------------------------------------------------------------
  1524. protected:
  1525. uint32_t handleGetBufferSize()
  1526. {
  1527. return kData->engine->getBufferSize();
  1528. }
  1529. double handleGetSampleRate()
  1530. {
  1531. return kData->engine->getSampleRate();
  1532. }
  1533. const ::TimeInfo* handleGetTimeInfo()
  1534. {
  1535. CARLA_ASSERT(fIsProcessing);
  1536. return &fTimeInfo;
  1537. }
  1538. bool handleWriteMidiEvent(const ::MidiEvent* const event)
  1539. {
  1540. CARLA_ASSERT(fEnabled);
  1541. CARLA_ASSERT(fIsProcessing);
  1542. CARLA_ASSERT(fMidiOut.count > 0 || kData->event.portOut != nullptr);
  1543. CARLA_ASSERT(event != nullptr);
  1544. CARLA_ASSERT(event->data[0] != 0);
  1545. if (! fEnabled)
  1546. return false;
  1547. if (fMidiOut.count == 0)
  1548. return false;
  1549. if (event == nullptr)
  1550. return false;
  1551. if (event->data[0] == 0)
  1552. return false;
  1553. if (! fIsProcessing)
  1554. {
  1555. carla_stderr2("NativePlugin::handleWriteMidiEvent(%p) - received MIDI out event outside audio thread, ignoring", event);
  1556. return false;
  1557. }
  1558. if (fMidiEventCount >= MAX_MIDI_EVENTS*2)
  1559. return false;
  1560. // reverse-find first free event, and put it there
  1561. for (uint32_t i=(MAX_MIDI_EVENTS*2)-1; i >= fMidiEventCount; --i)
  1562. {
  1563. if (fMidiEvents[i].data[0] == 0)
  1564. {
  1565. std::memcpy(&fMidiEvents[i], event, sizeof(::MidiEvent));
  1566. break;
  1567. }
  1568. }
  1569. return true;
  1570. }
  1571. void handleUiParameterChanged(const uint32_t index, const float value)
  1572. {
  1573. setParameterValue(index, value, false, true, true);
  1574. }
  1575. void handleUiCustomDataChanged(const char* const key, const char* const value)
  1576. {
  1577. setCustomData(CUSTOM_DATA_STRING, key, value, false);
  1578. }
  1579. void handleUiClosed()
  1580. {
  1581. kData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
  1582. fIsUiVisible = false;
  1583. }
  1584. const char* handleUiOpenFile(const bool isDir, const char* const title, const char* const filter)
  1585. {
  1586. static CarlaString retStr;
  1587. QFileDialog::Options options(isDir ? QFileDialog::ShowDirsOnly : 0x0);
  1588. retStr = QFileDialog::getOpenFileName(nullptr, title, "", filter, nullptr, options).toUtf8().constData();
  1589. return retStr.isNotEmpty() ? (const char*)retStr : nullptr;
  1590. }
  1591. const char* handleUiSaveFile(const bool isDir, const char* const title, const char* const filter)
  1592. {
  1593. static CarlaString retStr;
  1594. QFileDialog::Options options(isDir ? QFileDialog::ShowDirsOnly : 0x0);
  1595. retStr = QFileDialog::getSaveFileName(nullptr, title, "", filter, nullptr, options).toUtf8().constData();
  1596. return retStr.isNotEmpty() ? (const char*)retStr : nullptr;
  1597. }
  1598. // -------------------------------------------------------------------
  1599. public:
  1600. static size_t getPluginCount()
  1601. {
  1602. return sPluginDescriptors.count();
  1603. }
  1604. static const PluginDescriptor* getPluginDescriptor(const size_t index)
  1605. {
  1606. CARLA_ASSERT(index < sPluginDescriptors.count());
  1607. if (index < sPluginDescriptors.count())
  1608. return sPluginDescriptors.getAt(index);
  1609. return nullptr;
  1610. }
  1611. static void registerPlugin(const PluginDescriptor* desc)
  1612. {
  1613. sPluginDescriptors.append(desc);
  1614. }
  1615. // -------------------------------------------------------------------
  1616. bool init(const char* const name, const char* const label)
  1617. {
  1618. CARLA_ASSERT(kData->engine != nullptr);
  1619. CARLA_ASSERT(kData->client == nullptr);
  1620. CARLA_ASSERT(label != nullptr);
  1621. // ---------------------------------------------------------------
  1622. // first checks
  1623. if (kData->engine == nullptr)
  1624. {
  1625. return false;
  1626. }
  1627. if (kData->client != nullptr)
  1628. {
  1629. kData->engine->setLastError("Plugin client is already registered");
  1630. return false;
  1631. }
  1632. if (label == nullptr)
  1633. {
  1634. kData->engine->setLastError("null label");
  1635. return false;
  1636. }
  1637. // ---------------------------------------------------------------
  1638. // get descriptor that matches label
  1639. for (auto it = sPluginDescriptors.begin(); it.valid(); it.next())
  1640. {
  1641. fDescriptor = *it;
  1642. CARLA_ASSERT(fDescriptor != nullptr);
  1643. if (fDescriptor == nullptr)
  1644. break;
  1645. if (fDescriptor->label != nullptr && std::strcmp(fDescriptor->label, label) == 0)
  1646. break;
  1647. fDescriptor = nullptr;
  1648. }
  1649. if (fDescriptor == nullptr)
  1650. {
  1651. kData->engine->setLastError("Invalid internal plugin");
  1652. return false;
  1653. }
  1654. // ---------------------------------------------------------------
  1655. // get info
  1656. if (name != nullptr)
  1657. fName = kData->engine->getUniquePluginName(name);
  1658. else if (fDescriptor->name != nullptr)
  1659. fName = kData->engine->getUniquePluginName(fDescriptor->name);
  1660. else
  1661. fName = kData->engine->getUniquePluginName(label);
  1662. {
  1663. CARLA_ASSERT(fHost.ui_name == nullptr);
  1664. char uiName[fName.length()+6+1];
  1665. std::strcpy(uiName, (const char*)fName);
  1666. std::strcat(uiName, " (GUI)");
  1667. fHost.ui_name = carla_strdup(uiName);
  1668. }
  1669. // ---------------------------------------------------------------
  1670. // register client
  1671. kData->client = kData->engine->addClient(this);
  1672. if (kData->client == nullptr || ! kData->client->isOk())
  1673. {
  1674. kData->engine->setLastError("Failed to register plugin client");
  1675. return false;
  1676. }
  1677. // ---------------------------------------------------------------
  1678. // initialize plugin
  1679. fHandle = fDescriptor->instantiate(fDescriptor, &fHost);
  1680. if (fHandle == nullptr)
  1681. {
  1682. kData->engine->setLastError("Plugin failed to initialize");
  1683. return false;
  1684. }
  1685. // ---------------------------------------------------------------
  1686. // load plugin settings
  1687. {
  1688. // set default options
  1689. fOptions = 0x0;
  1690. fOptions |= PLUGIN_OPTION_FIXED_BUFFER;
  1691. fOptions |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  1692. if (kData->engine->getOptions().forceStereo)
  1693. fOptions |= PLUGIN_OPTION_FORCE_STEREO;
  1694. if (fDescriptor->midiIns > 0)
  1695. {
  1696. fOptions |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  1697. fOptions |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  1698. fOptions |= PLUGIN_OPTION_SEND_PITCHBEND;
  1699. fOptions |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  1700. }
  1701. // load settings
  1702. kData->idStr = "Native/";
  1703. kData->idStr += label;
  1704. fOptions = kData->loadSettings(fOptions, availableOptions());
  1705. }
  1706. return true;
  1707. }
  1708. class ScopedInitializer
  1709. {
  1710. public:
  1711. ScopedInitializer()
  1712. {
  1713. carla_register_all_plugins();
  1714. }
  1715. ~ScopedInitializer()
  1716. {
  1717. sPluginDescriptors.clear();
  1718. }
  1719. };
  1720. private:
  1721. PluginHandle fHandle;
  1722. PluginHandle fHandle2;
  1723. HostDescriptor fHost;
  1724. const PluginDescriptor* fDescriptor;
  1725. bool fIsProcessing;
  1726. bool fIsUiVisible;
  1727. float** fAudioInBuffers;
  1728. float** fAudioOutBuffers;
  1729. uint32_t fMidiEventCount;
  1730. ::MidiEvent fMidiEvents[MAX_MIDI_EVENTS*2];
  1731. NativePluginMidiData fMidiIn;
  1732. NativePluginMidiData fMidiOut;
  1733. ::TimeInfo fTimeInfo;
  1734. static NonRtList<const PluginDescriptor*> sPluginDescriptors;
  1735. // -------------------------------------------------------------------
  1736. #define handlePtr ((NativePlugin*)handle)
  1737. static uint32_t carla_host_get_buffer_size(HostHandle handle)
  1738. {
  1739. return handlePtr->handleGetBufferSize();
  1740. }
  1741. static double carla_host_get_sample_rate(HostHandle handle)
  1742. {
  1743. return handlePtr->handleGetSampleRate();
  1744. }
  1745. static const ::TimeInfo* carla_host_get_time_info(HostHandle handle)
  1746. {
  1747. return handlePtr->handleGetTimeInfo();
  1748. }
  1749. static bool carla_host_write_midi_event(HostHandle handle, const ::MidiEvent* event)
  1750. {
  1751. return handlePtr->handleWriteMidiEvent(event);
  1752. }
  1753. static void carla_host_ui_parameter_changed(HostHandle handle, uint32_t index, float value)
  1754. {
  1755. handlePtr->handleUiParameterChanged(index, value);
  1756. }
  1757. static void carla_host_ui_custom_data_changed(HostHandle handle, const char* key, const char* value)
  1758. {
  1759. handlePtr->handleUiCustomDataChanged(key, value);
  1760. }
  1761. static void carla_host_ui_closed(HostHandle handle)
  1762. {
  1763. handlePtr->handleUiClosed();
  1764. }
  1765. static const char* carla_host_ui_open_file(HostHandle handle, bool isDir, const char* title, const char* filter)
  1766. {
  1767. return handlePtr->handleUiOpenFile(isDir, title, filter);
  1768. }
  1769. static const char* carla_host_ui_save_file(HostHandle handle, bool isDir, const char* title, const char* filter)
  1770. {
  1771. return handlePtr->handleUiSaveFile(isDir, title, filter);
  1772. }
  1773. #undef handlePtr
  1774. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NativePlugin)
  1775. };
  1776. NonRtList<const PluginDescriptor*> NativePlugin::sPluginDescriptors;
  1777. static const NativePlugin::ScopedInitializer _si;
  1778. CARLA_BACKEND_END_NAMESPACE
  1779. void carla_register_native_plugin(const PluginDescriptor* desc)
  1780. {
  1781. CARLA_BACKEND_USE_NAMESPACE
  1782. NativePlugin::registerPlugin(desc);
  1783. }
  1784. #else // WANT_NATIVE
  1785. # warning Building without Internal plugin support
  1786. #endif
  1787. CARLA_BACKEND_START_NAMESPACE
  1788. // -----------------------------------------------------------------------
  1789. #ifdef WANT_NATIVE
  1790. size_t CarlaPlugin::getNativePluginCount()
  1791. {
  1792. return NativePlugin::getPluginCount();
  1793. }
  1794. const PluginDescriptor* CarlaPlugin::getNativePluginDescriptor(const size_t index)
  1795. {
  1796. return NativePlugin::getPluginDescriptor(index);
  1797. }
  1798. #endif
  1799. // -----------------------------------------------------------------------
  1800. CarlaPlugin* CarlaPlugin::newNative(const Initializer& init)
  1801. {
  1802. carla_debug("CarlaPlugin::newNative({%p, \"%s\", \"%s\", \"%s\"})", init.engine, init.filename, init.name, init.label);
  1803. #ifdef WANT_NATIVE
  1804. NativePlugin* const plugin(new NativePlugin(init.engine, init.id));
  1805. if (! plugin->init(init.name, init.label))
  1806. {
  1807. delete plugin;
  1808. return nullptr;
  1809. }
  1810. plugin->reload();
  1811. if (init.engine->getProccessMode() == PROCESS_MODE_CONTINUOUS_RACK && ! CarlaPluginProtectedData::canRunInRack(plugin))
  1812. {
  1813. init.engine->setLastError("Carla's rack mode can only work with Mono or Stereo Internal plugins, sorry!");
  1814. delete plugin;
  1815. return nullptr;
  1816. }
  1817. return plugin;
  1818. #else
  1819. init.engine->setLastError("Internal plugins support not available");
  1820. return nullptr;
  1821. #endif
  1822. }
  1823. CARLA_BACKEND_END_NAMESPACE