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