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

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