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.

FluidSynthPlugin.cpp 65KB

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