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