1 /* FluidSynth - A Software Synthesizer
2  *
3  * Copyright (C) 2003  Peter Hanappe and others.
4  *
5  * SoundFont file loading code borrowed from Smurf SoundFont Editor
6  * Copyright (C) 1999-2001 Josh Green
7  *
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.
12  *
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.
17  *
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
21  * 02110-1301, USA
22  */
23 
24 
25 #include "fluid_defsfont.h"
26 /* Todo: Get rid of that 'include' */
27 #include "fluid_sys.h"
28 
29 /***************************************************************
30  *
31  *                           SFONT LOADER
32  */
33 
new_fluid_defsfloader()34 fluid_sfloader_t* new_fluid_defsfloader()
35 {
36   fluid_sfloader_t* loader;
37 
38   loader = FLUID_NEW(fluid_sfloader_t);
39   if (loader == NULL) {
40     FLUID_LOG(FLUID_ERR, "Out of memory");
41     return NULL;
42   }
43 
44   loader->data = NULL;
45   loader->free = delete_fluid_defsfloader;
46   loader->load = fluid_defsfloader_load;
47 
48   return loader;
49 }
50 
delete_fluid_defsfloader(fluid_sfloader_t * loader)51 int delete_fluid_defsfloader(fluid_sfloader_t* loader)
52 {
53   if (loader) {
54     FLUID_FREE(loader);
55   }
56   return FLUID_OK;
57 }
58 
fluid_defsfloader_load(fluid_sfloader_t * loader,const char * filename)59 fluid_sfont_t* fluid_defsfloader_load(fluid_sfloader_t* loader, const char* filename)
60 {
61   fluid_defsfont_t* defsfont;
62   fluid_sfont_t* sfont;
63 
64   defsfont = new_fluid_defsfont();
65 
66   if (defsfont == NULL) {
67     return NULL;
68   }
69 
70   if (fluid_defsfont_load(defsfont, filename) == FLUID_FAILED) {
71     delete_fluid_defsfont(defsfont);
72     return NULL;
73   }
74 
75   sfont = FLUID_NEW(fluid_sfont_t);
76   if (sfont == NULL) {
77     FLUID_LOG(FLUID_ERR, "Out of memory");
78     return NULL;
79   }
80 
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;
87 
88   return sfont;
89 }
90 
91 
92 
93 /***************************************************************
94  *
95  *                           PUBLIC INTERFACE
96  */
97 
fluid_defsfont_sfont_delete(fluid_sfont_t * sfont)98 int fluid_defsfont_sfont_delete(fluid_sfont_t* sfont)
99 {
100   if (delete_fluid_defsfont(sfont->data) != 0) {
101     return -1;
102   }
103   FLUID_FREE(sfont);
104   return 0;
105 }
106 
fluid_defsfont_sfont_get_name(fluid_sfont_t * sfont)107 char* fluid_defsfont_sfont_get_name(fluid_sfont_t* sfont)
108 {
109   return fluid_defsfont_get_name((fluid_defsfont_t*) sfont->data);
110 }
111 
fluid_defsfont_get_sample(fluid_defsfont_t * sfont,char * s)112 fluid_sample_t* fluid_defsfont_get_sample(fluid_defsfont_t* sfont, char *s)
113 {
114   /* This function is here just to avoid an ABI/SONAME bump, see ticket #98. Should never be used. */
115   return NULL;
116 }
117 
118 fluid_preset_t*
fluid_defsfont_sfont_get_preset(fluid_sfont_t * sfont,unsigned int bank,unsigned int prenum)119 fluid_defsfont_sfont_get_preset(fluid_sfont_t* sfont, unsigned int bank, unsigned int prenum)
120 {
121   fluid_preset_t* preset;
122   fluid_defpreset_t* defpreset;
123 
124   defpreset = fluid_defsfont_get_preset((fluid_defsfont_t*) sfont->data, bank, prenum);
125 
126   if (defpreset == NULL) {
127     return NULL;
128   }
129 
130   preset = FLUID_NEW(fluid_preset_t);
131   if (preset == NULL) {
132     FLUID_LOG(FLUID_ERR, "Out of memory");
133     return NULL;
134   }
135 
136   preset->sfont = sfont;
137   preset->data = defpreset;
138   preset->free = fluid_defpreset_preset_delete;
139   preset->get_name = fluid_defpreset_preset_get_name;
140   preset->get_banknum = fluid_defpreset_preset_get_banknum;
141   preset->get_num = fluid_defpreset_preset_get_num;
142   preset->noteon = fluid_defpreset_preset_noteon;
143   preset->notify = NULL;
144 
145   return preset;
146 }
147 
fluid_defsfont_sfont_iteration_start(fluid_sfont_t * sfont)148 void fluid_defsfont_sfont_iteration_start(fluid_sfont_t* sfont)
149 {
150   fluid_defsfont_iteration_start((fluid_defsfont_t*) sfont->data);
151 }
152 
fluid_defsfont_sfont_iteration_next(fluid_sfont_t * sfont,fluid_preset_t * preset)153 int fluid_defsfont_sfont_iteration_next(fluid_sfont_t* sfont, fluid_preset_t* preset)
154 {
155   preset->free = fluid_defpreset_preset_delete;
156   preset->get_name = fluid_defpreset_preset_get_name;
157   preset->get_banknum = fluid_defpreset_preset_get_banknum;
158   preset->get_num = fluid_defpreset_preset_get_num;
159   preset->noteon = fluid_defpreset_preset_noteon;
160   preset->notify = NULL;
161 
162   return fluid_defsfont_iteration_next((fluid_defsfont_t*) sfont->data, preset);
163 }
164 
fluid_defpreset_preset_delete(fluid_preset_t * preset)165 int fluid_defpreset_preset_delete(fluid_preset_t* preset)
166 {
167   FLUID_FREE(preset);
168 
169   /* TODO: free modulators */
170 
171   return 0;
172 }
173 
fluid_defpreset_preset_get_name(fluid_preset_t * preset)174 char* fluid_defpreset_preset_get_name(fluid_preset_t* preset)
175 {
176   return fluid_defpreset_get_name((fluid_defpreset_t*) preset->data);
177 }
178 
fluid_defpreset_preset_get_banknum(fluid_preset_t * preset)179 int fluid_defpreset_preset_get_banknum(fluid_preset_t* preset)
180 {
181   return fluid_defpreset_get_banknum((fluid_defpreset_t*) preset->data);
182 }
183 
fluid_defpreset_preset_get_num(fluid_preset_t * preset)184 int fluid_defpreset_preset_get_num(fluid_preset_t* preset)
185 {
186   return fluid_defpreset_get_num((fluid_defpreset_t*) preset->data);
187 }
188 
fluid_defpreset_preset_noteon(fluid_preset_t * preset,fluid_synth_t * synth,int chan,int key,int vel)189 int fluid_defpreset_preset_noteon(fluid_preset_t* preset, fluid_synth_t* synth,
190 				 int chan, int key, int vel)
191 {
192   return fluid_defpreset_noteon((fluid_defpreset_t*) preset->data, synth, chan, key, vel);
193 }
194 
195 
196 
197 
198 /***************************************************************
199  *
200  *                           SFONT
201  */
202 
203 /*
204  * new_fluid_defsfont
205  */
new_fluid_defsfont()206 fluid_defsfont_t* new_fluid_defsfont()
207 {
208   fluid_defsfont_t* sfont;
209 
210   sfont = FLUID_NEW(fluid_defsfont_t);
211   if (sfont == NULL) {
212     FLUID_LOG(FLUID_ERR, "Out of memory");
213     return NULL;
214   }
215 
216   sfont->filename = NULL;
217   sfont->samplepos = 0;
218   sfont->samplesize = 0;
219   sfont->sample = NULL;
220   sfont->sampledata = NULL;
221   sfont->preset = NULL;
222 
223   return sfont;
224 }
225 
226 /*
227  * delete_fluid_defsfont
228  */
delete_fluid_defsfont(fluid_defsfont_t * sfont)229 int delete_fluid_defsfont(fluid_defsfont_t* sfont)
230 {
231   fluid_list_t *list;
232   fluid_defpreset_t* preset;
233   fluid_sample_t* sample;
234 
235   /* Check that no samples are currently used */
236   for (list = sfont->sample; list; list = fluid_list_next(list)) {
237     sample = (fluid_sample_t*) fluid_list_get(list);
238     if (fluid_sample_refcount(sample) != 0) {
239       return -1;
240     }
241   }
242 
243   if (sfont->filename != NULL) {
244     FLUID_FREE(sfont->filename);
245   }
246 
247   for (list = sfont->sample; list; list = fluid_list_next(list)) {
248     delete_fluid_sample((fluid_sample_t*) fluid_list_get(list));
249   }
250 
251   if (sfont->sample) {
252     delete_fluid_list(sfont->sample);
253   }
254 
255   if (sfont->sampledata != NULL) {
256     fluid_munlock(sfont->sampledata, sfont->samplesize);
257     FLUID_FREE(sfont->sampledata);
258   }
259 
260   preset = sfont->preset;
261   while (preset != NULL) {
262     sfont->preset = preset->next;
263     delete_fluid_defpreset(preset);
264     preset = sfont->preset;
265   }
266 
267   FLUID_FREE(sfont);
268   return FLUID_OK;
269 }
270 
271 /*
272  * fluid_defsfont_get_name
273  */
fluid_defsfont_get_name(fluid_defsfont_t * sfont)274 char* fluid_defsfont_get_name(fluid_defsfont_t* sfont)
275 {
276   return sfont->filename;
277 }
278 
279 
280 /*
281  * fluid_defsfont_load
282  */
fluid_defsfont_load(fluid_defsfont_t * sfont,const char * file)283 int fluid_defsfont_load(fluid_defsfont_t* sfont, const char* file)
284 {
285   SFData* sfdata;
286   fluid_list_t *p;
287   SFPreset* sfpreset;
288   SFSample* sfsample;
289   fluid_sample_t* sample;
290   fluid_defpreset_t* preset;
291 
292   sfont->filename = FLUID_MALLOC(1 + FLUID_STRLEN(file));
293   if (sfont->filename == NULL) {
294     FLUID_LOG(FLUID_ERR, "Out of memory");
295     return FLUID_FAILED;
296   }
297   FLUID_STRCPY(sfont->filename, file);
298 
299   /* The actual loading is done in the sfont and sffile files */
300   sfdata = sfload_file(file);
301   if (sfdata == NULL) {
302     FLUID_LOG(FLUID_ERR, "Couldn't load soundfont file");
303     return FLUID_FAILED;
304   }
305 
306   /* Keep track of the position and size of the sample data because
307      it's loaded separately (and might be unoaded/reloaded in future) */
308   sfont->samplepos = sfdata->samplepos;
309   sfont->samplesize = sfdata->samplesize;
310 
311   /* load sample data in one block */
312   if (fluid_defsfont_load_sampledata(sfont) != FLUID_OK)
313     goto err_exit;
314 
315   /* Create all the sample headers */
316   p = sfdata->sample;
317   while (p != NULL) {
318     sfsample = (SFSample *) p->data;
319 
320     sample = new_fluid_sample();
321     if (sample == NULL) goto err_exit;
322 
323     if (fluid_sample_import_sfont(sample, sfsample, sfont) != FLUID_OK)
324       goto err_exit;
325 
326     /* Store reference to FluidSynth sample in SFSample for later IZone fixups */
327     sfsample->fluid_sample = sample;
328 
329     fluid_defsfont_add_sample(sfont, sample);
330     fluid_voice_optimize_sample(sample);
331     p = fluid_list_next(p);
332   }
333 
334   /* Load all the presets */
335   p = sfdata->preset;
336   while (p != NULL) {
337     sfpreset = (SFPreset *) p->data;
338     preset = new_fluid_defpreset(sfont);
339     if (preset == NULL) goto err_exit;
340 
341     if (fluid_defpreset_import_sfont(preset, sfpreset, sfont) != FLUID_OK)
342       goto err_exit;
343 
344     fluid_defsfont_add_preset(sfont, preset);
345     p = fluid_list_next(p);
346   }
347   sfont_close (sfdata);
348 
349   return FLUID_OK;
350 
351 err_exit:
352   sfont_close (sfdata);
353   return FLUID_FAILED;
354 }
355 
356 /* fluid_defsfont_add_sample
357  *
358  * Add a sample to the SoundFont
359  */
fluid_defsfont_add_sample(fluid_defsfont_t * sfont,fluid_sample_t * sample)360 int fluid_defsfont_add_sample(fluid_defsfont_t* sfont, fluid_sample_t* sample)
361 {
362   sfont->sample = fluid_list_append(sfont->sample, sample);
363   return FLUID_OK;
364 }
365 
366 /* fluid_defsfont_add_preset
367  *
368  * Add a preset to the SoundFont
369  */
fluid_defsfont_add_preset(fluid_defsfont_t * sfont,fluid_defpreset_t * preset)370 int fluid_defsfont_add_preset(fluid_defsfont_t* sfont, fluid_defpreset_t* preset)
371 {
372   fluid_defpreset_t *cur, *prev;
373   if (sfont->preset == NULL) {
374     preset->next = NULL;
375     sfont->preset = preset;
376   } else {
377     /* sort them as we go along. very basic sorting trick. */
378     cur = sfont->preset;
379     prev = NULL;
380     while (cur != NULL) {
381       if ((preset->bank < cur->bank)
382 	  || ((preset->bank == cur->bank) && (preset->num < cur->num))) {
383 	if (prev == NULL) {
384 	  preset->next = cur;
385 	  sfont->preset = preset;
386 	} else {
387 	  preset->next = cur;
388 	  prev->next = preset;
389 	}
390 	return FLUID_OK;
391       }
392       prev = cur;
393       cur = cur->next;
394     }
395     preset->next = NULL;
396     prev->next = preset;
397   }
398   return FLUID_OK;
399 }
400 
401 /*
402  * fluid_defsfont_load_sampledata
403  */
404 int
fluid_defsfont_load_sampledata(fluid_defsfont_t * sfont)405 fluid_defsfont_load_sampledata(fluid_defsfont_t* sfont)
406 {
407   fluid_file fd;
408   unsigned short endian;
409   fd = FLUID_FOPEN(sfont->filename, "rb");
410   if (fd == NULL) {
411     FLUID_LOG(FLUID_ERR, "Can't open soundfont file");
412     return FLUID_FAILED;
413   }
414   if (FLUID_FSEEK(fd, sfont->samplepos, SEEK_SET) == -1) {
415     perror("error");
416     FLUID_LOG(FLUID_ERR, "Failed to seek position in data file");
417     return FLUID_FAILED;
418   }
419   sfont->sampledata = (short*) FLUID_MALLOC(sfont->samplesize);
420   if (sfont->sampledata == NULL) {
421     FLUID_LOG(FLUID_ERR, "Out of memory");
422     return FLUID_FAILED;
423   }
424   if (FLUID_FREAD(sfont->sampledata, 1, sfont->samplesize, fd) < sfont->samplesize) {
425     FLUID_LOG(FLUID_ERR, "Failed to read sample data");
426     return FLUID_FAILED;
427   }
428   FLUID_FCLOSE(fd);
429 
430   /* Lock the memory to disable paging. It's okay if this fails. It
431      probably means that the user doesn't have to required permission.  */
432   if (fluid_mlock(sfont->sampledata, sfont->samplesize) != 0) {
433     FLUID_LOG(FLUID_WARN, "Failed to pin the sample data to RAM; swapping is possible.");
434   }
435 
436 
437   /* I'm not sure this endian test is waterproof...  */
438   endian = 0x0100;
439 
440   /* If this machine is big endian, the sample have to byte swapped  */
441   if (((char *) &endian)[0]) {
442     unsigned char* cbuf;
443     unsigned char hi, lo;
444     unsigned int i, j;
445     short s;
446     cbuf = (unsigned char*) sfont->sampledata;
447     for (i = 0, j = 0; j < sfont->samplesize; i++) {
448       lo = cbuf[j++];
449       hi = cbuf[j++];
450       s = (hi << 8) | lo;
451       sfont->sampledata[i] = s;
452     }
453   }
454   return FLUID_OK;
455 }
456 
457 /*
458  * fluid_defsfont_get_preset
459  */
fluid_defsfont_get_preset(fluid_defsfont_t * sfont,unsigned int bank,unsigned int num)460 fluid_defpreset_t* fluid_defsfont_get_preset(fluid_defsfont_t* sfont, unsigned int bank, unsigned int num)
461 {
462   fluid_defpreset_t* preset = sfont->preset;
463   while (preset != NULL) {
464     if ((preset->bank == bank) && ((preset->num == num))) {
465       return preset;
466     }
467     preset = preset->next;
468   }
469   return NULL;
470 }
471 
472 /*
473  * fluid_defsfont_iteration_start
474  */
fluid_defsfont_iteration_start(fluid_defsfont_t * sfont)475 void fluid_defsfont_iteration_start(fluid_defsfont_t* sfont)
476 {
477   sfont->iter_cur = sfont->preset;
478 }
479 
480 /*
481  * fluid_defsfont_iteration_next
482  */
fluid_defsfont_iteration_next(fluid_defsfont_t * sfont,fluid_preset_t * preset)483 int fluid_defsfont_iteration_next(fluid_defsfont_t* sfont, fluid_preset_t* preset)
484 {
485   if (sfont->iter_cur == NULL) {
486     return 0;
487   }
488 
489   preset->data = (void*) sfont->iter_cur;
490   sfont->iter_cur = fluid_defpreset_next(sfont->iter_cur);
491   return 1;
492 }
493 
494 /***************************************************************
495  *
496  *                           PRESET
497  */
498 
499 /*
500  * new_fluid_defpreset
501  */
502 fluid_defpreset_t*
new_fluid_defpreset(fluid_defsfont_t * sfont)503 new_fluid_defpreset(fluid_defsfont_t* sfont)
504 {
505   fluid_defpreset_t* preset = FLUID_NEW(fluid_defpreset_t);
506   if (preset == NULL) {
507     FLUID_LOG(FLUID_ERR, "Out of memory");
508     return NULL;
509   }
510   preset->next = NULL;
511   preset->sfont = sfont;
512   preset->name[0] = 0;
513   preset->bank = 0;
514   preset->num = 0;
515   preset->global_zone = NULL;
516   preset->zone = NULL;
517   return preset;
518 }
519 
520 /*
521  * delete_fluid_defpreset
522  */
523 int
delete_fluid_defpreset(fluid_defpreset_t * preset)524 delete_fluid_defpreset(fluid_defpreset_t* preset)
525 {
526   int err = FLUID_OK;
527   fluid_preset_zone_t* zone;
528   if (preset->global_zone != NULL) {
529     if (delete_fluid_preset_zone(preset->global_zone) != FLUID_OK) {
530       err = FLUID_FAILED;
531     }
532     preset->global_zone = NULL;
533   }
534   zone = preset->zone;
535   while (zone != NULL) {
536     preset->zone = zone->next;
537     if (delete_fluid_preset_zone(zone) != FLUID_OK) {
538       err = FLUID_FAILED;
539     }
540     zone = preset->zone;
541   }
542   FLUID_FREE(preset);
543   return err;
544 }
545 
546 int
fluid_defpreset_get_banknum(fluid_defpreset_t * preset)547 fluid_defpreset_get_banknum(fluid_defpreset_t* preset)
548 {
549   return preset->bank;
550 }
551 
552 int
fluid_defpreset_get_num(fluid_defpreset_t * preset)553 fluid_defpreset_get_num(fluid_defpreset_t* preset)
554 {
555   return preset->num;
556 }
557 
558 char*
fluid_defpreset_get_name(fluid_defpreset_t * preset)559 fluid_defpreset_get_name(fluid_defpreset_t* preset)
560 {
561   return preset->name;
562 }
563 
564 /*
565  * fluid_defpreset_next
566  */
567 fluid_defpreset_t*
fluid_defpreset_next(fluid_defpreset_t * preset)568 fluid_defpreset_next(fluid_defpreset_t* preset)
569 {
570   return preset->next;
571 }
572 
573 
574 /*
575  * fluid_defpreset_noteon
576  */
577 int
fluid_defpreset_noteon(fluid_defpreset_t * preset,fluid_synth_t * synth,int chan,int key,int vel)578 fluid_defpreset_noteon(fluid_defpreset_t* preset, fluid_synth_t* synth, int chan, int key, int vel)
579 {
580   fluid_preset_zone_t *preset_zone, *global_preset_zone;
581   fluid_inst_t* inst;
582   fluid_inst_zone_t *inst_zone, *global_inst_zone, *z;
583   fluid_sample_t* sample;
584   fluid_voice_t* voice;
585   fluid_mod_t * mod;
586   fluid_mod_t * mod_list[FLUID_NUM_MOD]; /* list for 'sorting' preset modulators */
587   int mod_list_count;
588   int i;
589 
590   global_preset_zone = fluid_defpreset_get_global_zone(preset);
591 
592   /* run thru all the zones of this preset */
593   preset_zone = fluid_defpreset_get_zone(preset);
594   while (preset_zone != NULL) {
595 
596     /* check if the note falls into the key and velocity range of this
597        preset */
598     if (fluid_preset_zone_inside_range(preset_zone, key, vel)) {
599 
600       inst = fluid_preset_zone_get_inst(preset_zone);
601       global_inst_zone = fluid_inst_get_global_zone(inst);
602 
603       /* run thru all the zones of this instrument */
604       inst_zone = fluid_inst_get_zone(inst);
605 	  while (inst_zone != NULL) {
606 
607 	/* make sure this instrument zone has a valid sample */
608 	sample = fluid_inst_zone_get_sample(inst_zone);
609 	if (fluid_sample_in_rom(sample) || (sample == NULL)) {
610 	  inst_zone = fluid_inst_zone_next(inst_zone);
611 	  continue;
612 	}
613 
614 	/* check if the note falls into the key and velocity range of this
615 	   instrument */
616 
617 	if (fluid_inst_zone_inside_range(inst_zone, key, vel) && (sample != NULL)) {
618 
619 	  /* this is a good zone. allocate a new synthesis process and
620              initialize it */
621 
622 	  voice = fluid_synth_alloc_voice(synth, sample, chan, key, vel);
623 	  if (voice == NULL) {
624 	    return FLUID_FAILED;
625 	  }
626 
627 
628 	  z = inst_zone;
629 
630 	  /* Instrument level, generators */
631 
632 	  for (i = 0; i < GEN_LAST; i++) {
633 
634 	    /* SF 2.01 section 9.4 'bullet' 4:
635 	     *
636 	     * A generator in a local instrument zone supersedes a
637 	     * global instrument zone generator.  Both cases supersede
638 	     * the default generator -> voice_gen_set */
639 
640 	    if (inst_zone->gen[i].flags){
641 	      fluid_voice_gen_set(voice, i, inst_zone->gen[i].val);
642 
643 	    } else if ((global_inst_zone != NULL) && (global_inst_zone->gen[i].flags)) {
644 	      fluid_voice_gen_set(voice, i, global_inst_zone->gen[i].val);
645 
646 	    } else {
647 	      /* The generator has not been defined in this instrument.
648 	       * Do nothing, leave it at the default.
649 	       */
650 	    }
651 
652 	  } /* for all generators */
653 
654 	  /* global instrument zone, modulators: Put them all into a
655 	   * list. */
656 
657 	  mod_list_count = 0;
658 
659 	  if (global_inst_zone){
660 	    mod = global_inst_zone->mod;
661 	    while (mod){
662 	      mod_list[mod_list_count++] = mod;
663 	      mod = mod->next;
664 	    }
665 	  }
666 
667 	  /* local instrument zone, modulators.
668 	   * Replace modulators with the same definition in the list:
669 	   * SF 2.01 page 69, 'bullet' 8
670 	   */
671 	  mod = inst_zone->mod;
672 
673 	  while (mod){
674 
675 	    /* 'Identical' modulators will be deleted by setting their
676 	     *  list entry to NULL.  The list length is known, NULL
677 	     *  entries will be ignored later.  SF2.01 section 9.5.1
678 	     *  page 69, 'bullet' 3 defines 'identical'.  */
679 
680 	    for (i = 0; i < mod_list_count; i++){
681 	      if (mod_list[i] && fluid_mod_test_identity(mod,mod_list[i])){
682 		mod_list[i] = NULL;
683 	      }
684 	    }
685 
686 	    /* Finally add the new modulator to to the list. */
687 	    mod_list[mod_list_count++] = mod;
688 	    mod = mod->next;
689 	  }
690 
691 	  /* Add instrument modulators (global / local) to the voice. */
692 	  for (i = 0; i < mod_list_count; i++){
693 
694 	    mod = mod_list[i];
695 
696 	    if (mod != NULL){ /* disabled modulators CANNOT be skipped. */
697 
698 	      /* Instrument modulators -supersede- existing (default)
699 	       * modulators.  SF 2.01 page 69, 'bullet' 6 */
700 	      fluid_voice_add_mod(voice, mod, FLUID_VOICE_OVERWRITE);
701 	    }
702 	  }
703 
704 	  /* Preset level, generators */
705 
706 	  for (i = 0; i < GEN_LAST; i++) {
707 
708 	    /* SF 2.01 section 8.5 page 58: If some generators are
709 	     * encountered at preset level, they should be ignored */
710 	    if ((i != GEN_STARTADDROFS)
711 		&& (i != GEN_ENDADDROFS)
712 		&& (i != GEN_STARTLOOPADDROFS)
713 		&& (i != GEN_ENDLOOPADDROFS)
714 		&& (i != GEN_STARTADDRCOARSEOFS)
715 		&& (i != GEN_ENDADDRCOARSEOFS)
716 		&& (i != GEN_STARTLOOPADDRCOARSEOFS)
717 		&& (i != GEN_KEYNUM)
718 		&& (i != GEN_VELOCITY)
719 		&& (i != GEN_ENDLOOPADDRCOARSEOFS)
720 		&& (i != GEN_SAMPLEMODE)
721 		&& (i != GEN_EXCLUSIVECLASS)
722 		&& (i != GEN_OVERRIDEROOTKEY)) {
723 
724 	      /* SF 2.01 section 9.4 'bullet' 9: A generator in a
725 	       * local preset zone supersedes a global preset zone
726 	       * generator.  The effect is -added- to the destination
727 	       * summing node -> voice_gen_incr */
728 
729 	      if (preset_zone->gen[i].flags) {
730 		fluid_voice_gen_incr(voice, i, preset_zone->gen[i].val);
731 	      } else if ((global_preset_zone != NULL) && global_preset_zone->gen[i].flags) {
732 		fluid_voice_gen_incr(voice, i, global_preset_zone->gen[i].val);
733 	      } else {
734 		/* The generator has not been defined in this preset
735 		 * Do nothing, leave it unchanged.
736 		 */
737 	      }
738 	    } /* if available at preset level */
739 	  } /* for all generators */
740 
741 
742 	  /* Global preset zone, modulators: put them all into a
743 	   * list. */
744 	  mod_list_count = 0;
745 	  if (global_preset_zone){
746 	    mod = global_preset_zone->mod;
747 	    while (mod){
748 	      mod_list[mod_list_count++] = mod;
749 	      mod = mod->next;
750 	    }
751 	  }
752 
753 	  /* Process the modulators of the local preset zone.  Kick
754 	   * out all identical modulators from the global preset zone
755 	   * (SF 2.01 page 69, second-last bullet) */
756 
757 	  mod = preset_zone->mod;
758 	  while (mod){
759 	    for (i = 0; i < mod_list_count; i++){
760 	      if (mod_list[i] && fluid_mod_test_identity(mod,mod_list[i])){
761 		mod_list[i] = NULL;
762 	      }
763 	    }
764 
765 	    /* Finally add the new modulator to the list. */
766 	    mod_list[mod_list_count++] = mod;
767 	    mod = mod->next;
768 	  }
769 
770 	  /* Add preset modulators (global / local) to the voice. */
771 	  for (i = 0; i < mod_list_count; i++){
772 	    mod = mod_list[i];
773 	    if ((mod != NULL) && (mod->amount != 0)) { /* disabled modulators can be skipped. */
774 
775 	      /* Preset modulators -add- to existing instrument /
776 	       * default modulators.  SF2.01 page 70 first bullet on
777 	       * page */
778 	      fluid_voice_add_mod(voice, mod, FLUID_VOICE_ADD);
779 	    }
780 	  }
781 
782 	  /* add the synthesis process to the synthesis loop. */
783 	  fluid_synth_start_voice(synth, voice);
784 
785 	  /* Store the ID of the first voice that was created by this noteon event.
786 	   * Exclusive class may only terminate older voices.
787 	   * That avoids killing voices, which have just been created.
788 	   * (a noteon event can create several voice processes with the same exclusive
789 	   * class - for example when using stereo samples)
790 	   */
791 	}
792 
793 	inst_zone = fluid_inst_zone_next(inst_zone);
794       }
795 	}
796     preset_zone = fluid_preset_zone_next(preset_zone);
797   }
798 
799   return FLUID_OK;
800 }
801 
802 /*
803  * fluid_defpreset_set_global_zone
804  */
805 int
fluid_defpreset_set_global_zone(fluid_defpreset_t * preset,fluid_preset_zone_t * zone)806 fluid_defpreset_set_global_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone)
807 {
808   preset->global_zone = zone;
809   return FLUID_OK;
810 }
811 
812 /*
813  * fluid_defpreset_import_sfont
814  */
815 int
fluid_defpreset_import_sfont(fluid_defpreset_t * preset,SFPreset * sfpreset,fluid_defsfont_t * sfont)816 fluid_defpreset_import_sfont(fluid_defpreset_t* preset,
817 			     SFPreset* sfpreset,
818 			     fluid_defsfont_t* sfont)
819 {
820   fluid_list_t *p;
821   SFZone* sfzone;
822   fluid_preset_zone_t* zone;
823   int count;
824   char zone_name[256];
825   if (FLUID_STRLEN(sfpreset->name) > 0) {
826     FLUID_STRCPY(preset->name, sfpreset->name);
827   } else {
828     FLUID_SPRINTF(preset->name, "Bank%d,Preset%d", sfpreset->bank, sfpreset->prenum);
829   }
830   preset->bank = sfpreset->bank;
831   preset->num = sfpreset->prenum;
832   p = sfpreset->zone;
833   count = 0;
834   while (p != NULL) {
835     sfzone = (SFZone *) p->data;
836     FLUID_SPRINTF(zone_name, "%s/%d", preset->name, count);
837     zone = new_fluid_preset_zone(zone_name);
838     if (zone == NULL) {
839       return FLUID_FAILED;
840     }
841     if (fluid_preset_zone_import_sfont(zone, sfzone, sfont) != FLUID_OK) {
842       return FLUID_FAILED;
843     }
844     if ((count == 0) && (fluid_preset_zone_get_inst(zone) == NULL)) {
845       fluid_defpreset_set_global_zone(preset, zone);
846     } else if (fluid_defpreset_add_zone(preset, zone) != FLUID_OK) {
847       return FLUID_FAILED;
848     }
849     p = fluid_list_next(p);
850     count++;
851   }
852   return FLUID_OK;
853 }
854 
855 /*
856  * fluid_defpreset_add_zone
857  */
858 int
fluid_defpreset_add_zone(fluid_defpreset_t * preset,fluid_preset_zone_t * zone)859 fluid_defpreset_add_zone(fluid_defpreset_t* preset, fluid_preset_zone_t* zone)
860 {
861   if (preset->zone == NULL) {
862     zone->next = NULL;
863     preset->zone = zone;
864   } else {
865     zone->next = preset->zone;
866     preset->zone = zone;
867   }
868   return FLUID_OK;
869 }
870 
871 /*
872  * fluid_defpreset_get_zone
873  */
874 fluid_preset_zone_t*
fluid_defpreset_get_zone(fluid_defpreset_t * preset)875 fluid_defpreset_get_zone(fluid_defpreset_t* preset)
876 {
877   return preset->zone;
878 }
879 
880 /*
881  * fluid_defpreset_get_global_zone
882  */
883 fluid_preset_zone_t*
fluid_defpreset_get_global_zone(fluid_defpreset_t * preset)884 fluid_defpreset_get_global_zone(fluid_defpreset_t* preset)
885 {
886   return preset->global_zone;
887 }
888 
889 /*
890  * fluid_preset_zone_next
891  */
892 fluid_preset_zone_t*
fluid_preset_zone_next(fluid_preset_zone_t * preset)893 fluid_preset_zone_next(fluid_preset_zone_t* preset)
894 {
895   return preset->next;
896 }
897 
898 /*
899  * new_fluid_preset_zone
900  */
901 fluid_preset_zone_t*
new_fluid_preset_zone(char * name)902 new_fluid_preset_zone(char *name)
903 {
904   int size;
905   fluid_preset_zone_t* zone = NULL;
906   zone = FLUID_NEW(fluid_preset_zone_t);
907   if (zone == NULL) {
908     FLUID_LOG(FLUID_ERR, "Out of memory");
909     return NULL;
910   }
911   zone->next = NULL;
912   size = 1 + FLUID_STRLEN(name);
913   zone->name = FLUID_MALLOC(size);
914   if (zone->name == NULL) {
915     FLUID_LOG(FLUID_ERR, "Out of memory");
916     FLUID_FREE(zone);
917     return NULL;
918   }
919   FLUID_STRCPY(zone->name, name);
920   zone->inst = NULL;
921   zone->keylo = 0;
922   zone->keyhi = 128;
923   zone->vello = 0;
924   zone->velhi = 128;
925 
926   /* Flag all generators as unused (default, they will be set when they are found
927    * in the sound font).
928    * This also sets the generator values to default, but that is of no concern here.*/
929   fluid_gen_set_default_values(&zone->gen[0]);
930   zone->mod = NULL; /* list of modulators */
931   return zone;
932 }
933 
934 /***************************************************************
935  *
936  *                           PRESET_ZONE
937  */
938 
939 /*
940  * delete_fluid_preset_zone
941  */
942 int
delete_fluid_preset_zone(fluid_preset_zone_t * zone)943 delete_fluid_preset_zone(fluid_preset_zone_t* zone)
944 {
945   fluid_mod_t *mod, *tmp;
946 
947   mod = zone->mod;
948   while (mod)	/* delete the modulators */
949     {
950       tmp = mod;
951       mod = mod->next;
952       fluid_mod_delete (tmp);
953     }
954 
955   if (zone->name) FLUID_FREE (zone->name);
956   if (zone->inst) delete_fluid_inst (zone->inst);
957   FLUID_FREE(zone);
958   return FLUID_OK;
959 }
960 
961 /*
962  * fluid_preset_zone_import_sfont
963  */
964 int
fluid_preset_zone_import_sfont(fluid_preset_zone_t * zone,SFZone * sfzone,fluid_defsfont_t * sfont)965 fluid_preset_zone_import_sfont(fluid_preset_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont)
966 {
967   fluid_list_t *r;
968   SFGen* sfgen;
969   int count;
970   for (count = 0, r = sfzone->gen; r != NULL; count++) {
971     sfgen = (SFGen *) r->data;
972     switch (sfgen->id) {
973     case GEN_KEYRANGE:
974       zone->keylo = (int) sfgen->amount.range.lo;
975       zone->keyhi = (int) sfgen->amount.range.hi;
976       break;
977     case GEN_VELRANGE:
978       zone->vello = (int) sfgen->amount.range.lo;
979       zone->velhi = (int) sfgen->amount.range.hi;
980       break;
981     default:
982       /* FIXME: some generators have an unsigne word amount value but i don't know which ones */
983       zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword;
984       zone->gen[sfgen->id].flags = GEN_SET;
985       break;
986     }
987     r = fluid_list_next(r);
988   }
989   if ((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL)) {
990     zone->inst = (fluid_inst_t*) new_fluid_inst();
991     if (zone->inst == NULL) {
992       FLUID_LOG(FLUID_ERR, "Out of memory");
993       return FLUID_FAILED;
994     }
995     if (fluid_inst_import_sfont(zone->inst, (SFInst *) sfzone->instsamp->data, sfont) != FLUID_OK) {
996       return FLUID_FAILED;
997     }
998   }
999 
1000   /* Import the modulators (only SF2.1 and higher) */
1001   for (count = 0, r = sfzone->mod; r != NULL; count++) {
1002 
1003     SFMod* mod_src = (SFMod *)r->data;
1004     fluid_mod_t * mod_dest = fluid_mod_new();
1005     int type;
1006 
1007     if (mod_dest == NULL){
1008       return FLUID_FAILED;
1009     }
1010     mod_dest->next = NULL; /* pointer to next modulator, this is the end of the list now.*/
1011 
1012     /* *** Amount *** */
1013     mod_dest->amount = mod_src->amount;
1014 
1015     /* *** Source *** */
1016     mod_dest->src1 = mod_src->src & 127; /* index of source 1, seven-bit value, SF2.01 section 8.2, page 50 */
1017     mod_dest->flags1 = 0;
1018 
1019     /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/
1020     if (mod_src->src & (1<<7)){
1021       mod_dest->flags1 |= FLUID_MOD_CC;
1022     } else {
1023       mod_dest->flags1 |= FLUID_MOD_GC;
1024     }
1025 
1026     /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/
1027     if (mod_src->src & (1<<8)){
1028       mod_dest->flags1 |= FLUID_MOD_NEGATIVE;
1029     } else {
1030       mod_dest->flags1 |= FLUID_MOD_POSITIVE;
1031     }
1032 
1033     /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/
1034     if (mod_src->src & (1<<9)){
1035       mod_dest->flags1 |= FLUID_MOD_BIPOLAR;
1036     } else {
1037       mod_dest->flags1 |= FLUID_MOD_UNIPOLAR;
1038     }
1039 
1040     /* modulator source types: SF2.01 section 8.2.1 page 52 */
1041     type=(mod_src->src) >> 10;
1042     type &= 63; /* type is a 6-bit value */
1043     if (type == 0){
1044       mod_dest->flags1 |= FLUID_MOD_LINEAR;
1045     } else if (type == 1){
1046       mod_dest->flags1 |= FLUID_MOD_CONCAVE;
1047     } else if (type == 2){
1048       mod_dest->flags1 |= FLUID_MOD_CONVEX;
1049     } else if (type == 3){
1050       mod_dest->flags1 |= FLUID_MOD_SWITCH;
1051     } else {
1052       /* This shouldn't happen - unknown type!
1053        * Deactivate the modulator by setting the amount to 0. */
1054       mod_dest->amount=0;
1055     }
1056 
1057     /* *** Dest *** */
1058     mod_dest->dest = mod_src->dest; /* index of controlled generator */
1059 
1060     /* *** Amount source *** */
1061     mod_dest->src2 = mod_src->amtsrc & 127; /* index of source 2, seven-bit value, SF2.01 section 8.2, p.50 */
1062     mod_dest->flags2 = 0;
1063 
1064     /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/
1065     if (mod_src->amtsrc & (1<<7)){
1066       mod_dest->flags2 |= FLUID_MOD_CC;
1067     } else {
1068       mod_dest->flags2 |= FLUID_MOD_GC;
1069     }
1070 
1071     /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/
1072     if (mod_src->amtsrc & (1<<8)){
1073       mod_dest->flags2 |= FLUID_MOD_NEGATIVE;
1074     } else {
1075       mod_dest->flags2 |= FLUID_MOD_POSITIVE;
1076     }
1077 
1078     /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/
1079     if (mod_src->amtsrc & (1<<9)){
1080       mod_dest->flags2 |= FLUID_MOD_BIPOLAR;
1081     } else {
1082       mod_dest->flags2 |= FLUID_MOD_UNIPOLAR;
1083     }
1084 
1085     /* modulator source types: SF2.01 section 8.2.1 page 52 */
1086     type = (mod_src->amtsrc) >> 10;
1087     type &= 63; /* type is a 6-bit value */
1088     if (type == 0){
1089       mod_dest->flags2 |= FLUID_MOD_LINEAR;
1090     } else if (type == 1){
1091       mod_dest->flags2 |= FLUID_MOD_CONCAVE;
1092     } else if (type == 2){
1093       mod_dest->flags2 |= FLUID_MOD_CONVEX;
1094     } else if (type == 3){
1095       mod_dest->flags2 |= FLUID_MOD_SWITCH;
1096     } else {
1097       /* This shouldn't happen - unknown type!
1098        * Deactivate the modulator by setting the amount to 0. */
1099       mod_dest->amount=0;
1100     }
1101 
1102     /* *** Transform *** */
1103     /* SF2.01 only uses the 'linear' transform (0).
1104      * Deactivate the modulator by setting the amount to 0 in any other case.
1105      */
1106     if (mod_src->trans !=0){
1107       mod_dest->amount = 0;
1108     }
1109 
1110     /* Store the new modulator in the zone The order of modulators
1111      * will make a difference, at least in an instrument context: The
1112      * second modulator overwrites the first one, if they only differ
1113      * in amount. */
1114     if (count == 0){
1115       zone->mod = mod_dest;
1116     } else {
1117       fluid_mod_t * last_mod = zone->mod;
1118 
1119       /* Find the end of the list */
1120       while (last_mod->next != NULL){
1121 	last_mod=last_mod->next;
1122       }
1123 
1124       last_mod->next = mod_dest;
1125     }
1126 
1127     r = fluid_list_next(r);
1128   } /* foreach modulator */
1129 
1130   return FLUID_OK;
1131 }
1132 
1133 /*
1134  * fluid_preset_zone_get_inst
1135  */
1136 fluid_inst_t*
fluid_preset_zone_get_inst(fluid_preset_zone_t * zone)1137 fluid_preset_zone_get_inst(fluid_preset_zone_t* zone)
1138 {
1139   return zone->inst;
1140 }
1141 
1142 /*
1143  * fluid_preset_zone_inside_range
1144  */
1145 int
fluid_preset_zone_inside_range(fluid_preset_zone_t * zone,int key,int vel)1146 fluid_preset_zone_inside_range(fluid_preset_zone_t* zone, int key, int vel)
1147 {
1148   return ((zone->keylo <= key) &&
1149 	  (zone->keyhi >= key) &&
1150 	  (zone->vello <= vel) &&
1151 	  (zone->velhi >= vel));
1152 }
1153 
1154 /***************************************************************
1155  *
1156  *                           INST
1157  */
1158 
1159 /*
1160  * new_fluid_inst
1161  */
1162 fluid_inst_t*
new_fluid_inst()1163 new_fluid_inst()
1164 {
1165   fluid_inst_t* inst = FLUID_NEW(fluid_inst_t);
1166   if (inst == NULL) {
1167     FLUID_LOG(FLUID_ERR, "Out of memory");
1168     return NULL;
1169   }
1170   inst->name[0] = 0;
1171   inst->global_zone = NULL;
1172   inst->zone = NULL;
1173   return inst;
1174 }
1175 
1176 /*
1177  * delete_fluid_inst
1178  */
1179 int
delete_fluid_inst(fluid_inst_t * inst)1180 delete_fluid_inst(fluid_inst_t* inst)
1181 {
1182   fluid_inst_zone_t* zone;
1183   int err = FLUID_OK;
1184   if (inst->global_zone != NULL) {
1185     if (delete_fluid_inst_zone(inst->global_zone) != FLUID_OK) {
1186       err = FLUID_FAILED;
1187     }
1188     inst->global_zone = NULL;
1189   }
1190   zone = inst->zone;
1191   while (zone != NULL) {
1192     inst->zone = zone->next;
1193     if (delete_fluid_inst_zone(zone) != FLUID_OK) {
1194       err = FLUID_FAILED;
1195     }
1196     zone = inst->zone;
1197   }
1198   FLUID_FREE(inst);
1199   return err;
1200 }
1201 
1202 /*
1203  * fluid_inst_set_global_zone
1204  */
1205 int
fluid_inst_set_global_zone(fluid_inst_t * inst,fluid_inst_zone_t * zone)1206 fluid_inst_set_global_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone)
1207 {
1208   inst->global_zone = zone;
1209   return FLUID_OK;
1210 }
1211 
1212 /*
1213  * fluid_inst_import_sfont
1214  */
1215 int
fluid_inst_import_sfont(fluid_inst_t * inst,SFInst * sfinst,fluid_defsfont_t * sfont)1216 fluid_inst_import_sfont(fluid_inst_t* inst, SFInst *sfinst, fluid_defsfont_t* sfont)
1217 {
1218   fluid_list_t *p;
1219   SFZone* sfzone;
1220   fluid_inst_zone_t* zone;
1221   char zone_name[256];
1222   int count;
1223 
1224   p = sfinst->zone;
1225   if (FLUID_STRLEN(sfinst->name) > 0) {
1226     FLUID_STRCPY(inst->name, sfinst->name);
1227   } else {
1228     FLUID_STRCPY(inst->name, "<untitled>");
1229   }
1230 
1231   count = 0;
1232   while (p != NULL) {
1233 
1234     sfzone = (SFZone *) p->data;
1235     FLUID_SPRINTF(zone_name, "%s/%d", inst->name, count);
1236 
1237     zone = new_fluid_inst_zone(zone_name);
1238     if (zone == NULL) {
1239       return FLUID_FAILED;
1240     }
1241 
1242     if (fluid_inst_zone_import_sfont(zone, sfzone, sfont) != FLUID_OK) {
1243       return FLUID_FAILED;
1244     }
1245 
1246     if ((count == 0) && (fluid_inst_zone_get_sample(zone) == NULL)) {
1247       fluid_inst_set_global_zone(inst, zone);
1248 
1249     } else if (fluid_inst_add_zone(inst, zone) != FLUID_OK) {
1250       return FLUID_FAILED;
1251     }
1252 
1253     p = fluid_list_next(p);
1254     count++;
1255   }
1256   return FLUID_OK;
1257 }
1258 
1259 /*
1260  * fluid_inst_add_zone
1261  */
1262 int
fluid_inst_add_zone(fluid_inst_t * inst,fluid_inst_zone_t * zone)1263 fluid_inst_add_zone(fluid_inst_t* inst, fluid_inst_zone_t* zone)
1264 {
1265   if (inst->zone == NULL) {
1266     zone->next = NULL;
1267     inst->zone = zone;
1268   } else {
1269     zone->next = inst->zone;
1270     inst->zone = zone;
1271   }
1272   return FLUID_OK;
1273 }
1274 
1275 /*
1276  * fluid_inst_get_zone
1277  */
1278 fluid_inst_zone_t*
fluid_inst_get_zone(fluid_inst_t * inst)1279 fluid_inst_get_zone(fluid_inst_t* inst)
1280 {
1281   return inst->zone;
1282 }
1283 
1284 /*
1285  * fluid_inst_get_global_zone
1286  */
1287 fluid_inst_zone_t*
fluid_inst_get_global_zone(fluid_inst_t * inst)1288 fluid_inst_get_global_zone(fluid_inst_t* inst)
1289 {
1290   return inst->global_zone;
1291 }
1292 
1293 /***************************************************************
1294  *
1295  *                           INST_ZONE
1296  */
1297 
1298 /*
1299  * new_fluid_inst_zone
1300  */
1301 fluid_inst_zone_t*
new_fluid_inst_zone(char * name)1302 new_fluid_inst_zone(char* name)
1303 {
1304   int size;
1305   fluid_inst_zone_t* zone = NULL;
1306   zone = FLUID_NEW(fluid_inst_zone_t);
1307   if (zone == NULL) {
1308     FLUID_LOG(FLUID_ERR, "Out of memory");
1309     return NULL;
1310   }
1311   zone->next = NULL;
1312   size = 1 + FLUID_STRLEN(name);
1313   zone->name = FLUID_MALLOC(size);
1314   if (zone->name == NULL) {
1315     FLUID_LOG(FLUID_ERR, "Out of memory");
1316     FLUID_FREE(zone);
1317     return NULL;
1318   }
1319   FLUID_STRCPY(zone->name, name);
1320   zone->sample = NULL;
1321   zone->keylo = 0;
1322   zone->keyhi = 128;
1323   zone->vello = 0;
1324   zone->velhi = 128;
1325 
1326   /* Flag the generators as unused.
1327    * This also sets the generator values to default, but they will be overwritten anyway, if used.*/
1328   fluid_gen_set_default_values(&zone->gen[0]);
1329   zone->mod=NULL; /* list of modulators */
1330   return zone;
1331 }
1332 
1333 /*
1334  * delete_fluid_inst_zone
1335  */
1336 int
delete_fluid_inst_zone(fluid_inst_zone_t * zone)1337 delete_fluid_inst_zone(fluid_inst_zone_t* zone)
1338 {
1339   fluid_mod_t *mod, *tmp;
1340 
1341   mod = zone->mod;
1342   while (mod)	/* delete the modulators */
1343     {
1344       tmp = mod;
1345       mod = mod->next;
1346       fluid_mod_delete (tmp);
1347     }
1348 
1349   if (zone->name) FLUID_FREE (zone->name);
1350   FLUID_FREE(zone);
1351   return FLUID_OK;
1352 }
1353 
1354 /*
1355  * fluid_inst_zone_next
1356  */
1357 fluid_inst_zone_t*
fluid_inst_zone_next(fluid_inst_zone_t * zone)1358 fluid_inst_zone_next(fluid_inst_zone_t* zone)
1359 {
1360   return zone->next;
1361 }
1362 
1363 /*
1364  * fluid_inst_zone_import_sfont
1365  */
1366 int
fluid_inst_zone_import_sfont(fluid_inst_zone_t * zone,SFZone * sfzone,fluid_defsfont_t * sfont)1367 fluid_inst_zone_import_sfont(fluid_inst_zone_t* zone, SFZone *sfzone, fluid_defsfont_t* sfont)
1368 {
1369   fluid_list_t *r;
1370   SFGen* sfgen;
1371   int count;
1372 
1373   for (count = 0, r = sfzone->gen; r != NULL; count++) {
1374     sfgen = (SFGen *) r->data;
1375     switch (sfgen->id) {
1376     case GEN_KEYRANGE:
1377       zone->keylo = (int) sfgen->amount.range.lo;
1378       zone->keyhi = (int) sfgen->amount.range.hi;
1379       break;
1380     case GEN_VELRANGE:
1381       zone->vello = (int) sfgen->amount.range.lo;
1382       zone->velhi = (int) sfgen->amount.range.hi;
1383       break;
1384     default:
1385       /* FIXME: some generators have an unsigned word amount value but
1386 	 i don't know which ones */
1387       zone->gen[sfgen->id].val = (fluid_real_t) sfgen->amount.sword;
1388       zone->gen[sfgen->id].flags = GEN_SET;
1389       break;
1390     }
1391     r = fluid_list_next(r);
1392   }
1393 
1394   /* FIXME */
1395 /*    if (zone->gen[GEN_EXCLUSIVECLASS].flags == GEN_SET) { */
1396 /*      FLUID_LOG(FLUID_DBG, "ExclusiveClass=%d\n", (int) zone->gen[GEN_EXCLUSIVECLASS].val); */
1397 /*    } */
1398 
1399   /* fixup sample pointer */
1400   if ((sfzone->instsamp != NULL) && (sfzone->instsamp->data != NULL))
1401     zone->sample = ((SFSample *)(sfzone->instsamp->data))->fluid_sample;
1402 
1403   /* Import the modulators (only SF2.1 and higher) */
1404   for (count = 0, r = sfzone->mod; r != NULL; count++) {
1405     SFMod* mod_src = (SFMod *) r->data;
1406     int type;
1407     fluid_mod_t* mod_dest;
1408 
1409     mod_dest = fluid_mod_new();
1410     if (mod_dest == NULL){
1411       return FLUID_FAILED;
1412     }
1413 
1414     mod_dest->next = NULL; /* pointer to next modulator, this is the end of the list now.*/
1415 
1416     /* *** Amount *** */
1417     mod_dest->amount = mod_src->amount;
1418 
1419     /* *** Source *** */
1420     mod_dest->src1 = mod_src->src & 127; /* index of source 1, seven-bit value, SF2.01 section 8.2, page 50 */
1421     mod_dest->flags1 = 0;
1422 
1423     /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/
1424     if (mod_src->src & (1<<7)){
1425       mod_dest->flags1 |= FLUID_MOD_CC;
1426     } else {
1427       mod_dest->flags1 |= FLUID_MOD_GC;
1428     }
1429 
1430     /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/
1431     if (mod_src->src & (1<<8)){
1432       mod_dest->flags1 |= FLUID_MOD_NEGATIVE;
1433     } else {
1434       mod_dest->flags1 |= FLUID_MOD_POSITIVE;
1435     }
1436 
1437     /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/
1438     if (mod_src->src & (1<<9)){
1439       mod_dest->flags1 |= FLUID_MOD_BIPOLAR;
1440     } else {
1441       mod_dest->flags1 |= FLUID_MOD_UNIPOLAR;
1442     }
1443 
1444     /* modulator source types: SF2.01 section 8.2.1 page 52 */
1445     type = (mod_src->src) >> 10;
1446     type &= 63; /* type is a 6-bit value */
1447     if (type == 0){
1448       mod_dest->flags1 |= FLUID_MOD_LINEAR;
1449     } else if (type == 1){
1450       mod_dest->flags1 |= FLUID_MOD_CONCAVE;
1451     } else if (type == 2){
1452       mod_dest->flags1 |= FLUID_MOD_CONVEX;
1453     } else if (type == 3){
1454       mod_dest->flags1 |= FLUID_MOD_SWITCH;
1455     } else {
1456       /* This shouldn't happen - unknown type!
1457        * Deactivate the modulator by setting the amount to 0. */
1458       mod_dest->amount = 0;
1459     }
1460 
1461     /* *** Dest *** */
1462     mod_dest->dest=mod_src->dest; /* index of controlled generator */
1463 
1464     /* *** Amount source *** */
1465     mod_dest->src2=mod_src->amtsrc & 127; /* index of source 2, seven-bit value, SF2.01 section 8.2, page 50 */
1466     mod_dest->flags2 = 0;
1467 
1468     /* Bit 7: CC flag SF 2.01 section 8.2.1 page 50*/
1469     if (mod_src->amtsrc & (1<<7)){
1470       mod_dest->flags2 |= FLUID_MOD_CC;
1471     } else {
1472       mod_dest->flags2 |= FLUID_MOD_GC;
1473     }
1474 
1475     /* Bit 8: D flag SF 2.01 section 8.2.2 page 51*/
1476     if (mod_src->amtsrc & (1<<8)){
1477       mod_dest->flags2 |= FLUID_MOD_NEGATIVE;
1478     } else {
1479       mod_dest->flags2 |= FLUID_MOD_POSITIVE;
1480     }
1481 
1482     /* Bit 9: P flag SF 2.01 section 8.2.3 page 51*/
1483     if (mod_src->amtsrc & (1<<9)){
1484       mod_dest->flags2 |= FLUID_MOD_BIPOLAR;
1485     } else {
1486       mod_dest->flags2 |= FLUID_MOD_UNIPOLAR;
1487     }
1488 
1489     /* modulator source types: SF2.01 section 8.2.1 page 52 */
1490     type=(mod_src->amtsrc) >> 10;
1491     type &= 63; /* type is a 6-bit value */
1492     if (type == 0){
1493       mod_dest->flags2 |= FLUID_MOD_LINEAR;
1494     } else if (type == 1){
1495       mod_dest->flags2 |= FLUID_MOD_CONCAVE;
1496     } else if (type == 2){
1497       mod_dest->flags2 |= FLUID_MOD_CONVEX;
1498     } else if (type == 3){
1499       mod_dest->flags2 |= FLUID_MOD_SWITCH;
1500     } else {
1501       /* This shouldn't happen - unknown type!
1502        * Deactivate the modulator by setting the amount to 0. */
1503       mod_dest->amount = 0;
1504     }
1505 
1506     /* *** Transform *** */
1507     /* SF2.01 only uses the 'linear' transform (0).
1508      * Deactivate the modulator by setting the amount to 0 in any other case.
1509      */
1510     if (mod_src->trans !=0){
1511       mod_dest->amount = 0;
1512     }
1513 
1514     /* Store the new modulator in the zone
1515      * The order of modulators will make a difference, at least in an instrument context:
1516      * The second modulator overwrites the first one, if they only differ in amount. */
1517     if (count == 0){
1518       zone->mod=mod_dest;
1519     } else {
1520       fluid_mod_t * last_mod=zone->mod;
1521       /* Find the end of the list */
1522       while (last_mod->next != NULL){
1523 	last_mod=last_mod->next;
1524       }
1525       last_mod->next=mod_dest;
1526     }
1527 
1528     r = fluid_list_next(r);
1529   } /* foreach modulator */
1530   return FLUID_OK;
1531 }
1532 
1533 /*
1534  * fluid_inst_zone_get_sample
1535  */
1536 fluid_sample_t*
fluid_inst_zone_get_sample(fluid_inst_zone_t * zone)1537 fluid_inst_zone_get_sample(fluid_inst_zone_t* zone)
1538 {
1539   return zone->sample;
1540 }
1541 
1542 /*
1543  * fluid_inst_zone_inside_range
1544  */
1545 int
fluid_inst_zone_inside_range(fluid_inst_zone_t * zone,int key,int vel)1546 fluid_inst_zone_inside_range(fluid_inst_zone_t* zone, int key, int vel)
1547 {
1548   return ((zone->keylo <= key) &&
1549 	  (zone->keyhi >= key) &&
1550 	  (zone->vello <= vel) &&
1551 	  (zone->velhi >= vel));
1552 }
1553 
1554 /***************************************************************
1555  *
1556  *                           SAMPLE
1557  */
1558 
1559 /*
1560  * new_fluid_sample
1561  */
1562 fluid_sample_t*
new_fluid_sample()1563 new_fluid_sample()
1564 {
1565   fluid_sample_t* sample = NULL;
1566 
1567   sample = FLUID_NEW(fluid_sample_t);
1568   if (sample == NULL) {
1569     FLUID_LOG(FLUID_ERR, "Out of memory");
1570     return NULL;
1571   }
1572 
1573   memset(sample, 0, sizeof(fluid_sample_t));
1574   sample->valid = 1;
1575 
1576   return sample;
1577 }
1578 
1579 /*
1580  * delete_fluid_sample
1581  */
1582 int
delete_fluid_sample(fluid_sample_t * sample)1583 delete_fluid_sample(fluid_sample_t* sample)
1584 {
1585   FLUID_FREE(sample);
1586   return FLUID_OK;
1587 }
1588 
1589 /*
1590  * fluid_sample_in_rom
1591  */
1592 int
fluid_sample_in_rom(fluid_sample_t * sample)1593 fluid_sample_in_rom(fluid_sample_t* sample)
1594 {
1595   return (sample->sampletype & FLUID_SAMPLETYPE_ROM);
1596 }
1597 
1598 /*
1599  * fluid_sample_import_sfont
1600  */
1601 int
fluid_sample_import_sfont(fluid_sample_t * sample,SFSample * sfsample,fluid_defsfont_t * sfont)1602 fluid_sample_import_sfont(fluid_sample_t* sample, SFSample* sfsample, fluid_defsfont_t* sfont)
1603 {
1604   FLUID_STRCPY(sample->name, sfsample->name);
1605   sample->data = sfont->sampledata;
1606   sample->start = sfsample->start;
1607   sample->end = sfsample->start + sfsample->end;
1608   sample->loopstart = sfsample->start + sfsample->loopstart;
1609   sample->loopend = sfsample->start + sfsample->loopend;
1610   sample->samplerate = sfsample->samplerate;
1611   sample->origpitch = sfsample->origpitch;
1612   sample->pitchadj = sfsample->pitchadj;
1613   sample->sampletype = sfsample->sampletype;
1614 
1615   if (sample->sampletype & FLUID_SAMPLETYPE_ROM) {
1616     sample->valid = 0;
1617     FLUID_LOG(FLUID_WARN, "Ignoring sample %s: can't use ROM samples", sample->name);
1618   }
1619   if (sample->end - sample->start < 8) {
1620     sample->valid = 0;
1621     FLUID_LOG(FLUID_WARN, "Ignoring sample %s: too few sample data points", sample->name);
1622   } else {
1623 /*      if (sample->loopstart < sample->start + 8) { */
1624 /*        FLUID_LOG(FLUID_WARN, "Fixing sample %s: at least 8 data points required before loop start", sample->name);     */
1625 /*        sample->loopstart = sample->start + 8; */
1626 /*      } */
1627 /*      if (sample->loopend > sample->end - 8) { */
1628 /*        FLUID_LOG(FLUID_WARN, "Fixing sample %s: at least 8 data points required after loop end", sample->name);     */
1629 /*        sample->loopend = sample->end - 8; */
1630 /*      } */
1631   }
1632   return FLUID_OK;
1633 }
1634 
1635 
1636 
1637 /********************************************************************************/
1638 /********************************************************************************/
1639 /********************************************************************************/
1640 /********************************************************************************/
1641 /********************************************************************************/
1642 
1643 
1644 
1645 /*=================================sfload.c========================
1646   Borrowed from Smurf SoundFont Editor by Josh Green
1647   =================================================================*/
1648 
1649 /*
1650    functions for loading data from sfont files, with appropriate byte swapping
1651    on big endian machines. Sfont IDs are not swapped because the ID read is
1652    equivalent to the matching ID list in memory regardless of LE/BE machine
1653 */
1654 
1655 #if FLUID_IS_BIG_ENDIAN
1656 
1657 #define READCHUNK(var,fd)	G_STMT_START {		\
1658 	if (!safe_fread(var, 8, fd))			\
1659 		return(FAIL);				\
1660 	((SFChunk *)(var))->size = GUINT32_FROM_LE(((SFChunk *)(var))->size);  \
1661 } G_STMT_END
1662 
1663 #define READD(var,fd)		G_STMT_START {		\
1664 	unsigned int _temp;				\
1665 	if (!safe_fread(&_temp, 4, fd))			\
1666 		return(FAIL);				\
1667 	var = GINT32_FROM_LE(_temp);			\
1668 } G_STMT_END
1669 
1670 #define READW(var,fd)		G_STMT_START {		\
1671 	unsigned short _temp;				\
1672 	if (!safe_fread(&_temp, 2, fd))			\
1673 		return(FAIL);				\
1674 	var = GINT16_FROM_LE(_temp);			\
1675 } G_STMT_END
1676 
1677 #else
1678 
1679 #define READCHUNK(var,fd)	G_STMT_START {		\
1680     if (!safe_fread(var, 8, fd))			\
1681 	return(FAIL);					\
1682     ((SFChunk *)(var))->size = GUINT32_FROM_LE(((SFChunk *)(var))->size);  \
1683 } G_STMT_END
1684 
1685 #define READD(var,fd)		G_STMT_START {		\
1686     unsigned int _temp;					\
1687     if (!safe_fread(&_temp, 4, fd))			\
1688 	return(FAIL);					\
1689     var = GINT32_FROM_LE(_temp);			\
1690 } G_STMT_END
1691 
1692 #define READW(var,fd)		G_STMT_START {		\
1693     unsigned short _temp;					\
1694     if (!safe_fread(&_temp, 2, fd))			\
1695 	return(FAIL);					\
1696     var = GINT16_FROM_LE(_temp);			\
1697 } G_STMT_END
1698 
1699 #endif
1700 
1701 
1702 #define READID(var,fd)		G_STMT_START {		\
1703     if (!safe_fread(var, 4, fd))			\
1704 	return(FAIL);					\
1705 } G_STMT_END
1706 
1707 #define READSTR(var,fd)		G_STMT_START {		\
1708     if (!safe_fread(var, 20, fd))			\
1709 	return(FAIL);					\
1710     (*var)[20] = '\0';					\
1711 } G_STMT_END
1712 
1713 #define READB(var,fd)		G_STMT_START {		\
1714     if (!safe_fread(&var, 1, fd))			\
1715 	return(FAIL);					\
1716 } G_STMT_END
1717 
1718 #define FSKIP(size,fd)		G_STMT_START {		\
1719     if (!safe_fseek(fd, size, SEEK_CUR))		\
1720 	return(FAIL);					\
1721 } G_STMT_END
1722 
1723 #define FSKIPW(fd)		G_STMT_START {		\
1724     if (!safe_fseek(fd, 2, SEEK_CUR))			\
1725 	return(FAIL);					\
1726 } G_STMT_END
1727 
1728 /* removes and advances a fluid_list_t pointer */
1729 #define SLADVREM(list, item)	G_STMT_START {		\
1730     fluid_list_t *_temp = item;				\
1731     item = fluid_list_next(item);				\
1732     list = fluid_list_remove_link(list, _temp);		\
1733     delete1_fluid_list(_temp);				\
1734 } G_STMT_END
1735 
1736 static int chunkid (unsigned int id);
1737 static int load_body (unsigned int size, SFData * sf, FILE * fd);
1738 static int read_listchunk (SFChunk * chunk, FILE * fd);
1739 static int process_info (int size, SFData * sf, FILE * fd);
1740 static int process_sdta (unsigned int size, SFData * sf, FILE * fd);
1741 static int pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
1742   int * size, FILE * fd);
1743 static int process_pdta (int size, SFData * sf, FILE * fd);
1744 static int load_phdr (int size, SFData * sf, FILE * fd);
1745 static int load_pbag (int size, SFData * sf, FILE * fd);
1746 static int load_pmod (int size, SFData * sf, FILE * fd);
1747 static int load_pgen (int size, SFData * sf, FILE * fd);
1748 static int load_ihdr (int size, SFData * sf, FILE * fd);
1749 static int load_ibag (int size, SFData * sf, FILE * fd);
1750 static int load_imod (int size, SFData * sf, FILE * fd);
1751 static int load_igen (int size, SFData * sf, FILE * fd);
1752 static int load_shdr (unsigned int size, SFData * sf, FILE * fd);
1753 static int fixup_pgen (SFData * sf);
1754 static int fixup_igen (SFData * sf);
1755 static int fixup_sample (SFData * sf);
1756 
1757 char idlist[] = {
1758   "RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD"
1759     "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdr"
1760 };
1761 
1762 static unsigned int sdtachunk_size;
1763 
1764 /* sound font file load functions */
1765 static int
chunkid(unsigned int id)1766 chunkid (unsigned int id)
1767 {
1768   unsigned int i;
1769   unsigned int *p;
1770 
1771   p = (unsigned int *) & idlist;
1772   for (i = 0; i < sizeof (idlist) / sizeof (int); i++, p += 1)
1773     if (*p == id)
1774       return (i + 1);
1775 
1776   return (UNKN_ID);
1777 }
1778 
1779 SFData *
sfload_file(const char * fname)1780 sfload_file (const char * fname)
1781 {
1782   SFData *sf = NULL;
1783   FILE *fd;
1784   int fsize = 0;
1785   int err = FALSE;
1786 
1787   if (!(fd = fopen (fname, "rb")))
1788     {
1789       FLUID_LOG (FLUID_ERR, _("Unable to open file \"%s\""), fname);
1790       return (NULL);
1791     }
1792 
1793   if (!(sf = FLUID_NEW (SFData)))
1794     {
1795       FLUID_LOG(FLUID_ERR, "Out of memory");
1796       err = TRUE;
1797     }
1798 
1799   if (!err)
1800     {
1801       memset (sf, 0, sizeof (SFData));	/* zero sfdata */
1802       sf->fname = FLUID_STRDUP (fname);	/* copy file name */
1803       sf->sffd = fd;
1804     }
1805 
1806   /* get size of file */
1807   if (!err && fseek (fd, 0L, SEEK_END) == -1)
1808     {				/* seek to end of file */
1809       err = TRUE;
1810       FLUID_LOG (FLUID_ERR, _("Seek to end of file failed"));
1811     }
1812   if (!err && (fsize = ftell (fd)) == -1)
1813     {				/* position = size */
1814       err = TRUE;
1815       FLUID_LOG (FLUID_ERR, _("Get end of file position failed"));
1816     }
1817   if (!err)
1818     rewind (fd);
1819 
1820   if (!err && !load_body (fsize, sf, fd))
1821     err = TRUE;			/* load the sfont */
1822 
1823   if (err)
1824     {
1825       if (sf)
1826 	sfont_close (sf);
1827       return (NULL);
1828     }
1829 
1830   return (sf);
1831 }
1832 
1833 static int
load_body(unsigned int size,SFData * sf,FILE * fd)1834 load_body (unsigned int size, SFData * sf, FILE * fd)
1835 {
1836   SFChunk chunk;
1837 
1838   READCHUNK (&chunk, fd);	/* load RIFF chunk */
1839   if (chunkid (chunk.id) != RIFF_ID) {	/* error if not RIFF */
1840     FLUID_LOG (FLUID_ERR, _("Not a RIFF file"));
1841     return (FAIL);
1842   }
1843 
1844   READID (&chunk.id, fd);	/* load file ID */
1845   if (chunkid (chunk.id) != SFBK_ID) {	/* error if not SFBK_ID */
1846     FLUID_LOG (FLUID_ERR, _("Not a SoundFont file"));
1847     return (FAIL);
1848   }
1849 
1850   if (chunk.size != size - 8) {
1851     gerr (ErrCorr, _("SoundFont file size mismatch"));
1852     return (FAIL);
1853   }
1854 
1855   /* Process INFO block */
1856   if (!read_listchunk (&chunk, fd))
1857     return (FAIL);
1858   if (chunkid (chunk.id) != INFO_ID)
1859     return (gerr (ErrCorr, _("Invalid ID found when expecting INFO chunk")));
1860   if (!process_info (chunk.size, sf, fd))
1861     return (FAIL);
1862 
1863   /* Process sample chunk */
1864   if (!read_listchunk (&chunk, fd))
1865     return (FAIL);
1866   if (chunkid (chunk.id) != SDTA_ID)
1867     return (gerr (ErrCorr,
1868 	_("Invalid ID found when expecting SAMPLE chunk")));
1869   if (!process_sdta (chunk.size, sf, fd))
1870     return (FAIL);
1871 
1872   /* process HYDRA chunk */
1873   if (!read_listchunk (&chunk, fd))
1874     return (FAIL);
1875   if (chunkid (chunk.id) != PDTA_ID)
1876     return (gerr (ErrCorr, _("Invalid ID found when expecting HYDRA chunk")));
1877   if (!process_pdta (chunk.size, sf, fd))
1878     return (FAIL);
1879 
1880   if (!fixup_pgen (sf))
1881     return (FAIL);
1882   if (!fixup_igen (sf))
1883     return (FAIL);
1884   if (!fixup_sample (sf))
1885     return (FAIL);
1886 
1887   /* sort preset list by bank, preset # */
1888   sf->preset = fluid_list_sort (sf->preset,
1889     (fluid_compare_func_t) sfont_preset_compare_func);
1890 
1891   return (OK);
1892 }
1893 
1894 static int
read_listchunk(SFChunk * chunk,FILE * fd)1895 read_listchunk (SFChunk * chunk, FILE * fd)
1896 {
1897   READCHUNK (chunk, fd);	/* read list chunk */
1898   if (chunkid (chunk->id) != LIST_ID)	/* error if ! list chunk */
1899     return (gerr (ErrCorr, _("Invalid chunk id in level 0 parse")));
1900   READID (&chunk->id, fd);	/* read id string */
1901   chunk->size -= 4;
1902   return (OK);
1903 }
1904 
1905 static int
process_info(int size,SFData * sf,FILE * fd)1906 process_info (int size, SFData * sf, FILE * fd)
1907 {
1908   SFChunk chunk;
1909   unsigned char id;
1910   char *item;
1911   unsigned short ver;
1912 
1913   while (size > 0)
1914     {
1915       READCHUNK (&chunk, fd);
1916       size -= 8;
1917 
1918       id = chunkid (chunk.id);
1919 
1920       if (id == IFIL_ID)
1921 	{			/* sound font version chunk? */
1922 	  if (chunk.size != 4)
1923 	    return (gerr (ErrCorr,
1924 		_("Sound font version info chunk has invalid size")));
1925 
1926 	  READW (ver, fd);
1927 	  sf->version.major = ver;
1928 	  READW (ver, fd);
1929 	  sf->version.minor = ver;
1930 
1931 	  if (sf->version.major < 2) {
1932 	    FLUID_LOG (FLUID_ERR,
1933 		      _("Sound font version is %d.%d which is not"
1934 			" supported, convert to version 2.0x"),
1935 		      sf->version.major,
1936 		      sf->version.minor);
1937 	    return (FAIL);
1938 	  }
1939 
1940 	  if (sf->version.major > 2) {
1941 	    FLUID_LOG (FLUID_WARN,
1942 		      _("Sound font version is %d.%d which is newer than"
1943 			" what this version of FLUID Synth was designed for (v2.0x)"),
1944 		      sf->version.major,
1945 		      sf->version.minor);
1946 	    return (FAIL);
1947 	  }
1948 	}
1949       else if (id == IVER_ID)
1950 	{			/* ROM version chunk? */
1951 	  if (chunk.size != 4)
1952 	    return (gerr (ErrCorr,
1953 		_("ROM version info chunk has invalid size")));
1954 
1955 	  READW (ver, fd);
1956 	  sf->romver.major = ver;
1957 	  READW (ver, fd);
1958 	  sf->romver.minor = ver;
1959 	}
1960       else if (id != UNKN_ID)
1961 	{
1962 	  if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536)
1963 	    || (chunk.size % 2))
1964 	    return (gerr (ErrCorr,
1965 		_("INFO sub chunk %.4s has invalid chunk size"
1966 		  " of %d bytes"), &chunk.id, chunk.size));
1967 
1968 	  /* alloc for chunk id and da chunk */
1969 	  if (!(item = FLUID_MALLOC (chunk.size + 1)))
1970 	    {
1971 	      FLUID_LOG(FLUID_ERR, "Out of memory");
1972 	      return (FAIL);
1973 	    }
1974 
1975 	  /* attach to INFO list, sfont_close will cleanup if FAIL occurs */
1976 	  sf->info = fluid_list_append (sf->info, item);
1977 
1978 	  *(unsigned char *) item = id;
1979 	  if (!safe_fread (&item[1], chunk.size, fd))
1980 	    return (FAIL);
1981 
1982 	  /* force terminate info item (don't forget uint8 info ID) */
1983 	  *(item + chunk.size) = '\0';
1984 	}
1985       else
1986 	return (gerr (ErrCorr, _("Invalid chunk id in INFO chunk")));
1987       size -= chunk.size;
1988     }
1989 
1990   if (size < 0)
1991     return (gerr (ErrCorr, _("INFO chunk size mismatch")));
1992 
1993   return (OK);
1994 }
1995 
1996 static int
process_sdta(unsigned int size,SFData * sf,FILE * fd)1997 process_sdta (unsigned int size, SFData * sf, FILE * fd)
1998 {
1999   SFChunk chunk;
2000 
2001   if (size == 0)
2002     return (OK);		/* no sample data? */
2003 
2004   /* read sub chunk */
2005   READCHUNK (&chunk, fd);
2006   size -= 8;
2007 
2008   if (chunkid (chunk.id) != SMPL_ID)
2009     return (gerr (ErrCorr,
2010 	_("Expected SMPL chunk found invalid id instead")));
2011 
2012   /* SDTA chunk may also contain sm24 chunk for 24 bit samples
2013    * (not yet supported), only an error if SMPL chunk size is
2014    * greater than SDTA. */
2015   if (chunk.size > size)
2016     return (gerr (ErrCorr, _("SDTA chunk size mismatch")));
2017 
2018   /* sample data follows */
2019   sf->samplepos = ftell (fd);
2020 
2021   /* used in fixup_sample() to check validity of sample headers */
2022   sdtachunk_size = chunk.size;
2023   sf->samplesize = chunk.size;
2024 
2025   FSKIP (size, fd);
2026 
2027   return (OK);
2028 }
2029 
2030 static int
pdtahelper(unsigned int expid,unsigned int reclen,SFChunk * chunk,int * size,FILE * fd)2031 pdtahelper (unsigned int expid, unsigned int reclen, SFChunk * chunk,
2032   int * size, FILE * fd)
2033 {
2034   unsigned int id;
2035   char *expstr;
2036 
2037   expstr = CHNKIDSTR (expid);	/* in case we need it */
2038 
2039   READCHUNK (chunk, fd);
2040   *size -= 8;
2041 
2042   if ((id = chunkid (chunk->id)) != expid)
2043     return (gerr (ErrCorr, _("Expected"
2044 	  " PDTA sub-chunk \"%.4s\" found invalid id instead"), expstr));
2045 
2046   if (chunk->size % reclen)	/* valid chunk size? */
2047     return (gerr (ErrCorr,
2048 	_("\"%.4s\" chunk size is not a multiple of %d bytes"), expstr,
2049 	reclen));
2050   if ((*size -= chunk->size) < 0)
2051     return (gerr (ErrCorr,
2052 	_("\"%.4s\" chunk size exceeds remaining PDTA chunk size"), expstr));
2053   return (OK);
2054 }
2055 
2056 static int
process_pdta(int size,SFData * sf,FILE * fd)2057 process_pdta (int size, SFData * sf, FILE * fd)
2058 {
2059   SFChunk chunk;
2060 
2061   if (!pdtahelper (PHDR_ID, SFPHDRSIZE, &chunk, &size, fd))
2062     return (FAIL);
2063   if (!load_phdr (chunk.size, sf, fd))
2064     return (FAIL);
2065 
2066   if (!pdtahelper (PBAG_ID, SFBAGSIZE, &chunk, &size, fd))
2067     return (FAIL);
2068   if (!load_pbag (chunk.size, sf, fd))
2069     return (FAIL);
2070 
2071   if (!pdtahelper (PMOD_ID, SFMODSIZE, &chunk, &size, fd))
2072     return (FAIL);
2073   if (!load_pmod (chunk.size, sf, fd))
2074     return (FAIL);
2075 
2076   if (!pdtahelper (PGEN_ID, SFGENSIZE, &chunk, &size, fd))
2077     return (FAIL);
2078   if (!load_pgen (chunk.size, sf, fd))
2079     return (FAIL);
2080 
2081   if (!pdtahelper (IHDR_ID, SFIHDRSIZE, &chunk, &size, fd))
2082     return (FAIL);
2083   if (!load_ihdr (chunk.size, sf, fd))
2084     return (FAIL);
2085 
2086   if (!pdtahelper (IBAG_ID, SFBAGSIZE, &chunk, &size, fd))
2087     return (FAIL);
2088   if (!load_ibag (chunk.size, sf, fd))
2089     return (FAIL);
2090 
2091   if (!pdtahelper (IMOD_ID, SFMODSIZE, &chunk, &size, fd))
2092     return (FAIL);
2093   if (!load_imod (chunk.size, sf, fd))
2094     return (FAIL);
2095 
2096   if (!pdtahelper (IGEN_ID, SFGENSIZE, &chunk, &size, fd))
2097     return (FAIL);
2098   if (!load_igen (chunk.size, sf, fd))
2099     return (FAIL);
2100 
2101   if (!pdtahelper (SHDR_ID, SFSHDRSIZE, &chunk, &size, fd))
2102     return (FAIL);
2103   if (!load_shdr (chunk.size, sf, fd))
2104     return (FAIL);
2105 
2106   return (OK);
2107 }
2108 
2109 /* preset header loader */
2110 static int
load_phdr(int size,SFData * sf,FILE * fd)2111 load_phdr (int size, SFData * sf, FILE * fd)
2112 {
2113   int i, i2;
2114   SFPreset *p, *pr = NULL;	/* ptr to current & previous preset */
2115   unsigned short zndx, pzndx = 0;
2116 
2117   if (size % SFPHDRSIZE || size == 0)
2118     return (gerr (ErrCorr, _("Preset header chunk size is invalid")));
2119 
2120   i = size / SFPHDRSIZE - 1;
2121   if (i == 0)
2122     {				/* at least one preset + term record */
2123       FLUID_LOG (FLUID_WARN, _("File contains no presets"));
2124       FSKIP (SFPHDRSIZE, fd);
2125       return (OK);
2126     }
2127 
2128   for (; i > 0; i--)
2129     {				/* load all preset headers */
2130       p = FLUID_NEW (SFPreset);
2131       sf->preset = fluid_list_append (sf->preset, p);
2132       p->zone = NULL;		/* In case of failure, sfont_close can cleanup */
2133       READSTR (&p->name, fd);	/* possible read failure ^ */
2134       READW (p->prenum, fd);
2135       READW (p->bank, fd);
2136       READW (zndx, fd);
2137       READD (p->libr, fd);
2138       READD (p->genre, fd);
2139       READD (p->morph, fd);
2140 
2141       if (pr)
2142 	{			/* not first preset? */
2143 	  if (zndx < pzndx)
2144 	    return (gerr (ErrCorr, _("Preset header indices not monotonic")));
2145 	  i2 = zndx - pzndx;
2146 	  while (i2--)
2147 	    {
2148 	      pr->zone = fluid_list_prepend (pr->zone, NULL);
2149 	    }
2150 	}
2151       else if (zndx > 0)	/* 1st preset, warn if ofs >0 */
2152 	FLUID_LOG (FLUID_WARN, _("%d preset zones not referenced, discarding"), zndx);
2153       pr = p;			/* update preset ptr */
2154       pzndx = zndx;
2155     }
2156 
2157   FSKIP (24, fd);
2158   READW (zndx, fd);		/* Read terminal generator index */
2159   FSKIP (12, fd);
2160 
2161   if (zndx < pzndx)
2162     return (gerr (ErrCorr, _("Preset header indices not monotonic")));
2163   i2 = zndx - pzndx;
2164   while (i2--)
2165     {
2166       pr->zone = fluid_list_prepend (pr->zone, NULL);
2167     }
2168 
2169   return (OK);
2170 }
2171 
2172 /* preset bag loader */
2173 static int
load_pbag(int size,SFData * sf,FILE * fd)2174 load_pbag (int size, SFData * sf, FILE * fd)
2175 {
2176   fluid_list_t *p, *p2;
2177   SFZone *z, *pz = NULL;
2178   unsigned short genndx, modndx;
2179   unsigned short pgenndx = 0, pmodndx = 0;
2180   unsigned short i;
2181 
2182   if (size % SFBAGSIZE || size == 0)	/* size is multiple of SFBAGSIZE? */
2183     return (gerr (ErrCorr, _("Preset bag chunk size is invalid")));
2184 
2185   p = sf->preset;
2186   while (p)
2187     {				/* traverse through presets */
2188       p2 = ((SFPreset *) (p->data))->zone;
2189       while (p2)
2190 	{			/* traverse preset's zones */
2191 	  if ((size -= SFBAGSIZE) < 0)
2192 	    return (gerr (ErrCorr, _("Preset bag chunk size mismatch")));
2193 	  z = FLUID_NEW (SFZone);
2194 	  p2->data = z;
2195 	  z->gen = NULL;	/* Init gen and mod before possible failure, */
2196 	  z->mod = NULL;	/* to ensure proper cleanup (sfont_close) */
2197 	  READW (genndx, fd);	/* possible read failure ^ */
2198 	  READW (modndx, fd);
2199 	  z->instsamp = NULL;
2200 
2201 	  if (pz)
2202 	    {			/* if not first zone */
2203 	      if (genndx < pgenndx)
2204 		return (gerr (ErrCorr,
2205 		    _("Preset bag generator indices not monotonic")));
2206 	      if (modndx < pmodndx)
2207 		return (gerr (ErrCorr,
2208 		    _("Preset bag modulator indices not monotonic")));
2209 	      i = genndx - pgenndx;
2210 	      while (i--)
2211 		pz->gen = fluid_list_prepend (pz->gen, NULL);
2212 	      i = modndx - pmodndx;
2213 	      while (i--)
2214 		pz->mod = fluid_list_prepend (pz->mod, NULL);
2215 	    }
2216 	  pz = z;		/* update previous zone ptr */
2217 	  pgenndx = genndx;	/* update previous zone gen index */
2218 	  pmodndx = modndx;	/* update previous zone mod index */
2219 	  p2 = fluid_list_next (p2);
2220 	}
2221       p = fluid_list_next (p);
2222     }
2223 
2224   size -= SFBAGSIZE;
2225   if (size != 0)
2226     return (gerr (ErrCorr, _("Preset bag chunk size mismatch")));
2227 
2228   READW (genndx, fd);
2229   READW (modndx, fd);
2230 
2231   if (!pz)
2232     {
2233       if (genndx > 0)
2234 	FLUID_LOG (FLUID_WARN, _("No preset generators and terminal index not 0"));
2235       if (modndx > 0)
2236 	FLUID_LOG (FLUID_WARN, _("No preset modulators and terminal index not 0"));
2237       return (OK);
2238     }
2239 
2240   if (genndx < pgenndx)
2241     return (gerr (ErrCorr, _("Preset bag generator indices not monotonic")));
2242   if (modndx < pmodndx)
2243     return (gerr (ErrCorr, _("Preset bag modulator indices not monotonic")));
2244   i = genndx - pgenndx;
2245   while (i--)
2246     pz->gen = fluid_list_prepend (pz->gen, NULL);
2247   i = modndx - pmodndx;
2248   while (i--)
2249     pz->mod = fluid_list_prepend (pz->mod, NULL);
2250 
2251   return (OK);
2252 }
2253 
2254 /* preset modulator loader */
2255 static int
load_pmod(int size,SFData * sf,FILE * fd)2256 load_pmod (int size, SFData * sf, FILE * fd)
2257 {
2258   fluid_list_t *p, *p2, *p3;
2259   SFMod *m;
2260 
2261   p = sf->preset;
2262   while (p)
2263     {				/* traverse through all presets */
2264       p2 = ((SFPreset *) (p->data))->zone;
2265       while (p2)
2266 	{			/* traverse this preset's zones */
2267 	  p3 = ((SFZone *) (p2->data))->mod;
2268 	  while (p3)
2269 	    {			/* load zone's modulators */
2270 	      if ((size -= SFMODSIZE) < 0)
2271 		return (gerr (ErrCorr,
2272 		    _("Preset modulator chunk size mismatch")));
2273 	      m = FLUID_NEW (SFMod);
2274 	      p3->data = m;
2275 	      READW (m->src, fd);
2276 	      READW (m->dest, fd);
2277 	      READW (m->amount, fd);
2278 	      READW (m->amtsrc, fd);
2279 	      READW (m->trans, fd);
2280 	      p3 = fluid_list_next (p3);
2281 	    }
2282 	  p2 = fluid_list_next (p2);
2283 	}
2284       p = fluid_list_next (p);
2285     }
2286 
2287   /*
2288      If there isn't even a terminal record
2289      Hmmm, the specs say there should be one, but..
2290    */
2291   if (size == 0)
2292     return (OK);
2293 
2294   size -= SFMODSIZE;
2295   if (size != 0)
2296     return (gerr (ErrCorr, _("Preset modulator chunk size mismatch")));
2297   FSKIP (SFMODSIZE, fd);	/* terminal mod */
2298 
2299   return (OK);
2300 }
2301 
2302 /* -------------------------------------------------------------------
2303  * preset generator loader
2304  * generator (per preset) loading rules:
2305  * Zones with no generators or modulators shall be annihilated
2306  * Global zone must be 1st zone, discard additional ones (instrumentless zones)
2307  *
2308  * generator (per zone) loading rules (in order of decreasing precedence):
2309  * KeyRange is 1st in list (if exists), else discard
2310  * if a VelRange exists only preceded by a KeyRange, else discard
2311  * if a generator follows an instrument discard it
2312  * if a duplicate generator exists replace previous one
2313  * ------------------------------------------------------------------- */
2314 static int
load_pgen(int size,SFData * sf,FILE * fd)2315 load_pgen (int size, SFData * sf, FILE * fd)
2316 {
2317   fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
2318   SFZone *z;
2319   SFGen *g;
2320   SFGenAmount genval;
2321   unsigned short genid;
2322   int level, skip, drop, gzone, discarded;
2323 
2324   p = sf->preset;
2325   while (p)
2326     {				/* traverse through all presets */
2327       gzone = FALSE;
2328       discarded = FALSE;
2329       p2 = ((SFPreset *) (p->data))->zone;
2330       if (p2)
2331 	hz = &p2;
2332       while (p2)
2333 	{			/* traverse preset's zones */
2334 	  level = 0;
2335 	  z = (SFZone *) (p2->data);
2336 	  p3 = z->gen;
2337 	  while (p3)
2338 	    {			/* load zone's generators */
2339 	      dup = NULL;
2340 	      skip = FALSE;
2341 	      drop = FALSE;
2342 	      if ((size -= SFGENSIZE) < 0)
2343 		return (gerr (ErrCorr,
2344 		    _("Preset generator chunk size mismatch")));
2345 
2346 	      READW (genid, fd);
2347 
2348 	      if (genid == Gen_KeyRange)
2349 		{		/* nothing precedes */
2350 		  if (level == 0)
2351 		    {
2352 		      level = 1;
2353 		      READB (genval.range.lo, fd);
2354 		      READB (genval.range.hi, fd);
2355 		    }
2356 		  else
2357 		    skip = TRUE;
2358 		}
2359 	      else if (genid == Gen_VelRange)
2360 		{		/* only KeyRange precedes */
2361 		  if (level <= 1)
2362 		    {
2363 		      level = 2;
2364 		      READB (genval.range.lo, fd);
2365 		      READB (genval.range.hi, fd);
2366 		    }
2367 		  else
2368 		    skip = TRUE;
2369 		}
2370 	      else if (genid == Gen_Instrument)
2371 		{		/* inst is last gen */
2372 		  level = 3;
2373 		  READW (genval.uword, fd);
2374 		  ((SFZone *) (p2->data))->instsamp = GINT_TO_POINTER (genval.uword + 1);
2375 		  break;	/* break out of generator loop */
2376 		}
2377 	      else
2378 		{
2379 		  level = 2;
2380 		  if (gen_validp (genid))
2381 		    {		/* generator valid? */
2382 		      READW (genval.sword, fd);
2383 		      dup = gen_inlist (genid, z->gen);
2384 		    }
2385 		  else
2386 		    skip = TRUE;
2387 		}
2388 
2389 	      if (!skip)
2390 		{
2391 		  if (!dup)
2392 		    {		/* if gen ! dup alloc new */
2393 		      g = FLUID_NEW (SFGen);
2394 		      p3->data = g;
2395 		      g->id = genid;
2396 		    }
2397 		  else
2398 		    {
2399 		      g = (SFGen *) (dup->data);	/* ptr to orig gen */
2400 		      drop = TRUE;
2401 		    }
2402 		  g->amount = genval;
2403 		}
2404 	      else
2405 		{		/* Skip this generator */
2406 		  discarded = TRUE;
2407 		  drop = TRUE;
2408 		  FSKIPW (fd);
2409 		}
2410 
2411 	      if (!drop)
2412 		p3 = fluid_list_next (p3);	/* next gen */
2413 	      else
2414 		SLADVREM (z->gen, p3);	/* drop place holder */
2415 
2416 	    }			/* generator loop */
2417 
2418 	  if (level == 3)
2419 	    SLADVREM (z->gen, p3);	/* zone has inst? */
2420 	  else
2421 	    {			/* congratulations its a global zone */
2422 	      if (!gzone)
2423 		{		/* Prior global zones? */
2424 		  gzone = TRUE;
2425 
2426 		  /* if global zone is not 1st zone, relocate */
2427 		  if (*hz != p2)
2428 		    {
2429 		      void* save = p2->data;
2430 		      FLUID_LOG (FLUID_WARN,
2431 			_("Preset \"%s\": Global zone is not first zone"),
2432 			((SFPreset *) (p->data))->name);
2433 		      SLADVREM (*hz, p2);
2434 		      *hz = fluid_list_prepend (*hz, save);
2435 		      continue;
2436 		    }
2437 		}
2438 	      else
2439 		{		/* previous global zone exists, discard */
2440 		  FLUID_LOG (FLUID_WARN,
2441 		    _("Preset \"%s\": Discarding invalid global zone"),
2442 		    ((SFPreset *) (p->data))->name);
2443 		  sfont_zone_delete (sf, hz, (SFZone *) (p2->data));
2444 		}
2445 	    }
2446 
2447 	  while (p3)
2448 	    {			/* Kill any zones following an instrument */
2449 	      discarded = TRUE;
2450 	      if ((size -= SFGENSIZE) < 0)
2451 		return (gerr (ErrCorr,
2452 		    _("Preset generator chunk size mismatch")));
2453 	      FSKIP (SFGENSIZE, fd);
2454 	      SLADVREM (z->gen, p3);
2455 	    }
2456 
2457 	  p2 = fluid_list_next (p2);	/* next zone */
2458 	}
2459       if (discarded)
2460 	FLUID_LOG(FLUID_WARN,
2461 	  _("Preset \"%s\": Some invalid generators were discarded"),
2462 	  ((SFPreset *) (p->data))->name);
2463       p = fluid_list_next (p);
2464     }
2465 
2466   /* in case there isn't a terminal record */
2467   if (size == 0)
2468     return (OK);
2469 
2470   size -= SFGENSIZE;
2471   if (size != 0)
2472     return (gerr (ErrCorr, _("Preset generator chunk size mismatch")));
2473   FSKIP (SFGENSIZE, fd);	/* terminal gen */
2474 
2475   return (OK);
2476 }
2477 
2478 /* instrument header loader */
2479 static int
load_ihdr(int size,SFData * sf,FILE * fd)2480 load_ihdr (int size, SFData * sf, FILE * fd)
2481 {
2482   int i, i2;
2483   SFInst *p, *pr = NULL;	/* ptr to current & previous instrument */
2484   unsigned short zndx, pzndx = 0;
2485 
2486   if (size % SFIHDRSIZE || size == 0)	/* chunk size is valid? */
2487     return (gerr (ErrCorr, _("Instrument header has invalid size")));
2488 
2489   size = size / SFIHDRSIZE - 1;
2490   if (size == 0)
2491     {				/* at least one preset + term record */
2492       FLUID_LOG (FLUID_WARN, _("File contains no instruments"));
2493       FSKIP (SFIHDRSIZE, fd);
2494       return (OK);
2495     }
2496 
2497   for (i = 0; i < size; i++)
2498     {				/* load all instrument headers */
2499       p = FLUID_NEW (SFInst);
2500       sf->inst = fluid_list_append (sf->inst, p);
2501       p->zone = NULL;		/* For proper cleanup if fail (sfont_close) */
2502       READSTR (&p->name, fd);	/* Possible read failure ^ */
2503       READW (zndx, fd);
2504 
2505       if (pr)
2506 	{			/* not first instrument? */
2507 	  if (zndx < pzndx)
2508 	    return (gerr (ErrCorr,
2509 		_("Instrument header indices not monotonic")));
2510 	  i2 = zndx - pzndx;
2511 	  while (i2--)
2512 	    pr->zone = fluid_list_prepend (pr->zone, NULL);
2513 	}
2514       else if (zndx > 0)	/* 1st inst, warn if ofs >0 */
2515 	FLUID_LOG (FLUID_WARN, _("%d instrument zones not referenced, discarding"),
2516 	  zndx);
2517       pzndx = zndx;
2518       pr = p;			/* update instrument ptr */
2519     }
2520 
2521   FSKIP (20, fd);
2522   READW (zndx, fd);
2523 
2524   if (zndx < pzndx)
2525     return (gerr (ErrCorr, _("Instrument header indices not monotonic")));
2526   i2 = zndx - pzndx;
2527   while (i2--)
2528     pr->zone = fluid_list_prepend (pr->zone, NULL);
2529 
2530   return (OK);
2531 }
2532 
2533 /* instrument bag loader */
2534 static int
load_ibag(int size,SFData * sf,FILE * fd)2535 load_ibag (int size, SFData * sf, FILE * fd)
2536 {
2537   fluid_list_t *p, *p2;
2538   SFZone *z, *pz = NULL;
2539   unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0;
2540   int i;
2541 
2542   if (size % SFBAGSIZE || size == 0)	/* size is multiple of SFBAGSIZE? */
2543     return (gerr (ErrCorr, _("Instrument bag chunk size is invalid")));
2544 
2545   p = sf->inst;
2546   while (p)
2547     {				/* traverse through inst */
2548       p2 = ((SFInst *) (p->data))->zone;
2549       while (p2)
2550 	{			/* load this inst's zones */
2551 	  if ((size -= SFBAGSIZE) < 0)
2552 	    return (gerr (ErrCorr, _("Instrument bag chunk size mismatch")));
2553 	  z = FLUID_NEW (SFZone);
2554 	  p2->data = z;
2555 	  z->gen = NULL;	/* In case of failure, */
2556 	  z->mod = NULL;	/* sfont_close can clean up */
2557 	  READW (genndx, fd);	/* READW = possible read failure */
2558 	  READW (modndx, fd);
2559 	  z->instsamp = NULL;
2560 
2561 	  if (pz)
2562 	    {			/* if not first zone */
2563 	      if (genndx < pgenndx)
2564 		return (gerr (ErrCorr,
2565 		    _("Instrument generator indices not monotonic")));
2566 	      if (modndx < pmodndx)
2567 		return (gerr (ErrCorr,
2568 		    _("Instrument modulator indices not monotonic")));
2569 	      i = genndx - pgenndx;
2570 	      while (i--)
2571 		pz->gen = fluid_list_prepend (pz->gen, NULL);
2572 	      i = modndx - pmodndx;
2573 	      while (i--)
2574 		pz->mod = fluid_list_prepend (pz->mod, NULL);
2575 	    }
2576 	  pz = z;		/* update previous zone ptr */
2577 	  pgenndx = genndx;
2578 	  pmodndx = modndx;
2579 	  p2 = fluid_list_next (p2);
2580 	}
2581       p = fluid_list_next (p);
2582     }
2583 
2584   size -= SFBAGSIZE;
2585   if (size != 0)
2586     return (gerr (ErrCorr, _("Instrument chunk size mismatch")));
2587 
2588   READW (genndx, fd);
2589   READW (modndx, fd);
2590 
2591   if (!pz)
2592     {				/* in case that all are no zoners */
2593       if (genndx > 0)
2594 	FLUID_LOG (FLUID_WARN,
2595 	  _("No instrument generators and terminal index not 0"));
2596       if (modndx > 0)
2597 	FLUID_LOG (FLUID_WARN,
2598 	  _("No instrument modulators and terminal index not 0"));
2599       return (OK);
2600     }
2601 
2602   if (genndx < pgenndx)
2603     return (gerr (ErrCorr, _("Instrument generator indices not monotonic")));
2604   if (modndx < pmodndx)
2605     return (gerr (ErrCorr, _("Instrument modulator indices not monotonic")));
2606   i = genndx - pgenndx;
2607   while (i--)
2608     pz->gen = fluid_list_prepend (pz->gen, NULL);
2609   i = modndx - pmodndx;
2610   while (i--)
2611     pz->mod = fluid_list_prepend (pz->mod, NULL);
2612 
2613   return (OK);
2614 }
2615 
2616 /* instrument modulator loader */
2617 static int
load_imod(int size,SFData * sf,FILE * fd)2618 load_imod (int size, SFData * sf, FILE * fd)
2619 {
2620   fluid_list_t *p, *p2, *p3;
2621   SFMod *m;
2622 
2623   p = sf->inst;
2624   while (p)
2625     {				/* traverse through all inst */
2626       p2 = ((SFInst *) (p->data))->zone;
2627       while (p2)
2628 	{			/* traverse this inst's zones */
2629 	  p3 = ((SFZone *) (p2->data))->mod;
2630 	  while (p3)
2631 	    {			/* load zone's modulators */
2632 	      if ((size -= SFMODSIZE) < 0)
2633 		return (gerr (ErrCorr,
2634 		    _("Instrument modulator chunk size mismatch")));
2635 	      m = FLUID_NEW (SFMod);
2636 	      p3->data = m;
2637 	      READW (m->src, fd);
2638 	      READW (m->dest, fd);
2639 	      READW (m->amount, fd);
2640 	      READW (m->amtsrc, fd);
2641 	      READW (m->trans, fd);
2642 	      p3 = fluid_list_next (p3);
2643 	    }
2644 	  p2 = fluid_list_next (p2);
2645 	}
2646       p = fluid_list_next (p);
2647     }
2648 
2649   /*
2650      If there isn't even a terminal record
2651      Hmmm, the specs say there should be one, but..
2652    */
2653   if (size == 0)
2654     return (OK);
2655 
2656   size -= SFMODSIZE;
2657   if (size != 0)
2658     return (gerr (ErrCorr, _("Instrument modulator chunk size mismatch")));
2659   FSKIP (SFMODSIZE, fd);	/* terminal mod */
2660 
2661   return (OK);
2662 }
2663 
2664 /* load instrument generators (see load_pgen for loading rules) */
2665 static int
load_igen(int size,SFData * sf,FILE * fd)2666 load_igen (int size, SFData * sf, FILE * fd)
2667 {
2668   fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
2669   SFZone *z;
2670   SFGen *g;
2671   SFGenAmount genval;
2672   unsigned short genid;
2673   int level, skip, drop, gzone, discarded;
2674 
2675   p = sf->inst;
2676   while (p)
2677     {				/* traverse through all instruments */
2678       gzone = FALSE;
2679       discarded = FALSE;
2680       p2 = ((SFInst *) (p->data))->zone;
2681       if (p2)
2682 	hz = &p2;
2683       while (p2)
2684 	{			/* traverse this instrument's zones */
2685 	  level = 0;
2686 	  z = (SFZone *) (p2->data);
2687 	  p3 = z->gen;
2688 	  while (p3)
2689 	    {			/* load zone's generators */
2690 	      dup = NULL;
2691 	      skip = FALSE;
2692 	      drop = FALSE;
2693 	      if ((size -= SFGENSIZE) < 0)
2694 		return (gerr (ErrCorr, _("IGEN chunk size mismatch")));
2695 
2696 	      READW (genid, fd);
2697 
2698 	      if (genid == Gen_KeyRange)
2699 		{		/* nothing precedes */
2700 		  if (level == 0)
2701 		    {
2702 		      level = 1;
2703 		      READB (genval.range.lo, fd);
2704 		      READB (genval.range.hi, fd);
2705 		    }
2706 		  else
2707 		    skip = TRUE;
2708 		}
2709 	      else if (genid == Gen_VelRange)
2710 		{		/* only KeyRange precedes */
2711 		  if (level <= 1)
2712 		    {
2713 		      level = 2;
2714 		      READB (genval.range.lo, fd);
2715 		      READB (genval.range.hi, fd);
2716 		    }
2717 		  else
2718 		    skip = TRUE;
2719 		}
2720 	      else if (genid == Gen_SampleId)
2721 		{		/* sample is last gen */
2722 		  level = 3;
2723 		  READW (genval.uword, fd);
2724 		  ((SFZone *) (p2->data))->instsamp = GINT_TO_POINTER (genval.uword + 1);
2725 		  break;	/* break out of generator loop */
2726 		}
2727 	      else
2728 		{
2729 		  level = 2;
2730 		  if (gen_valid (genid))
2731 		    {		/* gen valid? */
2732 		      READW (genval.sword, fd);
2733 		      dup = gen_inlist (genid, z->gen);
2734 		    }
2735 		  else
2736 		    skip = TRUE;
2737 		}
2738 
2739 	      if (!skip)
2740 		{
2741 		  if (!dup)
2742 		    {		/* if gen ! dup alloc new */
2743 		      g = FLUID_NEW (SFGen);
2744 		      p3->data = g;
2745 		      g->id = genid;
2746 		    }
2747 		  else
2748 		    {
2749 		      g = (SFGen *) (dup->data);
2750 		      drop = TRUE;
2751 		    }
2752 		  g->amount = genval;
2753 		}
2754 	      else
2755 		{		/* skip this generator */
2756 		  discarded = TRUE;
2757 		  drop = TRUE;
2758 		  FSKIPW (fd);
2759 		}
2760 
2761 	      if (!drop)
2762 		p3 = fluid_list_next (p3);	/* next gen */
2763 	      else
2764 		SLADVREM (z->gen, p3);
2765 
2766 	    }			/* generator loop */
2767 
2768 	  if (level == 3)
2769 	    SLADVREM (z->gen, p3);	/* zone has sample? */
2770 	  else
2771 	    {			/* its a global zone */
2772 	      if (!gzone)
2773 		{
2774 		  gzone = TRUE;
2775 
2776 		  /* if global zone is not 1st zone, relocate */
2777 		  if (*hz != p2)
2778 		    {
2779 		      void* save = p2->data;
2780 		      FLUID_LOG (FLUID_WARN,
2781 			_("Instrument \"%s\": Global zone is not first zone"),
2782 			((SFPreset *) (p->data))->name);
2783 		      SLADVREM (*hz, p2);
2784 		      *hz = fluid_list_prepend (*hz, save);
2785 		      continue;
2786 		    }
2787 		}
2788 	      else
2789 		{		/* previous global zone exists, discard */
2790 		  FLUID_LOG (FLUID_WARN,
2791 		    _("Instrument \"%s\": Discarding invalid global zone"),
2792 		    ((SFInst *) (p->data))->name);
2793 		  sfont_zone_delete (sf, hz, (SFZone *) (p2->data));
2794 		}
2795 	    }
2796 
2797 	  while (p3)
2798 	    {			/* Kill any zones following a sample */
2799 	      discarded = TRUE;
2800 	      if ((size -= SFGENSIZE) < 0)
2801 		return (gerr (ErrCorr,
2802 		    _("Instrument generator chunk size mismatch")));
2803 	      FSKIP (SFGENSIZE, fd);
2804 	      SLADVREM (z->gen, p3);
2805 	    }
2806 
2807 	  p2 = fluid_list_next (p2);	/* next zone */
2808 	}
2809       if (discarded)
2810 	FLUID_LOG(FLUID_WARN,
2811 	  _("Instrument \"%s\": Some invalid generators were discarded"),
2812 	  ((SFInst *) (p->data))->name);
2813       p = fluid_list_next (p);
2814     }
2815 
2816   /* for those non-terminal record cases, grr! */
2817   if (size == 0)
2818     return (OK);
2819 
2820   size -= SFGENSIZE;
2821   if (size != 0)
2822     return (gerr (ErrCorr, _("IGEN chunk size mismatch")));
2823   FSKIP (SFGENSIZE, fd);	/* terminal gen */
2824 
2825   return (OK);
2826 }
2827 
2828 /* sample header loader */
2829 static int
load_shdr(unsigned int size,SFData * sf,FILE * fd)2830 load_shdr (unsigned int size, SFData * sf, FILE * fd)
2831 {
2832   unsigned int i;
2833   SFSample *p;
2834 
2835   if (size % SFSHDRSIZE || size == 0)	/* size is multiple of SHDR size? */
2836     return (gerr (ErrCorr, _("Sample header has invalid size")));
2837 
2838   size = size / SFSHDRSIZE - 1;
2839   if (size == 0)
2840     {				/* at least one sample + term record? */
2841       FLUID_LOG (FLUID_WARN, _("File contains no samples"));
2842       FSKIP (SFSHDRSIZE, fd);
2843       return (OK);
2844     }
2845 
2846   /* load all sample headers */
2847   for (i = 0; i < size; i++)
2848     {
2849       p = FLUID_NEW (SFSample);
2850       sf->sample = fluid_list_append (sf->sample, p);
2851       READSTR (&p->name, fd);
2852       READD (p->start, fd);
2853       READD (p->end, fd);	/* - end, loopstart and loopend */
2854       READD (p->loopstart, fd);	/* - will be checked and turned into */
2855       READD (p->loopend, fd);	/* - offsets in fixup_sample() */
2856       READD (p->samplerate, fd);
2857       READB (p->origpitch, fd);
2858       READB (p->pitchadj, fd);
2859       FSKIPW (fd);		/* skip sample link */
2860       READW (p->sampletype, fd);
2861       p->samfile = 0;
2862     }
2863 
2864   FSKIP (SFSHDRSIZE, fd);	/* skip terminal shdr */
2865 
2866   return (OK);
2867 }
2868 
2869 /* "fixup" (inst # -> inst ptr) instrument references in preset list */
2870 static int
fixup_pgen(SFData * sf)2871 fixup_pgen (SFData * sf)
2872 {
2873   fluid_list_t *p, *p2, *p3;
2874   SFZone *z;
2875   int i;
2876 
2877   p = sf->preset;
2878   while (p)
2879     {
2880       p2 = ((SFPreset *) (p->data))->zone;
2881       while (p2)
2882 	{			/* traverse this preset's zones */
2883 	  z = (SFZone *) (p2->data);
2884 	  if ((i = GPOINTER_TO_INT (z->instsamp)))
2885 	    {			/* load instrument # */
2886 	      p3 = fluid_list_nth (sf->inst, i - 1);
2887 	      if (!p3)
2888 		return (gerr (ErrCorr,
2889 		    _("Preset %03d %03d: Invalid instrument reference"),
2890 		    ((SFPreset *) (p->data))->bank,
2891 		    ((SFPreset *) (p->data))->prenum));
2892 	      z->instsamp = p3;
2893 	    }
2894 	  else
2895 	    z->instsamp = NULL;
2896 	  p2 = fluid_list_next (p2);
2897 	}
2898       p = fluid_list_next (p);
2899     }
2900 
2901   return (OK);
2902 }
2903 
2904 /* "fixup" (sample # -> sample ptr) sample references in instrument list */
2905 static int
fixup_igen(SFData * sf)2906 fixup_igen (SFData * sf)
2907 {
2908   fluid_list_t *p, *p2, *p3;
2909   SFZone *z;
2910   int i;
2911 
2912   p = sf->inst;
2913   while (p)
2914     {
2915       p2 = ((SFInst *) (p->data))->zone;
2916       while (p2)
2917 	{			/* traverse instrument's zones */
2918 	  z = (SFZone *) (p2->data);
2919 	  if ((i = GPOINTER_TO_INT (z->instsamp)))
2920 	    {			/* load sample # */
2921 	      p3 = fluid_list_nth (sf->sample, i - 1);
2922 	      if (!p3)
2923 		return (gerr (ErrCorr,
2924 		    _("Instrument \"%s\": Invalid sample reference"),
2925 		    ((SFInst *) (p->data))->name));
2926 	      z->instsamp = p3;
2927 	    }
2928 	  p2 = fluid_list_next (p2);
2929 	}
2930       p = fluid_list_next (p);
2931     }
2932 
2933   return (OK);
2934 }
2935 
2936 /* convert sample end, loopstart and loopend to offsets and check if valid */
2937 static int
fixup_sample(SFData * sf)2938 fixup_sample (SFData * sf)
2939 {
2940   fluid_list_t *p;
2941   SFSample *sam;
2942 
2943   p = sf->sample;
2944   while (p)
2945     {
2946       sam = (SFSample *) (p->data);
2947 
2948       /* if sample is not a ROM sample and end is over the sample data chunk
2949          or sam start is greater than 4 less than the end (at least 4 samples) */
2950       if ((!(sam->sampletype & FLUID_SAMPLETYPE_ROM)
2951 	  && sam->end > sdtachunk_size) || sam->start > (sam->end - 4))
2952 	{
2953 	  FLUID_LOG (FLUID_WARN, _("Sample '%s' start/end file positions are invalid,"
2954 	      " disabling and will not be saved"), sam->name);
2955 
2956 	  /* disable sample by setting all sample markers to 0 */
2957 	  sam->start = sam->end = sam->loopstart = sam->loopend = 0;
2958 
2959 	  return (OK);
2960 	}
2961       else if (sam->loopend > sam->end || sam->loopstart >= sam->loopend
2962 	|| sam->loopstart <= sam->start)
2963 	{			/* loop is fowled?? (cluck cluck :) */
2964 	  /* can pad loop by 8 samples and ensure at least 4 for loop (2*8+4) */
2965 	  if ((sam->end - sam->start) >= 20)
2966 	    {
2967 	      sam->loopstart = sam->start + 8;
2968 	      sam->loopend = sam->end - 8;
2969 	    }
2970 	  else
2971 	    {			/* loop is fowled, sample is tiny (can't pad 8 samples) */
2972 	      sam->loopstart = sam->start + 1;
2973 	      sam->loopend = sam->end - 1;
2974 	    }
2975 	}
2976 
2977       /* convert sample end, loopstart, loopend to offsets from sam->start */
2978       sam->end -= sam->start + 1;	/* marks last sample, contrary to SF spec. */
2979       sam->loopstart -= sam->start;
2980       sam->loopend -= sam->start;
2981 
2982       p = fluid_list_next (p);
2983     }
2984 
2985   return (OK);
2986 }
2987 
2988 /*=================================sfont.c========================
2989   Smurf SoundFont Editor
2990   ================================================================*/
2991 
2992 
2993 /* optimum chunk area sizes (could be more optimum) */
2994 #define PRESET_CHUNK_OPTIMUM_AREA	256
2995 #define INST_CHUNK_OPTIMUM_AREA		256
2996 #define SAMPLE_CHUNK_OPTIMUM_AREA	256
2997 #define ZONE_CHUNK_OPTIMUM_AREA		256
2998 #define MOD_CHUNK_OPTIMUM_AREA		256
2999 #define GEN_CHUNK_OPTIMUM_AREA		256
3000 
3001 unsigned short badgen[] = { Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4,
3002   Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0
3003 };
3004 
3005 unsigned short badpgen[] = { Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs,
3006   Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs,
3007   Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity,
3008   Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass,
3009   Gen_OverrideRootKey, 0
3010 };
3011 
3012 /* close SoundFont file and delete a SoundFont structure */
3013 void
sfont_close(SFData * sf)3014 sfont_close (SFData * sf)
3015 {
3016   fluid_list_t *p, *p2;
3017 
3018   if (sf->sffd)
3019     fclose (sf->sffd);
3020 
3021   if (sf->fname)
3022     free (sf->fname);
3023 
3024   p = sf->info;
3025   while (p)
3026     {
3027       free (p->data);
3028       p = fluid_list_next (p);
3029     }
3030   delete_fluid_list(sf->info);
3031   sf->info = NULL;
3032 
3033   p = sf->preset;
3034   while (p)
3035     {				/* loop over presets */
3036       p2 = ((SFPreset *) (p->data))->zone;
3037       while (p2)
3038 	{			/* loop over preset's zones */
3039 	  sfont_free_zone (p2->data);
3040 	  p2 = fluid_list_next (p2);
3041 	}			/* free preset's zone list */
3042       delete_fluid_list (((SFPreset *) (p->data))->zone);
3043       FLUID_FREE (p->data);	/* free preset chunk */
3044       p = fluid_list_next (p);
3045     }
3046   delete_fluid_list (sf->preset);
3047   sf->preset = NULL;
3048 
3049   p = sf->inst;
3050   while (p)
3051     {				/* loop over instruments */
3052       p2 = ((SFInst *) (p->data))->zone;
3053       while (p2)
3054 	{			/* loop over inst's zones */
3055 	  sfont_free_zone (p2->data);
3056 	  p2 = fluid_list_next (p2);
3057 	}			/* free inst's zone list */
3058       delete_fluid_list (((SFInst *) (p->data))->zone);
3059       FLUID_FREE (p->data);
3060       p = fluid_list_next (p);
3061     }
3062   delete_fluid_list (sf->inst);
3063   sf->inst = NULL;
3064 
3065   p = sf->sample;
3066   while (p)
3067     {
3068       FLUID_FREE (p->data);
3069       p = fluid_list_next (p);
3070     }
3071   delete_fluid_list (sf->sample);
3072   sf->sample = NULL;
3073 
3074   FLUID_FREE (sf);
3075 }
3076 
3077 /* free all elements of a zone (Preset or Instrument) */
3078 void
sfont_free_zone(SFZone * zone)3079 sfont_free_zone (SFZone * zone)
3080 {
3081   fluid_list_t *p;
3082 
3083   if (!zone)
3084     return;
3085 
3086   p = zone->gen;
3087   while (p)
3088     {				/* Free gen chunks for this zone */
3089       if (p->data)
3090 	FLUID_FREE (p->data);
3091       p = fluid_list_next (p);
3092     }
3093   delete_fluid_list (zone->gen);	/* free genlist */
3094 
3095   p = zone->mod;
3096   while (p)
3097     {				/* Free mod chunks for this zone */
3098       if (p->data)
3099 	FLUID_FREE (p->data);
3100       p = fluid_list_next (p);
3101     }
3102   delete_fluid_list (zone->mod);	/* free modlist */
3103 
3104   FLUID_FREE (zone);	/* free zone chunk */
3105 }
3106 
3107 /* preset sort function, first by bank, then by preset # */
3108 int
sfont_preset_compare_func(void * a,void * b)3109 sfont_preset_compare_func (void* a, void* b)
3110 {
3111   int aval, bval;
3112 
3113   aval = (int) (((SFPreset *) a)->bank) << 16 | ((SFPreset *) a)->prenum;
3114   bval = (int) (((SFPreset *) b)->bank) << 16 | ((SFPreset *) b)->prenum;
3115 
3116   return (aval - bval);
3117 }
3118 
3119 /* delete zone from zone list */
3120 void
sfont_zone_delete(SFData * sf,fluid_list_t ** zlist,SFZone * zone)3121 sfont_zone_delete (SFData * sf, fluid_list_t ** zlist, SFZone * zone)
3122 {
3123   *zlist = fluid_list_remove (*zlist, (void*) zone);
3124   sfont_free_zone (zone);
3125 }
3126 
3127 /* Find generator in gen list */
3128 fluid_list_t *
gen_inlist(int gen,fluid_list_t * genlist)3129 gen_inlist (int gen, fluid_list_t * genlist)
3130 {				/* is generator in gen list? */
3131   fluid_list_t *p;
3132 
3133   p = genlist;
3134   while (p)
3135     {
3136       if (p->data == NULL)
3137 	return (NULL);
3138       if (gen == ((SFGen *) p->data)->id)
3139 	break;
3140       p = fluid_list_next (p);
3141     }
3142   return (p);
3143 }
3144 
3145 /* check validity of instrument generator */
3146 int
gen_valid(int gen)3147 gen_valid (int gen)
3148 {				/* is generator id valid? */
3149   int i = 0;
3150 
3151   if (gen > Gen_MaxValid)
3152     return (FALSE);
3153   while (badgen[i] && badgen[i] != gen)
3154     i++;
3155   return (badgen[i] == 0);
3156 }
3157 
3158 /* check validity of preset generator */
3159 int
gen_validp(int gen)3160 gen_validp (int gen)
3161 {				/* is preset generator valid? */
3162   int i = 0;
3163 
3164   if (!gen_valid (gen))
3165     return (FALSE);
3166   while (badpgen[i] && badpgen[i] != (unsigned short) gen)
3167     i++;
3168   return (badpgen[i] == 0);
3169 }
3170 
3171 /*================================util.c===========================*/
3172 
3173 /* Logging function, returns FAIL to use as a return value in calling funcs */
3174 int
gerr(int ev,char * fmt,...)3175 gerr (int ev, char * fmt, ...)
3176 {
3177   va_list args;
3178 
3179   va_start (args, fmt);
3180   vprintf(fmt, args);
3181   va_end (args);
3182 
3183   printf("\n");
3184 
3185   return (FAIL);
3186 }
3187 
3188 int
safe_fread(void * buf,int count,FILE * fd)3189 safe_fread (void *buf, int count, FILE * fd)
3190 {
3191   if (fread (buf, count, 1, fd) != 1)
3192     {				/* size_t = count, nmemb = 1 */
3193       if (feof (fd))
3194 	gerr (ErrEof, _("EOF while attemping to read %d bytes"), count);
3195       else
3196 	FLUID_LOG (FLUID_ERR, _("File read failed"));
3197       return (FAIL);
3198     }
3199   return (OK);
3200 }
3201 
3202 int
safe_fseek(FILE * fd,long ofs,int whence)3203 safe_fseek (FILE * fd, long ofs, int whence)
3204 {
3205   if (fseek (fd, ofs, whence) == -1) {
3206     FLUID_LOG (FLUID_ERR, _("File seek failed with offset = %ld and whence = %d"), ofs, whence);
3207     return (FAIL);
3208   }
3209   return (OK);
3210 }
3211