1 /* FluidSynth - A Software Synthesizer
3 * Copyright (C) 2003 Peter Hanappe and others.
5 * SoundFont file loading code borrowed from Smurf SoundFont Editor
6 * Copyright (C) 1999-2001 Josh Green
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 #include "fluid_defsfont.h"
26 #include "fluid_sfont.h"
27 #include "fluid_sys.h"
28 #include "fluid_synth.h"
29 #include "fluid_samplecache.h"
31 /* EMU8k/10k hardware applies this factor to initial attenuation generator values set at preset and
32 * instrument level in a soundfont. We apply this factor when loading the generator values to stay
33 * compatible as most existing soundfonts expect exactly this (strange, non-standard) behaviour. */
34 #define EMU_ATTENUATION_FACTOR (0.4f)
36 /* Dynamic sample loading functions */
37 static int load_preset_samples(fluid_defsfont_t *defsfont, fluid_preset_t *preset);
38 static int unload_preset_samples(fluid_defsfont_t *defsfont, fluid_preset_t *preset);
39 static void unload_sample(fluid_sample_t *sample);
40 static int dynamic_samples_preset_notify(fluid_preset_t *preset, int reason, int chan);
41 static int dynamic_samples_sample_notify(fluid_sample_t *sample, int reason);
42 static int fluid_preset_zone_create_voice_zones(fluid_preset_zone_t *preset_zone);
43 static fluid_inst_t *find_inst_by_idx(fluid_defsfont_t *defsfont, int idx);
46 /***************************************************************
52 * Creates a default soundfont2 loader that can be used with fluid_synth_add_sfloader().
53 * By default every synth instance has an initial default soundfont loader instance.
54 * Calling this function is usually only necessary to load a soundfont from memory, by providing custom callback functions via fluid_sfloader_set_callbacks().
56 * @param settings A settings instance obtained by new_fluid_settings()
57 * @return A default soundfont2 loader struct
59 fluid_sfloader_t *new_fluid_defsfloader(fluid_settings_t *settings)
61 fluid_sfloader_t *loader;
62 fluid_return_val_if_fail(settings != NULL, NULL);
64 loader = new_fluid_sfloader(fluid_defsfloader_load, delete_fluid_sfloader);
68 FLUID_LOG(FLUID_ERR, "Out of memory");
72 fluid_sfloader_set_data(loader, settings);
77 fluid_sfont_t *fluid_defsfloader_load(fluid_sfloader_t *loader, const char *filename)
79 fluid_defsfont_t *defsfont;
82 defsfont = new_fluid_defsfont(fluid_sfloader_get_data(loader));
89 sfont = new_fluid_sfont(fluid_defsfont_sfont_get_name,
90 fluid_defsfont_sfont_get_preset,
91 fluid_defsfont_sfont_iteration_start,
92 fluid_defsfont_sfont_iteration_next,
93 fluid_defsfont_sfont_delete);
97 delete_fluid_defsfont(defsfont);
101 fluid_sfont_set_data(sfont, defsfont);
103 defsfont->sfont = sfont;
105 if(fluid_defsfont_load(defsfont, &loader->file_callbacks, filename) == FLUID_FAILED)
107 fluid_sfont_delete_internal(sfont);
116 /***************************************************************
121 int fluid_defsfont_sfont_delete(fluid_sfont_t *sfont)
123 if(delete_fluid_defsfont(fluid_sfont_get_data(sfont)) != FLUID_OK)
128 delete_fluid_sfont(sfont);
132 const char *fluid_defsfont_sfont_get_name(fluid_sfont_t *sfont)
134 return fluid_defsfont_get_name(fluid_sfont_get_data(sfont));
138 fluid_defsfont_sfont_get_preset(fluid_sfont_t *sfont, int bank, int prenum)
140 return fluid_defsfont_get_preset(fluid_sfont_get_data(sfont), bank, prenum);
143 void fluid_defsfont_sfont_iteration_start(fluid_sfont_t *sfont)
145 fluid_defsfont_iteration_start(fluid_sfont_get_data(sfont));
148 fluid_preset_t *fluid_defsfont_sfont_iteration_next(fluid_sfont_t *sfont)
150 return fluid_defsfont_iteration_next(fluid_sfont_get_data(sfont));
153 void fluid_defpreset_preset_delete(fluid_preset_t *preset)
155 fluid_defsfont_t *defsfont;
156 fluid_defpreset_t *defpreset;
158 defsfont = fluid_sfont_get_data(preset->sfont);
159 defpreset = fluid_preset_get_data(preset);
163 defsfont->preset = fluid_list_remove(defsfont->preset, defpreset);
166 delete_fluid_defpreset(defpreset);
167 delete_fluid_preset(preset);
170 const char *fluid_defpreset_preset_get_name(fluid_preset_t *preset)
172 return fluid_defpreset_get_name(fluid_preset_get_data(preset));
175 int fluid_defpreset_preset_get_banknum(fluid_preset_t *preset)
177 return fluid_defpreset_get_banknum(fluid_preset_get_data(preset));
180 int fluid_defpreset_preset_get_num(fluid_preset_t *preset)
182 return fluid_defpreset_get_num(fluid_preset_get_data(preset));
185 int fluid_defpreset_preset_noteon(fluid_preset_t *preset, fluid_synth_t *synth,
186 int chan, int key, int vel)
188 return fluid_defpreset_noteon(fluid_preset_get_data(preset), synth, chan, key, vel);
192 /***************************************************************
200 fluid_defsfont_t *new_fluid_defsfont(fluid_settings_t *settings)
202 fluid_defsfont_t *defsfont;
204 defsfont = FLUID_NEW(fluid_defsfont_t);
208 FLUID_LOG(FLUID_ERR, "Out of memory");
212 FLUID_MEMSET(defsfont, 0, sizeof(*defsfont));
214 fluid_settings_getint(settings, "synth.lock-memory", &defsfont->mlock);
215 fluid_settings_getint(settings, "synth.dynamic-sample-loading", &defsfont->dynamic_samples);
221 * delete_fluid_defsfont
223 int delete_fluid_defsfont(fluid_defsfont_t *defsfont)
226 fluid_preset_t *preset;
227 fluid_sample_t *sample;
229 fluid_return_val_if_fail(defsfont != NULL, FLUID_OK);
231 /* Check that no samples are currently used */
232 for(list = defsfont->sample; list; list = fluid_list_next(list))
234 sample = (fluid_sample_t *) fluid_list_get(list);
236 if(sample->refcount != 0)
242 if(defsfont->filename != NULL)
244 FLUID_FREE(defsfont->filename);
247 for(list = defsfont->sample; list; list = fluid_list_next(list))
249 delete_fluid_sample((fluid_sample_t *) fluid_list_get(list));
254 delete_fluid_list(defsfont->sample);
257 if(defsfont->sampledata != NULL)
259 fluid_samplecache_unload(defsfont->sampledata);
262 for(list = defsfont->preset; list; list = fluid_list_next(list))
264 preset = (fluid_preset_t *)fluid_list_get(list);
265 fluid_defpreset_preset_delete(preset);
268 delete_fluid_list(defsfont->preset);
270 for(list = defsfont->inst; list; list = fluid_list_next(list))
272 delete_fluid_inst(fluid_list_get(list));
275 delete_fluid_list(defsfont->inst);
277 FLUID_FREE(defsfont);
282 * fluid_defsfont_get_name
284 const char *fluid_defsfont_get_name(fluid_defsfont_t *defsfont)
286 return defsfont->filename;
289 /* Load sample data for a single sample from the Soundfont file.
290 * Returns FLUID_OK on error, otherwise FLUID_FAILED
292 int fluid_defsfont_load_sampledata(fluid_defsfont_t *defsfont, SFData *sfdata, fluid_sample_t *sample)
295 unsigned int source_end = sample->source_end;
297 /* For uncompressed samples we want to include the 46 zero sample word area following each sample
298 * in the Soundfont. Otherwise samples with loopend > end, which we have decided not to correct, would
299 * be corrected after all in fluid_sample_sanitize_loop */
300 if(!(sample->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS))
302 source_end += 46; /* Length of zero sample word after each sample, according to SF specs */
304 /* Safeguard against Soundfonts that are not quite valid and don't include 46 sample words after the
306 if(source_end >= (defsfont->samplesize / sizeof(short)))
308 source_end = defsfont->samplesize / sizeof(short);
312 num_samples = fluid_samplecache_load(
313 sfdata, sample->source_start, source_end, sample->sampletype,
314 defsfont->mlock, &sample->data, &sample->data24);
323 sample->start = sample->end = 0;
324 sample->loopstart = sample->loopend = 0;
328 /* Ogg Vorbis samples already have loop pointers relative to the invididual decompressed sample,
329 * but SF2 samples are relative to sample chunk start, so they need to be adjusted */
330 if(!(sample->sampletype & FLUID_SAMPLETYPE_OGG_VORBIS))
332 sample->loopstart = sample->source_loopstart - sample->source_start;
333 sample->loopend = sample->source_loopend - sample->source_start;
336 /* As we've just loaded an individual sample into it's own buffer, we need to adjust the start
337 * and end pointers */
339 sample->end = num_samples - 1;
344 /* Loads the sample data for all samples from the Soundfont file. For SF2 files, it loads the data in
345 * one large block. For SF3 files, each compressed sample gets loaded individually.
346 * Returns FLUID_OK on success, otherwise FLUID_FAILED
348 int fluid_defsfont_load_all_sampledata(fluid_defsfont_t *defsfont, SFData *sfdata)
351 fluid_sample_t *sample;
352 int sf3_file = (sfdata->version.major == 3);
354 /* For SF2 files, we load the sample data in one large block */
358 int num_samples = sfdata->samplesize / sizeof(short);
360 read_samples = fluid_samplecache_load(sfdata, 0, num_samples - 1, 0, defsfont->mlock,
361 &defsfont->sampledata, &defsfont->sample24data);
363 if(read_samples != num_samples)
365 FLUID_LOG(FLUID_ERR, "Attempted to read %d words of sample data, but got %d instead",
366 num_samples, read_samples);
371 for(list = defsfont->sample; list; list = fluid_list_next(list))
373 sample = fluid_list_get(list);
377 /* SF3 samples get loaded individually, as most (or all) of them are in Ogg Vorbis format
379 if(fluid_defsfont_load_sampledata(defsfont, sfdata, sample) == FLUID_FAILED)
381 FLUID_LOG(FLUID_ERR, "Failed to load sample '%s'", sample->name);
385 fluid_sample_sanitize_loop(sample, (sample->end + 1) * sizeof(short));
389 /* Data pointers of SF2 samples point to large sample data block loaded above */
390 sample->data = defsfont->sampledata;
391 sample->data24 = defsfont->sample24data;
392 fluid_sample_sanitize_loop(sample, defsfont->samplesize);
395 fluid_voice_optimize_sample(sample);
402 * fluid_defsfont_load
404 int fluid_defsfont_load(fluid_defsfont_t *defsfont, const fluid_file_callbacks_t *fcbs, const char *file)
410 fluid_sample_t *sample;
411 fluid_defpreset_t *defpreset = NULL;
413 defsfont->filename = FLUID_STRDUP(file);
415 if(defsfont->filename == NULL)
417 FLUID_LOG(FLUID_ERR, "Out of memory");
421 defsfont->fcbs = fcbs;
423 /* The actual loading is done in the sfont and sffile files */
424 sfdata = fluid_sffile_open(file, fcbs);
428 FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file");
432 if(fluid_sffile_parse_presets(sfdata) == FLUID_FAILED)
434 FLUID_LOG(FLUID_ERR, "Couldn't parse presets from soundfont file");
438 /* Keep track of the position and size of the sample data because
439 it's loaded separately (and might be unoaded/reloaded in future) */
440 defsfont->samplepos = sfdata->samplepos;
441 defsfont->samplesize = sfdata->samplesize;
442 defsfont->sample24pos = sfdata->sample24pos;
443 defsfont->sample24size = sfdata->sample24size;
445 /* Create all samples from sample headers */
450 sfsample = (SFSample *)fluid_list_get(p);
452 sample = new_fluid_sample();
459 if(fluid_sample_import_sfont(sample, sfsample, defsfont) == FLUID_OK)
461 fluid_defsfont_add_sample(defsfont, sample);
465 delete_fluid_sample(sample);
469 /* Store reference to FluidSynth sample in SFSample for later IZone fixups */
470 sfsample->fluid_sample = sample;
472 p = fluid_list_next(p);
475 /* If dynamic sample loading is disabled, load all samples in the Soundfont */
476 if(!defsfont->dynamic_samples)
478 if(fluid_defsfont_load_all_sampledata(defsfont, sfdata) == FLUID_FAILED)
480 FLUID_LOG(FLUID_ERR, "Unable to load all sample data");
485 /* Load all the presets */
490 sfpreset = (SFPreset *)fluid_list_get(p);
491 defpreset = new_fluid_defpreset(defsfont);
493 if(defpreset == NULL)
498 if(fluid_defpreset_import_sfont(defpreset, sfpreset, defsfont) != FLUID_OK)
503 if(fluid_defsfont_add_preset(defsfont, defpreset) == FLUID_FAILED)
508 p = fluid_list_next(p);
511 fluid_sffile_close(sfdata);
516 fluid_sffile_close(sfdata);
517 delete_fluid_defpreset(defpreset);
521 /* fluid_defsfont_add_sample
523 * Add a sample to the SoundFont
525 int fluid_defsfont_add_sample(fluid_defsfont_t *defsfont, fluid_sample_t *sample)
527 defsfont->sample = fluid_list_append(defsfont->sample, sample);
531 /* fluid_defsfont_add_preset
533 * Add a preset to the SoundFont
535 int fluid_defsfont_add_preset(fluid_defsfont_t *defsfont, fluid_defpreset_t *defpreset)
537 fluid_preset_t *preset;
539 preset = new_fluid_preset(defsfont->sfont,
540 fluid_defpreset_preset_get_name,
541 fluid_defpreset_preset_get_banknum,
542 fluid_defpreset_preset_get_num,
543 fluid_defpreset_preset_noteon,
544 fluid_defpreset_preset_delete);
546 if(defsfont->dynamic_samples)
548 preset->notify = dynamic_samples_preset_notify;
556 fluid_preset_set_data(preset, defpreset);
558 defsfont->preset = fluid_list_append(defsfont->preset, preset);
564 * fluid_defsfont_get_preset
566 fluid_preset_t *fluid_defsfont_get_preset(fluid_defsfont_t *defsfont, int bank, int num)
568 fluid_preset_t *preset;
571 for(list = defsfont->preset; list != NULL; list = fluid_list_next(list))
573 preset = (fluid_preset_t *)fluid_list_get(list);
575 if((fluid_preset_get_banknum(preset) == bank) && (fluid_preset_get_num(preset) == num))
585 * fluid_defsfont_iteration_start
587 void fluid_defsfont_iteration_start(fluid_defsfont_t *defsfont)
589 defsfont->preset_iter_cur = defsfont->preset;
593 * fluid_defsfont_iteration_next
595 fluid_preset_t *fluid_defsfont_iteration_next(fluid_defsfont_t *defsfont)
597 fluid_preset_t *preset = (fluid_preset_t *)fluid_list_get(defsfont->preset_iter_cur);
599 defsfont->preset_iter_cur = fluid_list_next(defsfont->preset_iter_cur);
604 /***************************************************************
610 * new_fluid_defpreset
613 new_fluid_defpreset(fluid_defsfont_t *defsfont)
615 fluid_defpreset_t *defpreset = FLUID_NEW(fluid_defpreset_t);
617 if(defpreset == NULL)
619 FLUID_LOG(FLUID_ERR, "Out of memory");
623 defpreset->next = NULL;
624 defpreset->defsfont = defsfont;
625 defpreset->name[0] = 0;
628 defpreset->global_zone = NULL;
629 defpreset->zone = NULL;
634 * delete_fluid_defpreset
637 delete_fluid_defpreset(fluid_defpreset_t *defpreset)
639 fluid_preset_zone_t *zone;
641 fluid_return_if_fail(defpreset != NULL);
643 delete_fluid_preset_zone(defpreset->global_zone);
644 defpreset->global_zone = NULL;
646 zone = defpreset->zone;
650 defpreset->zone = zone->next;
651 delete_fluid_preset_zone(zone);
652 zone = defpreset->zone;
655 FLUID_FREE(defpreset);
659 fluid_defpreset_get_banknum(fluid_defpreset_t *defpreset)
661 return defpreset->bank;
665 fluid_defpreset_get_num(fluid_defpreset_t *defpreset)
667 return defpreset->num;
671 fluid_defpreset_get_name(fluid_defpreset_t *defpreset)
673 return defpreset->name;
677 * fluid_defpreset_next
680 fluid_defpreset_next(fluid_defpreset_t *defpreset)
682 return defpreset->next;
686 * Adds global and local modulators list to the voice. This is done in 2 steps:
687 * - Step 1: Local modulators replace identic global modulators.
688 * - Step 2: global + local modulators are added to the voice using mode.
690 * Instrument zone list (local/global) must be added using FLUID_VOICE_OVERWRITE.
691 * Preset zone list (local/global) must be added using FLUID_VOICE_ADD.
693 * @param voice voice instance.
694 * @param global_mod global list of modulators.
695 * @param local_mod local list of modulators.
696 * @param mode Determines how to handle an existing identical modulator.
697 * #FLUID_VOICE_ADD to add (offset) the modulator amounts,
698 * #FLUID_VOICE_OVERWRITE to replace the modulator,
701 fluid_defpreset_noteon_add_mod_to_voice(fluid_voice_t *voice,
702 fluid_mod_t *global_mod, fluid_mod_t *local_mod,
706 /* list for 'sorting' global/local modulators */
707 fluid_mod_t *mod_list[FLUID_NUM_MOD];
708 int mod_list_count, i;
710 /* identity_limit_count is the modulator upper limit number to handle with
711 * existing identical modulators.
712 * When identity_limit_count is below the actual number of modulators, this
713 * will restrict identity check to this upper limit,
714 * This is useful when we know by advance that there is no duplicate with
715 * modulators at index above this limit. This avoid wasting cpu cycles at
718 int identity_limit_count;
720 /* Step 1: Local modulators replace identic global modulators. */
722 /* local (instrument zone/preset zone), modulators: Put them all into a list. */
727 /* As modulators number in local_mod list was limited to FLUID_NUM_MOD at
728 soundfont loading time (fluid_limit_mod_list()), here we don't need
729 to check if mod_list is full.
731 mod_list[mod_list_count++] = local_mod;
732 local_mod = local_mod->next;
735 /* global (instrument zone/preset zone), modulators.
736 * Replace modulators with the same definition in the global list:
737 * (Instrument zone: SF 2.01 page 69, 'bullet' 8)
738 * (Preset zone: SF 2.01 page 69, second-last bullet).
740 * mod_list contains local modulators. Now we know that there
741 * is no global modulator identic to another global modulator (this has
742 * been checked at soundfont loading time). So global modulators
743 * are only checked against local modulators number.
746 /* Restrict identity check to the number of local modulators */
747 identity_limit_count = mod_list_count;
751 /* 'Identical' global modulators are ignored.
752 * SF2.01 section 9.5.1
753 * page 69, 'bullet' 3 defines 'identical'. */
755 for(i = 0; i < identity_limit_count; i++)
757 if(fluid_mod_test_identity(global_mod, mod_list[i]))
763 /* Finally add the new modulator to the list. */
764 if(i >= identity_limit_count)
766 /* Although local_mod and global_mod lists was limited to
767 FLUID_NUM_MOD at soundfont loading time, it is possible that
768 local + global modulators exceeds FLUID_NUM_MOD.
769 So, checks if mod_list_count reachs the limit.
771 if(mod_list_count >= FLUID_NUM_MOD)
773 /* mod_list is full, we silently forget this modulator and
774 next global modulators. When mod_list will be added to the
775 voice, a warning will be displayed if the voice list is full.
776 (see fluid_voice_add_mod_local()).
781 mod_list[mod_list_count++] = global_mod;
784 global_mod = global_mod->next;
787 /* Step 2: global + local modulators are added to the voice using mode. */
790 * mod_list contains local and global modulators, we know that:
791 * - there is no global modulator identic to another global modulator,
792 * - there is no local modulator identic to another local modulator,
793 * So these local/global modulators are only checked against
794 * actual number of voice modulators.
797 /* Restrict identity check to the actual number of voice modulators */
798 /* Acual number of voice modulators : defaults + [instruments] */
799 identity_limit_count = voice->mod_count;
801 for(i = 0; i < mod_list_count; i++)
805 /* in mode FLUID_VOICE_OVERWRITE disabled instruments modulators CANNOT be skipped. */
806 /* in mode FLUID_VOICE_ADD disabled preset modulators can be skipped. */
808 if((mode == FLUID_VOICE_OVERWRITE) || (mod->amount != 0))
810 /* Instrument modulators -supersede- existing (default) modulators.
811 SF 2.01 page 69, 'bullet' 6 */
813 /* Preset modulators -add- to existing instrument modulators.
814 SF2.01 page 70 first bullet on page */
815 fluid_voice_add_mod_local(voice, mod, mode, identity_limit_count);
821 * fluid_defpreset_noteon
824 fluid_defpreset_noteon(fluid_defpreset_t *defpreset, fluid_synth_t *synth, int chan, int key, int vel)
826 fluid_preset_zone_t *preset_zone, *global_preset_zone;
828 fluid_inst_zone_t *inst_zone, *global_inst_zone;
829 fluid_voice_zone_t *voice_zone;
831 fluid_voice_t *voice;
834 global_preset_zone = fluid_defpreset_get_global_zone(defpreset);
836 /* run thru all the zones of this preset */
837 preset_zone = fluid_defpreset_get_zone(defpreset);
839 while(preset_zone != NULL)
842 /* check if the note falls into the key and velocity range of this
844 if(fluid_zone_inside_range(&preset_zone->range, key, vel))
847 inst = fluid_preset_zone_get_inst(preset_zone);
848 global_inst_zone = fluid_inst_get_global_zone(inst);
850 /* run thru all the zones of this instrument that could start a voice */
851 for(list = preset_zone->voice_zone; list != NULL; list = fluid_list_next(list))
853 voice_zone = fluid_list_get(list);
855 /* check if the instrument zone is ignored and the note falls into
856 the key and velocity range of this instrument zone.
857 An instrument zone must be ignored when its voice is already running
858 played by a legato passage (see fluid_synth_noteon_monopoly_legato()) */
859 if(fluid_zone_inside_range(&voice_zone->range, key, vel))
862 inst_zone = voice_zone->inst_zone;
864 /* this is a good zone. allocate a new synthesis process and initialize it */
865 voice = fluid_synth_alloc_voice_LOCAL(synth, inst_zone->sample, chan, key, vel, &voice_zone->range);
873 /* Instrument level, generators */
875 for(i = 0; i < GEN_LAST; i++)
878 /* SF 2.01 section 9.4 'bullet' 4:
880 * A generator in a local instrument zone supersedes a
881 * global instrument zone generator. Both cases supersede
882 * the default generator -> voice_gen_set */
884 if(inst_zone->gen[i].flags)
886 fluid_voice_gen_set(voice, i, inst_zone->gen[i].val);
889 else if((global_inst_zone != NULL) && (global_inst_zone->gen[i].flags))
891 fluid_voice_gen_set(voice, i, global_inst_zone->gen[i].val);
896 /* The generator has not been defined in this instrument.
897 * Do nothing, leave it at the default.
901 } /* for all generators */
903 /* Adds instrument zone modulators (global and local) to the voice.*/
904 fluid_defpreset_noteon_add_mod_to_voice(voice,
905 /* global instrument modulators */
906 global_inst_zone ? global_inst_zone->mod : NULL,
907 inst_zone->mod, /* local instrument modulators */
908 FLUID_VOICE_OVERWRITE); /* mode */
910 /* Preset level, generators */
912 for(i = 0; i < GEN_LAST; i++)
915 /* SF 2.01 section 8.5 page 58: If some generators are
916 encountered at preset level, they should be ignored.
917 However this check is not necessary when the soundfont
918 loader has ignored invalid preset generators.
919 Actually load_pgen()has ignored these invalid preset
921 GEN_STARTADDROFS, GEN_ENDADDROFS,
922 GEN_STARTLOOPADDROFS, GEN_ENDLOOPADDROFS,
923 GEN_STARTADDRCOARSEOFS,GEN_ENDADDRCOARSEOFS,
924 GEN_STARTLOOPADDRCOARSEOFS,
925 GEN_KEYNUM, GEN_VELOCITY,
926 GEN_ENDLOOPADDRCOARSEOFS,
927 GEN_SAMPLEMODE, GEN_EXCLUSIVECLASS,GEN_OVERRIDEROOTKEY
930 /* SF 2.01 section 9.4 'bullet' 9: A generator in a
931 * local preset zone supersedes a global preset zone
932 * generator. The effect is -added- to the destination
933 * summing node -> voice_gen_incr */
935 if(preset_zone->gen[i].flags)
937 fluid_voice_gen_incr(voice, i, preset_zone->gen[i].val);
939 else if((global_preset_zone != NULL) && global_preset_zone->gen[i].flags)
941 fluid_voice_gen_incr(voice, i, global_preset_zone->gen[i].val);
945 /* The generator has not been defined in this preset
946 * Do nothing, leave it unchanged.
949 } /* for all generators */
951 /* Adds preset zone modulators (global and local) to the voice.*/
952 fluid_defpreset_noteon_add_mod_to_voice(voice,
953 /* global preset modulators */
954 global_preset_zone ? global_preset_zone->mod : NULL,
955 preset_zone->mod, /* local preset modulators */
956 FLUID_VOICE_ADD); /* mode */
958 /* add the synthesis process to the synthesis loop. */
959 fluid_synth_start_voice(synth, voice);
961 /* Store the ID of the first voice that was created by this noteon event.
962 * Exclusive class may only terminate older voices.
963 * That avoids killing voices, which have just been created.
964 * (a noteon event can create several voice processes with the same exclusive
965 * class - for example when using stereo samples)
971 preset_zone = fluid_preset_zone_next(preset_zone);
978 * fluid_defpreset_set_global_zone
981 fluid_defpreset_set_global_zone(fluid_defpreset_t *defpreset, fluid_preset_zone_t *zone)
983 defpreset->global_zone = zone;
988 * fluid_defpreset_import_sfont
991 fluid_defpreset_import_sfont(fluid_defpreset_t *defpreset,
993 fluid_defsfont_t *defsfont)
997 fluid_preset_zone_t *zone;
1001 if(FLUID_STRLEN(sfpreset->name) > 0)
1003 FLUID_STRCPY(defpreset->name, sfpreset->name);
1007 FLUID_SNPRINTF(defpreset->name, sizeof(defpreset->name), "Bank%d,Pre%d", sfpreset->bank, sfpreset->prenum);
1010 defpreset->bank = sfpreset->bank;
1011 defpreset->num = sfpreset->prenum;
1017 sfzone = (SFZone *)fluid_list_get(p);
1018 FLUID_SNPRINTF(zone_name, sizeof(zone_name), "%s/%d", defpreset->name, count);
1019 zone = new_fluid_preset_zone(zone_name);
1023 return FLUID_FAILED;
1026 if(fluid_preset_zone_import_sfont(zone, sfzone, defsfont) != FLUID_OK)
1028 delete_fluid_preset_zone(zone);
1029 return FLUID_FAILED;
1032 if((count == 0) && (fluid_preset_zone_get_inst(zone) == NULL))
1034 fluid_defpreset_set_global_zone(defpreset, zone);
1036 else if(fluid_defpreset_add_zone(defpreset, zone) != FLUID_OK)
1038 return FLUID_FAILED;
1041 p = fluid_list_next(p);
1049 * fluid_defpreset_add_zone
1052 fluid_defpreset_add_zone(fluid_defpreset_t *defpreset, fluid_preset_zone_t *zone)
1054 if(defpreset->zone == NULL)
1057 defpreset->zone = zone;
1061 zone->next = defpreset->zone;
1062 defpreset->zone = zone;
1069 * fluid_defpreset_get_zone
1071 fluid_preset_zone_t *
1072 fluid_defpreset_get_zone(fluid_defpreset_t *defpreset)
1074 return defpreset->zone;
1078 * fluid_defpreset_get_global_zone
1080 fluid_preset_zone_t *
1081 fluid_defpreset_get_global_zone(fluid_defpreset_t *defpreset)
1083 return defpreset->global_zone;
1086 /***************************************************************
1092 * fluid_preset_zone_next
1094 fluid_preset_zone_t *
1095 fluid_preset_zone_next(fluid_preset_zone_t *zone)
1101 * new_fluid_preset_zone
1103 fluid_preset_zone_t *
1104 new_fluid_preset_zone(char *name)
1106 fluid_preset_zone_t *zone = NULL;
1107 zone = FLUID_NEW(fluid_preset_zone_t);
1111 FLUID_LOG(FLUID_ERR, "Out of memory");
1116 zone->voice_zone = NULL;
1117 zone->name = FLUID_STRDUP(name);
1119 if(zone->name == NULL)
1121 FLUID_LOG(FLUID_ERR, "Out of memory");
1127 zone->range.keylo = 0;
1128 zone->range.keyhi = 128;
1129 zone->range.vello = 0;
1130 zone->range.velhi = 128;
1131 zone->range.ignore = FALSE;
1133 /* Flag all generators as unused (default, they will be set when they are found
1134 * in the sound font).
1135 * This also sets the generator values to default, but that is of no concern here.*/
1136 fluid_gen_set_default_values(&zone->gen[0]);
1137 zone->mod = NULL; /* list of modulators */
1142 * delete list of modulators.
1144 static void delete_fluid_list_mod(fluid_mod_t *mod)
1148 while(mod) /* delete the modulators */
1152 delete_fluid_mod(tmp);
1157 * delete_fluid_preset_zone
1160 delete_fluid_preset_zone(fluid_preset_zone_t *zone)
1164 fluid_return_if_fail(zone != NULL);
1166 delete_fluid_list_mod(zone->mod);
1168 for(list = zone->voice_zone; list != NULL; list = fluid_list_next(list))
1170 FLUID_FREE(fluid_list_get(list));
1173 delete_fluid_list(zone->voice_zone);
1175 FLUID_FREE(zone->name);
1179 static int fluid_preset_zone_create_voice_zones(fluid_preset_zone_t *preset_zone)
1181 fluid_inst_zone_t *inst_zone;
1182 fluid_sample_t *sample;
1183 fluid_voice_zone_t *voice_zone;
1184 fluid_zone_range_t *irange;
1185 fluid_zone_range_t *prange = &preset_zone->range;
1187 fluid_return_val_if_fail(preset_zone->inst != NULL, FLUID_FAILED);
1189 inst_zone = fluid_inst_get_zone(preset_zone->inst);
1191 while(inst_zone != NULL)
1194 /* We only create voice ranges for zones that could actually start a voice,
1195 * i.e. that have a sample and don't point to ROM */
1196 sample = fluid_inst_zone_get_sample(inst_zone);
1198 if((sample == NULL) || fluid_sample_in_rom(sample))
1200 inst_zone = fluid_inst_zone_next(inst_zone);
1204 voice_zone = FLUID_NEW(fluid_voice_zone_t);
1206 if(voice_zone == NULL)
1208 FLUID_LOG(FLUID_ERR, "Out of memory");
1209 return FLUID_FAILED;
1212 voice_zone->inst_zone = inst_zone;
1214 irange = &inst_zone->range;
1216 voice_zone->range.keylo = (prange->keylo > irange->keylo) ? prange->keylo : irange->keylo;
1217 voice_zone->range.keyhi = (prange->keyhi < irange->keyhi) ? prange->keyhi : irange->keyhi;
1218 voice_zone->range.vello = (prange->vello > irange->vello) ? prange->vello : irange->vello;
1219 voice_zone->range.velhi = (prange->velhi < irange->velhi) ? prange->velhi : irange->velhi;
1220 voice_zone->range.ignore = FALSE;
1222 preset_zone->voice_zone = fluid_list_append(preset_zone->voice_zone, voice_zone);
1224 inst_zone = fluid_inst_zone_next(inst_zone);
1231 * Checks if modulator mod is identic to another modulator in the list
1232 * (specs SF 2.0X 7.4, 7.8).
1233 * @param mod, modulator list.
1234 * @param name, if not NULL, pointer on a string displayed as warning.
1235 * @return TRUE if mod is identic to another modulator, FALSE otherwise.
1238 fluid_zone_is_mod_identic(fluid_mod_t *mod, char *name)
1240 fluid_mod_t *next = mod->next;
1244 /* is mod identic to next ? */
1245 if(fluid_mod_test_identity(mod, next))
1249 FLUID_LOG(FLUID_WARN, "Ignoring identic modulator %s", name);
1262 * Limits the number of modulators in a modulator list.
1263 * This is appropriate to internal synthesizer modulators tables
1264 * which have a fixed size (FLUID_NUM_MOD).
1266 * @param zone_name, zone name
1267 * @param list_mod, address of pointer on modulator list.
1269 static void fluid_limit_mod_list(char *zone_name, fluid_mod_t **list_mod)
1271 int mod_idx = 0; /* modulator index */
1272 fluid_mod_t *prev_mod = NULL; /* previous modulator in list_mod */
1273 fluid_mod_t *mod = *list_mod; /* first modulator in list_mod */
1277 if((mod_idx + 1) > FLUID_NUM_MOD)
1279 /* truncation of list_mod */
1282 prev_mod->next = NULL;
1289 delete_fluid_list_mod(mod);
1290 FLUID_LOG(FLUID_WARN, "%s, modulators count limited to %d", zone_name,
1302 * Checks and remove invalid modulators from a zone modulators list.
1303 * - checks valid modulator sources (specs SF 2.01 7.4, 7.8, 8.2.1).
1304 * - checks identic modulators in the list (specs SF 2.01 7.4, 7.8).
1305 * @param zone_name, zone name.
1306 * @param list_mod, address of pointer on modulators list.
1309 fluid_zone_check_mod(char *zone_name, fluid_mod_t **list_mod)
1311 fluid_mod_t *prev_mod = NULL; /* previous modulator in list_mod */
1312 fluid_mod_t *mod = *list_mod; /* first modulator in list_mod */
1313 int mod_idx = 0; /* modulator index */
1317 char zone_mod_name[256];
1318 fluid_mod_t *next = mod->next;
1320 /* prepare modulator name: zonename/#modulator */
1321 FLUID_SNPRINTF(zone_mod_name, sizeof(zone_mod_name), "%s/mod%d", zone_name, mod_idx);
1323 /* has mod invalid sources ? */
1324 if(!fluid_mod_check_sources(mod, zone_mod_name)
1325 /* or is mod identic to any following modulator ? */
1326 || fluid_zone_is_mod_identic(mod, zone_mod_name))
1328 /* the modulator is useless so we remove it */
1331 prev_mod->next = next;
1338 delete_fluid_mod(mod); /* freeing */
1349 /* limits the size of modulators list */
1350 fluid_limit_mod_list(zone_name, list_mod);
1354 * fluid_zone_gen_import_sfont
1355 * Imports generators from sfzone to gen and range.
1356 * @param gen, pointer on destination generators table.
1357 * @param range, pointer on destination range generators.
1358 * @param sfzone, pointer on soundfont zone generators.
1361 fluid_zone_gen_import_sfont(fluid_gen_t *gen, fluid_zone_range_t *range, SFZone *sfzone)
1366 for(r = sfzone->gen; r != NULL;)
1368 sfgen = (SFGen *)fluid_list_get(r);
1373 range->keylo = sfgen->amount.range.lo;
1374 range->keyhi = sfgen->amount.range.hi;
1378 range->vello = sfgen->amount.range.lo;
1379 range->velhi = sfgen->amount.range.hi;
1382 case GEN_ATTENUATION:
1383 /* EMU8k/10k hardware applies a scale factor to initial attenuation generator values set at
1384 * preset and instrument level */
1385 gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword * EMU_ATTENUATION_FACTOR;
1386 gen[sfgen->id].flags = GEN_SET;
1390 /* FIXME: some generators have an unsigne word amount value but i don't know which ones */
1391 gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword;
1392 gen[sfgen->id].flags = GEN_SET;
1396 r = fluid_list_next(r);
1401 * fluid_zone_mod_source_import_sfont
1402 * Imports source information from sf_source to src and flags.
1403 * @param src, pointer on destination modulator source.
1404 * @param flags, pointer on destination modulator flags.
1405 * @param sf_source, soundfont modulator source.
1406 * @return return TRUE if success, FALSE if source type is unknow.
1409 fluid_zone_mod_source_import_sfont(unsigned char *src, unsigned char *flags, unsigned short sf_source)
1412 unsigned char flags_dest; /* destination flags */
1415 *src = sf_source & 127; /* index of source, seven-bit value, SF2.01 section 8.2, page 50 */
1417 /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/
1420 if(sf_source & (1 << 7))
1422 flags_dest |= FLUID_MOD_CC;
1426 flags_dest |= FLUID_MOD_GC;
1429 /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/
1430 if(sf_source & (1 << 8))
1432 flags_dest |= FLUID_MOD_NEGATIVE;
1436 flags_dest |= FLUID_MOD_POSITIVE;
1439 /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/
1440 if(sf_source & (1 << 9))
1442 flags_dest |= FLUID_MOD_BIPOLAR;
1446 flags_dest |= FLUID_MOD_UNIPOLAR;
1449 /* modulator source types: SF2.01 section 8.2.1 page 52 */
1450 type = sf_source >> 10;
1451 type &= 63; /* type is a 6-bit value */
1455 flags_dest |= FLUID_MOD_LINEAR;
1459 flags_dest |= FLUID_MOD_CONCAVE;
1463 flags_dest |= FLUID_MOD_CONVEX;
1467 flags_dest |= FLUID_MOD_SWITCH;
1471 *flags = flags_dest;
1472 /* This shouldn't happen - unknown type! */
1476 *flags = flags_dest;
1481 * fluid_zone_mod_import_sfont
1482 * Imports modulators from sfzone to modulators list mod.
1483 * @param zone_name, zone name.
1484 * @param mod, address of pointer on modulators list to return.
1485 * @param sfzone, pointer on soundfont zone.
1486 * @return FLUID_OK if success, FLUID_FAILED otherwise.
1489 fluid_zone_mod_import_sfont(char *zone_name, fluid_mod_t **mod, SFZone *sfzone)
1494 /* Import the modulators (only SF2.1 and higher) */
1495 for(count = 0, r = sfzone->mod; r != NULL; count++)
1498 SFMod *mod_src = (SFMod *)fluid_list_get(r);
1499 fluid_mod_t *mod_dest = new_fluid_mod();
1501 if(mod_dest == NULL)
1503 return FLUID_FAILED;
1506 mod_dest->next = NULL; /* pointer to next modulator, this is the end of the list now.*/
1508 /* *** Amount *** */
1509 mod_dest->amount = mod_src->amount;
1511 /* *** Source *** */
1512 if(!fluid_zone_mod_source_import_sfont(&mod_dest->src1, &mod_dest->flags1, mod_src->src))
1514 /* This shouldn't happen - unknown type!
1515 * Deactivate the modulator by setting the amount to 0. */
1516 mod_dest->amount = 0;
1519 /* Note: When primary source input (src1) is set to General Controller 'No Controller',
1520 output will be forced to 0.0 at synthesis time (see fluid_mod_get_value()).
1521 That means that the minimum value of the modulator will be always 0.0.
1522 We need to force amount value to 0 to ensure a correct evaluation of the minimum
1523 value later (see fluid_voice_get_lower_boundary_for_attenuation()).
1525 if(((mod_dest->flags1 & FLUID_MOD_CC) == FLUID_MOD_GC) &&
1526 (mod_dest->src1 == FLUID_MOD_NONE))
1528 mod_dest->amount = 0;
1532 mod_dest->dest = mod_src->dest; /* index of controlled generator */
1534 /* *** Amount source *** */
1535 if(!fluid_zone_mod_source_import_sfont(&mod_dest->src2, &mod_dest->flags2, mod_src->amtsrc))
1537 /* This shouldn't happen - unknown type!
1538 * Deactivate the modulator by setting the amount to 0. */
1539 mod_dest->amount = 0;
1541 /* Note: When secondary source input (src2) is set to General Controller 'No Controller',
1542 output will be forced to +1.0 at synthesis time (see fluid_mod_get_value()).
1543 That means that this source will behave unipolar only. We need to force the
1544 unipolar flag to ensure to ensure a correct evaluation of the minimum
1545 value later (see fluid_voice_get_lower_boundary_for_attenuation()).
1547 if(((mod_dest->flags2 & FLUID_MOD_CC) == FLUID_MOD_GC) &&
1548 (mod_dest->src2 == FLUID_MOD_NONE))
1550 mod_dest->flags2 &= ~FLUID_MOD_BIPOLAR;
1553 /* *** Transform *** */
1554 /* SF2.01 only uses the 'linear' transform (0).
1555 * Deactivate the modulator by setting the amount to 0 in any other case.
1557 if(mod_src->trans != 0)
1559 mod_dest->amount = 0;
1562 /* Store the new modulator in the zone The order of modulators
1563 * will make a difference, at least in an instrument context: The
1564 * second modulator overwrites the first one, if they only differ
1572 fluid_mod_t *last_mod = *mod;
1574 /* Find the end of the list */
1575 while(last_mod->next != NULL)
1577 last_mod = last_mod->next;
1580 last_mod->next = mod_dest;
1583 r = fluid_list_next(r);
1584 } /* foreach modulator */
1586 /* checks and removes invalid modulators in modulators list*/
1587 fluid_zone_check_mod(zone_name, mod);
1592 * fluid_preset_zone_import_sfont
1595 fluid_preset_zone_import_sfont(fluid_preset_zone_t *zone, SFZone *sfzone, fluid_defsfont_t *defsfont)
1597 /* import the generators */
1598 fluid_zone_gen_import_sfont(zone->gen, &zone->range, sfzone);
1600 if((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL))
1602 SFInst *sfinst = sfzone->instsamp->data;
1604 zone->inst = find_inst_by_idx(defsfont, sfinst->idx);
1606 if(zone->inst == NULL)
1608 zone->inst = fluid_inst_import_sfont(zone, sfinst, defsfont);
1611 if(zone->inst == NULL)
1613 return FLUID_FAILED;
1616 if(fluid_preset_zone_create_voice_zones(zone) == FLUID_FAILED)
1618 return FLUID_FAILED;
1622 /* Import the modulators (only SF2.1 and higher) */
1623 return fluid_zone_mod_import_sfont(zone->name, &zone->mod, sfzone);
1627 * fluid_preset_zone_get_inst
1630 fluid_preset_zone_get_inst(fluid_preset_zone_t *zone)
1636 /***************************************************************
1647 fluid_inst_t *inst = FLUID_NEW(fluid_inst_t);
1651 FLUID_LOG(FLUID_ERR, "Out of memory");
1656 inst->global_zone = NULL;
1665 delete_fluid_inst(fluid_inst_t *inst)
1667 fluid_inst_zone_t *zone;
1669 fluid_return_if_fail(inst != NULL);
1671 delete_fluid_inst_zone(inst->global_zone);
1672 inst->global_zone = NULL;
1678 inst->zone = zone->next;
1679 delete_fluid_inst_zone(zone);
1687 * fluid_inst_set_global_zone
1690 fluid_inst_set_global_zone(fluid_inst_t *inst, fluid_inst_zone_t *zone)
1692 inst->global_zone = zone;
1697 * fluid_inst_import_sfont
1700 fluid_inst_import_sfont(fluid_preset_zone_t *preset_zone, SFInst *sfinst, fluid_defsfont_t *defsfont)
1705 fluid_inst_zone_t *inst_zone;
1706 char zone_name[256];
1709 inst = (fluid_inst_t *) new_fluid_inst();
1713 FLUID_LOG(FLUID_ERR, "Out of memory");
1717 inst->source_idx = sfinst->idx;
1721 if(FLUID_STRLEN(sfinst->name) > 0)
1723 FLUID_STRCPY(inst->name, sfinst->name);
1727 FLUID_STRCPY(inst->name, "<untitled>");
1735 sfzone = (SFZone *)fluid_list_get(p);
1736 /* integrates preset zone name in instrument zone name */
1737 FLUID_SNPRINTF(zone_name, sizeof(zone_name), "%s/%s/%d", preset_zone->name,
1740 inst_zone = new_fluid_inst_zone(zone_name);
1742 if(inst_zone == NULL)
1747 if(fluid_inst_zone_import_sfont(inst_zone, sfzone, defsfont) != FLUID_OK)
1749 delete_fluid_inst_zone(inst_zone);
1753 if((count == 0) && (fluid_inst_zone_get_sample(inst_zone) == NULL))
1755 fluid_inst_set_global_zone(inst, inst_zone);
1758 else if(fluid_inst_add_zone(inst, inst_zone) != FLUID_OK)
1763 p = fluid_list_next(p);
1767 defsfont->inst = fluid_list_append(defsfont->inst, inst);
1772 * fluid_inst_add_zone
1775 fluid_inst_add_zone(fluid_inst_t *inst, fluid_inst_zone_t *zone)
1777 if(inst->zone == NULL)
1784 zone->next = inst->zone;
1792 * fluid_inst_get_zone
1795 fluid_inst_get_zone(fluid_inst_t *inst)
1801 * fluid_inst_get_global_zone
1804 fluid_inst_get_global_zone(fluid_inst_t *inst)
1806 return inst->global_zone;
1809 /***************************************************************
1815 * new_fluid_inst_zone
1818 new_fluid_inst_zone(char *name)
1820 fluid_inst_zone_t *zone = NULL;
1821 zone = FLUID_NEW(fluid_inst_zone_t);
1825 FLUID_LOG(FLUID_ERR, "Out of memory");
1830 zone->name = FLUID_STRDUP(name);
1832 if(zone->name == NULL)
1834 FLUID_LOG(FLUID_ERR, "Out of memory");
1839 zone->sample = NULL;
1840 zone->range.keylo = 0;
1841 zone->range.keyhi = 128;
1842 zone->range.vello = 0;
1843 zone->range.velhi = 128;
1844 zone->range.ignore = FALSE;
1845 /* Flag the generators as unused.
1846 * This also sets the generator values to default, but they will be overwritten anyway, if used.*/
1847 fluid_gen_set_default_values(&zone->gen[0]);
1848 zone->mod = NULL; /* list of modulators */
1853 * delete_fluid_inst_zone
1856 delete_fluid_inst_zone(fluid_inst_zone_t *zone)
1858 fluid_return_if_fail(zone != NULL);
1860 delete_fluid_list_mod(zone->mod);
1862 FLUID_FREE(zone->name);
1867 * fluid_inst_zone_next
1870 fluid_inst_zone_next(fluid_inst_zone_t *zone)
1876 * fluid_inst_zone_import_sfont
1879 fluid_inst_zone_import_sfont(fluid_inst_zone_t *inst_zone, SFZone *sfzone, fluid_defsfont_t *defsfont)
1881 /* import the generators */
1882 fluid_zone_gen_import_sfont(inst_zone->gen, &inst_zone->range, sfzone);
1885 /* if (zone->gen[GEN_EXCLUSIVECLASS].flags == GEN_SET) { */
1886 /* FLUID_LOG(FLUID_DBG, "ExclusiveClass=%d\n", (int) zone->gen[GEN_EXCLUSIVECLASS].val); */
1889 /* fixup sample pointer */
1890 if((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL))
1892 inst_zone->sample = ((SFSample *)(sfzone->instsamp->data))->fluid_sample;
1895 /* Import the modulators (only SF2.1 and higher) */
1896 return fluid_zone_mod_import_sfont(inst_zone->name, &inst_zone->mod, sfzone);
1900 * fluid_inst_zone_get_sample
1903 fluid_inst_zone_get_sample(fluid_inst_zone_t *zone)
1905 return zone->sample;
1910 fluid_zone_inside_range(fluid_zone_range_t *range, int key, int vel)
1912 /* ignoreInstrumentZone is set in mono legato playing */
1913 int ignore_zone = range->ignore;
1915 /* Reset the 'ignore' request */
1916 range->ignore = FALSE;
1918 return !ignore_zone && ((range->keylo <= key) &&
1919 (range->keyhi >= key) &&
1920 (range->vello <= vel) &&
1921 (range->velhi >= vel));
1924 /***************************************************************
1930 * fluid_sample_in_rom
1933 fluid_sample_in_rom(fluid_sample_t *sample)
1935 return (sample->sampletype & FLUID_SAMPLETYPE_ROM);
1940 * fluid_sample_import_sfont
1943 fluid_sample_import_sfont(fluid_sample_t *sample, SFSample *sfsample, fluid_defsfont_t *defsfont)
1945 FLUID_STRCPY(sample->name, sfsample->name);
1947 sample->source_start = sfsample->start;
1948 sample->source_end = (sfsample->end > 0) ? sfsample->end - 1 : 0; /* marks last sample, contrary to SF spec. */
1949 sample->source_loopstart = sfsample->loopstart;
1950 sample->source_loopend = sfsample->loopend;
1952 sample->start = sample->source_start;
1953 sample->end = sample->source_end;
1954 sample->loopstart = sample->source_loopstart;
1955 sample->loopend = sample->source_loopend;
1956 sample->samplerate = sfsample->samplerate;
1957 sample->origpitch = sfsample->origpitch;
1958 sample->pitchadj = sfsample->pitchadj;
1959 sample->sampletype = sfsample->sampletype;
1961 if(defsfont->dynamic_samples)
1963 sample->notify = dynamic_samples_sample_notify;
1966 if(fluid_sample_validate(sample, defsfont->samplesize) == FLUID_FAILED)
1968 return FLUID_FAILED;
1974 /* Called if a sample is no longer used by a voice. Used by dynamic sample loading
1975 * to unload a sample that is not used by any loaded presets anymore but couldn't
1976 * be unloaded straight away because it was still in use by a voice. */
1977 static int dynamic_samples_sample_notify(fluid_sample_t *sample, int reason)
1979 if(reason == FLUID_SAMPLE_DONE && sample->preset_count == 0)
1981 unload_sample(sample);
1987 /* Called if a preset has been selected for or unselected from a channel. Used by
1988 * dynamic sample loading to load and unload samples on demand. */
1989 static int dynamic_samples_preset_notify(fluid_preset_t *preset, int reason, int chan)
1991 fluid_defsfont_t *defsfont;
1993 if(reason == FLUID_PRESET_SELECTED)
1995 FLUID_LOG(FLUID_DBG, "Selected preset '%s' on channel %d", fluid_preset_get_name(preset), chan);
1996 defsfont = fluid_sfont_get_data(preset->sfont);
1997 load_preset_samples(defsfont, preset);
1999 else if(reason == FLUID_PRESET_UNSELECTED)
2001 FLUID_LOG(FLUID_DBG, "Deselected preset '%s' from channel %d", fluid_preset_get_name(preset), chan);
2002 defsfont = fluid_sfont_get_data(preset->sfont);
2003 unload_preset_samples(defsfont, preset);
2010 /* Walk through all samples used by the passed in preset and make sure that the
2011 * sample data is loaded for each sample. Used by dynamic sample loading. */
2012 static int load_preset_samples(fluid_defsfont_t *defsfont, fluid_preset_t *preset)
2014 fluid_defpreset_t *defpreset;
2015 fluid_preset_zone_t *preset_zone;
2017 fluid_inst_zone_t *inst_zone;
2018 fluid_sample_t *sample;
2019 SFData *sffile = NULL;
2021 defpreset = fluid_preset_get_data(preset);
2022 preset_zone = fluid_defpreset_get_zone(defpreset);
2024 while(preset_zone != NULL)
2026 inst = fluid_preset_zone_get_inst(preset_zone);
2027 inst_zone = fluid_inst_get_zone(inst);
2029 while(inst_zone != NULL)
2031 sample = fluid_inst_zone_get_sample(inst_zone);
2033 if((sample != NULL) && (sample->start != sample->end))
2035 sample->preset_count++;
2037 /* If this is the first time this sample has been selected,
2038 * load the sampledata */
2039 if(sample->preset_count == 1)
2041 /* Make sure we have an open Soundfont file. Do this here
2042 * to avoid having to open the file if no loading is necessary
2046 sffile = fluid_sffile_open(defsfont->filename, defsfont->fcbs);
2050 FLUID_LOG(FLUID_ERR, "Unable to open Soundfont file");
2051 return FLUID_FAILED;
2055 if(fluid_defsfont_load_sampledata(defsfont, sffile, sample) == FLUID_OK)
2057 fluid_sample_sanitize_loop(sample, (sample->end + 1) * sizeof(short));
2058 fluid_voice_optimize_sample(sample);
2062 FLUID_LOG(FLUID_ERR, "Unable to load sample '%s', disabling", sample->name);
2063 sample->start = sample->end = 0;
2068 inst_zone = fluid_inst_zone_next(inst_zone);
2071 preset_zone = fluid_preset_zone_next(preset_zone);
2076 fluid_sffile_close(sffile);
2082 /* Walk through all samples used by the passed in preset and unload the sample data
2083 * of each sample that is not used by any selected preset anymore. Used by dynamic
2084 * sample loading. */
2085 static int unload_preset_samples(fluid_defsfont_t *defsfont, fluid_preset_t *preset)
2087 fluid_defpreset_t *defpreset;
2088 fluid_preset_zone_t *preset_zone;
2090 fluid_inst_zone_t *inst_zone;
2091 fluid_sample_t *sample;
2093 defpreset = fluid_preset_get_data(preset);
2094 preset_zone = fluid_defpreset_get_zone(defpreset);
2096 while(preset_zone != NULL)
2098 inst = fluid_preset_zone_get_inst(preset_zone);
2099 inst_zone = fluid_inst_get_zone(inst);
2101 while(inst_zone != NULL)
2103 sample = fluid_inst_zone_get_sample(inst_zone);
2105 if((sample != NULL) && (sample->preset_count > 0))
2107 sample->preset_count--;
2109 /* If the sample is not used by any preset or used by a
2110 * sounding voice, unload it from the sample cache. If it's
2111 * still in use by a voice, dynamic_samples_sample_notify will
2112 * take care of unloading the sample as soon as the voice is
2113 * finished with it (but only on the next API call). */
2114 if(sample->preset_count == 0 && sample->refcount == 0)
2116 unload_sample(sample);
2120 inst_zone = fluid_inst_zone_next(inst_zone);
2123 preset_zone = fluid_preset_zone_next(preset_zone);
2129 /* Unload an unused sample from the samplecache */
2130 static void unload_sample(fluid_sample_t *sample)
2132 fluid_return_if_fail(sample != NULL);
2133 fluid_return_if_fail(sample->data != NULL);
2134 fluid_return_if_fail(sample->preset_count == 0);
2135 fluid_return_if_fail(sample->refcount == 0);
2137 FLUID_LOG(FLUID_DBG, "Unloading sample '%s'", sample->name);
2139 if(fluid_samplecache_unload(sample->data) == FLUID_FAILED)
2141 FLUID_LOG(FLUID_ERR, "Unable to unload sample '%s'", sample->name);
2145 sample->data = NULL;
2146 sample->data24 = NULL;
2150 static fluid_inst_t *find_inst_by_idx(fluid_defsfont_t *defsfont, int idx)
2155 for(list = defsfont->inst; list != NULL; list = fluid_list_next(list))
2157 inst = fluid_list_get(list);
2159 if(inst->source_idx == idx)