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

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