fluidsynth.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. #include "config.h"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <limits.h>
  5. #include "midi/base.h"
  6. #include "alMain.h"
  7. #include "alError.h"
  8. #include "alMidi.h"
  9. #include "evtqueue.h"
  10. #include "rwlock.h"
  11. #include "alu.h"
  12. #ifdef HAVE_FLUIDSYNTH
  13. #include <fluidsynth.h>
  14. /* MIDI events */
  15. #define SYSEX_EVENT (0xF0)
  16. /* MIDI controllers */
  17. #define CTRL_BANKSELECT_MSB (0)
  18. #define CTRL_BANKSELECT_LSB (32)
  19. #define CTRL_ALLNOTESOFF (123)
  20. static int getGenInput(ALenum input)
  21. {
  22. switch(input)
  23. {
  24. case AL_ONE_SOFT: return FLUID_MOD_NONE;
  25. case AL_NOTEON_VELOCITY_SOFT: return FLUID_MOD_VELOCITY;
  26. case AL_NOTEON_KEY_SOFT: return FLUID_MOD_KEY;
  27. case AL_KEYPRESSURE_SOFT: return FLUID_MOD_KEYPRESSURE;
  28. case AL_CHANNELPRESSURE_SOFT: return FLUID_MOD_CHANNELPRESSURE;
  29. case AL_PITCHBEND_SOFT: return FLUID_MOD_PITCHWHEEL;
  30. case AL_PITCHBEND_SENSITIVITY_SOFT: return FLUID_MOD_PITCHWHEELSENS;
  31. }
  32. return input&0x7F;
  33. }
  34. static int getGenFlags(ALenum input, ALenum type, ALenum form)
  35. {
  36. int ret = 0;
  37. switch(type)
  38. {
  39. case AL_UNORM_SOFT: ret |= FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE; break;
  40. case AL_UNORM_REV_SOFT: ret |= FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE; break;
  41. case AL_SNORM_SOFT: ret |= FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE; break;
  42. case AL_SNORM_REV_SOFT: ret |= FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE; break;
  43. }
  44. switch(form)
  45. {
  46. case AL_LINEAR_SOFT: ret |= FLUID_MOD_LINEAR; break;
  47. case AL_CONCAVE_SOFT: ret |= FLUID_MOD_CONCAVE; break;
  48. case AL_CONVEX_SOFT: ret |= FLUID_MOD_CONVEX; break;
  49. case AL_SWITCH_SOFT: ret |= FLUID_MOD_SWITCH; break;
  50. }
  51. /* Source input values less than 128 correspond to a MIDI continuous
  52. * controller. Otherwise, it's a general controller. */
  53. if(input < 128) ret |= FLUID_MOD_CC;
  54. else ret |= FLUID_MOD_GC;
  55. return ret;
  56. }
  57. static enum fluid_gen_type getSf2Gen(ALenum gen)
  58. {
  59. switch(gen)
  60. {
  61. case AL_MOD_LFO_TO_PITCH_SOFT: return GEN_MODLFOTOPITCH;
  62. case AL_VIBRATO_LFO_TO_PITCH_SOFT: return GEN_VIBLFOTOPITCH;
  63. case AL_MOD_ENV_TO_PITCH_SOFT: return GEN_MODENVTOPITCH;
  64. case AL_FILTER_CUTOFF_SOFT: return GEN_FILTERFC;
  65. case AL_FILTER_RESONANCE_SOFT: return GEN_FILTERQ;
  66. case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: return GEN_MODLFOTOFILTERFC;
  67. case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: return GEN_MODENVTOFILTERFC;
  68. case AL_MOD_LFO_TO_VOLUME_SOFT: return GEN_MODLFOTOVOL;
  69. case AL_CHORUS_SEND_SOFT: return GEN_CHORUSSEND;
  70. case AL_REVERB_SEND_SOFT: return GEN_REVERBSEND;
  71. case AL_PAN_SOFT: return GEN_PAN;
  72. case AL_MOD_LFO_DELAY_SOFT: return GEN_MODLFODELAY;
  73. case AL_MOD_LFO_FREQUENCY_SOFT: return GEN_MODLFOFREQ;
  74. case AL_VIBRATO_LFO_DELAY_SOFT: return GEN_VIBLFODELAY;
  75. case AL_VIBRATO_LFO_FREQUENCY_SOFT: return GEN_VIBLFOFREQ;
  76. case AL_MOD_ENV_DELAYTIME_SOFT: return GEN_MODENVDELAY;
  77. case AL_MOD_ENV_ATTACKTIME_SOFT: return GEN_MODENVATTACK;
  78. case AL_MOD_ENV_HOLDTIME_SOFT: return GEN_MODENVHOLD;
  79. case AL_MOD_ENV_DECAYTIME_SOFT: return GEN_MODENVDECAY;
  80. case AL_MOD_ENV_SUSTAINVOLUME_SOFT: return GEN_MODENVSUSTAIN;
  81. case AL_MOD_ENV_RELEASETIME_SOFT: return GEN_MODENVRELEASE;
  82. case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: return GEN_KEYTOMODENVHOLD;
  83. case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: return GEN_KEYTOMODENVDECAY;
  84. case AL_VOLUME_ENV_DELAYTIME_SOFT: return GEN_VOLENVDELAY;
  85. case AL_VOLUME_ENV_ATTACKTIME_SOFT: return GEN_VOLENVATTACK;
  86. case AL_VOLUME_ENV_HOLDTIME_SOFT: return GEN_VOLENVHOLD;
  87. case AL_VOLUME_ENV_DECAYTIME_SOFT: return GEN_VOLENVDECAY;
  88. case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: return GEN_VOLENVSUSTAIN;
  89. case AL_VOLUME_ENV_RELEASETIME_SOFT: return GEN_VOLENVRELEASE;
  90. case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: return GEN_KEYTOVOLENVHOLD;
  91. case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: return GEN_KEYTOVOLENVDECAY;
  92. case AL_ATTENUATION_SOFT: return GEN_ATTENUATION;
  93. case AL_TUNING_COARSE_SOFT: return GEN_COARSETUNE;
  94. case AL_TUNING_FINE_SOFT: return GEN_FINETUNE;
  95. case AL_TUNING_SCALE_SOFT: return GEN_SCALETUNE;
  96. }
  97. ERR("Unhandled generator: 0x%04x\n", gen);
  98. return 0;
  99. }
  100. static int getSf2LoopMode(ALenum mode)
  101. {
  102. switch(mode)
  103. {
  104. case AL_NONE: return 0;
  105. case AL_LOOP_CONTINUOUS_SOFT: return 1;
  106. case AL_LOOP_UNTIL_RELEASE_SOFT: return 3;
  107. }
  108. return 0;
  109. }
  110. static int getSampleType(ALenum type)
  111. {
  112. switch(type)
  113. {
  114. case AL_MONO_SOFT: return FLUID_SAMPLETYPE_MONO;
  115. case AL_RIGHT_SOFT: return FLUID_SAMPLETYPE_RIGHT;
  116. case AL_LEFT_SOFT: return FLUID_SAMPLETYPE_LEFT;
  117. }
  118. return FLUID_SAMPLETYPE_MONO;
  119. }
  120. typedef struct FSample {
  121. DERIVE_FROM_TYPE(fluid_sample_t);
  122. ALfontsound *Sound;
  123. fluid_mod_t *Mods;
  124. ALsizei NumMods;
  125. } FSample;
  126. static void FSample_Construct(FSample *self, ALfontsound *sound, ALsoundfont *sfont)
  127. {
  128. fluid_sample_t *sample = STATIC_CAST(fluid_sample_t, self);
  129. memset(sample->name, 0, sizeof(sample->name));
  130. sample->start = sound->Start;
  131. sample->end = sound->End;
  132. sample->loopstart = sound->LoopStart;
  133. sample->loopend = sound->LoopEnd;
  134. sample->samplerate = sound->SampleRate;
  135. sample->origpitch = sound->PitchKey;
  136. sample->pitchadj = sound->PitchCorrection;
  137. sample->sampletype = getSampleType(sound->SampleType);
  138. sample->valid = 1;
  139. sample->data = sfont->Samples;
  140. sample->amplitude_that_reaches_noise_floor_is_valid = 0;
  141. sample->amplitude_that_reaches_noise_floor = 0.0;
  142. sample->refcount = 0;
  143. sample->notify = NULL;
  144. sample->userdata = self;
  145. self->Sound = sound;
  146. self->NumMods = 0;
  147. self->Mods = calloc(sound->ModulatorMap.size, sizeof(self->Mods[0]));
  148. if(self->Mods)
  149. {
  150. ALsizei i;
  151. self->NumMods = sound->ModulatorMap.size;
  152. for(i = 0;i < self->NumMods;i++)
  153. {
  154. ALsfmodulator *mod = sound->ModulatorMap.array[i].value;
  155. fluid_mod_set_source1(&self->Mods[i], getGenInput(mod->Source[0].Input),
  156. getGenFlags(mod->Source[0].Input, mod->Source[0].Type,
  157. mod->Source[0].Form));
  158. fluid_mod_set_source2(&self->Mods[i], getGenInput(mod->Source[1].Input),
  159. getGenFlags(mod->Source[1].Input, mod->Source[1].Type,
  160. mod->Source[1].Form));
  161. fluid_mod_set_amount(&self->Mods[i], mod->Amount);
  162. fluid_mod_set_dest(&self->Mods[i], getSf2Gen(mod->Dest));
  163. self->Mods[i].next = NULL;
  164. }
  165. }
  166. }
  167. static void FSample_Destruct(FSample *self)
  168. {
  169. free(self->Mods);
  170. self->Mods = NULL;
  171. self->NumMods = 0;
  172. }
  173. typedef struct FPreset {
  174. DERIVE_FROM_TYPE(fluid_preset_t);
  175. char Name[16];
  176. int Preset;
  177. int Bank;
  178. FSample *Samples;
  179. ALsizei NumSamples;
  180. } FPreset;
  181. static char* FPreset_getName(fluid_preset_t *preset);
  182. static int FPreset_getPreset(fluid_preset_t *preset);
  183. static int FPreset_getBank(fluid_preset_t *preset);
  184. static int FPreset_noteOn(fluid_preset_t *preset, fluid_synth_t *synth, int channel, int key, int velocity);
  185. static void FPreset_Construct(FPreset *self, ALsfpreset *preset, fluid_sfont_t *parent, ALsoundfont *sfont)
  186. {
  187. STATIC_CAST(fluid_preset_t, self)->data = self;
  188. STATIC_CAST(fluid_preset_t, self)->sfont = parent;
  189. STATIC_CAST(fluid_preset_t, self)->free = NULL;
  190. STATIC_CAST(fluid_preset_t, self)->get_name = FPreset_getName;
  191. STATIC_CAST(fluid_preset_t, self)->get_banknum = FPreset_getBank;
  192. STATIC_CAST(fluid_preset_t, self)->get_num = FPreset_getPreset;
  193. STATIC_CAST(fluid_preset_t, self)->noteon = FPreset_noteOn;
  194. STATIC_CAST(fluid_preset_t, self)->notify = NULL;
  195. memset(self->Name, 0, sizeof(self->Name));
  196. self->Preset = preset->Preset;
  197. self->Bank = preset->Bank;
  198. self->NumSamples = 0;
  199. self->Samples = calloc(1, preset->NumSounds * sizeof(self->Samples[0]));
  200. if(self->Samples)
  201. {
  202. ALsizei i;
  203. self->NumSamples = preset->NumSounds;
  204. for(i = 0;i < self->NumSamples;i++)
  205. FSample_Construct(&self->Samples[i], preset->Sounds[i], sfont);
  206. }
  207. }
  208. static void FPreset_Destruct(FPreset *self)
  209. {
  210. ALsizei i;
  211. for(i = 0;i < self->NumSamples;i++)
  212. FSample_Destruct(&self->Samples[i]);
  213. free(self->Samples);
  214. self->Samples = NULL;
  215. self->NumSamples = 0;
  216. }
  217. static ALboolean FPreset_canDelete(FPreset *self)
  218. {
  219. ALsizei i;
  220. for(i = 0;i < self->NumSamples;i++)
  221. {
  222. if(fluid_sample_refcount(STATIC_CAST(fluid_sample_t, &self->Samples[i])) != 0)
  223. return AL_FALSE;
  224. }
  225. return AL_TRUE;
  226. }
  227. static char* FPreset_getName(fluid_preset_t *preset)
  228. {
  229. return ((FPreset*)preset->data)->Name;
  230. }
  231. static int FPreset_getPreset(fluid_preset_t *preset)
  232. {
  233. return ((FPreset*)preset->data)->Preset;
  234. }
  235. static int FPreset_getBank(fluid_preset_t *preset)
  236. {
  237. return ((FPreset*)preset->data)->Bank;
  238. }
  239. static int FPreset_noteOn(fluid_preset_t *preset, fluid_synth_t *synth, int channel, int key, int vel)
  240. {
  241. FPreset *self = ((FPreset*)preset->data);
  242. ALsizei i;
  243. for(i = 0;i < self->NumSamples;i++)
  244. {
  245. FSample *sample = &self->Samples[i];
  246. ALfontsound *sound = sample->Sound;
  247. fluid_voice_t *voice;
  248. ALsizei m;
  249. if(!(key >= sound->MinKey && key <= sound->MaxKey && vel >= sound->MinVelocity && vel <= sound->MaxVelocity))
  250. continue;
  251. voice = fluid_synth_alloc_voice(synth, STATIC_CAST(fluid_sample_t, sample), channel, key, vel);
  252. if(voice == NULL)
  253. return FLUID_FAILED;
  254. fluid_voice_gen_set(voice, GEN_MODLFOTOPITCH, sound->ModLfoToPitch);
  255. fluid_voice_gen_set(voice, GEN_VIBLFOTOPITCH, sound->VibratoLfoToPitch);
  256. fluid_voice_gen_set(voice, GEN_MODENVTOPITCH, sound->ModEnvToPitch);
  257. fluid_voice_gen_set(voice, GEN_FILTERFC, sound->FilterCutoff);
  258. fluid_voice_gen_set(voice, GEN_FILTERQ, sound->FilterQ);
  259. fluid_voice_gen_set(voice, GEN_MODLFOTOFILTERFC, sound->ModLfoToFilterCutoff);
  260. fluid_voice_gen_set(voice, GEN_MODENVTOFILTERFC, sound->ModEnvToFilterCutoff);
  261. fluid_voice_gen_set(voice, GEN_MODLFOTOVOL, sound->ModLfoToVolume);
  262. fluid_voice_gen_set(voice, GEN_CHORUSSEND, sound->ChorusSend);
  263. fluid_voice_gen_set(voice, GEN_REVERBSEND, sound->ReverbSend);
  264. fluid_voice_gen_set(voice, GEN_PAN, sound->Pan);
  265. fluid_voice_gen_set(voice, GEN_MODLFODELAY, sound->ModLfo.Delay);
  266. fluid_voice_gen_set(voice, GEN_MODLFOFREQ, sound->ModLfo.Frequency);
  267. fluid_voice_gen_set(voice, GEN_VIBLFODELAY, sound->VibratoLfo.Delay);
  268. fluid_voice_gen_set(voice, GEN_VIBLFOFREQ, sound->VibratoLfo.Frequency);
  269. fluid_voice_gen_set(voice, GEN_MODENVDELAY, sound->ModEnv.DelayTime);
  270. fluid_voice_gen_set(voice, GEN_MODENVATTACK, sound->ModEnv.AttackTime);
  271. fluid_voice_gen_set(voice, GEN_MODENVHOLD, sound->ModEnv.HoldTime);
  272. fluid_voice_gen_set(voice, GEN_MODENVDECAY, sound->ModEnv.DecayTime);
  273. fluid_voice_gen_set(voice, GEN_MODENVSUSTAIN, sound->ModEnv.SustainAttn);
  274. fluid_voice_gen_set(voice, GEN_MODENVRELEASE, sound->ModEnv.ReleaseTime);
  275. fluid_voice_gen_set(voice, GEN_KEYTOMODENVHOLD, sound->ModEnv.KeyToHoldTime);
  276. fluid_voice_gen_set(voice, GEN_KEYTOMODENVDECAY, sound->ModEnv.KeyToDecayTime);
  277. fluid_voice_gen_set(voice, GEN_VOLENVDELAY, sound->VolEnv.DelayTime);
  278. fluid_voice_gen_set(voice, GEN_VOLENVATTACK, sound->VolEnv.AttackTime);
  279. fluid_voice_gen_set(voice, GEN_VOLENVHOLD, sound->VolEnv.HoldTime);
  280. fluid_voice_gen_set(voice, GEN_VOLENVDECAY, sound->VolEnv.DecayTime);
  281. fluid_voice_gen_set(voice, GEN_VOLENVSUSTAIN, sound->VolEnv.SustainAttn);
  282. fluid_voice_gen_set(voice, GEN_VOLENVRELEASE, sound->VolEnv.ReleaseTime);
  283. fluid_voice_gen_set(voice, GEN_KEYTOVOLENVHOLD, sound->VolEnv.KeyToHoldTime);
  284. fluid_voice_gen_set(voice, GEN_KEYTOVOLENVDECAY, sound->VolEnv.KeyToDecayTime);
  285. fluid_voice_gen_set(voice, GEN_ATTENUATION, sound->Attenuation);
  286. fluid_voice_gen_set(voice, GEN_COARSETUNE, sound->CoarseTuning);
  287. fluid_voice_gen_set(voice, GEN_FINETUNE, sound->FineTuning);
  288. fluid_voice_gen_set(voice, GEN_SAMPLEMODE, getSf2LoopMode(sound->LoopMode));
  289. fluid_voice_gen_set(voice, GEN_SCALETUNE, sound->TuningScale);
  290. fluid_voice_gen_set(voice, GEN_EXCLUSIVECLASS, sound->ExclusiveClass);
  291. for(m = 0;m < sample->NumMods;m++)
  292. fluid_voice_add_mod(voice, &sample->Mods[m], FLUID_VOICE_OVERWRITE);
  293. fluid_synth_start_voice(synth, voice);
  294. }
  295. return FLUID_OK;
  296. }
  297. typedef struct FSfont {
  298. DERIVE_FROM_TYPE(fluid_sfont_t);
  299. char Name[16];
  300. FPreset *Presets;
  301. ALsizei NumPresets;
  302. ALsizei CurrentPos;
  303. } FSfont;
  304. static int FSfont_free(fluid_sfont_t *sfont);
  305. static char* FSfont_getName(fluid_sfont_t *sfont);
  306. static fluid_preset_t* FSfont_getPreset(fluid_sfont_t *sfont, unsigned int bank, unsigned int prenum);
  307. static void FSfont_iterStart(fluid_sfont_t *sfont);
  308. static int FSfont_iterNext(fluid_sfont_t *sfont, fluid_preset_t *preset);
  309. static void FSfont_Construct(FSfont *self, ALsoundfont *sfont)
  310. {
  311. STATIC_CAST(fluid_sfont_t, self)->data = self;
  312. STATIC_CAST(fluid_sfont_t, self)->id = FLUID_FAILED;
  313. STATIC_CAST(fluid_sfont_t, self)->free = FSfont_free;
  314. STATIC_CAST(fluid_sfont_t, self)->get_name = FSfont_getName;
  315. STATIC_CAST(fluid_sfont_t, self)->get_preset = FSfont_getPreset;
  316. STATIC_CAST(fluid_sfont_t, self)->iteration_start = FSfont_iterStart;
  317. STATIC_CAST(fluid_sfont_t, self)->iteration_next = FSfont_iterNext;
  318. memset(self->Name, 0, sizeof(self->Name));
  319. self->CurrentPos = 0;
  320. self->NumPresets = 0;
  321. self->Presets = calloc(1, sfont->NumPresets * sizeof(self->Presets[0]));
  322. if(self->Presets)
  323. {
  324. ALsizei i;
  325. self->NumPresets = sfont->NumPresets;
  326. for(i = 0;i < self->NumPresets;i++)
  327. FPreset_Construct(&self->Presets[i], sfont->Presets[i], STATIC_CAST(fluid_sfont_t, self), sfont);
  328. }
  329. }
  330. static void FSfont_Destruct(FSfont *self)
  331. {
  332. ALsizei i;
  333. for(i = 0;i < self->NumPresets;i++)
  334. FPreset_Destruct(&self->Presets[i]);
  335. free(self->Presets);
  336. self->Presets = NULL;
  337. self->NumPresets = 0;
  338. self->CurrentPos = 0;
  339. }
  340. static int FSfont_free(fluid_sfont_t *sfont)
  341. {
  342. FSfont *self = STATIC_UPCAST(FSfont, fluid_sfont_t, sfont);
  343. ALsizei i;
  344. for(i = 0;i < self->NumPresets;i++)
  345. {
  346. if(!FPreset_canDelete(&self->Presets[i]))
  347. return 1;
  348. }
  349. FSfont_Destruct(self);
  350. free(self);
  351. return 0;
  352. }
  353. static char* FSfont_getName(fluid_sfont_t *sfont)
  354. {
  355. return STATIC_UPCAST(FSfont, fluid_sfont_t, sfont)->Name;
  356. }
  357. static fluid_preset_t *FSfont_getPreset(fluid_sfont_t *sfont, unsigned int bank, unsigned int prenum)
  358. {
  359. FSfont *self = STATIC_UPCAST(FSfont, fluid_sfont_t, sfont);
  360. ALsizei i;
  361. for(i = 0;i < self->NumPresets;i++)
  362. {
  363. FPreset *preset = &self->Presets[i];
  364. if(preset->Bank == (int)bank && preset->Preset == (int)prenum)
  365. return STATIC_CAST(fluid_preset_t, preset);
  366. }
  367. return NULL;
  368. }
  369. static void FSfont_iterStart(fluid_sfont_t *sfont)
  370. {
  371. STATIC_UPCAST(FSfont, fluid_sfont_t, sfont)->CurrentPos = 0;
  372. }
  373. static int FSfont_iterNext(fluid_sfont_t *sfont, fluid_preset_t *preset)
  374. {
  375. FSfont *self = STATIC_UPCAST(FSfont, fluid_sfont_t, sfont);
  376. if(self->CurrentPos >= self->NumPresets)
  377. return 0;
  378. *preset = *STATIC_CAST(fluid_preset_t, &self->Presets[self->CurrentPos++]);
  379. preset->free = NULL;
  380. return 1;
  381. }
  382. typedef struct FSynth {
  383. DERIVE_FROM_TYPE(MidiSynth);
  384. DERIVE_FROM_TYPE(fluid_sfloader_t);
  385. fluid_settings_t *Settings;
  386. fluid_synth_t *Synth;
  387. int *FontIDs;
  388. ALsizei NumFontIDs;
  389. ALboolean ForceGM2BankSelect;
  390. ALfloat GainScale;
  391. } FSynth;
  392. static void FSynth_Construct(FSynth *self, ALCdevice *device);
  393. static void FSynth_Destruct(FSynth *self);
  394. static ALboolean FSynth_init(FSynth *self, ALCdevice *device);
  395. static ALenum FSynth_selectSoundfonts(FSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids);
  396. static void FSynth_setGain(FSynth *self, ALfloat gain);
  397. static void FSynth_setState(FSynth *self, ALenum state);
  398. static void FSynth_stop(FSynth *self);
  399. static void FSynth_reset(FSynth *self);
  400. static void FSynth_update(FSynth *self, ALCdevice *device);
  401. static void FSynth_processQueue(FSynth *self, ALuint64 time);
  402. static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]);
  403. static void FSynth_Delete(FSynth *self);
  404. DEFINE_MIDISYNTH_VTABLE(FSynth);
  405. static fluid_sfont_t *FSynth_loadSfont(fluid_sfloader_t *loader, const char *filename);
  406. static void FSynth_Construct(FSynth *self, ALCdevice *device)
  407. {
  408. MidiSynth_Construct(STATIC_CAST(MidiSynth, self), device);
  409. SET_VTABLE2(FSynth, MidiSynth, self);
  410. STATIC_CAST(fluid_sfloader_t, self)->data = self;
  411. STATIC_CAST(fluid_sfloader_t, self)->free = NULL;
  412. STATIC_CAST(fluid_sfloader_t, self)->load = FSynth_loadSfont;
  413. self->Settings = NULL;
  414. self->Synth = NULL;
  415. self->FontIDs = NULL;
  416. self->NumFontIDs = 0;
  417. self->ForceGM2BankSelect = AL_FALSE;
  418. self->GainScale = 0.2f;
  419. }
  420. static void FSynth_Destruct(FSynth *self)
  421. {
  422. ALsizei i;
  423. for(i = 0;i < self->NumFontIDs;i++)
  424. fluid_synth_sfunload(self->Synth, self->FontIDs[i], 0);
  425. free(self->FontIDs);
  426. self->FontIDs = NULL;
  427. self->NumFontIDs = 0;
  428. if(self->Synth != NULL)
  429. delete_fluid_synth(self->Synth);
  430. self->Synth = NULL;
  431. if(self->Settings != NULL)
  432. delete_fluid_settings(self->Settings);
  433. self->Settings = NULL;
  434. MidiSynth_Destruct(STATIC_CAST(MidiSynth, self));
  435. }
  436. static ALboolean FSynth_init(FSynth *self, ALCdevice *device)
  437. {
  438. ALfloat vol;
  439. if(ConfigValueFloat("midi", "volume", &vol))
  440. {
  441. if(!(vol <= 0.0f))
  442. {
  443. ERR("MIDI volume %f clamped to 0\n", vol);
  444. vol = 0.0f;
  445. }
  446. self->GainScale = powf(10.0f, vol / 20.0f);
  447. }
  448. self->Settings = new_fluid_settings();
  449. if(!self->Settings)
  450. {
  451. ERR("Failed to create FluidSettings\n");
  452. return AL_FALSE;
  453. }
  454. fluid_settings_setint(self->Settings, "synth.polyphony", 256);
  455. fluid_settings_setnum(self->Settings, "synth.gain", self->GainScale);
  456. fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency);
  457. self->Synth = new_fluid_synth(self->Settings);
  458. if(!self->Synth)
  459. {
  460. ERR("Failed to create FluidSynth\n");
  461. return AL_FALSE;
  462. }
  463. fluid_synth_add_sfloader(self->Synth, STATIC_CAST(fluid_sfloader_t, self));
  464. return AL_TRUE;
  465. }
  466. static fluid_sfont_t *FSynth_loadSfont(fluid_sfloader_t *loader, const char *filename)
  467. {
  468. FSynth *self = STATIC_UPCAST(FSynth, fluid_sfloader_t, loader);
  469. FSfont *sfont;
  470. int idx;
  471. if(!filename || sscanf(filename, "_al_internal %d", &idx) != 1)
  472. return NULL;
  473. if(idx < 0 || idx >= STATIC_CAST(MidiSynth, self)->NumSoundfonts)
  474. {
  475. ERR("Received invalid soundfont index %d (max: %d)\n", idx, STATIC_CAST(MidiSynth, self)->NumSoundfonts);
  476. return NULL;
  477. }
  478. sfont = calloc(1, sizeof(sfont[0]));
  479. if(!sfont) return NULL;
  480. FSfont_Construct(sfont, STATIC_CAST(MidiSynth, self)->Soundfonts[idx]);
  481. return STATIC_CAST(fluid_sfont_t, sfont);
  482. }
  483. static ALenum FSynth_selectSoundfonts(FSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids)
  484. {
  485. int *fontid;
  486. ALenum ret;
  487. ALsizei i;
  488. ret = MidiSynth_selectSoundfonts(STATIC_CAST(MidiSynth, self), context, count, ids);
  489. if(ret != AL_NO_ERROR) return ret;
  490. ALCdevice_Lock(context->Device);
  491. for(i = 0;i < 16;i++)
  492. fluid_synth_all_sounds_off(self->Synth, i);
  493. ALCdevice_Unlock(context->Device);
  494. fontid = malloc(count * sizeof(fontid[0]));
  495. if(fontid)
  496. {
  497. for(i = 0;i < STATIC_CAST(MidiSynth, self)->NumSoundfonts;i++)
  498. {
  499. char name[16];
  500. snprintf(name, sizeof(name), "_al_internal %d", i);
  501. fontid[i] = fluid_synth_sfload(self->Synth, name, 0);
  502. if(fontid[i] == FLUID_FAILED)
  503. ERR("Failed to load selected soundfont %d\n", i);
  504. }
  505. fontid = ExchangePtr((XchgPtr*)&self->FontIDs, fontid);
  506. count = ExchangeInt(&self->NumFontIDs, count);
  507. }
  508. else
  509. {
  510. ERR("Failed to allocate space for %d font IDs!\n", count);
  511. fontid = ExchangePtr((XchgPtr*)&self->FontIDs, NULL);
  512. count = ExchangeInt(&self->NumFontIDs, 0);
  513. }
  514. for(i = 0;i < count;i++)
  515. fluid_synth_sfunload(self->Synth, fontid[i], 0);
  516. free(fontid);
  517. return ret;
  518. }
  519. static void FSynth_setGain(FSynth *self, ALfloat gain)
  520. {
  521. fluid_settings_setnum(self->Settings, "synth.gain", self->GainScale * gain);
  522. fluid_synth_set_gain(self->Synth, self->GainScale * gain);
  523. MidiSynth_setGain(STATIC_CAST(MidiSynth, self), gain);
  524. }
  525. static void FSynth_setState(FSynth *self, ALenum state)
  526. {
  527. MidiSynth_setState(STATIC_CAST(MidiSynth, self), state);
  528. }
  529. static void FSynth_stop(FSynth *self)
  530. {
  531. MidiSynth *synth = STATIC_CAST(MidiSynth, self);
  532. ALsizei chan;
  533. /* Make sure all pending events are processed. */
  534. while(!(synth->SamplesToNext >= 1.0))
  535. {
  536. ALuint64 time = synth->NextEvtTime;
  537. if(time == UINT64_MAX)
  538. break;
  539. synth->SamplesSinceLast -= (time - synth->LastEvtTime) * synth->SamplesPerTick;
  540. synth->SamplesSinceLast = maxd(synth->SamplesSinceLast, 0.0);
  541. synth->LastEvtTime = time;
  542. FSynth_processQueue(self, time);
  543. synth->NextEvtTime = MidiSynth_getNextEvtTime(synth);
  544. if(synth->NextEvtTime != UINT64_MAX)
  545. synth->SamplesToNext += (synth->NextEvtTime - synth->LastEvtTime) * synth->SamplesPerTick;
  546. }
  547. /* All notes off */
  548. for(chan = 0;chan < 16;chan++)
  549. fluid_synth_cc(self->Synth, chan, CTRL_ALLNOTESOFF, 0);
  550. MidiSynth_stop(STATIC_CAST(MidiSynth, self));
  551. }
  552. static void FSynth_reset(FSynth *self)
  553. {
  554. /* Reset to power-up status. */
  555. fluid_synth_system_reset(self->Synth);
  556. MidiSynth_reset(STATIC_CAST(MidiSynth, self));
  557. }
  558. static void FSynth_update(FSynth *self, ALCdevice *device)
  559. {
  560. fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency);
  561. fluid_synth_set_sample_rate(self->Synth, device->Frequency);
  562. MidiSynth_update(STATIC_CAST(MidiSynth, self), device);
  563. }
  564. static void FSynth_processQueue(FSynth *self, ALuint64 time)
  565. {
  566. EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue;
  567. while(queue->pos < queue->size && queue->events[queue->pos].time <= time)
  568. {
  569. const MidiEvent *evt = &queue->events[queue->pos];
  570. if(evt->event == SYSEX_EVENT)
  571. {
  572. static const ALbyte gm2_on[] = { 0x7E, 0x7F, 0x09, 0x03 };
  573. static const ALbyte gm2_off[] = { 0x7E, 0x7F, 0x09, 0x02 };
  574. int handled = 0;
  575. fluid_synth_sysex(self->Synth, evt->param.sysex.data, evt->param.sysex.size, NULL, NULL, &handled, 0);
  576. if(!handled && evt->param.sysex.size >= (ALsizei)sizeof(gm2_on))
  577. {
  578. if(memcmp(evt->param.sysex.data, gm2_on, sizeof(gm2_on)) == 0)
  579. self->ForceGM2BankSelect = AL_TRUE;
  580. else if(memcmp(evt->param.sysex.data, gm2_off, sizeof(gm2_off)) == 0)
  581. self->ForceGM2BankSelect = AL_FALSE;
  582. }
  583. }
  584. else switch((evt->event&0xF0))
  585. {
  586. case AL_NOTEOFF_SOFT:
  587. fluid_synth_noteoff(self->Synth, (evt->event&0x0F), evt->param.val[0]);
  588. break;
  589. case AL_NOTEON_SOFT:
  590. fluid_synth_noteon(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]);
  591. break;
  592. case AL_KEYPRESSURE_SOFT:
  593. break;
  594. case AL_CONTROLLERCHANGE_SOFT:
  595. if(self->ForceGM2BankSelect)
  596. {
  597. int chan = (evt->event&0x0F);
  598. if(evt->param.val[0] == CTRL_BANKSELECT_MSB)
  599. {
  600. if(evt->param.val[1] == 120 && (chan == 9 || chan == 10))
  601. fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_DRUM);
  602. else if(evt->param.val[1] == 121)
  603. fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_MELODIC);
  604. break;
  605. }
  606. if(evt->param.val[0] == CTRL_BANKSELECT_LSB)
  607. {
  608. fluid_synth_bank_select(self->Synth, chan, evt->param.val[1]);
  609. break;
  610. }
  611. }
  612. fluid_synth_cc(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]);
  613. break;
  614. case AL_PROGRAMCHANGE_SOFT:
  615. fluid_synth_program_change(self->Synth, (evt->event&0x0F), evt->param.val[0]);
  616. break;
  617. case AL_CHANNELPRESSURE_SOFT:
  618. fluid_synth_channel_pressure(self->Synth, (evt->event&0x0F), evt->param.val[0]);
  619. break;
  620. case AL_PITCHBEND_SOFT:
  621. fluid_synth_pitch_bend(self->Synth, (evt->event&0x0F), (evt->param.val[0]&0x7F) |
  622. ((evt->param.val[1]&0x7F)<<7));
  623. break;
  624. }
  625. queue->pos++;
  626. }
  627. }
  628. static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE])
  629. {
  630. MidiSynth *synth = STATIC_CAST(MidiSynth, self);
  631. ALenum state = synth->State;
  632. ALuint total = 0;
  633. if(state == AL_INITIAL)
  634. return;
  635. if(state != AL_PLAYING)
  636. {
  637. fluid_synth_write_float(self->Synth, SamplesToDo, DryBuffer[FrontLeft], 0, 1,
  638. DryBuffer[FrontRight], 0, 1);
  639. return;
  640. }
  641. while(total < SamplesToDo)
  642. {
  643. if(synth->SamplesToNext >= 1.0)
  644. {
  645. ALuint todo = minu(SamplesToDo - total, fastf2u(synth->SamplesToNext));
  646. fluid_synth_write_float(self->Synth, todo,
  647. &DryBuffer[FrontLeft][total], 0, 1,
  648. &DryBuffer[FrontRight][total], 0, 1);
  649. total += todo;
  650. synth->SamplesSinceLast += todo;
  651. synth->SamplesToNext -= todo;
  652. }
  653. else
  654. {
  655. ALuint64 time = synth->NextEvtTime;
  656. if(time == UINT64_MAX)
  657. {
  658. synth->SamplesSinceLast += SamplesToDo-total;
  659. fluid_synth_write_float(self->Synth, SamplesToDo-total,
  660. &DryBuffer[FrontLeft][total], 0, 1,
  661. &DryBuffer[FrontRight][total], 0, 1);
  662. break;
  663. }
  664. synth->SamplesSinceLast -= (time - synth->LastEvtTime) * synth->SamplesPerTick;
  665. synth->SamplesSinceLast = maxd(synth->SamplesSinceLast, 0.0);
  666. synth->LastEvtTime = time;
  667. FSynth_processQueue(self, time);
  668. synth->NextEvtTime = MidiSynth_getNextEvtTime(synth);
  669. if(synth->NextEvtTime != UINT64_MAX)
  670. synth->SamplesToNext += (synth->NextEvtTime - synth->LastEvtTime) * synth->SamplesPerTick;
  671. }
  672. }
  673. }
  674. static void FSynth_Delete(FSynth *self)
  675. {
  676. free(self);
  677. }
  678. MidiSynth *FSynth_create(ALCdevice *device)
  679. {
  680. FSynth *synth = calloc(1, sizeof(*synth));
  681. if(!synth)
  682. {
  683. ERR("Failed to allocate FSynth\n");
  684. return NULL;
  685. }
  686. FSynth_Construct(synth, device);
  687. if(FSynth_init(synth, device) == AL_FALSE)
  688. {
  689. DELETE_OBJ(STATIC_CAST(MidiSynth, synth));
  690. return NULL;
  691. }
  692. return STATIC_CAST(MidiSynth, synth);
  693. }
  694. #else
  695. MidiSynth *FSynth_create(ALCdevice* UNUSED(device))
  696. {
  697. return NULL;
  698. }
  699. #endif