Collection of tools useful for audio production
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.

1355 lines
45KB

  1. /*
  2. * Carla Backend
  3. * Copyright (C) 2011-2012 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * 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 COPYING file
  16. */
  17. #ifdef BUILD_BRIDGE
  18. # error Should not use fluidsynth for bridges!
  19. #endif
  20. #include "carla_plugin.hpp"
  21. #ifdef WANT_FLUIDSYNTH
  22. #include <fluidsynth.h>
  23. #define FLUIDSYNTH_VERSION_NEW_API (FLUIDSYNTH_VERSION_MAJOR >= 1 && FLUIDSYNTH_VERSION_MINOR >= 1 && FLUIDSYNTH_VERSION_MICRO >= 4)
  24. CARLA_BACKEND_START_NAMESPACE
  25. /*!
  26. * @defgroup CarlaBackendFluidSynthPlugin Carla Backend FluidSynth Plugin
  27. *
  28. * The Carla Backend FluidSynth Plugin.\n
  29. * http://www.fluidsynth.org/
  30. * @{
  31. */
  32. class FluidSynthPlugin : public CarlaPlugin
  33. {
  34. public:
  35. FluidSynthPlugin(CarlaEngine* const engine, const unsigned short id)
  36. : CarlaPlugin(engine, id)
  37. {
  38. qDebug("FluidSynthPlugin::FluidSynthPlugin()");
  39. m_type = PLUGIN_SF2;
  40. m_label = nullptr;
  41. // create settings
  42. f_settings = new_fluid_settings();
  43. // define settings
  44. fluid_settings_setnum(f_settings, "synth.sample-rate", x_engine->getSampleRate());
  45. fluid_settings_setint(f_settings, "synth.threadsafe-api ", 0);
  46. // create synth
  47. f_synth = new_fluid_synth(f_settings);
  48. #ifdef FLUIDSYNTH_VERSION_NEW_API
  49. fluid_synth_set_sample_rate(f_synth, x_engine->getSampleRate());
  50. #endif
  51. // set default values
  52. fluid_synth_set_reverb_on(f_synth, 0);
  53. fluid_synth_set_reverb(f_synth, FLUID_REVERB_DEFAULT_ROOMSIZE, FLUID_REVERB_DEFAULT_DAMP, FLUID_REVERB_DEFAULT_WIDTH, FLUID_REVERB_DEFAULT_LEVEL);
  54. fluid_synth_set_chorus_on(f_synth, 0);
  55. fluid_synth_set_chorus(f_synth, FLUID_CHORUS_DEFAULT_N, FLUID_CHORUS_DEFAULT_LEVEL, FLUID_CHORUS_DEFAULT_SPEED, FLUID_CHORUS_DEFAULT_DEPTH, FLUID_CHORUS_DEFAULT_TYPE);
  56. fluid_synth_set_polyphony(f_synth, 64);
  57. for (int i=0; i < 16; i++)
  58. fluid_synth_set_interp_method(f_synth, i, FLUID_INTERP_DEFAULT);
  59. }
  60. ~FluidSynthPlugin()
  61. {
  62. qDebug("FluidSynthPlugin::~FluidSynthPlugin()");
  63. if (m_label)
  64. free((void*)m_label);
  65. delete_fluid_synth(f_synth);
  66. delete_fluid_settings(f_settings);
  67. }
  68. // -------------------------------------------------------------------
  69. // Information (base)
  70. PluginCategory category()
  71. {
  72. return PLUGIN_CATEGORY_SYNTH;
  73. }
  74. // -------------------------------------------------------------------
  75. // Information (count)
  76. uint32_t parameterScalePointCount(const uint32_t parameterId)
  77. {
  78. CARLA_ASSERT(parameterId < param.count);
  79. switch (parameterId)
  80. {
  81. case FluidSynthChorusType:
  82. return 2;
  83. case FluidSynthInterpolation:
  84. return 4;
  85. default:
  86. return 0;
  87. }
  88. }
  89. // -------------------------------------------------------------------
  90. // Information (per-plugin data)
  91. double getParameterValue(const uint32_t parameterId)
  92. {
  93. CARLA_ASSERT(parameterId < param.count);
  94. return paramBuffers[parameterId];
  95. }
  96. double getParameterScalePointValue(const uint32_t parameterId, const uint32_t scalePointId)
  97. {
  98. CARLA_ASSERT(parameterId < param.count);
  99. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  100. switch (parameterId)
  101. {
  102. case FluidSynthChorusType:
  103. switch (scalePointId)
  104. {
  105. case 0:
  106. return FLUID_CHORUS_MOD_SINE;
  107. case 1:
  108. return FLUID_CHORUS_MOD_TRIANGLE;
  109. default:
  110. return FLUID_CHORUS_DEFAULT_TYPE;
  111. }
  112. case FluidSynthInterpolation:
  113. switch (scalePointId)
  114. {
  115. case 0:
  116. return FLUID_INTERP_NONE;
  117. case 1:
  118. return FLUID_INTERP_LINEAR;
  119. case 2:
  120. return FLUID_INTERP_4THORDER;
  121. case 3:
  122. return FLUID_INTERP_7THORDER;
  123. default:
  124. return FLUID_INTERP_DEFAULT;
  125. }
  126. default:
  127. return 0.0;
  128. }
  129. }
  130. void getLabel(char* const strBuf)
  131. {
  132. if (m_label)
  133. strncpy(strBuf, m_label, STR_MAX);
  134. else
  135. CarlaPlugin::getLabel(strBuf);
  136. }
  137. void getMaker(char* const strBuf)
  138. {
  139. strncpy(strBuf, "FluidSynth SF2 engine", STR_MAX);
  140. }
  141. void getCopyright(char* const strBuf)
  142. {
  143. strncpy(strBuf, "GNU GPL v2+", STR_MAX);
  144. }
  145. void getRealName(char* const strBuf)
  146. {
  147. getLabel(strBuf);
  148. }
  149. void getParameterName(const uint32_t parameterId, char* const strBuf)
  150. {
  151. CARLA_ASSERT(parameterId < param.count);
  152. switch (parameterId)
  153. {
  154. case FluidSynthReverbOnOff:
  155. strncpy(strBuf, "Reverb On/Off", STR_MAX);
  156. break;
  157. case FluidSynthReverbRoomSize:
  158. strncpy(strBuf, "Reverb Room Size", STR_MAX);
  159. break;
  160. case FluidSynthReverbDamp:
  161. strncpy(strBuf, "Reverb Damp", STR_MAX);
  162. break;
  163. case FluidSynthReverbLevel:
  164. strncpy(strBuf, "Reverb Level", STR_MAX);
  165. break;
  166. case FluidSynthReverbWidth:
  167. strncpy(strBuf, "Reverb Width", STR_MAX);
  168. break;
  169. case FluidSynthChorusOnOff:
  170. strncpy(strBuf, "Chorus On/Off", STR_MAX);
  171. break;
  172. case FluidSynthChorusNr:
  173. strncpy(strBuf, "Chorus Voice Count", STR_MAX);
  174. break;
  175. case FluidSynthChorusLevel:
  176. strncpy(strBuf, "Chorus Level", STR_MAX);
  177. break;
  178. case FluidSynthChorusSpeedHz:
  179. strncpy(strBuf, "Chorus Speed", STR_MAX);
  180. break;
  181. case FluidSynthChorusDepthMs:
  182. strncpy(strBuf, "Chorus Depth", STR_MAX);
  183. break;
  184. case FluidSynthChorusType:
  185. strncpy(strBuf, "Chorus Type", STR_MAX);
  186. break;
  187. case FluidSynthPolyphony:
  188. strncpy(strBuf, "Polyphony", STR_MAX);
  189. break;
  190. case FluidSynthInterpolation:
  191. strncpy(strBuf, "Interpolation", STR_MAX);
  192. break;
  193. case FluidSynthVoiceCount:
  194. strncpy(strBuf, "Voice Count", STR_MAX);
  195. break;
  196. default:
  197. CarlaPlugin::getParameterName(parameterId, strBuf);
  198. break;
  199. }
  200. }
  201. void getParameterUnit(const uint32_t parameterId, char* const strBuf)
  202. {
  203. CARLA_ASSERT(parameterId < param.count);
  204. switch (parameterId)
  205. {
  206. case FluidSynthChorusSpeedHz:
  207. strncpy(strBuf, "Hz", STR_MAX);
  208. break;
  209. case FluidSynthChorusDepthMs:
  210. strncpy(strBuf, "ms", STR_MAX);
  211. break;
  212. default:
  213. CarlaPlugin::getParameterUnit(parameterId, strBuf);
  214. break;
  215. }
  216. }
  217. void getParameterScalePointLabel(const uint32_t parameterId, const uint32_t scalePointId, char* const strBuf)
  218. {
  219. CARLA_ASSERT(parameterId < param.count);
  220. CARLA_ASSERT(scalePointId < parameterScalePointCount(parameterId));
  221. switch (parameterId)
  222. {
  223. case FluidSynthChorusType:
  224. switch (scalePointId)
  225. {
  226. case 0:
  227. strncpy(strBuf, "Sine wave", STR_MAX);
  228. return;
  229. case 1:
  230. strncpy(strBuf, "Triangle wave", STR_MAX);
  231. return;
  232. }
  233. case FluidSynthInterpolation:
  234. switch (scalePointId)
  235. {
  236. case 0:
  237. strncpy(strBuf, "None", STR_MAX);
  238. return;
  239. case 1:
  240. strncpy(strBuf, "Straight-line", STR_MAX);
  241. return;
  242. case 2:
  243. strncpy(strBuf, "Fourth-order", STR_MAX);
  244. return;
  245. case 3:
  246. strncpy(strBuf, "Seventh-order", STR_MAX);
  247. return;
  248. }
  249. }
  250. CarlaPlugin::getParameterScalePointLabel(parameterId, scalePointId, strBuf);
  251. }
  252. // -------------------------------------------------------------------
  253. // Set data (plugin-specific stuff)
  254. void setParameterValue(const uint32_t parameterId, double value, const bool sendGui, const bool sendOsc, const bool sendCallback)
  255. {
  256. CARLA_ASSERT(parameterId < param.count);
  257. paramBuffers[parameterId] = fixParameterValue(value, param.ranges[parameterId]);
  258. switch (parameterId)
  259. {
  260. case FluidSynthReverbOnOff:
  261. value = value > 0.5 ? 1 : 0;
  262. fluid_synth_set_reverb_on(f_synth, value);
  263. break;
  264. case FluidSynthReverbRoomSize:
  265. case FluidSynthReverbDamp:
  266. case FluidSynthReverbLevel:
  267. case FluidSynthReverbWidth:
  268. fluid_synth_set_reverb(f_synth, paramBuffers[FluidSynthReverbRoomSize], paramBuffers[FluidSynthReverbDamp], paramBuffers[FluidSynthReverbWidth], paramBuffers[FluidSynthReverbLevel]);
  269. break;
  270. case FluidSynthChorusOnOff:
  271. {
  272. const ScopedDisabler m(this, ! x_engine->isOffline());
  273. value = value > 0.5 ? 1 : 0;
  274. fluid_synth_set_chorus_on(f_synth, value);
  275. break;
  276. }
  277. case FluidSynthChorusNr:
  278. case FluidSynthChorusLevel:
  279. case FluidSynthChorusSpeedHz:
  280. case FluidSynthChorusDepthMs:
  281. case FluidSynthChorusType:
  282. {
  283. const ScopedDisabler m(this, ! x_engine->isOffline());
  284. fluid_synth_set_chorus(f_synth, rint(paramBuffers[FluidSynthChorusNr]), paramBuffers[FluidSynthChorusLevel], paramBuffers[FluidSynthChorusSpeedHz], paramBuffers[FluidSynthChorusDepthMs], rint(paramBuffers[FluidSynthChorusType]));
  285. break;
  286. }
  287. case FluidSynthPolyphony:
  288. {
  289. const ScopedDisabler m(this, ! x_engine->isOffline());
  290. fluid_synth_set_polyphony(f_synth, rint(value));
  291. break;
  292. }
  293. case FluidSynthInterpolation:
  294. {
  295. const ScopedDisabler m(this, ! x_engine->isOffline());
  296. for (int i=0; i < 16; i++)
  297. fluid_synth_set_interp_method(f_synth, i, rint(value));
  298. break;
  299. }
  300. default:
  301. break;
  302. }
  303. CarlaPlugin::setParameterValue(parameterId, value, sendGui, sendOsc, sendCallback);
  304. }
  305. void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback, const bool block)
  306. {
  307. CARLA_ASSERT(index >= -1 && index < (int32_t)midiprog.count);
  308. if (index < -1)
  309. index = -1;
  310. else if (index > (int32_t)midiprog.count)
  311. return;
  312. if (m_ctrlInChannel < 0 || m_ctrlInChannel > 15)
  313. return;
  314. if (index >= 0)
  315. {
  316. if (x_engine->isOffline())
  317. {
  318. const CarlaEngine::ScopedLocker m(x_engine, block);
  319. fluid_synth_program_select(f_synth, m_ctrlInChannel, f_id, midiprog.data[index].bank, midiprog.data[index].program);
  320. }
  321. else
  322. {
  323. const ScopedDisabler m(this, block);
  324. fluid_synth_program_select(f_synth, m_ctrlInChannel, f_id, midiprog.data[index].bank, midiprog.data[index].program);
  325. }
  326. }
  327. CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback, block);
  328. }
  329. // -------------------------------------------------------------------
  330. // Plugin state
  331. void reload()
  332. {
  333. qDebug("FluidSynthPlugin::reload() - start");
  334. CARLA_ASSERT(f_synth);
  335. // Safely disable plugin for reload
  336. const ScopedDisabler m(this);
  337. if (x_client->isActive())
  338. x_client->deactivate();
  339. // Remove client ports
  340. removeClientPorts();
  341. // Delete old data
  342. deleteBuffers();
  343. uint32_t aOuts, params, j;
  344. aOuts = 2;
  345. params = FluidSynthParametersMax;
  346. aOut.ports = new CarlaEngineAudioPort*[aOuts];
  347. aOut.rindexes = new uint32_t[aOuts];
  348. param.data = new ParameterData[params];
  349. param.ranges = new ParameterRanges[params];
  350. const int portNameSize = x_engine->maxPortNameSize() - 1;
  351. char portName[portNameSize];
  352. // ---------------------------------------
  353. // Audio Outputs
  354. #ifndef BUILD_BRIDGE
  355. if (x_engine->processMode() == PROCESS_MODE_SINGLE_CLIENT)
  356. {
  357. strcpy(portName, m_name);
  358. strcat(portName, ":out-left");
  359. }
  360. else
  361. #endif
  362. strcpy(portName, "out-left");
  363. aOut.ports[0] = (CarlaEngineAudioPort*)x_client->addPort(CarlaEnginePortTypeAudio, portName, false);
  364. aOut.rindexes[0] = 0;
  365. #ifndef BUILD_BRIDGE
  366. if (x_engine->processMode() == PROCESS_MODE_SINGLE_CLIENT)
  367. {
  368. strcpy(portName, m_name);
  369. strcat(portName, ":out-right");
  370. }
  371. else
  372. #endif
  373. strcpy(portName, "out-right");
  374. aOut.ports[1] = (CarlaEngineAudioPort*)x_client->addPort(CarlaEnginePortTypeAudio, portName, false);
  375. aOut.rindexes[1] = 1;
  376. // ---------------------------------------
  377. // MIDI Input
  378. #ifndef BUILD_BRIDGE
  379. if (x_engine->processMode() == PROCESS_MODE_SINGLE_CLIENT)
  380. {
  381. strcpy(portName, m_name);
  382. strcat(portName, ":midi-in");
  383. }
  384. else
  385. #endif
  386. strcpy(portName, "midi-in");
  387. midi.portMin = (CarlaEngineMidiPort*)x_client->addPort(CarlaEnginePortTypeMIDI, portName, true);
  388. // ---------------------------------------
  389. // Parameters
  390. #ifndef BUILD_BRIDGE
  391. if (x_engine->processMode() == PROCESS_MODE_SINGLE_CLIENT)
  392. {
  393. strcpy(portName, m_name);
  394. strcat(portName, ":control-in");
  395. }
  396. else
  397. #endif
  398. strcpy(portName, "control-in");
  399. param.portCin = (CarlaEngineControlPort*)x_client->addPort(CarlaEnginePortTypeControl, portName, true);
  400. #ifndef BUILD_BRIDGE
  401. if (x_engine->processMode() == PROCESS_MODE_SINGLE_CLIENT)
  402. {
  403. strcpy(portName, m_name);
  404. strcat(portName, ":control-out");
  405. }
  406. else
  407. #endif
  408. strcpy(portName, "control-out");
  409. param.portCout = (CarlaEngineControlPort*)x_client->addPort(CarlaEnginePortTypeControl, portName, false);
  410. // ----------------------
  411. j = FluidSynthReverbOnOff;
  412. param.data[j].index = j;
  413. param.data[j].rindex = j;
  414. param.data[j].type = PARAMETER_INPUT;
  415. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE | PARAMETER_IS_BOOLEAN;
  416. param.data[j].midiChannel = 0;
  417. param.data[j].midiCC = -1;
  418. param.ranges[j].min = 0.0;
  419. param.ranges[j].max = 1.0;
  420. param.ranges[j].def = 0.0; // off
  421. param.ranges[j].step = 1.0;
  422. param.ranges[j].stepSmall = 1.0;
  423. param.ranges[j].stepLarge = 1.0;
  424. paramBuffers[j] = param.ranges[j].def;
  425. // ----------------------
  426. j = FluidSynthReverbRoomSize;
  427. param.data[j].index = j;
  428. param.data[j].rindex = j;
  429. param.data[j].type = PARAMETER_INPUT;
  430. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE;
  431. param.data[j].midiChannel = 0;
  432. param.data[j].midiCC = -1;
  433. param.ranges[j].min = 0.0;
  434. param.ranges[j].max = 1.2;
  435. param.ranges[j].def = FLUID_REVERB_DEFAULT_ROOMSIZE;
  436. param.ranges[j].step = 0.01;
  437. param.ranges[j].stepSmall = 0.0001;
  438. param.ranges[j].stepLarge = 0.1;
  439. paramBuffers[j] = param.ranges[j].def;
  440. // ----------------------
  441. j = FluidSynthReverbDamp;
  442. param.data[j].index = j;
  443. param.data[j].rindex = j;
  444. param.data[j].type = PARAMETER_INPUT;
  445. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE;
  446. param.data[j].midiChannel = 0;
  447. param.data[j].midiCC = -1;
  448. param.ranges[j].min = 0.0;
  449. param.ranges[j].max = 1.0;
  450. param.ranges[j].def = FLUID_REVERB_DEFAULT_DAMP;
  451. param.ranges[j].step = 0.01;
  452. param.ranges[j].stepSmall = 0.0001;
  453. param.ranges[j].stepLarge = 0.1;
  454. paramBuffers[j] = param.ranges[j].def;
  455. // ----------------------
  456. j = FluidSynthReverbLevel;
  457. param.data[j].index = j;
  458. param.data[j].rindex = j;
  459. param.data[j].type = PARAMETER_INPUT;
  460. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE;
  461. param.data[j].midiChannel = 0;
  462. param.data[j].midiCC = MIDI_CONTROL_REVERB_SEND_LEVEL;
  463. param.ranges[j].min = 0.0;
  464. param.ranges[j].max = 1.0;
  465. param.ranges[j].def = FLUID_REVERB_DEFAULT_LEVEL;
  466. param.ranges[j].step = 0.01;
  467. param.ranges[j].stepSmall = 0.0001;
  468. param.ranges[j].stepLarge = 0.1;
  469. paramBuffers[j] = param.ranges[j].def;
  470. // ----------------------
  471. j = FluidSynthReverbWidth;
  472. param.data[j].index = j;
  473. param.data[j].rindex = j;
  474. param.data[j].type = PARAMETER_INPUT;
  475. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE;
  476. param.data[j].midiChannel = 0;
  477. param.data[j].midiCC = -1;
  478. param.ranges[j].min = 0.0;
  479. param.ranges[j].max = 10.0; // should be 100, but that sounds too much
  480. param.ranges[j].def = FLUID_REVERB_DEFAULT_WIDTH;
  481. param.ranges[j].step = 0.01;
  482. param.ranges[j].stepSmall = 0.0001;
  483. param.ranges[j].stepLarge = 0.1;
  484. paramBuffers[j] = param.ranges[j].def;
  485. // ----------------------
  486. j = FluidSynthChorusOnOff;
  487. param.data[j].index = j;
  488. param.data[j].rindex = j;
  489. param.data[j].type = PARAMETER_INPUT;
  490. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_BOOLEAN;
  491. param.data[j].midiChannel = 0;
  492. param.data[j].midiCC = -1;
  493. param.ranges[j].min = 0.0;
  494. param.ranges[j].max = 1.0;
  495. param.ranges[j].def = 0.0; // off
  496. param.ranges[j].step = 1.0;
  497. param.ranges[j].stepSmall = 1.0;
  498. param.ranges[j].stepLarge = 1.0;
  499. paramBuffers[j] = param.ranges[j].def;
  500. // ----------------------
  501. j = FluidSynthChorusNr;
  502. param.data[j].index = j;
  503. param.data[j].rindex = j;
  504. param.data[j].type = PARAMETER_INPUT;
  505. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER;
  506. param.data[j].midiChannel = 0;
  507. param.data[j].midiCC = -1;
  508. param.ranges[j].min = 0.0;
  509. param.ranges[j].max = 99.0;
  510. param.ranges[j].def = FLUID_CHORUS_DEFAULT_N;
  511. param.ranges[j].step = 1.0;
  512. param.ranges[j].stepSmall = 1.0;
  513. param.ranges[j].stepLarge = 10.0;
  514. paramBuffers[j] = param.ranges[j].def;
  515. // ----------------------
  516. j = FluidSynthChorusLevel;
  517. param.data[j].index = j;
  518. param.data[j].rindex = j;
  519. param.data[j].type = PARAMETER_INPUT;
  520. param.data[j].hints = PARAMETER_IS_ENABLED;
  521. param.data[j].midiChannel = 0;
  522. param.data[j].midiCC = 0; //MIDI_CONTROL_CHORUS_SEND_LEVEL;
  523. param.ranges[j].min = 0.0;
  524. param.ranges[j].max = 10.0;
  525. param.ranges[j].def = FLUID_CHORUS_DEFAULT_LEVEL;
  526. param.ranges[j].step = 0.01;
  527. param.ranges[j].stepSmall = 0.0001;
  528. param.ranges[j].stepLarge = 0.1;
  529. paramBuffers[j] = param.ranges[j].def;
  530. // ----------------------
  531. j = FluidSynthChorusSpeedHz;
  532. param.data[j].index = j;
  533. param.data[j].rindex = j;
  534. param.data[j].type = PARAMETER_INPUT;
  535. param.data[j].hints = PARAMETER_IS_ENABLED;
  536. param.data[j].midiChannel = 0;
  537. param.data[j].midiCC = -1;
  538. param.ranges[j].min = 0.29;
  539. param.ranges[j].max = 5.0;
  540. param.ranges[j].def = FLUID_CHORUS_DEFAULT_SPEED;
  541. param.ranges[j].step = 0.01;
  542. param.ranges[j].stepSmall = 0.0001;
  543. param.ranges[j].stepLarge = 0.1;
  544. paramBuffers[j] = param.ranges[j].def;
  545. // ----------------------
  546. j = FluidSynthChorusDepthMs;
  547. param.data[j].index = j;
  548. param.data[j].rindex = j;
  549. param.data[j].type = PARAMETER_INPUT;
  550. param.data[j].hints = PARAMETER_IS_ENABLED;
  551. param.data[j].midiChannel = 0;
  552. param.data[j].midiCC = -1;
  553. param.ranges[j].min = 0.0;
  554. param.ranges[j].max = 2048000.0 / x_engine->getSampleRate();
  555. param.ranges[j].def = FLUID_CHORUS_DEFAULT_DEPTH;
  556. param.ranges[j].step = 0.01;
  557. param.ranges[j].stepSmall = 0.0001;
  558. param.ranges[j].stepLarge = 0.1;
  559. paramBuffers[j] = param.ranges[j].def;
  560. // ----------------------
  561. j = FluidSynthChorusType;
  562. param.data[j].index = j;
  563. param.data[j].rindex = j;
  564. param.data[j].type = PARAMETER_INPUT;
  565. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER | PARAMETER_USES_SCALEPOINTS;
  566. param.data[j].midiChannel = 0;
  567. param.data[j].midiCC = -1;
  568. param.ranges[j].min = FLUID_CHORUS_MOD_SINE;
  569. param.ranges[j].max = FLUID_CHORUS_MOD_TRIANGLE;
  570. param.ranges[j].def = FLUID_CHORUS_DEFAULT_TYPE;
  571. param.ranges[j].step = 1;
  572. param.ranges[j].stepSmall = 1;
  573. param.ranges[j].stepLarge = 1;
  574. paramBuffers[j] = param.ranges[j].def;
  575. // ----------------------
  576. j = FluidSynthPolyphony;
  577. param.data[j].index = j;
  578. param.data[j].rindex = j;
  579. param.data[j].type = PARAMETER_INPUT;
  580. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER;
  581. param.data[j].midiChannel = 0;
  582. param.data[j].midiCC = -1;
  583. param.ranges[j].min = 1;
  584. param.ranges[j].max = 512; // max theoric is 65535
  585. param.ranges[j].def = fluid_synth_get_polyphony(f_synth);
  586. param.ranges[j].step = 1;
  587. param.ranges[j].stepSmall = 1;
  588. param.ranges[j].stepLarge = 10;
  589. paramBuffers[j] = param.ranges[j].def;
  590. // ----------------------
  591. j = FluidSynthInterpolation;
  592. param.data[j].index = j;
  593. param.data[j].rindex = j;
  594. param.data[j].type = PARAMETER_INPUT;
  595. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_INTEGER | PARAMETER_USES_SCALEPOINTS;
  596. param.data[j].midiChannel = 0;
  597. param.data[j].midiCC = -1;
  598. param.ranges[j].min = FLUID_INTERP_NONE;
  599. param.ranges[j].max = FLUID_INTERP_HIGHEST;
  600. param.ranges[j].def = FLUID_INTERP_DEFAULT;
  601. param.ranges[j].step = 1;
  602. param.ranges[j].stepSmall = 1;
  603. param.ranges[j].stepLarge = 1;
  604. paramBuffers[j] = param.ranges[j].def;
  605. // ----------------------
  606. j = FluidSynthVoiceCount;
  607. param.data[j].index = j;
  608. param.data[j].rindex = j;
  609. param.data[j].type = PARAMETER_OUTPUT;
  610. param.data[j].hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE | PARAMETER_IS_INTEGER;
  611. param.data[j].midiChannel = 0;
  612. param.data[j].midiCC = -1;
  613. param.ranges[j].min = 0;
  614. param.ranges[j].max = 65535;
  615. param.ranges[j].def = 0;
  616. param.ranges[j].step = 1;
  617. param.ranges[j].stepSmall = 1;
  618. param.ranges[j].stepLarge = 1;
  619. paramBuffers[j] = param.ranges[j].def;
  620. // ---------------------------------------
  621. aOut.count = aOuts;
  622. param.count = params;
  623. // plugin checks
  624. m_hints &= ~(PLUGIN_IS_SYNTH | PLUGIN_USES_CHUNKS | PLUGIN_CAN_DRYWET | PLUGIN_CAN_VOLUME | PLUGIN_CAN_BALANCE | PLUGIN_CAN_FORCE_STEREO);
  625. m_hints |= PLUGIN_IS_SYNTH;
  626. m_hints |= PLUGIN_CAN_VOLUME;
  627. m_hints |= PLUGIN_CAN_BALANCE;
  628. m_hints |= PLUGIN_CAN_FORCE_STEREO;
  629. reloadPrograms(true);
  630. x_client->activate();
  631. qDebug("FluidSynthPlugin::reload() - end");
  632. }
  633. void reloadPrograms(const bool init)
  634. {
  635. qDebug("FluidSynthPlugin::reloadPrograms(%s)", bool2str(init));
  636. // Delete old programs
  637. if (midiprog.count > 0)
  638. {
  639. for (uint32_t i=0; i < midiprog.count; i++)
  640. free((void*)midiprog.data[i].name);
  641. delete[] midiprog.data;
  642. }
  643. midiprog.count = 0;
  644. midiprog.data = nullptr;
  645. // Query new programs
  646. fluid_sfont_t* f_sfont;
  647. fluid_preset_t f_preset;
  648. bool hasDrums = false;
  649. f_sfont = fluid_synth_get_sfont_by_id(f_synth, f_id);
  650. // initial check to know how much midi-programs we have
  651. f_sfont->iteration_start(f_sfont);
  652. while (f_sfont->iteration_next(f_sfont, &f_preset))
  653. midiprog.count += 1;
  654. // soundfonts must always have at least 1 midi-program
  655. CARLA_ASSERT(midiprog.count > 0);
  656. if (midiprog.count > 0)
  657. midiprog.data = new MidiProgramData[midiprog.count];
  658. // Update data
  659. uint32_t i = 0;
  660. f_sfont->iteration_start(f_sfont);
  661. while (f_sfont->iteration_next(f_sfont, &f_preset))
  662. {
  663. CARLA_ASSERT(i < midiprog.count);
  664. midiprog.data[i].bank = f_preset.get_banknum(&f_preset);
  665. midiprog.data[i].program = f_preset.get_num(&f_preset);
  666. midiprog.data[i].name = strdup(f_preset.get_name(&f_preset));
  667. if (midiprog.data[i].bank == 128)
  668. hasDrums = true;
  669. i++;
  670. }
  671. //f_sfont->free(f_sfont);
  672. #ifndef BUILD_BRIDGE
  673. // Update OSC Names
  674. if (x_engine->isOscControlRegisted())
  675. {
  676. x_engine->osc_send_control_set_midi_program_count(m_id, midiprog.count);
  677. for (i=0; i < midiprog.count; i++)
  678. x_engine->osc_send_control_set_midi_program_data(m_id, i, midiprog.data[i].bank, midiprog.data[i].program, midiprog.data[i].name);
  679. }
  680. #endif
  681. if (init)
  682. {
  683. fluid_synth_program_reset(f_synth);
  684. for (i=0; i < 16 && i != 9; i++)
  685. {
  686. fluid_synth_program_select(f_synth, i, f_id, midiprog.data[0].bank, midiprog.data[0].program);
  687. #ifdef FLUIDSYNTH_VERSION_NEW_API
  688. fluid_synth_set_channel_type(f_synth, i, CHANNEL_TYPE_MELODIC);
  689. #endif
  690. }
  691. if (hasDrums)
  692. {
  693. fluid_synth_program_select(f_synth, 9, f_id, 128, 0);
  694. #ifdef FLUIDSYNTH_VERSION_NEW_API
  695. fluid_synth_set_channel_type(f_synth, 9, CHANNEL_TYPE_DRUM);
  696. #endif
  697. }
  698. else
  699. {
  700. fluid_synth_program_select(f_synth, 9, f_id, midiprog.data[0].bank, midiprog.data[0].program);
  701. #ifdef FLUIDSYNTH_VERSION_NEW_API
  702. fluid_synth_set_channel_type(f_synth, 9, CHANNEL_TYPE_MELODIC);
  703. #endif
  704. }
  705. setMidiProgram(0, false, false, false, true);
  706. }
  707. else
  708. {
  709. x_engine->callback(CALLBACK_RELOAD_PROGRAMS, m_id, 0, 0, 0.0);
  710. }
  711. }
  712. // -------------------------------------------------------------------
  713. // Plugin processing
  714. void process(float** const, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
  715. {
  716. uint32_t i, k;
  717. uint32_t midiEventCount = 0;
  718. double aOutsPeak[2] = { 0.0 };
  719. CARLA_PROCESS_CONTINUE_CHECK;
  720. // --------------------------------------------------------------------------------------------------------
  721. // Parameters Input [Automation]
  722. if (m_active && m_activeBefore)
  723. {
  724. bool allNotesOffSent = false;
  725. const CarlaEngineControlEvent* cinEvent;
  726. uint32_t time, nEvents = param.portCin->getEventCount();
  727. unsigned char nextBankIds[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0 };
  728. if (midiprog.current >= 0 && midiprog.count > 0 && m_ctrlInChannel >= 0 && m_ctrlInChannel < 16)
  729. nextBankIds[m_ctrlInChannel] = midiprog.data[midiprog.current].bank;
  730. for (i=0; i < nEvents; i++)
  731. {
  732. cinEvent = param.portCin->getEvent(i);
  733. if (! cinEvent)
  734. continue;
  735. time = cinEvent->time - framesOffset;
  736. if (time >= frames)
  737. continue;
  738. // Control change
  739. switch (cinEvent->type)
  740. {
  741. case CarlaEngineNullEvent:
  742. break;
  743. case CarlaEngineParameterChangeEvent:
  744. {
  745. double value;
  746. // Control backend stuff
  747. if (cinEvent->channel == m_ctrlInChannel)
  748. {
  749. if (MIDI_IS_CONTROL_BREATH_CONTROLLER(cinEvent->parameter) && (m_hints & PLUGIN_CAN_DRYWET) > 0)
  750. {
  751. value = cinEvent->value;
  752. setDryWet(value, false, false);
  753. postponeEvent(PluginPostEventParameterChange, PARAMETER_DRYWET, 0, value);
  754. continue;
  755. }
  756. if (MIDI_IS_CONTROL_CHANNEL_VOLUME(cinEvent->parameter) && (m_hints & PLUGIN_CAN_VOLUME) > 0)
  757. {
  758. value = cinEvent->value*127/100;
  759. setVolume(value, false, false);
  760. postponeEvent(PluginPostEventParameterChange, PARAMETER_VOLUME, 0, value);
  761. continue;
  762. }
  763. if (MIDI_IS_CONTROL_BALANCE(cinEvent->parameter) && (m_hints & PLUGIN_CAN_BALANCE) > 0)
  764. {
  765. double left, right;
  766. value = cinEvent->value/0.5 - 1.0;
  767. if (value < 0.0)
  768. {
  769. left = -1.0;
  770. right = (value*2)+1.0;
  771. }
  772. else if (value > 0.0)
  773. {
  774. left = (value*2)-1.0;
  775. right = 1.0;
  776. }
  777. else
  778. {
  779. left = -1.0;
  780. right = 1.0;
  781. }
  782. setBalanceLeft(left, false, false);
  783. setBalanceRight(right, false, false);
  784. postponeEvent(PluginPostEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
  785. postponeEvent(PluginPostEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
  786. continue;
  787. }
  788. }
  789. // Control plugin parameters
  790. for (k=0; k < param.count; k++)
  791. {
  792. if (param.data[k].midiChannel != cinEvent->channel)
  793. continue;
  794. if (param.data[k].midiCC != cinEvent->parameter)
  795. continue;
  796. if (param.data[k].type != PARAMETER_INPUT)
  797. continue;
  798. if (param.data[k].hints & PARAMETER_IS_AUTOMABLE)
  799. {
  800. if (param.data[k].hints & PARAMETER_IS_BOOLEAN)
  801. {
  802. value = cinEvent->value < 0.5 ? param.ranges[k].min : param.ranges[k].max;
  803. }
  804. else
  805. {
  806. value = cinEvent->value * (param.ranges[k].max - param.ranges[k].min) + param.ranges[k].min;
  807. if (param.data[k].hints & PARAMETER_IS_INTEGER)
  808. value = rint(value);
  809. }
  810. setParameterValue(k, value, false, false, false);
  811. postponeEvent(PluginPostEventParameterChange, k, 0, value);
  812. }
  813. }
  814. break;
  815. }
  816. case CarlaEngineMidiBankChangeEvent:
  817. if (cinEvent->channel < 16)
  818. nextBankIds[cinEvent->channel] = rint(cinEvent->value);
  819. break;
  820. case CarlaEngineMidiProgramChangeEvent:
  821. if (cinEvent->channel < 16)
  822. {
  823. uint32_t bankId = nextBankIds[cinEvent->channel];
  824. uint32_t progId = rint(cinEvent->value);
  825. for (k=0; k < midiprog.count; k++)
  826. {
  827. if (midiprog.data[k].bank == bankId && midiprog.data[k].program == progId)
  828. {
  829. if (cinEvent->channel == m_ctrlInChannel)
  830. {
  831. setMidiProgram(k, false, false, false, false);
  832. postponeEvent(PluginPostEventMidiProgramChange, k, 0, 0.0);
  833. }
  834. else
  835. fluid_synth_program_select(f_synth, cinEvent->channel, f_id, bankId, progId);
  836. break;
  837. }
  838. }
  839. }
  840. break;
  841. case CarlaEngineAllSoundOffEvent:
  842. if (cinEvent->channel == m_ctrlInChannel)
  843. {
  844. if (! allNotesOffSent)
  845. sendMidiAllNotesOff();
  846. postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 0.0);
  847. postponeEvent(PluginPostEventParameterChange, PARAMETER_ACTIVE, 0, 1.0);
  848. allNotesOffSent = true;
  849. }
  850. break;
  851. case CarlaEngineAllNotesOffEvent:
  852. if (cinEvent->channel == m_ctrlInChannel)
  853. {
  854. if (! allNotesOffSent)
  855. sendMidiAllNotesOff();
  856. allNotesOffSent = true;
  857. }
  858. break;
  859. }
  860. }
  861. } // End of Parameters Input
  862. CARLA_PROCESS_CONTINUE_CHECK;
  863. // --------------------------------------------------------------------------------------------------------
  864. // MIDI Input
  865. if (m_active && m_activeBefore)
  866. {
  867. // ----------------------------------------------------------------------------------------------------
  868. // MIDI Input (External)
  869. {
  870. engineMidiLock();
  871. for (i=0; i < MAX_MIDI_EVENTS && midiEventCount < MAX_MIDI_EVENTS; i++)
  872. {
  873. if (extMidiNotes[i].channel < 0)
  874. break;
  875. if (extMidiNotes[i].velo)
  876. fluid_synth_noteon(f_synth, m_ctrlInChannel, extMidiNotes[i].note, extMidiNotes[i].velo);
  877. else
  878. fluid_synth_noteoff(f_synth, m_ctrlInChannel, extMidiNotes[i].note);
  879. extMidiNotes[i].channel = -1; // mark as invalid
  880. midiEventCount += 1;
  881. }
  882. engineMidiUnlock();
  883. } // End of MIDI Input (External)
  884. CARLA_PROCESS_CONTINUE_CHECK;
  885. // ----------------------------------------------------------------------------------------------------
  886. // MIDI Input (System)
  887. {
  888. const CarlaEngineMidiEvent* minEvent;
  889. uint32_t time, nEvents = midi.portMin->getEventCount();
  890. for (i=0; i < nEvents && midiEventCount < MAX_MIDI_EVENTS; i++)
  891. {
  892. minEvent = midi.portMin->getEvent(i);
  893. if (! minEvent)
  894. continue;
  895. time = minEvent->time - framesOffset;
  896. if (time >= frames)
  897. continue;
  898. uint8_t status = minEvent->data[0];
  899. uint8_t channel = status & 0x0F;
  900. // Fix bad note-off
  901. if (MIDI_IS_STATUS_NOTE_ON(status) && minEvent->data[2] == 0)
  902. status -= 0x10;
  903. if (MIDI_IS_STATUS_NOTE_OFF(status))
  904. {
  905. uint8_t note = minEvent->data[1];
  906. fluid_synth_noteoff(f_synth, channel, note);
  907. postponeEvent(PluginPostEventNoteOff, channel, note, 0.0);
  908. }
  909. else if (MIDI_IS_STATUS_NOTE_ON(status))
  910. {
  911. uint8_t note = minEvent->data[1];
  912. uint8_t velo = minEvent->data[2];
  913. fluid_synth_noteon(f_synth, channel, note, velo);
  914. postponeEvent(PluginPostEventNoteOn, channel, note, velo);
  915. }
  916. else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
  917. {
  918. // TODO, not in fluidsynth API?
  919. }
  920. else if (MIDI_IS_STATUS_AFTERTOUCH(status))
  921. {
  922. uint8_t pressure = minEvent->data[1];
  923. fluid_synth_channel_pressure(f_synth, channel, pressure);
  924. }
  925. else if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status))
  926. {
  927. uint8_t lsb = minEvent->data[1];
  928. uint8_t msb = minEvent->data[2];
  929. fluid_synth_pitch_bend(f_synth, channel, (msb << 7) | lsb);
  930. }
  931. else
  932. continue;
  933. midiEventCount += 1;
  934. }
  935. } // End of MIDI Input (System)
  936. } // End of MIDI Input
  937. CARLA_PROCESS_CONTINUE_CHECK;
  938. // --------------------------------------------------------------------------------------------------------
  939. // Plugin processing
  940. if (m_active)
  941. {
  942. if (! m_activeBefore)
  943. {
  944. for (int c=0; c < MAX_MIDI_CHANNELS; c++)
  945. {
  946. #ifdef FLUIDSYNTH_VERSION_NEW_API
  947. fluid_synth_all_notes_off(f_synth, c);
  948. fluid_synth_all_sounds_off(f_synth, c);
  949. #else
  950. fluid_synth_cc(f_synth, c, MIDI_CONTROL_ALL_SOUND_OFF, 0);
  951. fluid_synth_cc(f_synth, c, MIDI_CONTROL_ALL_NOTES_OFF, 0);
  952. #endif
  953. }
  954. }
  955. fluid_synth_process(f_synth, frames, 0, nullptr, 2, outBuffer);
  956. }
  957. CARLA_PROCESS_CONTINUE_CHECK;
  958. // --------------------------------------------------------------------------------------------------------
  959. // Post-processing (balance and volume)
  960. if (m_active)
  961. {
  962. bool do_balance = (x_balanceLeft != -1.0 || x_balanceRight != 1.0);
  963. double bal_rangeL, bal_rangeR;
  964. float oldBufLeft[do_balance ? frames : 0];
  965. for (i=0; i < aOut.count; i++)
  966. {
  967. // Balance
  968. if (do_balance)
  969. {
  970. if (i%2 == 0)
  971. memcpy(&oldBufLeft, outBuffer[i], sizeof(float)*frames);
  972. bal_rangeL = (x_balanceLeft+1.0)/2;
  973. bal_rangeR = (x_balanceRight+1.0)/2;
  974. for (k=0; k < frames; k++)
  975. {
  976. if (i%2 == 0)
  977. {
  978. // left output
  979. outBuffer[i][k] = oldBufLeft[k]*(1.0-bal_rangeL);
  980. outBuffer[i][k] += outBuffer[i+1][k]*(1.0-bal_rangeR);
  981. }
  982. else
  983. {
  984. // right
  985. outBuffer[i][k] = outBuffer[i][k]*bal_rangeR;
  986. outBuffer[i][k] += oldBufLeft[k]*bal_rangeL;
  987. }
  988. }
  989. }
  990. // Volume, using fluidsynth internals
  991. fluid_synth_set_gain(f_synth, x_volume);
  992. // Output VU
  993. #ifndef BUILD_BRIDGE
  994. if (x_engine->processMode() != PROCESS_MODE_CONTINUOUS_RACK)
  995. #endif
  996. {
  997. for (k=0; i < 2 && k < frames; k++)
  998. {
  999. if (abs(outBuffer[i][k]) > aOutsPeak[i])
  1000. aOutsPeak[i] = abs(outBuffer[i][k]);
  1001. }
  1002. }
  1003. }
  1004. }
  1005. else
  1006. {
  1007. // disable any output sound if not active
  1008. for (i=0; i < aOut.count; i++)
  1009. carla_zeroF(outBuffer[i], frames);
  1010. aOutsPeak[0] = 0.0;
  1011. aOutsPeak[1] = 0.0;
  1012. } // End of Post-processing
  1013. CARLA_PROCESS_CONTINUE_CHECK;
  1014. // --------------------------------------------------------------------------------------------------------
  1015. // Control Output
  1016. if (m_active)
  1017. {
  1018. k = FluidSynthVoiceCount;
  1019. paramBuffers[k] = fluid_synth_get_active_voice_count(f_synth);
  1020. fixParameterValue(paramBuffers[k], param.ranges[k]);
  1021. if (param.data[k].midiCC > 0)
  1022. {
  1023. double value = (paramBuffers[k] - param.ranges[k].min) / (param.ranges[k].max - param.ranges[k].min);
  1024. param.portCout->writeEvent(CarlaEngineParameterChangeEvent, framesOffset, param.data[k].midiChannel, param.data[k].midiCC, value);
  1025. }
  1026. } // End of Control Output
  1027. CARLA_PROCESS_CONTINUE_CHECK;
  1028. // --------------------------------------------------------------------------------------------------------
  1029. // Peak Values
  1030. x_engine->setOutputPeak(m_id, 0, aOutsPeak[0]);
  1031. x_engine->setOutputPeak(m_id, 1, aOutsPeak[1]);
  1032. m_activeBefore = m_active;
  1033. }
  1034. // -------------------------------------------------------------------
  1035. bool init(const char* const filename, const char* const name, const char* const label)
  1036. {
  1037. // ---------------------------------------------------------------
  1038. // open soundfont
  1039. f_id = fluid_synth_sfload(f_synth, filename, 0);
  1040. if (f_id < 0)
  1041. {
  1042. x_engine->setLastError("Failed to load SoundFont file");
  1043. return false;
  1044. }
  1045. // ---------------------------------------------------------------
  1046. // get info
  1047. m_filename = strdup(filename);
  1048. m_label = strdup(label);
  1049. if (name)
  1050. m_name = x_engine->getUniquePluginName(name);
  1051. else
  1052. m_name = x_engine->getUniquePluginName(label);
  1053. // ---------------------------------------------------------------
  1054. // register client
  1055. x_client = x_engine->addClient(this);
  1056. if (! x_client->isOk())
  1057. {
  1058. x_engine->setLastError("Failed to register plugin client");
  1059. return false;
  1060. }
  1061. return true;
  1062. }
  1063. private:
  1064. enum FluidSynthInputParameters {
  1065. FluidSynthReverbOnOff = 0,
  1066. FluidSynthReverbRoomSize = 1,
  1067. FluidSynthReverbDamp = 2,
  1068. FluidSynthReverbLevel = 3,
  1069. FluidSynthReverbWidth = 4,
  1070. FluidSynthChorusOnOff = 5,
  1071. FluidSynthChorusNr = 6,
  1072. FluidSynthChorusLevel = 7,
  1073. FluidSynthChorusSpeedHz = 8,
  1074. FluidSynthChorusDepthMs = 9,
  1075. FluidSynthChorusType = 10,
  1076. FluidSynthPolyphony = 11,
  1077. FluidSynthInterpolation = 12,
  1078. FluidSynthVoiceCount = 13,
  1079. FluidSynthParametersMax = 14
  1080. };
  1081. fluid_settings_t* f_settings;
  1082. fluid_synth_t* f_synth;
  1083. int f_id;
  1084. double paramBuffers[FluidSynthParametersMax];
  1085. const char* m_label;
  1086. };
  1087. /**@}*/
  1088. CARLA_BACKEND_END_NAMESPACE
  1089. #else // WANT_FLUIDSYNTH
  1090. # warning fluidsynth not available (no SF2 support)
  1091. #endif
  1092. CARLA_BACKEND_START_NAMESPACE
  1093. CarlaPlugin* CarlaPlugin::newSF2(const initializer& init)
  1094. {
  1095. qDebug("CarlaPlugin::newSF2(%p, \"%s\", \"%s\", \"%s\")", init.engine, init.filename, init.name, init.label);
  1096. #ifdef WANT_FLUIDSYNTH
  1097. short id = init.engine->getNewPluginId();
  1098. if (id < 0 || id > init.engine->maxPluginNumber())
  1099. {
  1100. init.engine->setLastError("Maximum number of plugins reached");
  1101. return nullptr;
  1102. }
  1103. if (! fluid_is_soundfont(init.filename))
  1104. {
  1105. init.engine->setLastError("Requested file is not a valid SoundFont");
  1106. return nullptr;
  1107. }
  1108. FluidSynthPlugin* const plugin = new FluidSynthPlugin(init.engine, id);
  1109. if (! plugin->init(init.filename, init.name, init.label))
  1110. {
  1111. delete plugin;
  1112. return nullptr;
  1113. }
  1114. plugin->reload();
  1115. plugin->registerToOscControl();
  1116. return plugin;
  1117. #else
  1118. init.engine->setLastError("fluidsynth support not available");
  1119. return nullptr;
  1120. #endif
  1121. }
  1122. CARLA_BACKEND_END_NAMESPACE