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.

CarlaPluginFluidSynth.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
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
6 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939
  1. /*
  2. * Carla FluidSynth Plugin
  3. * Copyright (C) 2011-2020 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "CarlaPluginInternal.hpp"
  18. #include "CarlaEngine.hpp"
  19. #ifdef HAVE_FLUIDSYNTH
  20. #include "CarlaBackendUtils.hpp"
  21. #include "CarlaMathUtils.hpp"
  22. #include "water/text/StringArray.h"
  23. #include <fluidsynth.h>
  24. #define FLUID_DEFAULT_POLYPHONY 64
  25. using water::String;
  26. using water::StringArray;
  27. CARLA_BACKEND_START_NAMESPACE
  28. // -------------------------------------------------------------------------------------------------------------------
  29. // Fallback data
  30. static const ExternalMidiNote kExternalMidiNoteFallback = { -1, 0, 0 };
  31. // -------------------------------------------------------------------------------------------------------------------
  32. class CarlaPluginFluidSynth : public CarlaPlugin
  33. {
  34. public:
  35. CarlaPluginFluidSynth(CarlaEngine* const engine, const uint id, const bool use16Outs)
  36. : CarlaPlugin(engine, id),
  37. kUse16Outs(use16Outs),
  38. fSettings(nullptr),
  39. fSynth(nullptr),
  40. fSynthId(0),
  41. fAudio16Buffers(nullptr),
  42. fLabel(nullptr)
  43. {
  44. carla_debug("CarlaPluginFluidSynth::CarlaPluginFluidSynth(%p, %i, %s)", engine, id, bool2str(use16Outs));
  45. carla_zeroFloats(fParamBuffers, FluidSynthParametersMax);
  46. carla_fill<int32_t>(fCurMidiProgs, 0, MAX_MIDI_CHANNELS);
  47. // create settings
  48. fSettings = new_fluid_settings();
  49. CARLA_SAFE_ASSERT_RETURN(fSettings != nullptr,);
  50. // define settings
  51. fluid_settings_setint(fSettings, "synth.audio-channels", use16Outs ? 16 : 1);
  52. fluid_settings_setint(fSettings, "synth.audio-groups", use16Outs ? 16 : 1);
  53. fluid_settings_setnum(fSettings, "synth.sample-rate", pData->engine->getSampleRate());
  54. //fluid_settings_setnum(fSettings, "synth.cpu-cores", 2);
  55. fluid_settings_setint(fSettings, "synth.ladspa.active", 0);
  56. fluid_settings_setint(fSettings, "synth.lock-memory", 1);
  57. #if FLUIDSYNTH_VERSION_MAJOR < 2
  58. fluid_settings_setint(fSettings, "synth.parallel-render", 1);
  59. #endif
  60. fluid_settings_setint(fSettings, "synth.threadsafe-api", 0);
  61. #ifdef DEBUG
  62. fluid_settings_setint(fSettings, "synth.verbose", 1);
  63. #endif
  64. // create synth
  65. fSynth = new_fluid_synth(fSettings);
  66. CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,);
  67. initializeFluidDefaultsIfNeeded();
  68. #if FLUIDSYNTH_VERSION_MAJOR < 2
  69. fluid_synth_set_sample_rate(fSynth, static_cast<float>(pData->engine->getSampleRate()));
  70. #endif
  71. // set default values
  72. fluid_synth_set_reverb_on(fSynth, 1);
  73. fluid_synth_set_reverb(fSynth,
  74. sFluidDefaults[FluidSynthReverbRoomSize],
  75. sFluidDefaults[FluidSynthReverbDamp],
  76. sFluidDefaults[FluidSynthReverbWidth],
  77. sFluidDefaults[FluidSynthReverbLevel]);
  78. fluid_synth_set_chorus_on(fSynth, 1);
  79. fluid_synth_set_chorus(fSynth,
  80. static_cast<int>(sFluidDefaults[FluidSynthChorusNr] + 0.5f),
  81. sFluidDefaults[FluidSynthChorusLevel],
  82. sFluidDefaults[FluidSynthChorusSpeedHz],
  83. sFluidDefaults[FluidSynthChorusDepthMs],
  84. static_cast<int>(sFluidDefaults[FluidSynthChorusType] + 0.5f));
  85. fluid_synth_set_polyphony(fSynth, FLUID_DEFAULT_POLYPHONY);
  86. fluid_synth_set_gain(fSynth, 1.0f);
  87. for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
  88. fluid_synth_set_interp_method(fSynth, i, static_cast<int>(sFluidDefaults[FluidSynthInterpolation] + 0.5f));
  89. }
  90. ~CarlaPluginFluidSynth() override
  91. {
  92. carla_debug("CarlaPluginFluidSynth::~CarlaPluginFluidSynth()");
  93. pData->singleMutex.lock();
  94. pData->masterMutex.lock();
  95. if (pData->client != nullptr && pData->client->isActive())
  96. pData->client->deactivate(true);
  97. if (pData->active)
  98. {
  99. deactivate();
  100. pData->active = false;
  101. }
  102. if (fSynth != nullptr)
  103. {
  104. delete_fluid_synth(fSynth);
  105. fSynth = nullptr;
  106. }
  107. if (fSettings != nullptr)
  108. {
  109. delete_fluid_settings(fSettings);
  110. fSettings = nullptr;
  111. }
  112. if (fLabel != nullptr)
  113. {
  114. delete[] fLabel;
  115. fLabel = nullptr;
  116. }
  117. clearBuffers();
  118. }
  119. // -------------------------------------------------------------------
  120. // Information (base)
  121. PluginType getType() const noexcept override
  122. {
  123. return PLUGIN_SF2;
  124. }
  125. PluginCategory getCategory() const noexcept override
  126. {
  127. return PLUGIN_CATEGORY_SYNTH;
  128. }
  129. // -------------------------------------------------------------------
  130. // Information (count)
  131. uint32_t getParameterScalePointCount(const uint32_t parameterId) const noexcept override
  132. {
  133. switch (parameterId)
  134. {
  135. case FluidSynthChorusType:
  136. return 2;
  137. case FluidSynthInterpolation:
  138. return 4;
  139. default:
  140. return 0;
  141. }
  142. }
  143. // -------------------------------------------------------------------
  144. // Information (current data)
  145. // nothing
  146. // -------------------------------------------------------------------
  147. // Information (per-plugin data)
  148. uint getOptionsAvailable() const noexcept override
  149. {
  150. uint options = 0x0;
  151. options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  152. options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  153. options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  154. options |= PLUGIN_OPTION_SEND_PITCHBEND;
  155. options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  156. options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
  157. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  158. options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  159. #endif
  160. return options;
  161. }
  162. float getParameterValue(const uint32_t parameterId) const noexcept override
  163. {
  164. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
  165. return fParamBuffers[parameterId];
  166. }
  167. float getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId) const noexcept override
  168. {
  169. switch (parameterId)
  170. {
  171. case FluidSynthChorusType:
  172. switch (scalePointId)
  173. {
  174. case 0:
  175. return FLUID_CHORUS_MOD_SINE;
  176. case 1:
  177. return FLUID_CHORUS_MOD_TRIANGLE;
  178. default:
  179. return sFluidDefaults[FluidSynthChorusType];
  180. }
  181. case FluidSynthInterpolation:
  182. switch (scalePointId)
  183. {
  184. case 0:
  185. return FLUID_INTERP_NONE;
  186. case 1:
  187. return FLUID_INTERP_LINEAR;
  188. case 2:
  189. return FLUID_INTERP_4THORDER;
  190. case 3:
  191. return FLUID_INTERP_7THORDER;
  192. default:
  193. return sFluidDefaults[FluidSynthInterpolation];
  194. }
  195. default:
  196. return 0.0f;
  197. }
  198. }
  199. bool getLabel(char* const strBuf) const noexcept override
  200. {
  201. if (fLabel != nullptr)
  202. {
  203. std::strncpy(strBuf, fLabel, STR_MAX);
  204. return true;
  205. }
  206. return CarlaPlugin::getLabel(strBuf);
  207. }
  208. bool getMaker(char* const strBuf) const noexcept override
  209. {
  210. std::strncpy(strBuf, "FluidSynth SF2 engine", STR_MAX);
  211. return true;
  212. }
  213. bool getCopyright(char* const strBuf) const noexcept override
  214. {
  215. std::strncpy(strBuf, "GNU GPL v2+", STR_MAX);
  216. return true;
  217. }
  218. bool getRealName(char* const strBuf) const noexcept override
  219. {
  220. return getLabel(strBuf);
  221. }
  222. bool getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
  223. {
  224. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  225. switch (parameterId)
  226. {
  227. case FluidSynthReverbOnOff:
  228. std::strncpy(strBuf, "Reverb On/Off", STR_MAX);
  229. return true;
  230. case FluidSynthReverbRoomSize:
  231. std::strncpy(strBuf, "Reverb Room Size", STR_MAX);
  232. return true;
  233. case FluidSynthReverbDamp:
  234. std::strncpy(strBuf, "Reverb Damp", STR_MAX);
  235. return true;
  236. case FluidSynthReverbLevel:
  237. std::strncpy(strBuf, "Reverb Level", STR_MAX);
  238. return true;
  239. case FluidSynthReverbWidth:
  240. std::strncpy(strBuf, "Reverb Width", STR_MAX);
  241. return true;
  242. case FluidSynthChorusOnOff:
  243. std::strncpy(strBuf, "Chorus On/Off", STR_MAX);
  244. return true;
  245. case FluidSynthChorusNr:
  246. std::strncpy(strBuf, "Chorus Voice Count", STR_MAX);
  247. return true;
  248. case FluidSynthChorusLevel:
  249. std::strncpy(strBuf, "Chorus Level", STR_MAX);
  250. return true;
  251. case FluidSynthChorusSpeedHz:
  252. std::strncpy(strBuf, "Chorus Speed", STR_MAX);
  253. return true;
  254. case FluidSynthChorusDepthMs:
  255. std::strncpy(strBuf, "Chorus Depth", STR_MAX);
  256. return true;
  257. case FluidSynthChorusType:
  258. std::strncpy(strBuf, "Chorus Type", STR_MAX);
  259. return true;
  260. case FluidSynthPolyphony:
  261. std::strncpy(strBuf, "Polyphony", STR_MAX);
  262. return true;
  263. case FluidSynthInterpolation:
  264. std::strncpy(strBuf, "Interpolation", STR_MAX);
  265. return true;
  266. case FluidSynthVoiceCount:
  267. std::strncpy(strBuf, "Voice Count", STR_MAX);
  268. return true;
  269. }
  270. return CarlaPlugin::getParameterName(parameterId, strBuf);
  271. }
  272. bool getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
  273. {
  274. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  275. switch (parameterId)
  276. {
  277. case FluidSynthChorusSpeedHz:
  278. std::strncpy(strBuf, "Hz", STR_MAX);
  279. return true;
  280. case FluidSynthChorusDepthMs:
  281. std::strncpy(strBuf, "ms", STR_MAX);
  282. return true;
  283. }
  284. return CarlaPlugin::getParameterUnit(parameterId, strBuf);
  285. }
  286. bool getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf) const noexcept override
  287. {
  288. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
  289. CARLA_SAFE_ASSERT_RETURN(scalePointId < getParameterScalePointCount(parameterId), false);
  290. switch (parameterId)
  291. {
  292. case FluidSynthChorusType:
  293. switch (scalePointId)
  294. {
  295. case 0:
  296. std::strncpy(strBuf, "Sine wave", STR_MAX);
  297. return true;
  298. case 1:
  299. std::strncpy(strBuf, "Triangle wave", STR_MAX);
  300. return true;
  301. }
  302. break;
  303. case FluidSynthInterpolation:
  304. switch (scalePointId)
  305. {
  306. case 0:
  307. std::strncpy(strBuf, "None", STR_MAX);
  308. return true;
  309. case 1:
  310. std::strncpy(strBuf, "Straight-line", STR_MAX);
  311. return true;
  312. case 2:
  313. std::strncpy(strBuf, "Fourth-order", STR_MAX);
  314. return true;
  315. case 3:
  316. std::strncpy(strBuf, "Seventh-order", STR_MAX);
  317. return true;
  318. }
  319. break;
  320. }
  321. return CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf);
  322. }
  323. // -------------------------------------------------------------------
  324. // Set data (state)
  325. void prepareForSave(bool) override
  326. {
  327. char strBuf[STR_MAX+1];
  328. std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i:%i",
  329. fCurMidiProgs[0], fCurMidiProgs[1], fCurMidiProgs[2], fCurMidiProgs[3],
  330. fCurMidiProgs[4], fCurMidiProgs[5], fCurMidiProgs[6], fCurMidiProgs[7],
  331. fCurMidiProgs[8], fCurMidiProgs[9], fCurMidiProgs[10], fCurMidiProgs[11],
  332. fCurMidiProgs[12], fCurMidiProgs[13], fCurMidiProgs[14], fCurMidiProgs[15]);
  333. CarlaPlugin::setCustomData(CUSTOM_DATA_TYPE_STRING, "midiPrograms", strBuf, false);
  334. }
  335. // -------------------------------------------------------------------
  336. // Set data (internal stuff)
  337. void setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) noexcept override
  338. {
  339. if (channel >= 0 && channel < MAX_MIDI_CHANNELS)
  340. pData->midiprog.current = fCurMidiProgs[channel];
  341. CarlaPlugin::setCtrlChannel(channel, sendOsc, sendCallback);
  342. }
  343. // -------------------------------------------------------------------
  344. // Set data (plugin-specific stuff)
  345. void setParameterValue(const uint32_t parameterId, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
  346. {
  347. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
  348. CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback,);
  349. float fixedValue;
  350. {
  351. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  352. fixedValue = setParameterValueInFluidSynth(parameterId, value);
  353. }
  354. CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
  355. }
  356. void setParameterValueRT(const uint32_t parameterId, const float value, const bool sendCallbackLater) noexcept override
  357. {
  358. const float fixedValue = setParameterValueInFluidSynth(parameterId, value);
  359. CarlaPlugin::setParameterValueRT(parameterId, fixedValue, sendCallbackLater);
  360. }
  361. float setParameterValueInFluidSynth(const uint32_t parameterId, const float value) noexcept
  362. {
  363. CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, value);
  364. const float fixedValue(pData->param.getFixedValue(parameterId, value));
  365. fParamBuffers[parameterId] = fixedValue;
  366. switch (parameterId)
  367. {
  368. case FluidSynthReverbOnOff:
  369. try {
  370. fluid_synth_set_reverb_on(fSynth, (fixedValue > 0.5f) ? 1 : 0);
  371. } CARLA_SAFE_EXCEPTION("fluid_synth_set_reverb_on")
  372. break;
  373. case FluidSynthReverbRoomSize:
  374. case FluidSynthReverbDamp:
  375. case FluidSynthReverbLevel:
  376. case FluidSynthReverbWidth:
  377. try {
  378. fluid_synth_set_reverb(fSynth,
  379. fParamBuffers[FluidSynthReverbRoomSize],
  380. fParamBuffers[FluidSynthReverbDamp],
  381. fParamBuffers[FluidSynthReverbWidth],
  382. fParamBuffers[FluidSynthReverbLevel]);
  383. } CARLA_SAFE_EXCEPTION("fluid_synth_set_reverb")
  384. break;
  385. case FluidSynthChorusOnOff:
  386. try {
  387. fluid_synth_set_chorus_on(fSynth, (value > 0.5f) ? 1 : 0);
  388. } CARLA_SAFE_EXCEPTION("fluid_synth_set_chorus_on")
  389. break;
  390. case FluidSynthChorusNr:
  391. case FluidSynthChorusLevel:
  392. case FluidSynthChorusSpeedHz:
  393. case FluidSynthChorusDepthMs:
  394. case FluidSynthChorusType:
  395. try {
  396. fluid_synth_set_chorus(fSynth,
  397. static_cast<int>(fParamBuffers[FluidSynthChorusNr] + 0.5f),
  398. fParamBuffers[FluidSynthChorusLevel],
  399. fParamBuffers[FluidSynthChorusSpeedHz],
  400. fParamBuffers[FluidSynthChorusDepthMs],
  401. static_cast<int>(fParamBuffers[FluidSynthChorusType] + 0.5f));
  402. } CARLA_SAFE_EXCEPTION("fluid_synth_set_chorus")
  403. break;
  404. case FluidSynthPolyphony:
  405. try {
  406. fluid_synth_set_polyphony(fSynth, static_cast<int>(value + 0.5f));
  407. } CARLA_SAFE_EXCEPTION("fluid_synth_set_polyphony")
  408. break;
  409. case FluidSynthInterpolation:
  410. for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
  411. {
  412. try {
  413. fluid_synth_set_interp_method(fSynth, i, static_cast<int>(value + 0.5f));
  414. } CARLA_SAFE_EXCEPTION_BREAK("fluid_synth_set_interp_method")
  415. }
  416. break;
  417. default:
  418. break;
  419. }
  420. return fixedValue;
  421. }
  422. void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override
  423. {
  424. CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,);
  425. CARLA_SAFE_ASSERT_RETURN(type != nullptr && type[0] != '\0',);
  426. CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',);
  427. CARLA_SAFE_ASSERT_RETURN(value != nullptr && value[0] != '\0',);
  428. carla_debug("CarlaPluginFluidSynth::setCustomData(%s, \"%s\", \"%s\", %s)", type, key, value, bool2str(sendGui));
  429. if (std::strcmp(type, CUSTOM_DATA_TYPE_PROPERTY) == 0)
  430. return CarlaPlugin::setCustomData(type, key, value, sendGui);
  431. if (std::strcmp(type, CUSTOM_DATA_TYPE_STRING) != 0)
  432. return carla_stderr2("CarlaPluginFluidSynth::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui));
  433. if (std::strcmp(key, "midiPrograms") != 0)
  434. return carla_stderr2("CarlaPluginFluidSynth::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is not string", type, key, value, bool2str(sendGui));
  435. StringArray midiProgramList(StringArray::fromTokens(value, ":", ""));
  436. if (midiProgramList.size() == MAX_MIDI_CHANNELS)
  437. {
  438. uint8_t channel = 0;
  439. for (String *it=midiProgramList.begin(), *end=midiProgramList.end(); it != end; ++it)
  440. {
  441. const int index(it->getIntValue());
  442. if (index >= 0 && index < static_cast<int>(pData->midiprog.count))
  443. {
  444. const uint32_t bank = pData->midiprog.data[index].bank;
  445. const uint32_t program = pData->midiprog.data[index].program;
  446. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  447. fluid_synth_program_select(fSynth,
  448. static_cast<int>(channel),
  449. fSynthId,
  450. static_cast<int>(bank),
  451. static_cast<int>(program));
  452. #else
  453. fluid_synth_program_select(fSynth, channel, fSynthId, bank, program);
  454. #endif
  455. fCurMidiProgs[channel] = index;
  456. if (pData->ctrlChannel == static_cast<int32_t>(channel))
  457. {
  458. pData->midiprog.current = index;
  459. pData->engine->callback(true, true,
  460. ENGINE_CALLBACK_MIDI_PROGRAM_CHANGED,
  461. pData->id,
  462. index,
  463. 0, 0, 0.0f, nullptr);
  464. }
  465. }
  466. ++channel;
  467. }
  468. CARLA_SAFE_ASSERT(channel == MAX_MIDI_CHANNELS);
  469. }
  470. CarlaPlugin::setCustomData(type, key, value, sendGui);
  471. }
  472. void setMidiProgram(const int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool doingInit) noexcept override
  473. {
  474. CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,);
  475. CARLA_SAFE_ASSERT_RETURN(index >= -1 && index < static_cast<int32_t>(pData->midiprog.count),);
  476. CARLA_SAFE_ASSERT_RETURN(sendGui || sendOsc || sendCallback || doingInit,);
  477. if (index >= 0 && pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  478. {
  479. const uint32_t bank = pData->midiprog.data[index].bank;
  480. const uint32_t program = pData->midiprog.data[index].program;
  481. const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
  482. try {
  483. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  484. fluid_synth_program_select(fSynth, pData->ctrlChannel, fSynthId,
  485. static_cast<int>(bank), static_cast<int>(program));
  486. #else
  487. fluid_synth_program_select(fSynth, pData->ctrlChannel, fSynthId, bank, program);
  488. #endif
  489. } CARLA_SAFE_EXCEPTION("fluid_synth_program_select")
  490. fCurMidiProgs[pData->ctrlChannel] = index;
  491. }
  492. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, doingInit);
  493. }
  494. // FIXME: this is never used
  495. void setMidiProgramRT(const uint32_t uindex, const bool sendCallbackLater) noexcept override
  496. {
  497. CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,);
  498. CARLA_SAFE_ASSERT_RETURN(uindex < pData->midiprog.count,);
  499. if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  500. {
  501. const uint32_t bank = pData->midiprog.data[uindex].bank;
  502. const uint32_t program = pData->midiprog.data[uindex].program;
  503. try {
  504. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  505. fluid_synth_program_select(fSynth, pData->ctrlChannel, fSynthId,
  506. static_cast<int>(bank), static_cast<int>(program));
  507. #else
  508. fluid_synth_program_select(fSynth, pData->ctrlChannel, fSynthId, bank, program);
  509. #endif
  510. } CARLA_SAFE_EXCEPTION("fluid_synth_program_select")
  511. fCurMidiProgs[pData->ctrlChannel] = static_cast<int32_t>(uindex);
  512. }
  513. CarlaPlugin::setMidiProgramRT(uindex, sendCallbackLater);
  514. }
  515. // -------------------------------------------------------------------
  516. // Set ui stuff
  517. // nothing
  518. // -------------------------------------------------------------------
  519. // Plugin state
  520. void reload() override
  521. {
  522. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
  523. CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,);
  524. carla_debug("CarlaPluginFluidSynth::reload() - start");
  525. const EngineProcessMode processMode(pData->engine->getProccessMode());
  526. // Safely disable plugin for reload
  527. const ScopedDisabler sd(this);
  528. if (pData->active)
  529. deactivate();
  530. clearBuffers();
  531. uint32_t aOuts, params;
  532. aOuts = kUse16Outs ? 32 : 2;
  533. params = FluidSynthParametersMax;
  534. pData->audioOut.createNew(aOuts);
  535. pData->param.createNew(params, false);
  536. const uint portNameSize(pData->engine->getMaxPortNameSize());
  537. CarlaString portName;
  538. // ---------------------------------------
  539. // Audio Outputs
  540. if (kUse16Outs)
  541. {
  542. for (uint32_t i=0; i < 32; ++i)
  543. {
  544. portName.clear();
  545. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  546. {
  547. portName = pData->name;
  548. portName += ":";
  549. }
  550. portName += "out-";
  551. if ((i+2)/2 < 9)
  552. portName += "0";
  553. portName += CarlaString((i+2)/2);
  554. if (i % 2 == 0)
  555. portName += "L";
  556. else
  557. portName += "R";
  558. portName.truncate(portNameSize);
  559. pData->audioOut.ports[i].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, i);
  560. pData->audioOut.ports[i].rindex = i;
  561. }
  562. fAudio16Buffers = new float*[aOuts];
  563. for (uint32_t i=0; i < aOuts; ++i)
  564. fAudio16Buffers[i] = nullptr;
  565. }
  566. else
  567. {
  568. // out-left
  569. portName.clear();
  570. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  571. {
  572. portName = pData->name;
  573. portName += ":";
  574. }
  575. portName += "out-left";
  576. portName.truncate(portNameSize);
  577. pData->audioOut.ports[0].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, 0);
  578. pData->audioOut.ports[0].rindex = 0;
  579. // out-right
  580. portName.clear();
  581. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  582. {
  583. portName = pData->name;
  584. portName += ":";
  585. }
  586. portName += "out-right";
  587. portName.truncate(portNameSize);
  588. pData->audioOut.ports[1].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, 1);
  589. pData->audioOut.ports[1].rindex = 1;
  590. }
  591. // ---------------------------------------
  592. // Event Input
  593. {
  594. portName.clear();
  595. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  596. {
  597. portName = pData->name;
  598. portName += ":";
  599. }
  600. portName += "events-in";
  601. portName.truncate(portNameSize);
  602. pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
  603. }
  604. // ---------------------------------------
  605. // Event Output
  606. {
  607. portName.clear();
  608. if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
  609. {
  610. portName = pData->name;
  611. portName += ":";
  612. }
  613. portName += "events-out";
  614. portName.truncate(portNameSize);
  615. pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
  616. }
  617. // ---------------------------------------
  618. // Parameters
  619. {
  620. int j;
  621. // ----------------------
  622. j = FluidSynthReverbOnOff;
  623. pData->param.data[j].type = PARAMETER_INPUT;
  624. pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/ | PARAMETER_IS_BOOLEAN;
  625. pData->param.data[j].index = j;
  626. pData->param.data[j].rindex = j;
  627. pData->param.ranges[j].min = 0.0f;
  628. pData->param.ranges[j].max = 1.0f;
  629. pData->param.ranges[j].def = sFluidDefaults[j];
  630. pData->param.ranges[j].step = 1.0f;
  631. pData->param.ranges[j].stepSmall = 1.0f;
  632. pData->param.ranges[j].stepLarge = 1.0f;
  633. // ----------------------
  634. j = FluidSynthReverbRoomSize;
  635. pData->param.data[j].type = PARAMETER_INPUT;
  636. pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/;
  637. pData->param.data[j].index = j;
  638. pData->param.data[j].rindex = j;
  639. pData->param.ranges[j].min = 0.0f;
  640. pData->param.ranges[j].max = 1.0f;
  641. pData->param.ranges[j].def = sFluidDefaults[j];
  642. pData->param.ranges[j].step = 0.01f;
  643. pData->param.ranges[j].stepSmall = 0.0001f;
  644. pData->param.ranges[j].stepLarge = 0.1f;
  645. // ----------------------
  646. j = FluidSynthReverbDamp;
  647. pData->param.data[j].type = PARAMETER_INPUT;
  648. pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/;
  649. pData->param.data[j].index = j;
  650. pData->param.data[j].rindex = j;
  651. pData->param.ranges[j].min = 0.0f;
  652. pData->param.ranges[j].max = 1.0f;
  653. pData->param.ranges[j].def = sFluidDefaults[j];
  654. pData->param.ranges[j].step = 0.01f;
  655. pData->param.ranges[j].stepSmall = 0.0001f;
  656. pData->param.ranges[j].stepLarge = 0.1f;
  657. // ----------------------
  658. j = FluidSynthReverbLevel;
  659. pData->param.data[j].type = PARAMETER_INPUT;
  660. pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/;
  661. pData->param.data[j].index = j;
  662. pData->param.data[j].rindex = j;
  663. pData->param.data[j].mappedControlIndex = MIDI_CONTROL_REVERB_SEND_LEVEL;
  664. pData->param.ranges[j].min = 0.0f;
  665. pData->param.ranges[j].max = 1.0f;
  666. pData->param.ranges[j].def = sFluidDefaults[j];
  667. pData->param.ranges[j].step = 0.01f;
  668. pData->param.ranges[j].stepSmall = 0.0001f;
  669. pData->param.ranges[j].stepLarge = 0.1f;
  670. // ----------------------
  671. j = FluidSynthReverbWidth;
  672. pData->param.data[j].type = PARAMETER_INPUT;
  673. pData->param.data[j].hints = PARAMETER_IS_ENABLED /*| PARAMETER_IS_AUTOMABLE*/;
  674. pData->param.data[j].index = j;
  675. pData->param.data[j].rindex = j;
  676. pData->param.ranges[j].min = 0.0f;
  677. pData->param.ranges[j].max = 10.0f; // should be 100, but that sounds too much
  678. pData->param.ranges[j].def = sFluidDefaults[j];
  679. pData->param.ranges[j].step = 0.01f;
  680. pData->param.ranges[j].stepSmall = 0.0001f;
  681. pData->param.ranges[j].stepLarge = 0.1f;
  682. // ----------------------
  683. j = FluidSynthChorusOnOff;
  684. pData->param.data[j].type = PARAMETER_INPUT;
  685. pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_BOOLEAN;
  686. pData->param.data[j].index = j;
  687. pData->param.data[j].rindex = j;
  688. pData->param.ranges[j].min = 0.0f;
  689. pData->param.ranges[j].max = 1.0f;
  690. pData->param.ranges[j].def = sFluidDefaults[j];
  691. pData->param.ranges[j].step = 1.0f;
  692. pData->param.ranges[j].stepSmall = 1.0f;
  693. pData->param.ranges[j].stepLarge = 1.0f;
  694. // ----------------------
  695. j = FluidSynthChorusNr;
  696. pData->param.data[j].type = PARAMETER_INPUT;
  697. pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER;
  698. pData->param.data[j].index = j;
  699. pData->param.data[j].rindex = j;
  700. pData->param.ranges[j].min = 0.0f;
  701. pData->param.ranges[j].max = 99.0f;
  702. pData->param.ranges[j].def = sFluidDefaults[j];
  703. pData->param.ranges[j].step = 1.0f;
  704. pData->param.ranges[j].stepSmall = 1.0f;
  705. pData->param.ranges[j].stepLarge = 10.0f;
  706. // ----------------------
  707. j = FluidSynthChorusLevel;
  708. pData->param.data[j].type = PARAMETER_INPUT;
  709. pData->param.data[j].hints = PARAMETER_IS_ENABLED;
  710. pData->param.data[j].index = j;
  711. pData->param.data[j].rindex = j;
  712. pData->param.ranges[j].min = 0.0f;
  713. pData->param.ranges[j].max = 10.0f;
  714. pData->param.ranges[j].def = sFluidDefaults[j];
  715. pData->param.ranges[j].step = 0.01f;
  716. pData->param.ranges[j].stepSmall = 0.0001f;
  717. pData->param.ranges[j].stepLarge = 0.1f;
  718. // ----------------------
  719. j = FluidSynthChorusSpeedHz;
  720. pData->param.data[j].type = PARAMETER_INPUT;
  721. pData->param.data[j].hints = PARAMETER_IS_ENABLED;
  722. pData->param.data[j].index = j;
  723. pData->param.data[j].rindex = j;
  724. pData->param.ranges[j].min = 0.29f;
  725. pData->param.ranges[j].max = 5.0f;
  726. pData->param.ranges[j].def = sFluidDefaults[j];
  727. pData->param.ranges[j].step = 0.01f;
  728. pData->param.ranges[j].stepSmall = 0.0001f;
  729. pData->param.ranges[j].stepLarge = 0.1f;
  730. // ----------------------
  731. j = FluidSynthChorusDepthMs;
  732. pData->param.data[j].type = PARAMETER_INPUT;
  733. pData->param.data[j].hints = PARAMETER_IS_ENABLED;
  734. pData->param.data[j].index = j;
  735. pData->param.data[j].rindex = j;
  736. pData->param.ranges[j].min = 0.0f;
  737. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  738. pData->param.ranges[j].max = 256.0f;
  739. #else
  740. pData->param.ranges[j].max = float(2048.0 * 1000.0 / pData->engine->getSampleRate()); // FIXME?
  741. #endif
  742. pData->param.ranges[j].def = sFluidDefaults[j];
  743. pData->param.ranges[j].step = 0.01f;
  744. pData->param.ranges[j].stepSmall = 0.0001f;
  745. pData->param.ranges[j].stepLarge = 0.1f;
  746. // ----------------------
  747. j = FluidSynthChorusType;
  748. pData->param.data[j].type = PARAMETER_INPUT;
  749. pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER | PARAMETER_USES_SCALEPOINTS;
  750. pData->param.data[j].index = j;
  751. pData->param.data[j].rindex = j;
  752. pData->param.ranges[j].min = FLUID_CHORUS_MOD_SINE;
  753. pData->param.ranges[j].max = FLUID_CHORUS_MOD_TRIANGLE;
  754. pData->param.ranges[j].def = sFluidDefaults[j];
  755. pData->param.ranges[j].step = 1.0f;
  756. pData->param.ranges[j].stepSmall = 1.0f;
  757. pData->param.ranges[j].stepLarge = 1.0f;
  758. // ----------------------
  759. j = FluidSynthPolyphony;
  760. pData->param.data[j].type = PARAMETER_INPUT;
  761. pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER;
  762. pData->param.data[j].index = j;
  763. pData->param.data[j].rindex = j;
  764. pData->param.ranges[j].min = 1.0f;
  765. pData->param.ranges[j].max = 512.0f; // max theoric is 65535
  766. pData->param.ranges[j].def = sFluidDefaults[j];
  767. pData->param.ranges[j].step = 1.0f;
  768. pData->param.ranges[j].stepSmall = 1.0f;
  769. pData->param.ranges[j].stepLarge = 10.0f;
  770. // ----------------------
  771. j = FluidSynthInterpolation;
  772. pData->param.data[j].type = PARAMETER_INPUT;
  773. pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER | PARAMETER_USES_SCALEPOINTS;
  774. pData->param.data[j].index = j;
  775. pData->param.data[j].rindex = j;
  776. pData->param.ranges[j].min = FLUID_INTERP_NONE;
  777. pData->param.ranges[j].max = FLUID_INTERP_HIGHEST;
  778. pData->param.ranges[j].def = sFluidDefaults[j];
  779. pData->param.ranges[j].step = 1.0f;
  780. pData->param.ranges[j].stepSmall = 1.0f;
  781. pData->param.ranges[j].stepLarge = 1.0f;
  782. // ----------------------
  783. j = FluidSynthVoiceCount;
  784. pData->param.data[j].type = PARAMETER_OUTPUT;
  785. pData->param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE | PARAMETER_IS_INTEGER;
  786. pData->param.data[j].index = j;
  787. pData->param.data[j].rindex = j;
  788. pData->param.ranges[j].min = 0.0f;
  789. pData->param.ranges[j].max = 65535.0f;
  790. pData->param.ranges[j].def = 0.0f;
  791. pData->param.ranges[j].step = 1.0f;
  792. pData->param.ranges[j].stepSmall = 1.0f;
  793. pData->param.ranges[j].stepLarge = 1.0f;
  794. for (j=0; j<FluidSynthParametersMax; ++j)
  795. fParamBuffers[j] = pData->param.ranges[j].def;
  796. }
  797. // ---------------------------------------
  798. // plugin hints
  799. pData->hints = 0x0;
  800. pData->hints |= PLUGIN_IS_SYNTH;
  801. pData->hints |= PLUGIN_CAN_VOLUME;
  802. pData->hints |= PLUGIN_USES_MULTI_PROGS;
  803. if (! kUse16Outs)
  804. pData->hints |= PLUGIN_CAN_BALANCE;
  805. // extra plugin hints
  806. pData->extraHints = 0x0;
  807. pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
  808. bufferSizeChanged(pData->engine->getBufferSize());
  809. reloadPrograms(true);
  810. if (pData->active)
  811. activate();
  812. carla_debug("CarlaPluginFluidSynth::reload() - end");
  813. }
  814. void reloadPrograms(const bool doInit) override
  815. {
  816. carla_debug("CarlaPluginFluidSynth::reloadPrograms(%s)", bool2str(doInit));
  817. // save drum info in case we have one program for it
  818. bool hasDrums = false;
  819. uint32_t drumIndex, drumProg;
  820. drumIndex = drumProg = 0;
  821. // Delete old programs
  822. pData->midiprog.clear();
  823. // Query new programs
  824. uint32_t count = 0;
  825. if (fluid_sfont_t* const f_sfont = fluid_synth_get_sfont_by_id(fSynth, fSynthId))
  826. {
  827. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  828. fluid_preset_t* f_preset;
  829. // initial check to know how many midi-programs we have
  830. fluid_sfont_iteration_start(f_sfont);
  831. for (; fluid_sfont_iteration_next(f_sfont);)
  832. ++count;
  833. // sound kits must always have at least 1 midi-program
  834. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  835. pData->midiprog.createNew(count);
  836. // Update data
  837. int tmp;
  838. uint32_t i = 0;
  839. fluid_sfont_iteration_start(f_sfont);
  840. for (; (f_preset = fluid_sfont_iteration_next(f_sfont));)
  841. {
  842. CARLA_SAFE_ASSERT_BREAK(i < count);
  843. tmp = fluid_preset_get_banknum(f_preset);
  844. pData->midiprog.data[i].bank = (tmp >= 0) ? static_cast<uint32_t>(tmp) : 0;
  845. tmp = fluid_preset_get_num(f_preset);
  846. pData->midiprog.data[i].program = (tmp >= 0) ? static_cast<uint32_t>(tmp) : 0;
  847. pData->midiprog.data[i].name = carla_strdup(fluid_preset_get_name(f_preset));
  848. #else
  849. fluid_preset_t f_preset;
  850. // initial check to know how many midi-programs we have
  851. f_sfont->iteration_start(f_sfont);
  852. for (; f_sfont->iteration_next(f_sfont, &f_preset);)
  853. ++count;
  854. // sound kits must always have at least 1 midi-program
  855. CARLA_SAFE_ASSERT_RETURN(count > 0,);
  856. pData->midiprog.createNew(count);
  857. // Update data
  858. int tmp;
  859. uint32_t i = 0;
  860. f_sfont->iteration_start(f_sfont);
  861. for (; f_sfont->iteration_next(f_sfont, &f_preset);)
  862. {
  863. CARLA_SAFE_ASSERT_BREAK(i < count);
  864. tmp = f_preset.get_banknum(&f_preset);
  865. pData->midiprog.data[i].bank = (tmp >= 0) ? static_cast<uint32_t>(tmp) : 0;
  866. tmp = f_preset.get_num(&f_preset);
  867. pData->midiprog.data[i].program = (tmp >= 0) ? static_cast<uint32_t>(tmp) : 0;
  868. pData->midiprog.data[i].name = carla_strdup(f_preset.get_name(&f_preset));
  869. #endif
  870. if (pData->midiprog.data[i].bank == 128 && ! hasDrums)
  871. {
  872. hasDrums = true;
  873. drumIndex = i;
  874. drumProg = pData->midiprog.data[i].program;
  875. }
  876. ++i;
  877. }
  878. }
  879. else
  880. {
  881. // failing means 0 midi-programs, it shouldn't happen!
  882. carla_safe_assert("fluid_sfont_t* const f_sfont = fluid_synth_get_sfont_by_id(fSynth, fSynthId)", __FILE__, __LINE__);
  883. return;
  884. }
  885. if (doInit)
  886. {
  887. fluid_synth_program_reset(fSynth);
  888. // select first program, or 128 for ch10
  889. for (int i=0; i < MAX_MIDI_CHANNELS && i != 9; ++i)
  890. {
  891. fluid_synth_set_channel_type(fSynth, i, CHANNEL_TYPE_MELODIC);
  892. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  893. fluid_synth_program_select(fSynth, i, fSynthId,
  894. static_cast<int>(pData->midiprog.data[0].bank),
  895. static_cast<int>(pData->midiprog.data[0].program));
  896. #else
  897. fluid_synth_program_select(fSynth, i, fSynthId,
  898. pData->midiprog.data[0].bank, pData->midiprog.data[0].program);
  899. #endif
  900. fCurMidiProgs[i] = 0;
  901. }
  902. if (hasDrums)
  903. {
  904. fluid_synth_set_channel_type(fSynth, 9, CHANNEL_TYPE_DRUM);
  905. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  906. fluid_synth_program_select(fSynth, 9, fSynthId, 128, static_cast<int>(drumProg));
  907. #else
  908. fluid_synth_program_select(fSynth, 9, fSynthId, 128, drumProg);
  909. #endif
  910. fCurMidiProgs[9] = static_cast<int32_t>(drumIndex);
  911. }
  912. else
  913. {
  914. fluid_synth_set_channel_type(fSynth, 9, CHANNEL_TYPE_MELODIC);
  915. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  916. fluid_synth_program_select(fSynth, 9, fSynthId,
  917. static_cast<int>(pData->midiprog.data[0].bank),
  918. static_cast<int>(pData->midiprog.data[0].program));
  919. #else
  920. fluid_synth_program_select(fSynth, 9, fSynthId,
  921. pData->midiprog.data[0].bank, pData->midiprog.data[0].program);
  922. #endif
  923. fCurMidiProgs[9] = 0;
  924. }
  925. pData->midiprog.current = 0;
  926. }
  927. else
  928. {
  929. pData->engine->callback(true, true, ENGINE_CALLBACK_RELOAD_PROGRAMS, pData->id, 0, 0, 0, 0.0f, nullptr);
  930. }
  931. }
  932. // -------------------------------------------------------------------
  933. // Plugin processing
  934. void process(const float* const* const, float** const audioOut,
  935. const float* const*, float**, const uint32_t frames) override
  936. {
  937. // --------------------------------------------------------------------------------------------------------
  938. // Check if active
  939. if (! pData->active)
  940. {
  941. // disable any output sound
  942. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  943. carla_zeroFloats(audioOut[i], frames);
  944. return;
  945. }
  946. // --------------------------------------------------------------------------------------------------------
  947. // Check if needs reset
  948. if (pData->needsReset)
  949. {
  950. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  951. {
  952. for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
  953. {
  954. fluid_synth_all_notes_off(fSynth, i);
  955. fluid_synth_all_sounds_off(fSynth, i);
  956. }
  957. }
  958. else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  959. {
  960. for (int i=0; i < MAX_MIDI_NOTE; ++i)
  961. fluid_synth_noteoff(fSynth, pData->ctrlChannel, i);
  962. }
  963. pData->needsReset = false;
  964. }
  965. // --------------------------------------------------------------------------------------------------------
  966. // Event Input and Processing
  967. {
  968. // ----------------------------------------------------------------------------------------------------
  969. // MIDI Input (External)
  970. if (pData->extNotes.mutex.tryLock())
  971. {
  972. for (RtLinkedList<ExternalMidiNote>::Itenerator it = pData->extNotes.data.begin2(); it.valid(); it.next())
  973. {
  974. const ExternalMidiNote& note(it.getValue(kExternalMidiNoteFallback));
  975. CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
  976. if (note.velo > 0)
  977. fluid_synth_noteon(fSynth, note.channel, note.note, note.velo);
  978. else
  979. fluid_synth_noteoff(fSynth,note.channel, note.note);
  980. }
  981. pData->extNotes.data.clear();
  982. pData->extNotes.mutex.unlock();
  983. } // End of MIDI Input (External)
  984. // ----------------------------------------------------------------------------------------------------
  985. // Event Input (System)
  986. #ifndef BUILD_BRIDGE
  987. bool allNotesOffSent = false;
  988. #endif
  989. uint32_t timeOffset = 0;
  990. uint32_t nextBankIds[MAX_MIDI_CHANNELS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0 };
  991. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0 && pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  992. nextBankIds[pData->ctrlChannel] = pData->midiprog.data[pData->midiprog.current].bank;
  993. for (uint32_t i=0, numEvents=pData->event.portIn->getEventCount(); i < numEvents; ++i)
  994. {
  995. const EngineEvent& event(pData->event.portIn->getEvent(i));
  996. uint32_t eventTime = event.time;
  997. CARLA_SAFE_ASSERT_UINT2_CONTINUE(eventTime < frames, eventTime, frames);
  998. if (eventTime < timeOffset)
  999. {
  1000. carla_stderr2("Timing error, eventTime:%u < timeOffset:%u for '%s'",
  1001. eventTime, timeOffset, pData->name);
  1002. eventTime = timeOffset;
  1003. }
  1004. else if (eventTime > timeOffset)
  1005. {
  1006. if (processSingle(audioOut, eventTime - timeOffset, timeOffset))
  1007. {
  1008. timeOffset = eventTime;
  1009. if (pData->midiprog.current >= 0 && pData->midiprog.count > 0 && pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
  1010. nextBankIds[pData->ctrlChannel] = pData->midiprog.data[pData->midiprog.current].bank;
  1011. }
  1012. }
  1013. // Control change
  1014. switch (event.type)
  1015. {
  1016. case kEngineEventTypeNull:
  1017. break;
  1018. case kEngineEventTypeControl:
  1019. {
  1020. const EngineControlEvent& ctrlEvent = event.ctrl;
  1021. switch (ctrlEvent.type)
  1022. {
  1023. case kEngineControlEventTypeNull:
  1024. break;
  1025. case kEngineControlEventTypeParameter:
  1026. {
  1027. float value;
  1028. #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
  1029. // Control backend stuff
  1030. if (event.channel == pData->ctrlChannel)
  1031. {
  1032. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
  1033. {
  1034. value = ctrlEvent.normalizedValue;
  1035. setDryWetRT(value, true);
  1036. }
  1037. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
  1038. {
  1039. value = ctrlEvent.normalizedValue*127.0f/100.0f;
  1040. setVolumeRT(value, true);
  1041. }
  1042. if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
  1043. {
  1044. float left, right;
  1045. value = ctrlEvent.normalizedValue/0.5f - 1.0f;
  1046. if (value < 0.0f)
  1047. {
  1048. left = -1.0f;
  1049. right = (value*2.0f)+1.0f;
  1050. }
  1051. else if (value > 0.0f)
  1052. {
  1053. left = (value*2.0f)-1.0f;
  1054. right = 1.0f;
  1055. }
  1056. else
  1057. {
  1058. left = -1.0f;
  1059. right = 1.0f;
  1060. }
  1061. setBalanceLeftRT(left, true);
  1062. setBalanceRightRT(right, true);
  1063. }
  1064. }
  1065. #endif
  1066. // Control plugin parameters
  1067. for (uint32_t k=0; k < pData->param.count; ++k)
  1068. {
  1069. if (pData->param.data[k].midiChannel != event.channel)
  1070. continue;
  1071. if (pData->param.data[k].mappedControlIndex != ctrlEvent.param)
  1072. continue;
  1073. if (pData->param.data[k].hints != PARAMETER_INPUT)
  1074. continue;
  1075. if ((pData->param.data[k].hints & PARAMETER_IS_AUTOMABLE) == 0)
  1076. continue;
  1077. value = pData->param.getFinalUnnormalizedValue(k, ctrlEvent.normalizedValue);
  1078. setParameterValueRT(k, value, true);
  1079. }
  1080. if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_VALUE)
  1081. {
  1082. fluid_synth_cc(fSynth, event.channel, ctrlEvent.param, int(ctrlEvent.normalizedValue*127.0f));
  1083. }
  1084. break;
  1085. }
  1086. case kEngineControlEventTypeMidiBank:
  1087. if (event.channel < MAX_MIDI_CHANNELS && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  1088. nextBankIds[event.channel] = ctrlEvent.param;
  1089. break;
  1090. case kEngineControlEventTypeMidiProgram:
  1091. if (event.channel < MAX_MIDI_CHANNELS && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
  1092. {
  1093. const uint32_t bankId(nextBankIds[event.channel]);
  1094. const uint32_t progId(ctrlEvent.param);
  1095. // TODO int32_t midiprog.find(bank, prog)
  1096. for (uint32_t k=0; k < pData->midiprog.count; ++k)
  1097. {
  1098. if (pData->midiprog.data[k].bank == bankId && pData->midiprog.data[k].program == progId)
  1099. {
  1100. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  1101. fluid_synth_program_select(fSynth, event.channel, fSynthId,
  1102. static_cast<int>(bankId), static_cast<int>(progId));
  1103. #else
  1104. fluid_synth_program_select(fSynth, event.channel, fSynthId, bankId, progId);
  1105. #endif
  1106. fCurMidiProgs[event.channel] = static_cast<int32_t>(k);
  1107. if (event.channel == pData->ctrlChannel)
  1108. {
  1109. pData->postponeMidiProgramChangeRtEvent(true, k);
  1110. }
  1111. break;
  1112. }
  1113. }
  1114. }
  1115. break;
  1116. case kEngineControlEventTypeAllSoundOff:
  1117. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1118. fluid_synth_all_sounds_off(fSynth, event.channel);
  1119. break;
  1120. case kEngineControlEventTypeAllNotesOff:
  1121. if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
  1122. {
  1123. #ifndef BUILD_BRIDGE
  1124. if (event.channel == pData->ctrlChannel && ! allNotesOffSent)
  1125. {
  1126. allNotesOffSent = true;
  1127. postponeRtAllNotesOff();
  1128. }
  1129. #endif
  1130. fluid_synth_all_notes_off(fSynth, event.channel);
  1131. }
  1132. break;
  1133. }
  1134. break;
  1135. }
  1136. case kEngineEventTypeMidi: {
  1137. const EngineMidiEvent& midiEvent(event.midi);
  1138. if (midiEvent.size > EngineMidiEvent::kDataSize)
  1139. continue;
  1140. uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data));
  1141. // Fix bad note-off
  1142. if (status == MIDI_STATUS_NOTE_ON && midiEvent.data[2] == 0)
  1143. status = MIDI_STATUS_NOTE_OFF;
  1144. switch (status)
  1145. {
  1146. case MIDI_STATUS_NOTE_OFF:
  1147. if ((pData->options & PLUGIN_OPTION_SKIP_SENDING_NOTES) == 0x0)
  1148. {
  1149. const uint8_t note = midiEvent.data[1];
  1150. fluid_synth_noteoff(fSynth, event.channel, note);
  1151. pData->postponeNoteOffRtEvent(true, event.channel, note);
  1152. }
  1153. break;
  1154. case MIDI_STATUS_NOTE_ON:
  1155. if ((pData->options & PLUGIN_OPTION_SKIP_SENDING_NOTES) == 0x0)
  1156. {
  1157. const uint8_t note = midiEvent.data[1];
  1158. const uint8_t velo = midiEvent.data[2];
  1159. fluid_synth_noteon(fSynth, event.channel, note, velo);
  1160. pData->postponeNoteOnRtEvent(true, event.channel, note, velo);
  1161. }
  1162. break;
  1163. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  1164. case MIDI_STATUS_POLYPHONIC_AFTERTOUCH:
  1165. if (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH)
  1166. {
  1167. const uint8_t note = midiEvent.data[1];
  1168. const uint8_t pressure = midiEvent.data[2];
  1169. fluid_synth_key_pressure(fSynth, event.channel, note, pressure);
  1170. }
  1171. break;
  1172. #endif
  1173. case MIDI_STATUS_CONTROL_CHANGE:
  1174. if (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES)
  1175. {
  1176. const uint8_t control = midiEvent.data[1];
  1177. const uint8_t value = midiEvent.data[2];
  1178. fluid_synth_cc(fSynth, event.channel, control, value);
  1179. }
  1180. break;
  1181. case MIDI_STATUS_CHANNEL_PRESSURE:
  1182. if (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE)
  1183. {
  1184. const uint8_t pressure = midiEvent.data[1];
  1185. fluid_synth_channel_pressure(fSynth, event.channel, pressure);;
  1186. }
  1187. break;
  1188. case MIDI_STATUS_PITCH_WHEEL_CONTROL:
  1189. if (pData->options & PLUGIN_OPTION_SEND_PITCHBEND)
  1190. {
  1191. const uint8_t lsb = midiEvent.data[1];
  1192. const uint8_t msb = midiEvent.data[2];
  1193. const int value = ((msb << 7) | lsb);
  1194. fluid_synth_pitch_bend(fSynth, event.channel, value);
  1195. }
  1196. break;
  1197. default:
  1198. continue;
  1199. break;
  1200. } // switch (status)
  1201. } break;
  1202. } // switch (event.type)
  1203. }
  1204. pData->postRtEvents.trySplice();
  1205. if (frames > timeOffset)
  1206. processSingle(audioOut, frames - timeOffset, timeOffset);
  1207. } // End of Event Input and Processing
  1208. #ifndef BUILD_BRIDGE
  1209. // --------------------------------------------------------------------------------------------------------
  1210. // Control Output
  1211. {
  1212. uint32_t k = FluidSynthVoiceCount;
  1213. fParamBuffers[k] = float(fluid_synth_get_active_voice_count(fSynth));
  1214. pData->param.ranges[k].fixValue(fParamBuffers[k]);
  1215. if (pData->param.data[k].mappedControlIndex > 0)
  1216. {
  1217. float value(pData->param.ranges[k].getNormalizedValue(fParamBuffers[k]));
  1218. pData->event.portOut->writeControlEvent(0,
  1219. pData->param.data[k].midiChannel,
  1220. kEngineControlEventTypeParameter,
  1221. static_cast<uint16_t>(pData->param.data[k].mappedControlIndex),
  1222. -1,
  1223. value);
  1224. }
  1225. } // End of Control Output
  1226. #endif
  1227. }
  1228. bool processSingle(float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
  1229. {
  1230. CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
  1231. CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
  1232. // --------------------------------------------------------------------------------------------------------
  1233. // Try lock, silence otherwise
  1234. #ifndef STOAT_TEST_BUILD
  1235. if (pData->engine->isOffline())
  1236. {
  1237. pData->singleMutex.lock();
  1238. }
  1239. else
  1240. #endif
  1241. if (! pData->singleMutex.tryLock())
  1242. {
  1243. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1244. {
  1245. for (uint32_t k=0; k < frames; ++k)
  1246. outBuffer[i][k+timeOffset] = 0.0f;
  1247. }
  1248. return false;
  1249. }
  1250. // --------------------------------------------------------------------------------------------------------
  1251. // Fill plugin buffers and Run plugin
  1252. if (kUse16Outs)
  1253. {
  1254. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1255. carla_zeroFloats(fAudio16Buffers[i], frames);
  1256. // FIXME use '32' or '16' instead of outs
  1257. fluid_synth_process(fSynth, static_cast<int>(frames),
  1258. 0, nullptr,
  1259. static_cast<int>(pData->audioOut.count), fAudio16Buffers);
  1260. }
  1261. else
  1262. {
  1263. fluid_synth_write_float(fSynth, static_cast<int>(frames),
  1264. outBuffer[0] + timeOffset, 0, 1,
  1265. outBuffer[1] + timeOffset, 0, 1);
  1266. }
  1267. #ifndef BUILD_BRIDGE
  1268. // --------------------------------------------------------------------------------------------------------
  1269. // Post-processing (volume and balance)
  1270. {
  1271. // note - balance not possible with kUse16Outs, so we can safely skip fAudioOutBuffers
  1272. const bool doVolume = (pData->hints & PLUGIN_CAN_VOLUME) != 0 && carla_isNotEqual(pData->postProc.volume, 1.0f);
  1273. const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f));
  1274. float oldBufLeft[doBalance ? frames : 1];
  1275. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1276. {
  1277. // Balance
  1278. if (doBalance)
  1279. {
  1280. if (i % 2 == 0)
  1281. carla_copyFloats(oldBufLeft, outBuffer[i]+timeOffset, frames);
  1282. float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f;
  1283. float balRangeR = (pData->postProc.balanceRight + 1.0f)/2.0f;
  1284. for (uint32_t k=0; k < frames; ++k)
  1285. {
  1286. if (i % 2 == 0)
  1287. {
  1288. // left
  1289. outBuffer[i][k+timeOffset] = oldBufLeft[k] * (1.0f - balRangeL);
  1290. outBuffer[i][k+timeOffset] += outBuffer[i+1][k+timeOffset] * (1.0f - balRangeR);
  1291. }
  1292. else
  1293. {
  1294. // right
  1295. outBuffer[i][k+timeOffset] = outBuffer[i][k+timeOffset] * balRangeR;
  1296. outBuffer[i][k+timeOffset] += oldBufLeft[k] * balRangeL;
  1297. }
  1298. }
  1299. }
  1300. // Volume
  1301. if (kUse16Outs)
  1302. {
  1303. for (uint32_t k=0; k < frames; ++k)
  1304. outBuffer[i][k+timeOffset] = fAudio16Buffers[i][k] * pData->postProc.volume;
  1305. }
  1306. else if (doVolume)
  1307. {
  1308. for (uint32_t k=0; k < frames; ++k)
  1309. outBuffer[i][k+timeOffset] *= pData->postProc.volume;
  1310. }
  1311. }
  1312. } // End of Post-processing
  1313. #else
  1314. if (kUse16Outs)
  1315. {
  1316. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1317. {
  1318. for (uint32_t k=0; k < frames; ++k)
  1319. outBuffer[i][k+timeOffset] = fAudio16Buffers[i][k];
  1320. }
  1321. }
  1322. #endif
  1323. // --------------------------------------------------------------------------------------------------------
  1324. pData->singleMutex.unlock();
  1325. return true;
  1326. }
  1327. void bufferSizeChanged(const uint32_t newBufferSize) override
  1328. {
  1329. if (! kUse16Outs)
  1330. return;
  1331. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1332. {
  1333. if (fAudio16Buffers[i] != nullptr)
  1334. delete[] fAudio16Buffers[i];
  1335. fAudio16Buffers[i] = new float[newBufferSize];
  1336. }
  1337. }
  1338. void sampleRateChanged(const double newSampleRate) override
  1339. {
  1340. CARLA_SAFE_ASSERT_RETURN(fSettings != nullptr,);
  1341. fluid_settings_setnum(fSettings, "synth.sample-rate", newSampleRate);
  1342. #if FLUIDSYNTH_VERSION_MAJOR < 2
  1343. CARLA_SAFE_ASSERT_RETURN(fSynth != nullptr,);
  1344. fluid_synth_set_sample_rate(fSynth, static_cast<float>(newSampleRate));
  1345. #endif
  1346. }
  1347. // -------------------------------------------------------------------
  1348. // Plugin buffers
  1349. void clearBuffers() noexcept override
  1350. {
  1351. carla_debug("CarlaPluginFluidSynth::clearBuffers() - start");
  1352. if (fAudio16Buffers != nullptr)
  1353. {
  1354. for (uint32_t i=0; i < pData->audioOut.count; ++i)
  1355. {
  1356. if (fAudio16Buffers[i] != nullptr)
  1357. {
  1358. delete[] fAudio16Buffers[i];
  1359. fAudio16Buffers[i] = nullptr;
  1360. }
  1361. }
  1362. delete[] fAudio16Buffers;
  1363. fAudio16Buffers = nullptr;
  1364. }
  1365. CarlaPlugin::clearBuffers();
  1366. carla_debug("CarlaPluginFluidSynth::clearBuffers() - end");
  1367. }
  1368. // -------------------------------------------------------------------
  1369. const void* getExtraStuff() const noexcept override
  1370. {
  1371. static const char xtrue[] = "true";
  1372. static const char xfalse[] = "false";
  1373. return kUse16Outs ? xtrue : xfalse;
  1374. }
  1375. // -------------------------------------------------------------------
  1376. bool init(const CarlaPluginPtr plugin,
  1377. const char* const filename, const char* const name, const char* const label, const uint options)
  1378. {
  1379. CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
  1380. // ---------------------------------------------------------------
  1381. // first checks
  1382. if (pData->client != nullptr)
  1383. {
  1384. pData->engine->setLastError("Plugin client is already registered");
  1385. return false;
  1386. }
  1387. if (fSynth == nullptr)
  1388. {
  1389. pData->engine->setLastError("null synth");
  1390. return false;
  1391. }
  1392. if (filename == nullptr || filename[0] == '\0')
  1393. {
  1394. pData->engine->setLastError("null filename");
  1395. return false;
  1396. }
  1397. if (label == nullptr || label[0] == '\0')
  1398. {
  1399. pData->engine->setLastError("null label");
  1400. return false;
  1401. }
  1402. // ---------------------------------------------------------------
  1403. // open soundfont
  1404. const int synthId = fluid_synth_sfload(fSynth, filename, 0);
  1405. if (synthId < 0)
  1406. {
  1407. pData->engine->setLastError("Failed to load SoundFont file");
  1408. return false;
  1409. }
  1410. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  1411. fSynthId = synthId;
  1412. #else
  1413. fSynthId = static_cast<uint>(synthId);
  1414. #endif
  1415. // ---------------------------------------------------------------
  1416. // get info
  1417. CarlaString label2(label);
  1418. if (kUse16Outs && ! label2.endsWith(" (16 outs)"))
  1419. label2 += " (16 outs)";
  1420. fLabel = label2.dup();
  1421. pData->filename = carla_strdup(filename);
  1422. if (name != nullptr && name[0] != '\0')
  1423. pData->name = pData->engine->getUniquePluginName(name);
  1424. else
  1425. pData->name = pData->engine->getUniquePluginName(label);
  1426. // ---------------------------------------------------------------
  1427. // register client
  1428. pData->client = pData->engine->addClient(plugin);
  1429. if (pData->client == nullptr || ! pData->client->isOk())
  1430. {
  1431. pData->engine->setLastError("Failed to register plugin client");
  1432. return false;
  1433. }
  1434. // ---------------------------------------------------------------
  1435. // set options
  1436. pData->options = 0x0;
  1437. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CONTROL_CHANGES))
  1438. pData->options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
  1439. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_CHANNEL_PRESSURE))
  1440. pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
  1441. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_PITCHBEND))
  1442. pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
  1443. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_ALL_SOUND_OFF))
  1444. pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
  1445. if (isPluginOptionEnabled(options, PLUGIN_OPTION_MAP_PROGRAM_CHANGES))
  1446. pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
  1447. if (isPluginOptionInverseEnabled(options, PLUGIN_OPTION_SKIP_SENDING_NOTES))
  1448. pData->options |= PLUGIN_OPTION_SKIP_SENDING_NOTES;
  1449. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  1450. if (isPluginOptionEnabled(options, PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH))
  1451. pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
  1452. #endif
  1453. return true;
  1454. }
  1455. private:
  1456. void initializeFluidDefaultsIfNeeded()
  1457. {
  1458. if (sFluidDefaultsStored)
  1459. return;
  1460. sFluidDefaultsStored = true;
  1461. // reverb defaults
  1462. sFluidDefaults[FluidSynthReverbOnOff] = 1.0f;
  1463. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  1464. double reverbVal;
  1465. reverbVal = 0.2;
  1466. fluid_settings_getnum_default(fSettings, "synth.reverb.room-size", &reverbVal);
  1467. sFluidDefaults[FluidSynthReverbRoomSize] = static_cast<float>(reverbVal);
  1468. reverbVal = 0.0;
  1469. fluid_settings_getnum_default(fSettings, "synth.reverb.damp", &reverbVal);
  1470. sFluidDefaults[FluidSynthReverbDamp] = static_cast<float>(reverbVal);
  1471. reverbVal = 0.9;
  1472. fluid_settings_getnum_default(fSettings, "synth.reverb.level", &reverbVal);
  1473. sFluidDefaults[FluidSynthReverbLevel] = static_cast<float>(reverbVal);
  1474. reverbVal = 0.5;
  1475. fluid_settings_getnum_default(fSettings, "synth.reverb.width", &reverbVal);
  1476. sFluidDefaults[FluidSynthReverbWidth] = static_cast<float>(reverbVal);
  1477. #else
  1478. sFluidDefaults[FluidSynthReverbRoomSize] = FLUID_REVERB_DEFAULT_ROOMSIZE;
  1479. sFluidDefaults[FluidSynthReverbDamp] = FLUID_REVERB_DEFAULT_DAMP;
  1480. sFluidDefaults[FluidSynthReverbLevel] = FLUID_REVERB_DEFAULT_LEVEL;
  1481. sFluidDefaults[FluidSynthReverbWidth] = FLUID_REVERB_DEFAULT_WIDTH;
  1482. #endif
  1483. // chorus defaults
  1484. sFluidDefaults[FluidSynthChorusOnOff] = 1.0f;
  1485. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  1486. double chorusVal;
  1487. chorusVal = 3.0;
  1488. fluid_settings_getnum_default(fSettings, "synth.chorus.nr", &chorusVal);
  1489. sFluidDefaults[FluidSynthChorusNr] = static_cast<float>(chorusVal);
  1490. chorusVal = 2.0;
  1491. fluid_settings_getnum_default(fSettings, "synth.chorus.level", &chorusVal);
  1492. sFluidDefaults[FluidSynthChorusLevel] = static_cast<float>(chorusVal);
  1493. chorusVal = 0.3;
  1494. fluid_settings_getnum_default(fSettings, "synth.chorus.speed", &chorusVal);
  1495. sFluidDefaults[FluidSynthChorusSpeedHz] = static_cast<float>(chorusVal);
  1496. chorusVal = 8.0;
  1497. fluid_settings_getnum_default(fSettings, "synth.chorus.depth", &chorusVal);
  1498. sFluidDefaults[FluidSynthChorusDepthMs] = static_cast<float>(chorusVal);
  1499. // There is no settings for chorus default type
  1500. sFluidDefaults[FluidSynthChorusType] = static_cast<float>(fluid_synth_get_chorus_type(fSynth));
  1501. #else
  1502. sFluidDefaults[FluidSynthChorusNr] = FLUID_CHORUS_DEFAULT_N;
  1503. sFluidDefaults[FluidSynthChorusLevel] = FLUID_CHORUS_DEFAULT_LEVEL;
  1504. sFluidDefaults[FluidSynthChorusSpeedHz] = FLUID_CHORUS_DEFAULT_SPEED;
  1505. sFluidDefaults[FluidSynthChorusDepthMs] = FLUID_CHORUS_DEFAULT_DEPTH;
  1506. sFluidDefaults[FluidSynthChorusType] = FLUID_CHORUS_DEFAULT_TYPE;
  1507. #endif
  1508. // misc. defaults
  1509. sFluidDefaults[FluidSynthInterpolation] = FLUID_INTERP_DEFAULT;
  1510. sFluidDefaults[FluidSynthPolyphony] = FLUID_DEFAULT_POLYPHONY;
  1511. }
  1512. enum FluidSynthParameters {
  1513. FluidSynthReverbOnOff = 0,
  1514. FluidSynthReverbRoomSize = 1,
  1515. FluidSynthReverbDamp = 2,
  1516. FluidSynthReverbLevel = 3,
  1517. FluidSynthReverbWidth = 4,
  1518. FluidSynthChorusOnOff = 5,
  1519. FluidSynthChorusNr = 6,
  1520. FluidSynthChorusLevel = 7,
  1521. FluidSynthChorusSpeedHz = 8,
  1522. FluidSynthChorusDepthMs = 9,
  1523. FluidSynthChorusType = 10,
  1524. FluidSynthPolyphony = 11,
  1525. FluidSynthInterpolation = 12,
  1526. FluidSynthVoiceCount = 13,
  1527. FluidSynthParametersMax = 14
  1528. };
  1529. const bool kUse16Outs;
  1530. fluid_settings_t* fSettings;
  1531. fluid_synth_t* fSynth;
  1532. #if FLUIDSYNTH_VERSION_MAJOR >= 2
  1533. int fSynthId;
  1534. #else
  1535. uint fSynthId;
  1536. #endif
  1537. float** fAudio16Buffers;
  1538. float fParamBuffers[FluidSynthParametersMax];
  1539. static bool sFluidDefaultsStored;
  1540. static float sFluidDefaults[FluidSynthParametersMax];
  1541. int32_t fCurMidiProgs[MAX_MIDI_CHANNELS];
  1542. const char* fLabel;
  1543. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginFluidSynth)
  1544. };
  1545. bool CarlaPluginFluidSynth::sFluidDefaultsStored = false;
  1546. float CarlaPluginFluidSynth::sFluidDefaults[FluidSynthParametersMax] = {
  1547. 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
  1548. };
  1549. CARLA_BACKEND_END_NAMESPACE
  1550. #endif // HAVE_FLUIDSYNTH
  1551. CARLA_BACKEND_START_NAMESPACE
  1552. // -------------------------------------------------------------------------------------------------------------------
  1553. CarlaPluginPtr CarlaPlugin::newFluidSynth(const Initializer& init, PluginType ptype, bool use16Outs)
  1554. {
  1555. carla_debug("CarlaPlugin::newFluidSynth({%p, \"%s\", \"%s\", \"%s\", " P_INT64 "}, %s)",
  1556. init.engine, init.filename, init.name, init.label, init.uniqueId, bool2str(use16Outs));
  1557. #ifdef HAVE_FLUIDSYNTH
  1558. if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
  1559. use16Outs = false;
  1560. if (ptype == PLUGIN_SF2 && ! fluid_is_soundfont(init.filename))
  1561. {
  1562. init.engine->setLastError("Requested file is not a valid SoundFont");
  1563. return nullptr;
  1564. }
  1565. #ifndef HAVE_FLUIDSYNTH_INSTPATCH
  1566. if (ptype == PLUGIN_DLS)
  1567. {
  1568. init.engine->setLastError("DLS file support not available");
  1569. return nullptr;
  1570. }
  1571. if (ptype == PLUGIN_GIG)
  1572. {
  1573. init.engine->setLastError("GIG file support not available");
  1574. return nullptr;
  1575. }
  1576. #endif
  1577. std::shared_ptr<CarlaPluginFluidSynth> plugin(new CarlaPluginFluidSynth(init.engine, init.id, use16Outs));
  1578. if (! plugin->init(plugin, init.filename, init.name, init.label, init.options))
  1579. return nullptr;
  1580. return plugin;
  1581. #else
  1582. init.engine->setLastError("fluidsynth support not available");
  1583. return nullptr;
  1584. // unused
  1585. (void)ptype;
  1586. (void)use16Outs;
  1587. #endif
  1588. }
  1589. // -------------------------------------------------------------------------------------------------------------------
  1590. CARLA_BACKEND_END_NAMESPACE