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

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