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