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 Library General Public License
10 * as published by the Free Software Foundation; either version 2 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 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library 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 /* Todo: Get rid of that 'include' */
27 #include "fluid_sys.h"
29 /***************************************************************
34 fluid_sfloader_t* new_fluid_defsfloader(fluid_settings_t* settings)
36 fluid_sfloader_t* loader;
38 loader = FLUID_NEW(fluid_sfloader_t);
40 FLUID_LOG(FLUID_ERR, "Out of memory");
44 loader->data = settings;
45 loader->free = delete_fluid_defsfloader;
46 loader->load = fluid_defsfloader_load;
51 int delete_fluid_defsfloader(fluid_sfloader_t* loader)
59 fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* filename)
61 fluid_defsfont_t* defsfont;
64 defsfont = new_fluid_defsfont(loader->data);
66 if (defsfont == NULL) {
70 if (fluid_defsfont_load(defsfont, filename) == FLUID_FAILED) {
71 delete_fluid_defsfont(defsfont);
75 sfont = FLUID_NEW(fluid_sfont_t);
77 FLUID_LOG(FLUID_ERR, "Out of memory");
81 sfont->data = defsfont;
82 sfont->free = fluid_defsfont_sfont_delete;
83 sfont->get_name = fluid_defsfont_sfont_get_name;
84 sfont->get_preset = fluid_defsfont_sfont_get_preset;
85 sfont->iteration_start = fluid_defsfont_sfont_iteration_start;
86 sfont->iteration_next = fluid_defsfont_sfont_iteration_next;
93 /***************************************************************
98 int fluid_defsfont_sfont_delete(fluid_sfont_t* sfont)
100 if (delete_fluid_defsfont(sfont->data) != 0) {
107 char* fluid_defsfont_sfont_get_name(fluid_sfont_t* sfont)
109 return fluid_defsfont_get_name((fluid_defsfont_t*) sfont->data);
113 fluid_sample_t* fluid_defsfont_get_sample(fluid_defsfont_t* sfont, char *s)
115 /* This function is here just to avoid an ABI/SONAME bump, see ticket #98. Should never be used. */
121 fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum)
123 fluid_preset_t* preset = NULL;
124 fluid_defpreset_t* defpreset;
125 fluid_defsfont_t* defsfont = sfont->data;
127 defpreset = fluid_defsfont_get_preset(defsfont, bank, prenum);
129 if (defpreset == NULL) {
133 if (defsfont->preset_stack_size > 0) {
134 defsfont->preset_stack_size--;
135 preset = defsfont->preset_stack[defsfont->preset_stack_size];
138 preset = FLUID_NEW(fluid_preset_t);
140 FLUID_LOG(FLUID_ERR, "Out of memory");
144 preset->sfont = sfont;
145 preset->data = defpreset;
146 preset->free = fluid_defpreset_preset_delete;
147 preset->get_name = fluid_defpreset_preset_get_name;
148 preset->get_banknum = fluid_defpreset_preset_get_banknum;
149 preset->get_num = fluid_defpreset_preset_get_num;
150 preset->noteon = fluid_defpreset_preset_noteon;
151 preset->notify = NULL;
156 void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont)
158 fluid_defsfont_iteration_start((fluid_defsfont_t*) sfont->data);
161 int fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset)
163 preset->free = fluid_defpreset_preset_delete;
164 preset->get_name = fluid_defpreset_preset_get_name;
165 preset->get_banknum = fluid_defpreset_preset_get_banknum;
166 preset->get_num = fluid_defpreset_preset_get_num;
167 preset->noteon = fluid_defpreset_preset_noteon;
168 preset->notify = NULL;
170 return fluid_defsfont_iteration_next((fluid_defsfont_t*) sfont->data, preset);
173 int fluid_defpreset_preset_delete(fluid_preset_t* preset)
175 fluid_defpreset_t* defpreset = preset ? preset->data : NULL;
176 fluid_defsfont_t* sfont = defpreset ? defpreset->sfont : NULL;
178 if (sfont && sfont->preset_stack_size < sfont->preset_stack_capacity) {
179 sfont->preset_stack[sfont->preset_stack_size] = preset;
180 sfont->preset_stack_size++;
188 char* fluid_defpreset_preset_get_name(fluid_preset_t* preset)
190 return fluid_defpreset_get_name((fluid_defpreset_t*) preset->data);
193 int fluid_defpreset_preset_get_banknum(fluid_preset_t* preset)
195 return fluid_defpreset_get_banknum((fluid_defpreset_t*) preset->data);
198 int fluid_defpreset_preset_get_num(fluid_preset_t* preset)
200 return fluid_defpreset_get_num((fluid_defpreset_t*) preset->data);
203 int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth,
204 int chan, int key, int vel)
206 return fluid_defpreset_noteon((fluid_defpreset_t*) preset->data, synth, chan, key, vel);
212 /***************************************************************
214 * CACHED SAMPLEDATA LOADER
217 typedef struct _fluid_cached_sampledata_t {
218 struct _fluid_cached_sampledata_t *next;
221 time_t modification_time;
225 const short* sampledata;
226 unsigned int samplesize;
227 } fluid_cached_sampledata_t;
229 static fluid_cached_sampledata_t* all_cached_sampledata = NULL;
230 static fluid_mutex_t cached_sampledata_mutex = FLUID_MUTEX_INIT;
232 static int fluid_get_file_modification_time(char *filename, time_t *modification_time)
234 #if defined(WIN32) || defined(__OS2__)
235 *modification_time = 0;
240 if (stat(filename, &buf) == -1) {
244 *modification_time = buf.st_mtime;
249 static int fluid_cached_sampledata_load(char *filename, unsigned int samplepos,
250 unsigned int samplesize, short **sampledata, int try_mlock)
252 fluid_file fd = NULL;
253 short *loaded_sampledata = NULL;
254 fluid_cached_sampledata_t* cached_sampledata = NULL;
255 time_t modification_time;
257 fluid_mutex_lock(cached_sampledata_mutex);
259 if (fluid_get_file_modification_time(filename, &modification_time) == FLUID_FAILED) {
260 FLUID_LOG(FLUID_WARN, "Unable to read modificaton time of soundfont file.");
261 modification_time = 0;
264 for (cached_sampledata = all_cached_sampledata; cached_sampledata; cached_sampledata = cached_sampledata->next) {
265 if (strcmp(filename, cached_sampledata->filename))
267 if (cached_sampledata->modification_time != modification_time)
269 if (cached_sampledata->samplesize != samplesize) {
270 FLUID_LOG(FLUID_ERR, "Cached size of soundfont doesn't match actual size of soundfont (cached: %u. actual: %u)",
271 cached_sampledata->samplesize, samplesize);
275 if (try_mlock && !cached_sampledata->mlock) {
276 if (fluid_mlock(cached_sampledata->sampledata, samplesize) != 0)
277 FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible.");
279 cached_sampledata->mlock = try_mlock;
282 cached_sampledata->num_references++;
283 loaded_sampledata = (short*) cached_sampledata->sampledata;
287 fd = FLUID_FOPEN(filename, "rb");
289 FLUID_LOG(FLUID_ERR, "Can't open soundfont file");
292 if (FLUID_FSEEK(fd, samplepos, SEEK_SET) == -1) {
294 FLUID_LOG(FLUID_ERR, "Failed to seek position in data file");
299 loaded_sampledata = (short*) FLUID_MALLOC(samplesize);
300 if (loaded_sampledata == NULL) {
301 FLUID_LOG(FLUID_ERR, "Out of memory");
304 if (FLUID_FREAD(loaded_sampledata, 1, samplesize, fd) < samplesize) {
305 FLUID_LOG(FLUID_ERR, "Failed to read sample data");
313 cached_sampledata = (fluid_cached_sampledata_t*) FLUID_MALLOC(sizeof(fluid_cached_sampledata_t));
314 if (cached_sampledata == NULL) {
315 FLUID_LOG(FLUID_ERR, "Out of memory.");
319 /* Lock the memory to disable paging. It's okay if this fails. It
320 probably means that the user doesn't have to required permission. */
321 cached_sampledata->mlock = 0;
323 if (fluid_mlock(loaded_sampledata, samplesize) != 0)
324 FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible.");
326 cached_sampledata->mlock = try_mlock;
329 /* If this machine is big endian, the sample have to byte swapped */
330 if (FLUID_IS_BIG_ENDIAN) {
332 unsigned char hi, lo;
335 cbuf = (unsigned char*)loaded_sampledata;
336 for (i = 0, j = 0; j < samplesize; i++) {
340 loaded_sampledata[i] = s;
344 cached_sampledata->filename = (char*) FLUID_MALLOC(strlen(filename) + 1);
345 if (cached_sampledata->filename == NULL) {
346 FLUID_LOG(FLUID_ERR, "Out of memory.");
350 sprintf(cached_sampledata->filename, "%s", filename);
351 cached_sampledata->modification_time = modification_time;
352 cached_sampledata->num_references = 1;
353 cached_sampledata->sampledata = loaded_sampledata;
354 cached_sampledata->samplesize = samplesize;
356 cached_sampledata->next = all_cached_sampledata;
357 all_cached_sampledata = cached_sampledata;
361 fluid_mutex_unlock(cached_sampledata_mutex);
362 *sampledata = loaded_sampledata;
369 if (loaded_sampledata != NULL) {
370 FLUID_FREE(loaded_sampledata);
373 if (cached_sampledata != NULL) {
374 if (cached_sampledata->filename != NULL) {
375 FLUID_FREE(cached_sampledata->filename);
377 FLUID_FREE(cached_sampledata);
380 fluid_mutex_unlock(cached_sampledata_mutex);
385 static int fluid_cached_sampledata_unload(const short *sampledata)
387 fluid_cached_sampledata_t* prev = NULL;
388 fluid_cached_sampledata_t* cached_sampledata;
390 fluid_mutex_lock(cached_sampledata_mutex);
391 cached_sampledata = all_cached_sampledata;
393 while (cached_sampledata != NULL) {
394 if (sampledata == cached_sampledata->sampledata) {
396 cached_sampledata->num_references--;
398 if (cached_sampledata->num_references == 0) {
399 if (cached_sampledata->mlock)
400 fluid_munlock(cached_sampledata->sampledata, cached_sampledata->samplesize);
401 FLUID_FREE((short*) cached_sampledata->sampledata);
402 FLUID_FREE(cached_sampledata->filename);
405 prev->next = cached_sampledata->next;
407 all_cached_sampledata = cached_sampledata->next;
410 FLUID_FREE(cached_sampledata);
416 prev = cached_sampledata;
417 cached_sampledata = cached_sampledata->next;
420 FLUID_LOG(FLUID_ERR, "Trying to free sampledata not found in cache.");
424 fluid_mutex_unlock(cached_sampledata_mutex);
428 fluid_mutex_unlock(cached_sampledata_mutex);
435 /***************************************************************
443 fluid_defsfont_t* new_fluid_defsfont(fluid_settings_t* settings)
445 fluid_defsfont_t* sfont;
448 sfont = FLUID_NEW(fluid_defsfont_t);
450 FLUID_LOG(FLUID_ERR, "Out of memory");
454 sfont->filename = NULL;
455 sfont->samplepos = 0;
456 sfont->samplesize = 0;
457 sfont->sample = NULL;
458 sfont->sampledata = NULL;
459 sfont->preset = NULL;
460 fluid_settings_getint(settings, "synth.lock-memory", &sfont->mlock);
462 /* Initialise preset cache, so we don't have to call malloc on program changes.
463 Usually, we have at most one preset per channel plus one temporarily used,
464 so optimise for that case. */
465 fluid_settings_getint(settings, "synth.midi-channels", &sfont->preset_stack_capacity);
466 sfont->preset_stack_capacity++;
467 sfont->preset_stack_size = 0;
468 sfont->preset_stack = FLUID_ARRAY(fluid_preset_t*, sfont->preset_stack_capacity);
469 if (!sfont->preset_stack) {
470 FLUID_LOG(FLUID_ERR, "Out of memory");
475 for (i = 0; i < sfont->preset_stack_capacity; i++) {
476 sfont->preset_stack[i] = FLUID_NEW(fluid_preset_t);
477 if (!sfont->preset_stack[i]) {
478 FLUID_LOG(FLUID_ERR, "Out of memory");
479 delete_fluid_defsfont(sfont);
482 sfont->preset_stack_size++;
489 * delete_fluid_defsfont
491 int delete_fluid_defsfont(fluid_defsfont_t* sfont)
494 fluid_defpreset_t* preset;
495 fluid_sample_t* sample;
497 /* Check that no samples are currently used */
498 for (list = sfont->sample; list; list = fluid_list_next(list)) {
499 sample = (fluid_sample_t*) fluid_list_get(list);
500 if (fluid_sample_refcount(sample) != 0) {
505 if (sfont->filename != NULL) {
506 FLUID_FREE(sfont->filename);
509 for (list = sfont->sample; list; list = fluid_list_next(list)) {
510 delete_fluid_sample((fluid_sample_t*) fluid_list_get(list));
514 delete_fluid_list(sfont->sample);
517 if (sfont->sampledata != NULL) {
518 fluid_cached_sampledata_unload(sfont->sampledata);
521 while (sfont->preset_stack_size > 0)
522 FLUID_FREE(sfont->preset_stack[--sfont->preset_stack_size]);
523 FLUID_FREE(sfont->preset_stack);
525 preset = sfont->preset;
526 while (preset != NULL) {
527 sfont->preset = preset->next;
528 delete_fluid_defpreset(preset);
529 preset = sfont->preset;
537 * fluid_defsfont_get_name
539 char* fluid_defsfont_get_name(fluid_defsfont_t* sfont)
541 return sfont->filename;
546 * fluid_defsfont_load
548 int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file)
554 fluid_sample_t* sample;
555 fluid_defpreset_t* preset = NULL;
557 sfont->filename = FLUID_MALLOC(1 + FLUID_STRLEN(file));
558 if (sfont->filename == NULL) {
559 FLUID_LOG(FLUID_ERR, "Out of memory");
562 FLUID_STRCPY(sfont->filename, file);
564 /* The actual loading is done in the sfont and sffile files */
565 sfdata = sfload_file(file);
566 if (sfdata == NULL) {
567 FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file");
571 /* Keep track of the position and size of the sample data because
572 it's loaded separately (and might be unoaded/reloaded in future) */
573 sfont->samplepos = sfdata->samplepos;
574 sfont->samplesize = sfdata->samplesize;
576 /* load sample data in one block */
577 if (fluid_defsfont_load_sampledata(sfont) != FLUID_OK)
580 /* Create all the sample headers */
583 sfsample = (SFSample *) p->data;
585 sample = new_fluid_sample();
586 if (sample == NULL) goto err_exit;
588 if (fluid_sample_import_sfont(sample, sfsample, sfont) != FLUID_OK)
591 /* Store reference to FluidSynth sample in SFSample for later IZone fixups */
592 sfsample->fluid_sample = sample;
594 fluid_defsfont_add_sample(sfont, sample);
595 fluid_voice_optimize_sample(sample);
596 p = fluid_list_next(p);
599 /* Load all the presets */
602 sfpreset = (SFPreset *) p->data;
603 preset = new_fluid_defpreset(sfont);
604 if (preset == NULL) goto err_exit;
606 if (fluid_defpreset_import_sfont(preset, sfpreset, sfont) != FLUID_OK)
609 fluid_defsfont_add_preset(sfont, preset);
610 p = fluid_list_next(p);
612 sfont_close (sfdata);
617 sfont_close (sfdata);
619 delete_fluid_defpreset(preset);
623 /* fluid_defsfont_add_sample
625 * Add a sample to the SoundFont
627 int fluid_defsfont_add_sample(fluid_defsfont_t* sfont, fluid_sample_t* sample)
629 sfont->sample = fluid_list_append(sfont->sample, sample);
633 /* fluid_defsfont_add_preset
635 * Add a preset to the SoundFont
637 int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset)
639 fluid_defpreset_t *cur, *prev;
640 if (sfont->preset == NULL) {
642 sfont->preset = preset;
644 /* sort them as we go along. very basic sorting trick. */
647 while (cur != NULL) {
648 if ((preset->bank < cur->bank)
649 || ((preset->bank == cur->bank) && (preset->num < cur->num))) {
652 sfont->preset = preset;
669 * fluid_defsfont_load_sampledata
672 fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont)
674 return fluid_cached_sampledata_load(sfont->filename, sfont->samplepos,
675 sfont->samplesize, &sfont->sampledata, sfont->mlock);
679 * fluid_defsfont_get_preset
681 fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* sfont, unsigned int bank, unsigned int num)
683 fluid_defpreset_t* preset = sfont->preset;
684 while (preset != NULL) {
685 if ((preset->bank == bank) && ((preset->num == num))) {
688 preset = preset->next;
694 * fluid_defsfont_iteration_start
696 void fluid_defsfont_iteration_start(fluid_defsfont_t* sfont)
698 sfont->iter_cur = sfont->preset;
702 * fluid_defsfont_iteration_next
704 int fluid_defsfont_iteration_next(fluid_defsfont_t* sfont, fluid_preset_t* preset)
706 if (sfont->iter_cur == NULL) {
710 preset->data = (void*) sfont->iter_cur;
711 sfont->iter_cur = fluid_defpreset_next(sfont->iter_cur);
715 /***************************************************************
721 * new_fluid_defpreset
724 new_fluid_defpreset(fluid_defsfont_t* sfont)
726 fluid_defpreset_t* preset = FLUID_NEW(fluid_defpreset_t);
727 if (preset == NULL) {
728 FLUID_LOG(FLUID_ERR, "Out of memory");
732 preset->sfont = sfont;
736 preset->global_zone = NULL;
742 * delete_fluid_defpreset
745 delete_fluid_defpreset(fluid_defpreset_t* preset)
748 fluid_preset_zone_t* zone;
749 if (preset->global_zone != NULL) {
750 if (delete_fluid_preset_zone(preset->global_zone) != FLUID_OK) {
753 preset->global_zone = NULL;
756 while (zone != NULL) {
757 preset->zone = zone->next;
758 if (delete_fluid_preset_zone(zone) != FLUID_OK) {
768 fluid_defpreset_get_banknum(fluid_defpreset_t* preset)
774 fluid_defpreset_get_num(fluid_defpreset_t* preset)
780 fluid_defpreset_get_name(fluid_defpreset_t* preset)
786 * fluid_defpreset_next
789 fluid_defpreset_next(fluid_defpreset_t* preset)
796 * fluid_defpreset_noteon
799 fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel)
801 fluid_preset_zone_t *preset_zone, *global_preset_zone;
803 fluid_inst_zone_t *inst_zone, *global_inst_zone;
804 fluid_sample_t* sample;
805 fluid_voice_t* voice;
807 fluid_mod_t * mod_list[FLUID_NUM_MOD]; /* list for 'sorting' preset modulators */
811 global_preset_zone = fluid_defpreset_get_global_zone(preset);
813 /* run thru all the zones of this preset */
814 preset_zone = fluid_defpreset_get_zone(preset);
815 while (preset_zone != NULL) {
817 /* check if the note falls into the key and velocity range of this
819 if (fluid_preset_zone_inside_range(preset_zone, key, vel)) {
821 inst = fluid_preset_zone_get_inst(preset_zone);
822 global_inst_zone = fluid_inst_get_global_zone(inst);
824 /* run thru all the zones of this instrument */
825 inst_zone = fluid_inst_get_zone(inst);
826 while (inst_zone != NULL) {
828 /* make sure this instrument zone has a valid sample */
829 sample = fluid_inst_zone_get_sample(inst_zone);
830 if ((sample == NULL) || fluid_sample_in_rom(sample)) {
831 inst_zone = fluid_inst_zone_next(inst_zone);
835 /* check if the note falls into the key and velocity range of this
838 if (fluid_inst_zone_inside_range(inst_zone, key, vel) && (sample != NULL)) {
840 /* this is a good zone. allocate a new synthesis process and
843 voice = fluid_synth_alloc_voice(synth, sample, chan, key, vel);
849 /* Instrument level, generators */
851 for (i = 0; i < GEN_LAST; i++) {
853 /* SF 2.01 section 9.4 'bullet' 4:
855 * A generator in a local instrument zone supersedes a
856 * global instrument zone generator. Both cases supersede
857 * the default generator -> voice_gen_set */
859 if (inst_zone->gen[i].flags){
860 fluid_voice_gen_set(voice, i, inst_zone->gen[i].val);
862 } else if ((global_inst_zone != NULL) && (global_inst_zone->gen[i].flags)) {
863 fluid_voice_gen_set(voice, i, global_inst_zone->gen[i].val);
866 /* The generator has not been defined in this instrument.
867 * Do nothing, leave it at the default.
871 } /* for all generators */
873 /* global instrument zone, modulators: Put them all into a
878 if (global_inst_zone){
879 mod = global_inst_zone->mod;
881 mod_list[mod_list_count++] = mod;
886 /* local instrument zone, modulators.
887 * Replace modulators with the same definition in the list:
888 * SF 2.01 page 69, 'bullet' 8
890 mod = inst_zone->mod;
894 /* 'Identical' modulators will be deleted by setting their
895 * list entry to NULL. The list length is known, NULL
896 * entries will be ignored later. SF2.01 section 9.5.1
897 * page 69, 'bullet' 3 defines 'identical'. */
899 for (i = 0; i < mod_list_count; i++){
900 if (mod_list[i] && fluid_mod_test_identity(mod,mod_list[i])){
905 /* Finally add the new modulator to to the list. */
906 mod_list[mod_list_count++] = mod;
910 /* Add instrument modulators (global / local) to the voice. */
911 for (i = 0; i < mod_list_count; i++){
915 if (mod != NULL){ /* disabled modulators CANNOT be skipped. */
917 /* Instrument modulators -supersede- existing (default)
918 * modulators. SF 2.01 page 69, 'bullet' 6 */
919 fluid_voice_add_mod(voice, mod, FLUID_VOICE_OVERWRITE);
923 /* Preset level, generators */
925 for (i = 0; i < GEN_LAST; i++) {
927 /* SF 2.01 section 8.5 page 58: If some generators are
928 * encountered at preset level, they should be ignored */
929 if ((i != GEN_STARTADDROFS)
930 && (i != GEN_ENDADDROFS)
931 && (i != GEN_STARTLOOPADDROFS)
932 && (i != GEN_ENDLOOPADDROFS)
933 && (i != GEN_STARTADDRCOARSEOFS)
934 && (i != GEN_ENDADDRCOARSEOFS)
935 && (i != GEN_STARTLOOPADDRCOARSEOFS)
937 && (i != GEN_VELOCITY)
938 && (i != GEN_ENDLOOPADDRCOARSEOFS)
939 && (i != GEN_SAMPLEMODE)
940 && (i != GEN_EXCLUSIVECLASS)
941 && (i != GEN_OVERRIDEROOTKEY)) {
943 /* SF 2.01 section 9.4 'bullet' 9: A generator in a
944 * local preset zone supersedes a global preset zone
945 * generator. The effect is -added- to the destination
946 * summing node -> voice_gen_incr */
948 if (preset_zone->gen[i].flags) {
949 fluid_voice_gen_incr(voice, i, preset_zone->gen[i].val);
950 } else if ((global_preset_zone != NULL) && global_preset_zone->gen[i].flags) {
951 fluid_voice_gen_incr(voice, i, global_preset_zone->gen[i].val);
953 /* The generator has not been defined in this preset
954 * Do nothing, leave it unchanged.
957 } /* if available at preset level */
958 } /* for all generators */
961 /* Global preset zone, modulators: put them all into a
964 if (global_preset_zone){
965 mod = global_preset_zone->mod;
967 mod_list[mod_list_count++] = mod;
972 /* Process the modulators of the local preset zone. Kick
973 * out all identical modulators from the global preset zone
974 * (SF 2.01 page 69, second-last bullet) */
976 mod = preset_zone->mod;
978 for (i = 0; i < mod_list_count; i++){
979 if (mod_list[i] && fluid_mod_test_identity(mod,mod_list[i])){
984 /* Finally add the new modulator to the list. */
985 mod_list[mod_list_count++] = mod;
989 /* Add preset modulators (global / local) to the voice. */
990 for (i = 0; i < mod_list_count; i++){
992 if ((mod != NULL) && (mod->amount != 0)) { /* disabled modulators can be skipped. */
994 /* Preset modulators -add- to existing instrument /
995 * default modulators. SF2.01 page 70 first bullet on
997 fluid_voice_add_mod(voice, mod, FLUID_VOICE_ADD);
1001 /* add the synthesis process to the synthesis loop. */
1002 fluid_synth_start_voice(synth, voice);
1004 /* Store the ID of the first voice that was created by this noteon event.
1005 * Exclusive class may only terminate older voices.
1006 * That avoids killing voices, which have just been created.
1007 * (a noteon event can create several voice processes with the same exclusive
1008 * class - for example when using stereo samples)
1012 inst_zone = fluid_inst_zone_next(inst_zone);
1015 preset_zone = fluid_preset_zone_next(preset_zone);
1022 * fluid_defpreset_set_global_zone
1025 fluid_defpreset_set_global_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone)
1027 preset->global_zone = zone;
1032 * fluid_defpreset_import_sfont
1035 fluid_defpreset_import_sfont(fluid_defpreset_t* preset,
1037 fluid_defsfont_t* sfont)
1041 fluid_preset_zone_t* zone;
1043 char zone_name[256];
1044 if ((sfpreset->name != NULL) && (FLUID_STRLEN(sfpreset->name) > 0)) {
1045 FLUID_STRCPY(preset->name, sfpreset->name);
1047 FLUID_SPRINTF(preset->name, "Bank%d,Preset%d", sfpreset->bank, sfpreset->prenum);
1049 preset->bank = sfpreset->bank;
1050 preset->num = sfpreset->prenum;
1054 sfzone = (SFZone *) p->data;
1055 FLUID_SPRINTF(zone_name, "%s/%d", preset->name, count);
1056 zone = new_fluid_preset_zone(zone_name);
1058 return FLUID_FAILED;
1060 if (fluid_preset_zone_import_sfont(zone, sfzone, sfont) != FLUID_OK) {
1061 delete_fluid_preset_zone(zone);
1062 return FLUID_FAILED;
1064 if ((count == 0) && (fluid_preset_zone_get_inst(zone) == NULL)) {
1065 fluid_defpreset_set_global_zone(preset, zone);
1066 } else if (fluid_defpreset_add_zone(preset, zone) != FLUID_OK) {
1067 return FLUID_FAILED;
1069 p = fluid_list_next(p);
1076 * fluid_defpreset_add_zone
1079 fluid_defpreset_add_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone)
1081 if (preset->zone == NULL) {
1083 preset->zone = zone;
1085 zone->next = preset->zone;
1086 preset->zone = zone;
1092 * fluid_defpreset_get_zone
1094 fluid_preset_zone_t*
1095 fluid_defpreset_get_zone(fluid_defpreset_t* preset)
1097 return preset->zone;
1101 * fluid_defpreset_get_global_zone
1103 fluid_preset_zone_t*
1104 fluid_defpreset_get_global_zone(fluid_defpreset_t* preset)
1106 return preset->global_zone;
1110 * fluid_preset_zone_next
1112 fluid_preset_zone_t*
1113 fluid_preset_zone_next(fluid_preset_zone_t* preset)
1115 return preset->next;
1119 * new_fluid_preset_zone
1121 fluid_preset_zone_t*
1122 new_fluid_preset_zone(char *name)
1125 fluid_preset_zone_t* zone = NULL;
1126 zone = FLUID_NEW(fluid_preset_zone_t);
1128 FLUID_LOG(FLUID_ERR, "Out of memory");
1132 size = 1 + FLUID_STRLEN(name);
1133 zone->name = FLUID_MALLOC(size);
1134 if (zone->name == NULL) {
1135 FLUID_LOG(FLUID_ERR, "Out of memory");
1139 FLUID_STRCPY(zone->name, name);
1146 /* Flag all generators as unused (default, they will be set when they are found
1147 * in the sound font).
1148 * This also sets the generator values to default, but that is of no concern here.*/
1149 fluid_gen_set_default_values(&zone->gen[0]);
1150 zone->mod = NULL; /* list of modulators */
1154 /***************************************************************
1160 * delete_fluid_preset_zone
1163 delete_fluid_preset_zone(fluid_preset_zone_t* zone)
1165 fluid_mod_t *mod, *tmp;
1168 while (mod) /* delete the modulators */
1172 fluid_mod_delete (tmp);
1175 if (zone->name) FLUID_FREE (zone->name);
1176 if (zone->inst) delete_fluid_inst (zone->inst);
1182 * fluid_preset_zone_import_sfont
1185 fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont)
1190 for (count = 0, r = sfzone->gen; r != NULL; count++) {
1191 sfgen = (SFGen *) r->data;
1192 switch (sfgen->id) {
1194 zone->keylo = (int) sfgen->amount.range.lo;
1195 zone->keyhi = (int) sfgen->amount.range.hi;
1198 zone->vello = (int) sfgen->amount.range.lo;
1199 zone->velhi = (int) sfgen->amount.range.hi;
1202 /* FIXME: some generators have an unsigne word amount value but i don't know which ones */
1203 zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword;
1204 zone->gen[sfgen->id].flags = GEN_SET;
1207 r = fluid_list_next(r);
1209 if ((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL)) {
1210 zone->inst = (fluid_inst_t*) new_fluid_inst();
1211 if (zone->inst == NULL) {
1212 FLUID_LOG(FLUID_ERR, "Out of memory");
1213 return FLUID_FAILED;
1215 if (fluid_inst_import_sfont(zone->inst, (SFInst *) sfzone->instsamp->data, sfont) != FLUID_OK) {
1216 return FLUID_FAILED;
1220 /* Import the modulators (only SF2.1 and higher) */
1221 for (count = 0, r = sfzone->mod; r != NULL; count++) {
1223 SFMod* mod_src = (SFMod *)r->data;
1224 fluid_mod_t * mod_dest = fluid_mod_new();
1227 if (mod_dest == NULL){
1228 return FLUID_FAILED;
1230 mod_dest->next = NULL; /* pointer to next modulator, this is the end of the list now.*/
1232 /* *** Amount *** */
1233 mod_dest->amount = mod_src->amount;
1235 /* *** Source *** */
1236 mod_dest->src1 = mod_src->src & 127; /* index of source 1, seven-bit value, SF2.01 section 8.2, page 50 */
1237 mod_dest->flags1 = 0;
1239 /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/
1240 if (mod_src->src & (1<<7)){
1241 mod_dest->flags1 |= FLUID_MOD_CC;
1243 mod_dest->flags1 |= FLUID_MOD_GC;
1246 /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/
1247 if (mod_src->src & (1<<8)){
1248 mod_dest->flags1 |= FLUID_MOD_NEGATIVE;
1250 mod_dest->flags1 |= FLUID_MOD_POSITIVE;
1253 /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/
1254 if (mod_src->src & (1<<9)){
1255 mod_dest->flags1 |= FLUID_MOD_BIPOLAR;
1257 mod_dest->flags1 |= FLUID_MOD_UNIPOLAR;
1260 /* modulator source types: SF2.01 section 8.2.1 page 52 */
1261 type=(mod_src->src) >> 10;
1262 type &= 63; /* type is a 6-bit value */
1264 mod_dest->flags1 |= FLUID_MOD_LINEAR;
1265 } else if (type == 1){
1266 mod_dest->flags1 |= FLUID_MOD_CONCAVE;
1267 } else if (type == 2){
1268 mod_dest->flags1 |= FLUID_MOD_CONVEX;
1269 } else if (type == 3){
1270 mod_dest->flags1 |= FLUID_MOD_SWITCH;
1272 /* This shouldn't happen - unknown type!
1273 * Deactivate the modulator by setting the amount to 0. */
1278 mod_dest->dest = mod_src->dest; /* index of controlled generator */
1280 /* *** Amount source *** */
1281 mod_dest->src2 = mod_src->amtsrc & 127; /* index of source 2, seven-bit value, SF2.01 section 8.2, p.50 */
1282 mod_dest->flags2 = 0;
1284 /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/
1285 if (mod_src->amtsrc & (1<<7)){
1286 mod_dest->flags2 |= FLUID_MOD_CC;
1288 mod_dest->flags2 |= FLUID_MOD_GC;
1291 /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/
1292 if (mod_src->amtsrc & (1<<8)){
1293 mod_dest->flags2 |= FLUID_MOD_NEGATIVE;
1295 mod_dest->flags2 |= FLUID_MOD_POSITIVE;
1298 /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/
1299 if (mod_src->amtsrc & (1<<9)){
1300 mod_dest->flags2 |= FLUID_MOD_BIPOLAR;
1302 mod_dest->flags2 |= FLUID_MOD_UNIPOLAR;
1305 /* modulator source types: SF2.01 section 8.2.1 page 52 */
1306 type = (mod_src->amtsrc) >> 10;
1307 type &= 63; /* type is a 6-bit value */
1309 mod_dest->flags2 |= FLUID_MOD_LINEAR;
1310 } else if (type == 1){
1311 mod_dest->flags2 |= FLUID_MOD_CONCAVE;
1312 } else if (type == 2){
1313 mod_dest->flags2 |= FLUID_MOD_CONVEX;
1314 } else if (type == 3){
1315 mod_dest->flags2 |= FLUID_MOD_SWITCH;
1317 /* This shouldn't happen - unknown type!
1318 * Deactivate the modulator by setting the amount to 0. */
1322 /* *** Transform *** */
1323 /* SF2.01 only uses the 'linear' transform (0).
1324 * Deactivate the modulator by setting the amount to 0 in any other case.
1326 if (mod_src->trans !=0){
1327 mod_dest->amount = 0;
1330 /* Store the new modulator in the zone The order of modulators
1331 * will make a difference, at least in an instrument context: The
1332 * second modulator overwrites the first one, if they only differ
1335 zone->mod = mod_dest;
1337 fluid_mod_t * last_mod = zone->mod;
1339 /* Find the end of the list */
1340 while (last_mod->next != NULL){
1341 last_mod=last_mod->next;
1344 last_mod->next = mod_dest;
1347 r = fluid_list_next(r);
1348 } /* foreach modulator */
1354 * fluid_preset_zone_get_inst
1357 fluid_preset_zone_get_inst(fluid_preset_zone_t* zone)
1363 * fluid_preset_zone_inside_range
1366 fluid_preset_zone_inside_range(fluid_preset_zone_t* zone, int key, int vel)
1368 return ((zone->keylo <= key) &&
1369 (zone->keyhi >= key) &&
1370 (zone->vello <= vel) &&
1371 (zone->velhi >= vel));
1374 /***************************************************************
1385 fluid_inst_t* inst = FLUID_NEW(fluid_inst_t);
1387 FLUID_LOG(FLUID_ERR, "Out of memory");
1391 inst->global_zone = NULL;
1400 delete_fluid_inst(fluid_inst_t* inst)
1402 fluid_inst_zone_t* zone;
1404 if (inst->global_zone != NULL) {
1405 if (delete_fluid_inst_zone(inst->global_zone) != FLUID_OK) {
1408 inst->global_zone = NULL;
1411 while (zone != NULL) {
1412 inst->zone = zone->next;
1413 if (delete_fluid_inst_zone(zone) != FLUID_OK) {
1423 * fluid_inst_set_global_zone
1426 fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone)
1428 inst->global_zone = zone;
1433 * fluid_inst_import_sfont
1436 fluid_inst_import_sfont(fluid_inst_t* inst, SFInst *sfinst, fluid_defsfont_t* sfont)
1440 fluid_inst_zone_t* zone;
1441 char zone_name[256];
1445 if ((sfinst->name != NULL) && (FLUID_STRLEN(sfinst->name) > 0)) {
1446 FLUID_STRCPY(inst->name, sfinst->name);
1448 FLUID_STRCPY(inst->name, "<untitled>");
1454 sfzone = (SFZone *) p->data;
1455 FLUID_SPRINTF(zone_name, "%s/%d", inst->name, count);
1457 zone = new_fluid_inst_zone(zone_name);
1459 return FLUID_FAILED;
1462 if (fluid_inst_zone_import_sfont(zone, sfzone, sfont) != FLUID_OK) {
1463 delete_fluid_inst_zone(zone);
1464 return FLUID_FAILED;
1467 if ((count == 0) && (fluid_inst_zone_get_sample(zone) == NULL)) {
1468 fluid_inst_set_global_zone(inst, zone);
1470 } else if (fluid_inst_add_zone(inst, zone) != FLUID_OK) {
1471 return FLUID_FAILED;
1474 p = fluid_list_next(p);
1481 * fluid_inst_add_zone
1484 fluid_inst_add_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone)
1486 if (inst->zone == NULL) {
1490 zone->next = inst->zone;
1497 * fluid_inst_get_zone
1500 fluid_inst_get_zone(fluid_inst_t* inst)
1506 * fluid_inst_get_global_zone
1509 fluid_inst_get_global_zone(fluid_inst_t* inst)
1511 return inst->global_zone;
1514 /***************************************************************
1520 * new_fluid_inst_zone
1523 new_fluid_inst_zone(char* name)
1526 fluid_inst_zone_t* zone = NULL;
1527 zone = FLUID_NEW(fluid_inst_zone_t);
1529 FLUID_LOG(FLUID_ERR, "Out of memory");
1533 size = 1 + FLUID_STRLEN(name);
1534 zone->name = FLUID_MALLOC(size);
1535 if (zone->name == NULL) {
1536 FLUID_LOG(FLUID_ERR, "Out of memory");
1540 FLUID_STRCPY(zone->name, name);
1541 zone->sample = NULL;
1547 /* Flag the generators as unused.
1548 * This also sets the generator values to default, but they will be overwritten anyway, if used.*/
1549 fluid_gen_set_default_values(&zone->gen[0]);
1550 zone->mod=NULL; /* list of modulators */
1555 * delete_fluid_inst_zone
1558 delete_fluid_inst_zone(fluid_inst_zone_t* zone)
1560 fluid_mod_t *mod, *tmp;
1563 while (mod) /* delete the modulators */
1567 fluid_mod_delete (tmp);
1570 if (zone->name) FLUID_FREE (zone->name);
1576 * fluid_inst_zone_next
1579 fluid_inst_zone_next(fluid_inst_zone_t* zone)
1585 * fluid_inst_zone_import_sfont
1588 fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont)
1594 for (count = 0, r = sfzone->gen; r != NULL; count++) {
1595 sfgen = (SFGen *) r->data;
1596 switch (sfgen->id) {
1598 zone->keylo = (int) sfgen->amount.range.lo;
1599 zone->keyhi = (int) sfgen->amount.range.hi;
1602 zone->vello = (int) sfgen->amount.range.lo;
1603 zone->velhi = (int) sfgen->amount.range.hi;
1606 /* FIXME: some generators have an unsigned word amount value but
1607 i don't know which ones */
1608 zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword;
1609 zone->gen[sfgen->id].flags = GEN_SET;
1612 r = fluid_list_next(r);
1616 /* if (zone->gen[GEN_EXCLUSIVECLASS].flags == GEN_SET) { */
1617 /* FLUID_LOG(FLUID_DBG, "ExclusiveClass=%d\n", (int) zone->gen[GEN_EXCLUSIVECLASS].val); */
1620 /* fixup sample pointer */
1621 if ((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL))
1622 zone->sample = ((SFSample *)(sfzone->instsamp->data))->fluid_sample;
1624 /* Import the modulators (only SF2.1 and higher) */
1625 for (count = 0, r = sfzone->mod; r != NULL; count++) {
1626 SFMod* mod_src = (SFMod *) r->data;
1628 fluid_mod_t* mod_dest;
1630 mod_dest = fluid_mod_new();
1631 if (mod_dest == NULL){
1632 return FLUID_FAILED;
1635 mod_dest->next = NULL; /* pointer to next modulator, this is the end of the list now.*/
1637 /* *** Amount *** */
1638 mod_dest->amount = mod_src->amount;
1640 /* *** Source *** */
1641 mod_dest->src1 = mod_src->src & 127; /* index of source 1, seven-bit value, SF2.01 section 8.2, page 50 */
1642 mod_dest->flags1 = 0;
1644 /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/
1645 if (mod_src->src & (1<<7)){
1646 mod_dest->flags1 |= FLUID_MOD_CC;
1648 mod_dest->flags1 |= FLUID_MOD_GC;
1651 /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/
1652 if (mod_src->src & (1<<8)){
1653 mod_dest->flags1 |= FLUID_MOD_NEGATIVE;
1655 mod_dest->flags1 |= FLUID_MOD_POSITIVE;
1658 /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/
1659 if (mod_src->src & (1<<9)){
1660 mod_dest->flags1 |= FLUID_MOD_BIPOLAR;
1662 mod_dest->flags1 |= FLUID_MOD_UNIPOLAR;
1665 /* modulator source types: SF2.01 section 8.2.1 page 52 */
1666 type = (mod_src->src) >> 10;
1667 type &= 63; /* type is a 6-bit value */
1669 mod_dest->flags1 |= FLUID_MOD_LINEAR;
1670 } else if (type == 1){
1671 mod_dest->flags1 |= FLUID_MOD_CONCAVE;
1672 } else if (type == 2){
1673 mod_dest->flags1 |= FLUID_MOD_CONVEX;
1674 } else if (type == 3){
1675 mod_dest->flags1 |= FLUID_MOD_SWITCH;
1677 /* This shouldn't happen - unknown type!
1678 * Deactivate the modulator by setting the amount to 0. */
1679 mod_dest->amount = 0;
1683 mod_dest->dest=mod_src->dest; /* index of controlled generator */
1685 /* *** Amount source *** */
1686 mod_dest->src2=mod_src->amtsrc & 127; /* index of source 2, seven-bit value, SF2.01 section 8.2, page 50 */
1687 mod_dest->flags2 = 0;
1689 /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/
1690 if (mod_src->amtsrc & (1<<7)){
1691 mod_dest->flags2 |= FLUID_MOD_CC;
1693 mod_dest->flags2 |= FLUID_MOD_GC;
1696 /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/
1697 if (mod_src->amtsrc & (1<<8)){
1698 mod_dest->flags2 |= FLUID_MOD_NEGATIVE;
1700 mod_dest->flags2 |= FLUID_MOD_POSITIVE;
1703 /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/
1704 if (mod_src->amtsrc & (1<<9)){
1705 mod_dest->flags2 |= FLUID_MOD_BIPOLAR;
1707 mod_dest->flags2 |= FLUID_MOD_UNIPOLAR;
1710 /* modulator source types: SF2.01 section 8.2.1 page 52 */
1711 type=(mod_src->amtsrc) >> 10;
1712 type &= 63; /* type is a 6-bit value */
1714 mod_dest->flags2 |= FLUID_MOD_LINEAR;
1715 } else if (type == 1){
1716 mod_dest->flags2 |= FLUID_MOD_CONCAVE;
1717 } else if (type == 2){
1718 mod_dest->flags2 |= FLUID_MOD_CONVEX;
1719 } else if (type == 3){
1720 mod_dest->flags2 |= FLUID_MOD_SWITCH;
1722 /* This shouldn't happen - unknown type!
1723 * Deactivate the modulator by setting the amount to 0. */
1724 mod_dest->amount = 0;
1727 /* *** Transform *** */
1728 /* SF2.01 only uses the 'linear' transform (0).
1729 * Deactivate the modulator by setting the amount to 0 in any other case.
1731 if (mod_src->trans !=0){
1732 mod_dest->amount = 0;
1735 /* Store the new modulator in the zone
1736 * The order of modulators will make a difference, at least in an instrument context:
1737 * The second modulator overwrites the first one, if they only differ in amount. */
1741 fluid_mod_t * last_mod=zone->mod;
1742 /* Find the end of the list */
1743 while (last_mod->next != NULL){
1744 last_mod=last_mod->next;
1746 last_mod->next=mod_dest;
1749 r = fluid_list_next(r);
1750 } /* foreach modulator */
1755 * fluid_inst_zone_get_sample
1758 fluid_inst_zone_get_sample(fluid_inst_zone_t* zone)
1760 return zone->sample;
1764 * fluid_inst_zone_inside_range
1767 fluid_inst_zone_inside_range(fluid_inst_zone_t* zone, int key, int vel)
1769 return ((zone->keylo <= key) &&
1770 (zone->keyhi >= key) &&
1771 (zone->vello <= vel) &&
1772 (zone->velhi >= vel));
1775 /***************************************************************
1786 fluid_sample_t* sample = NULL;
1788 sample = FLUID_NEW(fluid_sample_t);
1789 if (sample == NULL) {
1790 FLUID_LOG(FLUID_ERR, "Out of memory");
1794 memset(sample, 0, sizeof(fluid_sample_t));
1801 * delete_fluid_sample
1804 delete_fluid_sample(fluid_sample_t* sample)
1811 * fluid_sample_in_rom
1814 fluid_sample_in_rom(fluid_sample_t* sample)
1816 return (sample->sampletype & FLUID_SAMPLETYPE_ROM);
1820 * fluid_sample_import_sfont
1823 fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defsfont_t* sfont)
1825 FLUID_STRCPY(sample->name, sfsample->name);
1826 sample->data = sfont->sampledata;
1827 sample->start = sfsample->start;
1828 sample->end = sfsample->start + sfsample->end;
1829 sample->loopstart = sfsample->start + sfsample->loopstart;
1830 sample->loopend = sfsample->start + sfsample->loopend;
1831 sample->samplerate = sfsample->samplerate;
1832 sample->origpitch = sfsample->origpitch;
1833 sample->pitchadj = sfsample->pitchadj;
1834 sample->sampletype = sfsample->sampletype;
1836 if (sample->sampletype & FLUID_SAMPLETYPE_ROM) {
1838 FLUID_LOG(FLUID_WARN, "Ignoring sample %s: can't use ROM samples", sample->name);
1840 if (sample->end - sample->start < 8) {
1842 FLUID_LOG(FLUID_WARN, "Ignoring sample %s: too few sample data points", sample->name);
1844 /* if (sample->loopstart < sample->start + 8) { */
1845 /* FLUID_LOG(FLUID_WARN, "Fixing sample %s: at least 8 data points required before loop start", sample->name); */
1846 /* sample->loopstart = sample->start + 8; */
1848 /* if (sample->loopend > sample->end - 8) { */
1849 /* FLUID_LOG(FLUID_WARN, "Fixing sample %s: at least 8 data points required after loop end", sample->name); */
1850 /* sample->loopend = sample->end - 8; */
1858 /********************************************************************************/
1859 /********************************************************************************/
1860 /********************************************************************************/
1861 /********************************************************************************/
1862 /********************************************************************************/
1866 /*=================================sfload.c========================
1867 Borrowed from Smurf SoundFont Editor by Josh Green
1868 =================================================================*/
1871 functions for loading data from sfont files, with appropriate byte swapping
1872 on big endian machines. Sfont IDs are not swapped because the ID read is
1873 equivalent to the matching ID list in memory regardless of LE/BE machine
1876 #if FLUID_IS_BIG_ENDIAN
1878 #define READCHUNK(var,fd) G_STMT_START { \
1879 if (!safe_fread(var, 8, fd)) \
1881 ((SFChunk *)(var))->size = GUINT32_FROM_LE(((SFChunk *)(var))->size); \
1884 #define READD(var,fd) G_STMT_START { \
1885 unsigned int _temp; \
1886 if (!safe_fread(&_temp, 4, fd)) \
1888 var = GINT32_FROM_LE(_temp); \
1891 #define READW(var,fd) G_STMT_START { \
1892 unsigned short _temp; \
1893 if (!safe_fread(&_temp, 2, fd)) \
1895 var = GINT16_FROM_LE(_temp); \
1900 #define READCHUNK(var,fd) G_STMT_START { \
1901 if (!safe_fread(var, 8, fd)) \
1903 ((SFChunk *)(var))->size = GUINT32_FROM_LE(((SFChunk *)(var))->size); \
1906 #define READD(var,fd) G_STMT_START { \
1907 unsigned int _temp; \
1908 if (!safe_fread(&_temp, 4, fd)) \
1910 var = GINT32_FROM_LE(_temp); \
1913 #define READW(var,fd) G_STMT_START { \
1914 unsigned short _temp; \
1915 if (!safe_fread(&_temp, 2, fd)) \
1917 var = GINT16_FROM_LE(_temp); \
1923 #define READID(var,fd) G_STMT_START { \
1924 if (!safe_fread(var, 4, fd)) \
1928 #define READSTR(var,fd) G_STMT_START { \
1929 if (!safe_fread(var, 20, fd)) \
1931 (*var)[20] = '\0'; \
1934 #define READB(var,fd) G_STMT_START { \
1935 if (!safe_fread(&var, 1, fd)) \
1939 #define FSKIP(size,fd) G_STMT_START { \
1940 if (!safe_fseek(fd, size, SEEK_CUR)) \
1944 #define FSKIPW(fd) G_STMT_START { \
1945 if (!safe_fseek(fd, 2, SEEK_CUR)) \
1949 /* removes and advances a fluid_list_t pointer */
1950 #define SLADVREM(list, item) G_STMT_START { \
1951 fluid_list_t *_temp = item; \
1952 item = fluid_list_next(item); \
1953 list = fluid_list_remove_link(list, _temp); \
1954 delete1_fluid_list(_temp); \
1957 static int chunkid (unsigned int id);
1958 static int load_body (unsigned int size, SFData * sf, FILE * fd);
1959 static int read_listchunk (SFChunk * chunk, FILE * fd);
1960 static int process_info (int size, SFData * sf, FILE * fd);
1961 static int process_sdta (unsigned int size, SFData * sf, FILE * fd);
1962 static int pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
1963 int * size, FILE * fd);
1964 static int process_pdta (int size, SFData * sf, FILE * fd);
1965 static int load_phdr (int size, SFData * sf, FILE * fd);
1966 static int load_pbag (int size, SFData * sf, FILE * fd);
1967 static int load_pmod (int size, SFData * sf, FILE * fd);
1968 static int load_pgen (int size, SFData * sf, FILE * fd);
1969 static int load_ihdr (int size, SFData * sf, FILE * fd);
1970 static int load_ibag (int size, SFData * sf, FILE * fd);
1971 static int load_imod (int size, SFData * sf, FILE * fd);
1972 static int load_igen (int size, SFData * sf, FILE * fd);
1973 static int load_shdr (unsigned int size, SFData * sf, FILE * fd);
1974 static int fixup_pgen (SFData * sf);
1975 static int fixup_igen (SFData * sf);
1976 static int fixup_sample (SFData * sf);
1979 "RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD"
1980 "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdr"
1983 static unsigned int sdtachunk_size;
1985 /* sound font file load functions */
1987 chunkid (unsigned int id)
1992 p = (unsigned int *) & idlist;
1993 for (i = 0; i < sizeof (idlist) / sizeof (int); i++, p += 1)
2001 sfload_file (const char * fname)
2008 if (!(fd = fopen (fname, "rb")))
2010 FLUID_LOG (FLUID_ERR, _("Unable to open file \"%s\""), fname);
2014 if (!(sf = FLUID_NEW (SFData)))
2016 FLUID_LOG(FLUID_ERR, "Out of memory");
2023 memset (sf, 0, sizeof (SFData)); /* zero sfdata */
2024 sf->fname = FLUID_STRDUP (fname); /* copy file name */
2028 /* get size of file */
2029 if (!err && fseek (fd, 0L, SEEK_END) == -1)
2030 { /* seek to end of file */
2032 FLUID_LOG (FLUID_ERR, _("Seek to end of file failed"));
2034 if (!err && (fsize = ftell (fd)) == -1)
2035 { /* position = size */
2037 FLUID_LOG (FLUID_ERR, _("Get end of file position failed"));
2042 if (!err && !load_body (fsize, sf, fd))
2043 err = TRUE; /* load the sfont */
2056 load_body (unsigned int size, SFData * sf, FILE * fd)
2060 READCHUNK (&chunk, fd); /* load RIFF chunk */
2061 if (chunkid (chunk.id) != RIFF_ID) { /* error if not RIFF */
2062 FLUID_LOG (FLUID_ERR, _("Not a RIFF file"));
2066 READID (&chunk.id, fd); /* load file ID */
2067 if (chunkid (chunk.id) != SFBK_ID) { /* error if not SFBK_ID */
2068 FLUID_LOG (FLUID_ERR, _("Not a SoundFont file"));
2072 if (chunk.size != size - 8) {
2073 gerr (ErrCorr, _("SoundFont file size mismatch"));
2077 /* Process INFO block */
2078 if (!read_listchunk (&chunk, fd))
2080 if (chunkid (chunk.id) != INFO_ID)
2081 return (gerr (ErrCorr, _("Invalid ID found when expecting INFO chunk")));
2082 if (!process_info (chunk.size, sf, fd))
2085 /* Process sample chunk */
2086 if (!read_listchunk (&chunk, fd))
2088 if (chunkid (chunk.id) != SDTA_ID)
2089 return (gerr (ErrCorr,
2090 _("Invalid ID found when expecting SAMPLE chunk")));
2091 if (!process_sdta (chunk.size, sf, fd))
2094 /* process HYDRA chunk */
2095 if (!read_listchunk (&chunk, fd))
2097 if (chunkid (chunk.id) != PDTA_ID)
2098 return (gerr (ErrCorr, _("Invalid ID found when expecting HYDRA chunk")));
2099 if (!process_pdta (chunk.size, sf, fd))
2102 if (!fixup_pgen (sf))
2104 if (!fixup_igen (sf))
2106 if (!fixup_sample (sf))
2109 /* sort preset list by bank, preset # */
2110 sf->preset = fluid_list_sort (sf->preset,
2111 (fluid_compare_func_t) sfont_preset_compare_func);
2117 read_listchunk (SFChunk * chunk, FILE * fd)
2119 READCHUNK (chunk, fd); /* read list chunk */
2120 if (chunkid (chunk->id) != LIST_ID) /* error if ! list chunk */
2121 return (gerr (ErrCorr, _("Invalid chunk id in level 0 parse")));
2122 READID (&chunk->id, fd); /* read id string */
2128 process_info (int size, SFData * sf, FILE * fd)
2137 READCHUNK (&chunk, fd);
2140 id = chunkid (chunk.id);
2143 { /* sound font version chunk? */
2144 if (chunk.size != 4)
2145 return (gerr (ErrCorr,
2146 _("Sound font version info chunk has invalid size")));
2149 sf->version.major = ver;
2151 sf->version.minor = ver;
2153 if (sf->version.major < 2) {
2154 FLUID_LOG (FLUID_ERR,
2155 _("Sound font version is %d.%d which is not"
2156 " supported, convert to version 2.0x"),
2162 if (sf->version.major > 2) {
2163 FLUID_LOG (FLUID_WARN,
2164 _("Sound font version is %d.%d which is newer than"
2165 " what this version of FLUID Synth was designed for (v2.0x)"),
2171 else if (id == IVER_ID)
2172 { /* ROM version chunk? */
2173 if (chunk.size != 4)
2174 return (gerr (ErrCorr,
2175 _("ROM version info chunk has invalid size")));
2178 sf->romver.major = ver;
2180 sf->romver.minor = ver;
2182 else if (id != UNKN_ID)
2184 if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536)
2185 || (chunk.size % 2))
2186 return (gerr (ErrCorr,
2187 _("INFO sub chunk %.4s has invalid chunk size"
2188 " of %d bytes"), &chunk.id, chunk.size));
2190 /* alloc for chunk id and da chunk */
2191 if (!(item = FLUID_MALLOC (chunk.size + 1)))
2193 FLUID_LOG(FLUID_ERR, "Out of memory");
2197 /* attach to INFO list, sfont_close will cleanup if FAIL occurs */
2198 sf->info = fluid_list_append (sf->info, item);
2200 *(unsigned char *) item = id;
2201 if (!safe_fread (&item[1], chunk.size, fd))
2204 /* force terminate info item (don't forget uint8 info ID) */
2205 *(item + chunk.size) = '\0';
2208 return (gerr (ErrCorr, _("Invalid chunk id in INFO chunk")));
2213 return (gerr (ErrCorr, _("INFO chunk size mismatch")));
2219 process_sdta (unsigned int size, SFData * sf, FILE * fd)
2224 return (OK); /* no sample data? */
2226 /* read sub chunk */
2227 READCHUNK (&chunk, fd);
2230 if (chunkid (chunk.id) != SMPL_ID)
2231 return (gerr (ErrCorr,
2232 _("Expected SMPL chunk found invalid id instead")));
2234 /* SDTA chunk may also contain sm24 chunk for 24 bit samples
2235 * (not yet supported), only an error if SMPL chunk size is
2236 * greater than SDTA. */
2237 if (chunk.size > size)
2238 return (gerr (ErrCorr, _("SDTA chunk size mismatch")));
2240 /* sample data follows */
2241 sf->samplepos = ftell (fd);
2243 /* used in fixup_sample() to check validity of sample headers */
2244 sdtachunk_size = chunk.size;
2245 sf->samplesize = chunk.size;
2253 pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
2254 int * size, FILE * fd)
2259 expstr = CHNKIDSTR (expid); /* in case we need it */
2261 READCHUNK (chunk, fd);
2264 if ((id = chunkid (chunk->id)) != expid)
2265 return (gerr (ErrCorr, _("Expected"
2266 " PDTA sub-chunk \"%.4s\" found invalid id instead"), expstr));
2268 if (chunk->size % reclen) /* valid chunk size? */
2269 return (gerr (ErrCorr,
2270 _("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr,
2272 if ((*size -= chunk->size) < 0)
2273 return (gerr (ErrCorr,
2274 _("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr));
2279 process_pdta (int size, SFData * sf, FILE * fd)
2283 if (!pdtahelper (PHDR_ID, SFPHDRSIZE, &chunk, &size, fd))
2285 if (!load_phdr (chunk.size, sf, fd))
2288 if (!pdtahelper (PBAG_ID, SFBAGSIZE, &chunk, &size, fd))
2290 if (!load_pbag (chunk.size, sf, fd))
2293 if (!pdtahelper (PMOD_ID, SFMODSIZE, &chunk, &size, fd))
2295 if (!load_pmod (chunk.size, sf, fd))
2298 if (!pdtahelper (PGEN_ID, SFGENSIZE, &chunk, &size, fd))
2300 if (!load_pgen (chunk.size, sf, fd))
2303 if (!pdtahelper (IHDR_ID, SFIHDRSIZE, &chunk, &size, fd))
2305 if (!load_ihdr (chunk.size, sf, fd))
2308 if (!pdtahelper (IBAG_ID, SFBAGSIZE, &chunk, &size, fd))
2310 if (!load_ibag (chunk.size, sf, fd))
2313 if (!pdtahelper (IMOD_ID, SFMODSIZE, &chunk, &size, fd))
2315 if (!load_imod (chunk.size, sf, fd))
2318 if (!pdtahelper (IGEN_ID, SFGENSIZE, &chunk, &size, fd))
2320 if (!load_igen (chunk.size, sf, fd))
2323 if (!pdtahelper (SHDR_ID, SFSHDRSIZE, &chunk, &size, fd))
2325 if (!load_shdr (chunk.size, sf, fd))
2331 /* preset header loader */
2333 load_phdr (int size, SFData * sf, FILE * fd)
2336 SFPreset *p, *pr = NULL; /* ptr to current & previous preset */
2337 unsigned short zndx, pzndx = 0;
2339 if (size % SFPHDRSIZE || size == 0)
2340 return (gerr (ErrCorr, _("Preset header chunk size is invalid")));
2342 i = size / SFPHDRSIZE - 1;
2344 { /* at least one preset + term record */
2345 FLUID_LOG (FLUID_WARN, _("File contains no presets"));
2346 FSKIP (SFPHDRSIZE, fd);
2351 { /* load all preset headers */
2352 p = FLUID_NEW (SFPreset);
2353 sf->preset = fluid_list_append (sf->preset, p);
2354 p->zone = NULL; /* In case of failure, sfont_close can cleanup */
2355 READSTR (&p->name, fd); /* possible read failure ^ */
2356 READW (p->prenum, fd);
2357 READW (p->bank, fd);
2359 READD (p->libr, fd);
2360 READD (p->genre, fd);
2361 READD (p->morph, fd);
2364 { /* not first preset? */
2366 return (gerr (ErrCorr, _("Preset header indices not monotonic")));
2370 pr->zone = fluid_list_prepend (pr->zone, NULL);
2373 else if (zndx > 0) /* 1st preset, warn if ofs >0 */
2374 FLUID_LOG (FLUID_WARN, _("%d preset zones not referenced, discarding"), zndx);
2375 pr = p; /* update preset ptr */
2380 READW (zndx, fd); /* Read terminal generator index */
2384 return (gerr (ErrCorr, _("Preset header indices not monotonic")));
2388 pr->zone = fluid_list_prepend (pr->zone, NULL);
2394 /* preset bag loader */
2396 load_pbag (int size, SFData * sf, FILE * fd)
2398 fluid_list_t *p, *p2;
2399 SFZone *z, *pz = NULL;
2400 unsigned short genndx, modndx;
2401 unsigned short pgenndx = 0, pmodndx = 0;
2404 if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */
2405 return (gerr (ErrCorr, _("Preset bag chunk size is invalid")));
2409 { /* traverse through presets */
2410 p2 = ((SFPreset *) (p->data))->zone;
2412 { /* traverse preset's zones */
2413 if ((size -= SFBAGSIZE) < 0)
2414 return (gerr (ErrCorr, _("Preset bag chunk size mismatch")));
2415 z = FLUID_NEW (SFZone);
2417 z->gen = NULL; /* Init gen and mod before possible failure, */
2418 z->mod = NULL; /* to ensure proper cleanup (sfont_close) */
2419 READW (genndx, fd); /* possible read failure ^ */
2424 { /* if not first zone */
2425 if (genndx < pgenndx)
2426 return (gerr (ErrCorr,
2427 _("Preset bag generator indices not monotonic")));
2428 if (modndx < pmodndx)
2429 return (gerr (ErrCorr,
2430 _("Preset bag modulator indices not monotonic")));
2431 i = genndx - pgenndx;
2433 pz->gen = fluid_list_prepend (pz->gen, NULL);
2434 i = modndx - pmodndx;
2436 pz->mod = fluid_list_prepend (pz->mod, NULL);
2438 pz = z; /* update previous zone ptr */
2439 pgenndx = genndx; /* update previous zone gen index */
2440 pmodndx = modndx; /* update previous zone mod index */
2441 p2 = fluid_list_next (p2);
2443 p = fluid_list_next (p);
2448 return (gerr (ErrCorr, _("Preset bag chunk size mismatch")));
2456 FLUID_LOG (FLUID_WARN, _("No preset generators and terminal index not 0"));
2458 FLUID_LOG (FLUID_WARN, _("No preset modulators and terminal index not 0"));
2462 if (genndx < pgenndx)
2463 return (gerr (ErrCorr, _("Preset bag generator indices not monotonic")));
2464 if (modndx < pmodndx)
2465 return (gerr (ErrCorr, _("Preset bag modulator indices not monotonic")));
2466 i = genndx - pgenndx;
2468 pz->gen = fluid_list_prepend (pz->gen, NULL);
2469 i = modndx - pmodndx;
2471 pz->mod = fluid_list_prepend (pz->mod, NULL);
2476 /* preset modulator loader */
2478 load_pmod (int size, SFData * sf, FILE * fd)
2480 fluid_list_t *p, *p2, *p3;
2485 { /* traverse through all presets */
2486 p2 = ((SFPreset *) (p->data))->zone;
2488 { /* traverse this preset's zones */
2489 p3 = ((SFZone *) (p2->data))->mod;
2491 { /* load zone's modulators */
2492 if ((size -= SFMODSIZE) < 0)
2493 return (gerr (ErrCorr,
2494 _("Preset modulator chunk size mismatch")));
2495 m = FLUID_NEW (SFMod);
2498 READW (m->dest, fd);
2499 READW (m->amount, fd);
2500 READW (m->amtsrc, fd);
2501 READW (m->trans, fd);
2502 p3 = fluid_list_next (p3);
2504 p2 = fluid_list_next (p2);
2506 p = fluid_list_next (p);
2510 If there isn't even a terminal record
2511 Hmmm, the specs say there should be one, but..
2518 return (gerr (ErrCorr, _("Preset modulator chunk size mismatch")));
2519 FSKIP (SFMODSIZE, fd); /* terminal mod */
2524 /* -------------------------------------------------------------------
2525 * preset generator loader
2526 * generator (per preset) loading rules:
2527 * Zones with no generators or modulators shall be annihilated
2528 * Global zone must be 1st zone, discard additional ones (instrumentless zones)
2530 * generator (per zone) loading rules (in order of decreasing precedence):
2531 * KeyRange is 1st in list (if exists), else discard
2532 * if a VelRange exists only preceded by a KeyRange, else discard
2533 * if a generator follows an instrument discard it
2534 * if a duplicate generator exists replace previous one
2535 * ------------------------------------------------------------------- */
2537 load_pgen (int size, SFData * sf, FILE * fd)
2539 fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
2543 unsigned short genid;
2544 int level, skip, drop, gzone, discarded;
2548 { /* traverse through all presets */
2551 p2 = ((SFPreset *) (p->data))->zone;
2555 { /* traverse preset's zones */
2557 z = (SFZone *) (p2->data);
2560 { /* load zone's generators */
2564 if ((size -= SFGENSIZE) < 0)
2565 return (gerr (ErrCorr,
2566 _("Preset generator chunk size mismatch")));
2570 if (genid == Gen_KeyRange)
2571 { /* nothing precedes */
2575 READB (genval.range.lo, fd);
2576 READB (genval.range.hi, fd);
2581 else if (genid == Gen_VelRange)
2582 { /* only KeyRange precedes */
2586 READB (genval.range.lo, fd);
2587 READB (genval.range.hi, fd);
2592 else if (genid == Gen_Instrument)
2593 { /* inst is last gen */
2595 READW (genval.uword, fd);
2596 ((SFZone *) (p2->data))->instsamp = GINT_TO_POINTER (genval.uword + 1);
2597 break; /* break out of generator loop */
2602 if (gen_validp (genid))
2603 { /* generator valid? */
2604 READW (genval.sword, fd);
2605 dup = gen_inlist (genid, z->gen);
2614 { /* if gen ! dup alloc new */
2615 g = FLUID_NEW (SFGen);
2621 g = (SFGen *) (dup->data); /* ptr to orig gen */
2627 { /* Skip this generator */
2634 p3 = fluid_list_next (p3); /* next gen */
2636 SLADVREM (z->gen, p3); /* drop place holder */
2638 } /* generator loop */
2641 SLADVREM (z->gen, p3); /* zone has inst? */
2643 { /* congratulations its a global zone */
2645 { /* Prior global zones? */
2648 /* if global zone is not 1st zone, relocate */
2651 void* save = p2->data;
2652 FLUID_LOG (FLUID_WARN,
2653 _("Preset \"%s\": Global zone is not first zone"),
2654 ((SFPreset *) (p->data))->name);
2656 *hz = fluid_list_prepend (*hz, save);
2661 { /* previous global zone exists, discard */
2662 FLUID_LOG (FLUID_WARN,
2663 _("Preset \"%s\": Discarding invalid global zone"),
2664 ((SFPreset *) (p->data))->name);
2665 sfont_zone_delete (sf, hz, (SFZone *) (p2->data));
2670 { /* Kill any zones following an instrument */
2672 if ((size -= SFGENSIZE) < 0)
2673 return (gerr (ErrCorr,
2674 _("Preset generator chunk size mismatch")));
2675 FSKIP (SFGENSIZE, fd);
2676 SLADVREM (z->gen, p3);
2679 p2 = fluid_list_next (p2); /* next zone */
2682 FLUID_LOG(FLUID_WARN,
2683 _("Preset \"%s\": Some invalid generators were discarded"),
2684 ((SFPreset *) (p->data))->name);
2685 p = fluid_list_next (p);
2688 /* in case there isn't a terminal record */
2694 return (gerr (ErrCorr, _("Preset generator chunk size mismatch")));
2695 FSKIP (SFGENSIZE, fd); /* terminal gen */
2700 /* instrument header loader */
2702 load_ihdr (int size, SFData * sf, FILE * fd)
2705 SFInst *p, *pr = NULL; /* ptr to current & previous instrument */
2706 unsigned short zndx, pzndx = 0;
2708 if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */
2709 return (gerr (ErrCorr, _("Instrument header has invalid size")));
2711 size = size / SFIHDRSIZE - 1;
2713 { /* at least one preset + term record */
2714 FLUID_LOG (FLUID_WARN, _("File contains no instruments"));
2715 FSKIP (SFIHDRSIZE, fd);
2719 for (i = 0; i < size; i++)
2720 { /* load all instrument headers */
2721 p = FLUID_NEW (SFInst);
2722 sf->inst = fluid_list_append (sf->inst, p);
2723 p->zone = NULL; /* For proper cleanup if fail (sfont_close) */
2724 READSTR (&p->name, fd); /* Possible read failure ^ */
2728 { /* not first instrument? */
2730 return (gerr (ErrCorr,
2731 _("Instrument header indices not monotonic")));
2734 pr->zone = fluid_list_prepend (pr->zone, NULL);
2736 else if (zndx > 0) /* 1st inst, warn if ofs >0 */
2737 FLUID_LOG (FLUID_WARN, _("%d instrument zones not referenced, discarding"),
2740 pr = p; /* update instrument ptr */
2747 return (gerr (ErrCorr, _("Instrument header indices not monotonic")));
2750 pr->zone = fluid_list_prepend (pr->zone, NULL);
2755 /* instrument bag loader */
2757 load_ibag (int size, SFData * sf, FILE * fd)
2759 fluid_list_t *p, *p2;
2760 SFZone *z, *pz = NULL;
2761 unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0;
2764 if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */
2765 return (gerr (ErrCorr, _("Instrument bag chunk size is invalid")));
2769 { /* traverse through inst */
2770 p2 = ((SFInst *) (p->data))->zone;
2772 { /* load this inst's zones */
2773 if ((size -= SFBAGSIZE) < 0)
2774 return (gerr (ErrCorr, _("Instrument bag chunk size mismatch")));
2775 z = FLUID_NEW (SFZone);
2777 z->gen = NULL; /* In case of failure, */
2778 z->mod = NULL; /* sfont_close can clean up */
2779 READW (genndx, fd); /* READW = possible read failure */
2784 { /* if not first zone */
2785 if (genndx < pgenndx)
2786 return (gerr (ErrCorr,
2787 _("Instrument generator indices not monotonic")));
2788 if (modndx < pmodndx)
2789 return (gerr (ErrCorr,
2790 _("Instrument modulator indices not monotonic")));
2791 i = genndx - pgenndx;
2793 pz->gen = fluid_list_prepend (pz->gen, NULL);
2794 i = modndx - pmodndx;
2796 pz->mod = fluid_list_prepend (pz->mod, NULL);
2798 pz = z; /* update previous zone ptr */
2801 p2 = fluid_list_next (p2);
2803 p = fluid_list_next (p);
2808 return (gerr (ErrCorr, _("Instrument chunk size mismatch")));
2814 { /* in case that all are no zoners */
2816 FLUID_LOG (FLUID_WARN,
2817 _("No instrument generators and terminal index not 0"));
2819 FLUID_LOG (FLUID_WARN,
2820 _("No instrument modulators and terminal index not 0"));
2824 if (genndx < pgenndx)
2825 return (gerr (ErrCorr, _("Instrument generator indices not monotonic")));
2826 if (modndx < pmodndx)
2827 return (gerr (ErrCorr, _("Instrument modulator indices not monotonic")));
2828 i = genndx - pgenndx;
2830 pz->gen = fluid_list_prepend (pz->gen, NULL);
2831 i = modndx - pmodndx;
2833 pz->mod = fluid_list_prepend (pz->mod, NULL);
2838 /* instrument modulator loader */
2840 load_imod (int size, SFData * sf, FILE * fd)
2842 fluid_list_t *p, *p2, *p3;
2847 { /* traverse through all inst */
2848 p2 = ((SFInst *) (p->data))->zone;
2850 { /* traverse this inst's zones */
2851 p3 = ((SFZone *) (p2->data))->mod;
2853 { /* load zone's modulators */
2854 if ((size -= SFMODSIZE) < 0)
2855 return (gerr (ErrCorr,
2856 _("Instrument modulator chunk size mismatch")));
2857 m = FLUID_NEW (SFMod);
2860 READW (m->dest, fd);
2861 READW (m->amount, fd);
2862 READW (m->amtsrc, fd);
2863 READW (m->trans, fd);
2864 p3 = fluid_list_next (p3);
2866 p2 = fluid_list_next (p2);
2868 p = fluid_list_next (p);
2872 If there isn't even a terminal record
2873 Hmmm, the specs say there should be one, but..
2880 return (gerr (ErrCorr, _("Instrument modulator chunk size mismatch")));
2881 FSKIP (SFMODSIZE, fd); /* terminal mod */
2886 /* load instrument generators (see load_pgen for loading rules) */
2888 load_igen (int size, SFData * sf, FILE * fd)
2890 fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
2894 unsigned short genid;
2895 int level, skip, drop, gzone, discarded;
2899 { /* traverse through all instruments */
2902 p2 = ((SFInst *) (p->data))->zone;
2906 { /* traverse this instrument's zones */
2908 z = (SFZone *) (p2->data);
2911 { /* load zone's generators */
2915 if ((size -= SFGENSIZE) < 0)
2916 return (gerr (ErrCorr, _("IGEN chunk size mismatch")));
2920 if (genid == Gen_KeyRange)
2921 { /* nothing precedes */
2925 READB (genval.range.lo, fd);
2926 READB (genval.range.hi, fd);
2931 else if (genid == Gen_VelRange)
2932 { /* only KeyRange precedes */
2936 READB (genval.range.lo, fd);
2937 READB (genval.range.hi, fd);
2942 else if (genid == Gen_SampleId)
2943 { /* sample is last gen */
2945 READW (genval.uword, fd);
2946 ((SFZone *) (p2->data))->instsamp = GINT_TO_POINTER (genval.uword + 1);
2947 break; /* break out of generator loop */
2952 if (gen_valid (genid))
2954 READW (genval.sword, fd);
2955 dup = gen_inlist (genid, z->gen);
2964 { /* if gen ! dup alloc new */
2965 g = FLUID_NEW (SFGen);
2971 g = (SFGen *) (dup->data);
2977 { /* skip this generator */
2984 p3 = fluid_list_next (p3); /* next gen */
2986 SLADVREM (z->gen, p3);
2988 } /* generator loop */
2991 SLADVREM (z->gen, p3); /* zone has sample? */
2993 { /* its a global zone */
2998 /* if global zone is not 1st zone, relocate */
3001 void* save = p2->data;
3002 FLUID_LOG (FLUID_WARN,
3003 _("Instrument \"%s\": Global zone is not first zone"),
3004 ((SFPreset *) (p->data))->name);
3006 *hz = fluid_list_prepend (*hz, save);
3011 { /* previous global zone exists, discard */
3012 FLUID_LOG (FLUID_WARN,
3013 _("Instrument \"%s\": Discarding invalid global zone"),
3014 ((SFInst *) (p->data))->name);
3015 sfont_zone_delete (sf, hz, (SFZone *) (p2->data));
3020 { /* Kill any zones following a sample */
3022 if ((size -= SFGENSIZE) < 0)
3023 return (gerr (ErrCorr,
3024 _("Instrument generator chunk size mismatch")));
3025 FSKIP (SFGENSIZE, fd);
3026 SLADVREM (z->gen, p3);
3029 p2 = fluid_list_next (p2); /* next zone */
3032 FLUID_LOG(FLUID_WARN,
3033 _("Instrument \"%s\": Some invalid generators were discarded"),
3034 ((SFInst *) (p->data))->name);
3035 p = fluid_list_next (p);
3038 /* for those non-terminal record cases, grr! */
3044 return (gerr (ErrCorr, _("IGEN chunk size mismatch")));
3045 FSKIP (SFGENSIZE, fd); /* terminal gen */
3050 /* sample header loader */
3052 load_shdr (unsigned int size, SFData * sf, FILE * fd)
3057 if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */
3058 return (gerr (ErrCorr, _("Sample header has invalid size")));
3060 size = size / SFSHDRSIZE - 1;
3062 { /* at least one sample + term record? */
3063 FLUID_LOG (FLUID_WARN, _("File contains no samples"));
3064 FSKIP (SFSHDRSIZE, fd);
3068 /* load all sample headers */
3069 for (i = 0; i < size; i++)
3071 p = FLUID_NEW (SFSample);
3072 sf->sample = fluid_list_append (sf->sample, p);
3073 READSTR (&p->name, fd);
3074 READD (p->start, fd);
3075 READD (p->end, fd); /* - end, loopstart and loopend */
3076 READD (p->loopstart, fd); /* - will be checked and turned into */
3077 READD (p->loopend, fd); /* - offsets in fixup_sample() */
3078 READD (p->samplerate, fd);
3079 READB (p->origpitch, fd);
3080 READB (p->pitchadj, fd);
3081 FSKIPW (fd); /* skip sample link */
3082 READW (p->sampletype, fd);
3086 FSKIP (SFSHDRSIZE, fd); /* skip terminal shdr */
3091 /* "fixup" (inst # -> inst ptr) instrument references in preset list */
3093 fixup_pgen (SFData * sf)
3095 fluid_list_t *p, *p2, *p3;
3102 p2 = ((SFPreset *) (p->data))->zone;
3104 { /* traverse this preset's zones */
3105 z = (SFZone *) (p2->data);
3106 if ((i = GPOINTER_TO_INT (z->instsamp)))
3107 { /* load instrument # */
3108 p3 = fluid_list_nth (sf->inst, i - 1);
3110 return (gerr (ErrCorr,
3111 _("Preset %03d %03d: Invalid instrument reference"),
3112 ((SFPreset *) (p->data))->bank,
3113 ((SFPreset *) (p->data))->prenum));
3118 p2 = fluid_list_next (p2);
3120 p = fluid_list_next (p);
3126 /* "fixup" (sample # -> sample ptr) sample references in instrument list */
3128 fixup_igen (SFData * sf)
3130 fluid_list_t *p, *p2, *p3;
3137 p2 = ((SFInst *) (p->data))->zone;
3139 { /* traverse instrument's zones */
3140 z = (SFZone *) (p2->data);
3141 if ((i = GPOINTER_TO_INT (z->instsamp)))
3142 { /* load sample # */
3143 p3 = fluid_list_nth (sf->sample, i - 1);
3145 return (gerr (ErrCorr,
3146 _("Instrument \"%s\": Invalid sample reference"),
3147 ((SFInst *) (p->data))->name));
3150 p2 = fluid_list_next (p2);
3152 p = fluid_list_next (p);
3158 /* convert sample end, loopstart and loopend to offsets and check if valid */
3160 fixup_sample (SFData * sf)
3168 sam = (SFSample *) (p->data);
3170 /* if sample is not a ROM sample and end is over the sample data chunk
3171 or sam start is greater than 4 less than the end (at least 4 samples) */
3172 if ((!(sam->sampletype & FLUID_SAMPLETYPE_ROM)
3173 && sam->end > sdtachunk_size) || sam->start > (sam->end - 4))
3175 FLUID_LOG (FLUID_WARN, _("Sample '%s' start/end file positions are invalid,"
3176 " disabling and will not be saved"), sam->name);
3178 /* disable sample by setting all sample markers to 0 */
3179 sam->start = sam->end = sam->loopstart = sam->loopend = 0;
3183 else if (sam->loopend > sam->end || sam->loopstart >= sam->loopend
3184 || sam->loopstart <= sam->start)
3185 { /* loop is fowled?? (cluck cluck :) */
3186 /* can pad loop by 8 samples and ensure at least 4 for loop (2*8+4) */
3187 if ((sam->end - sam->start) >= 20)
3189 sam->loopstart = sam->start + 8;
3190 sam->loopend = sam->end - 8;
3193 { /* loop is fowled, sample is tiny (can't pad 8 samples) */
3194 sam->loopstart = sam->start + 1;
3195 sam->loopend = sam->end - 1;
3199 /* convert sample end, loopstart, loopend to offsets from sam->start */
3200 sam->end -= sam->start + 1; /* marks last sample, contrary to SF spec. */
3201 sam->loopstart -= sam->start;
3202 sam->loopend -= sam->start;
3204 p = fluid_list_next (p);
3210 /*=================================sfont.c========================
3211 Smurf SoundFont Editor
3212 ================================================================*/
3215 /* optimum chunk area sizes (could be more optimum) */
3216 #define PRESET_CHUNK_OPTIMUM_AREA 256
3217 #define INST_CHUNK_OPTIMUM_AREA 256
3218 #define SAMPLE_CHUNK_OPTIMUM_AREA 256
3219 #define ZONE_CHUNK_OPTIMUM_AREA 256
3220 #define MOD_CHUNK_OPTIMUM_AREA 256
3221 #define GEN_CHUNK_OPTIMUM_AREA 256
3223 unsigned short badgen[] = { Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4,
3224 Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0
3227 unsigned short badpgen[] = { Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs,
3228 Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs,
3229 Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity,
3230 Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass,
3231 Gen_OverrideRootKey, 0
3234 /* close SoundFont file and delete a SoundFont structure */
3236 sfont_close (SFData * sf)
3238 fluid_list_t *p, *p2;
3250 p = fluid_list_next (p);
3252 delete_fluid_list(sf->info);
3257 { /* loop over presets */
3258 p2 = ((SFPreset *) (p->data))->zone;
3260 { /* loop over preset's zones */
3261 sfont_free_zone (p2->data);
3262 p2 = fluid_list_next (p2);
3263 } /* free preset's zone list */
3264 delete_fluid_list (((SFPreset *) (p->data))->zone);
3265 FLUID_FREE (p->data); /* free preset chunk */
3266 p = fluid_list_next (p);
3268 delete_fluid_list (sf->preset);
3273 { /* loop over instruments */
3274 p2 = ((SFInst *) (p->data))->zone;
3276 { /* loop over inst's zones */
3277 sfont_free_zone (p2->data);
3278 p2 = fluid_list_next (p2);
3279 } /* free inst's zone list */
3280 delete_fluid_list (((SFInst *) (p->data))->zone);
3281 FLUID_FREE (p->data);
3282 p = fluid_list_next (p);
3284 delete_fluid_list (sf->inst);
3290 FLUID_FREE (p->data);
3291 p = fluid_list_next (p);
3293 delete_fluid_list (sf->sample);
3299 /* free all elements of a zone (Preset or Instrument) */
3301 sfont_free_zone (SFZone * zone)
3310 { /* Free gen chunks for this zone */
3312 FLUID_FREE (p->data);
3313 p = fluid_list_next (p);
3315 delete_fluid_list (zone->gen); /* free genlist */
3319 { /* Free mod chunks for this zone */
3321 FLUID_FREE (p->data);
3322 p = fluid_list_next (p);
3324 delete_fluid_list (zone->mod); /* free modlist */
3326 FLUID_FREE (zone); /* free zone chunk */
3329 /* preset sort function, first by bank, then by preset # */
3331 sfont_preset_compare_func (void* a, void* b)
3335 aval = (int) (((SFPreset *) a)->bank) << 16 | ((SFPreset *) a)->prenum;
3336 bval = (int) (((SFPreset *) b)->bank) << 16 | ((SFPreset *) b)->prenum;
3338 return (aval - bval);
3341 /* delete zone from zone list */
3343 sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone)
3345 *zlist = fluid_list_remove (*zlist, (void*) zone);
3346 sfont_free_zone (zone);
3349 /* Find generator in gen list */
3351 gen_inlist (int gen, fluid_list_t * genlist)
3352 { /* is generator in gen list? */
3358 if (p->data == NULL)
3360 if (gen == ((SFGen *) p->data)->id)
3362 p = fluid_list_next (p);
3367 /* check validity of instrument generator */
3370 { /* is generator id valid? */
3373 if (gen > Gen_MaxValid)
3375 while (badgen[i] && badgen[i] != gen)
3377 return (badgen[i] == 0);
3380 /* check validity of preset generator */
3382 gen_validp (int gen)
3383 { /* is preset generator valid? */
3386 if (!gen_valid (gen))
3388 while (badpgen[i] && badpgen[i] != (unsigned short) gen)
3390 return (badpgen[i] == 0);
3393 /*================================util.c===========================*/
3395 /* Logging function, returns FAIL to use as a return value in calling funcs */
3397 gerr (int ev, char * fmt, ...)
3401 va_start (args, fmt);
3411 safe_fread (void *buf, int count, FILE * fd)
3413 if (fread (buf, count, 1, fd) != 1)
3414 { /* size_t = count, nmemb = 1 */
3416 gerr (ErrEof, _("EOF while attemping to read %d bytes"), count);
3418 FLUID_LOG (FLUID_ERR, _("File read failed"));
3425 safe_fseek (FILE * fd, long ofs, int whence)
3427 if (fseek (fd, ofs, whence) == -1) {
3428 FLUID_LOG (FLUID_ERR, _("File seek failed with offset = %ld and whence = %d"), ofs, whence);