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