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

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