Update Fluidsynth to v2.0.3
[ardour.git] / libs / fluidsynth / src / fluid_sffile.c
1 /* FluidSynth - A Software Synthesizer
2  *
3  * Copyright (C) 2003  Peter Hanappe and others.
4  *
5  * SoundFont file loading code borrowed from Smurf SoundFont Editor
6  * Copyright (C) 1999-2001 Josh Green
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 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  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301, USA
22  */
23
24
25 #include "fluid_sffile.h"
26 #include "fluid_sfont.h"
27 #include "fluid_sys.h"
28
29 #if LIBSNDFILE_SUPPORT
30 #include <sndfile.h>
31 #endif
32
33 /*=================================sfload.c========================
34   Borrowed from Smurf SoundFont Editor by Josh Green
35   =================================================================*/
36
37 /* FOURCC definitions */
38 #define RIFF_FCC    FLUID_FOURCC('R','I','F','F')
39 #define LIST_FCC    FLUID_FOURCC('L','I','S','T')
40 #define SFBK_FCC    FLUID_FOURCC('s','f','b','k')
41 #define INFO_FCC    FLUID_FOURCC('I','N','F','O')
42 #define SDTA_FCC    FLUID_FOURCC('s','d','t','a')
43 #define PDTA_FCC    FLUID_FOURCC('p','d','t','a') /* info/sample/preset */
44
45 #define IFIL_FCC    FLUID_FOURCC('i','f','i','l')
46 #define ISNG_FCC    FLUID_FOURCC('i','s','n','g')
47 #define INAM_FCC    FLUID_FOURCC('I','N','A','M')
48 #define IROM_FCC    FLUID_FOURCC('i','r','o','m') /* info ids (1st byte of info strings) */
49 #define IVER_FCC    FLUID_FOURCC('i','v','e','r')
50 #define ICRD_FCC    FLUID_FOURCC('I','C','R','D')
51 #define IENG_FCC    FLUID_FOURCC('I','E','N','G')
52 #define IPRD_FCC    FLUID_FOURCC('I','P','R','D') /* more info ids */
53 #define ICOP_FCC    FLUID_FOURCC('I','C','O','P')
54 #define ICMT_FCC    FLUID_FOURCC('I','C','M','T')
55 #define ISFT_FCC    FLUID_FOURCC('I','S','F','T') /* and yet more info ids */
56
57 #define SNAM_FCC    FLUID_FOURCC('s','n','a','m')
58 #define SMPL_FCC    FLUID_FOURCC('s','m','p','l') /* sample ids */
59 #define PHDR_FCC    FLUID_FOURCC('p','h','d','r')
60 #define PBAG_FCC    FLUID_FOURCC('p','b','a','g')
61 #define PMOD_FCC    FLUID_FOURCC('p','m','o','d')
62 #define PGEN_FCC    FLUID_FOURCC('p','g','e','n') /* preset ids */
63 #define IHDR_FCC    FLUID_FOURCC('i','n','s','t')
64 #define IBAG_FCC    FLUID_FOURCC('i','b','a','g')
65 #define IMOD_FCC    FLUID_FOURCC('i','m','o','d')
66 #define IGEN_FCC    FLUID_FOURCC('i','g','e','n') /* instrument ids */
67 #define SHDR_FCC    FLUID_FOURCC('s','h','d','r') /* sample info */
68 #define SM24_FCC    FLUID_FOURCC('s','m','2','4')
69
70 /* Set when the FCC code is unknown */
71 #define UNKN_ID     FLUID_N_ELEMENTS(idlist)
72
73 /*
74  * This declares a uint32_t array containing the SF2 chunk identifiers.
75  */
76 static const uint32_t idlist[] =
77 {
78     RIFF_FCC,
79     LIST_FCC,
80     SFBK_FCC,
81     INFO_FCC,
82     SDTA_FCC,
83     PDTA_FCC,
84
85     IFIL_FCC,
86     ISNG_FCC,
87     INAM_FCC,
88     IROM_FCC,
89     IVER_FCC,
90     ICRD_FCC,
91     IENG_FCC,
92     IPRD_FCC,
93     ICOP_FCC,
94     ICMT_FCC,
95     ISFT_FCC,
96
97     SNAM_FCC,
98     SMPL_FCC,
99     PHDR_FCC,
100     PBAG_FCC,
101     PMOD_FCC,
102     PGEN_FCC,
103     IHDR_FCC,
104     IBAG_FCC,
105     IMOD_FCC,
106     IGEN_FCC,
107     SHDR_FCC,
108     SM24_FCC
109 };
110
111 /* generator types */
112 typedef enum
113 {
114     Gen_StartAddrOfs,
115     Gen_EndAddrOfs,
116     Gen_StartLoopAddrOfs,
117     Gen_EndLoopAddrOfs,
118     Gen_StartAddrCoarseOfs,
119     Gen_ModLFO2Pitch,
120     Gen_VibLFO2Pitch,
121     Gen_ModEnv2Pitch,
122     Gen_FilterFc,
123     Gen_FilterQ,
124     Gen_ModLFO2FilterFc,
125     Gen_ModEnv2FilterFc,
126     Gen_EndAddrCoarseOfs,
127     Gen_ModLFO2Vol,
128     Gen_Unused1,
129     Gen_ChorusSend,
130     Gen_ReverbSend,
131     Gen_Pan,
132     Gen_Unused2,
133     Gen_Unused3,
134     Gen_Unused4,
135     Gen_ModLFODelay,
136     Gen_ModLFOFreq,
137     Gen_VibLFODelay,
138     Gen_VibLFOFreq,
139     Gen_ModEnvDelay,
140     Gen_ModEnvAttack,
141     Gen_ModEnvHold,
142     Gen_ModEnvDecay,
143     Gen_ModEnvSustain,
144     Gen_ModEnvRelease,
145     Gen_Key2ModEnvHold,
146     Gen_Key2ModEnvDecay,
147     Gen_VolEnvDelay,
148     Gen_VolEnvAttack,
149     Gen_VolEnvHold,
150     Gen_VolEnvDecay,
151     Gen_VolEnvSustain,
152     Gen_VolEnvRelease,
153     Gen_Key2VolEnvHold,
154     Gen_Key2VolEnvDecay,
155     Gen_Instrument,
156     Gen_Reserved1,
157     Gen_KeyRange,
158     Gen_VelRange,
159     Gen_StartLoopAddrCoarseOfs,
160     Gen_Keynum,
161     Gen_Velocity,
162     Gen_Attenuation,
163     Gen_Reserved2,
164     Gen_EndLoopAddrCoarseOfs,
165     Gen_CoarseTune,
166     Gen_FineTune,
167     Gen_SampleId,
168     Gen_SampleModes,
169     Gen_Reserved3,
170     Gen_ScaleTune,
171     Gen_ExclusiveClass,
172     Gen_OverrideRootKey,
173     Gen_Dummy
174 } Gen_Type;
175
176 #define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */
177 #define Gen_Count Gen_Dummy /* count of generators */
178 #define GenArrSize sizeof(SFGenAmount) * Gen_Count /* gen array size */
179
180
181 static const unsigned short invalid_inst_gen[] =
182 {
183     Gen_Unused1,
184     Gen_Unused2,
185     Gen_Unused3,
186     Gen_Unused4,
187     Gen_Reserved1,
188     Gen_Reserved2,
189     Gen_Reserved3,
190     0
191 };
192
193 static const unsigned short invalid_preset_gen[] =
194 {
195     Gen_StartAddrOfs,
196     Gen_EndAddrOfs,
197     Gen_StartLoopAddrOfs,
198     Gen_EndLoopAddrOfs,
199     Gen_StartAddrCoarseOfs,
200     Gen_EndAddrCoarseOfs,
201     Gen_StartLoopAddrCoarseOfs,
202     Gen_Keynum,
203     Gen_Velocity,
204     Gen_EndLoopAddrCoarseOfs,
205     Gen_SampleModes,
206     Gen_ExclusiveClass,
207     Gen_OverrideRootKey,
208     0
209 };
210
211
212 /* sfont file chunk sizes */
213 #define SF_PHDR_SIZE (38)
214 #define SF_BAG_SIZE  (4)
215 #define SF_MOD_SIZE  (10)
216 #define SF_GEN_SIZE  (4)
217 #define SF_IHDR_SIZE (22)
218 #define SF_SHDR_SIZE (46)
219
220
221 #define READCHUNK(sf, var)                                                  \
222     do                                                                      \
223     {                                                                       \
224         if (sf->fcbs->fread(var, 8, sf->sffd) == FLUID_FAILED)              \
225             return FALSE;                                                   \
226         ((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \
227     } while (0)
228
229 #define READD(sf, var)                                            \
230     do                                                            \
231     {                                                             \
232         uint32_t _temp;                                           \
233         if (sf->fcbs->fread(&_temp, 4, sf->sffd) == FLUID_FAILED) \
234             return FALSE;                                         \
235         var = FLUID_LE32TOH(_temp);                               \
236     } while (0)
237
238 #define READW(sf, var)                                            \
239     do                                                            \
240     {                                                             \
241         uint16_t _temp;                                           \
242         if (sf->fcbs->fread(&_temp, 2, sf->sffd) == FLUID_FAILED) \
243             return FALSE;                                         \
244         var = FLUID_LE16TOH(_temp);                               \
245     } while (0)
246
247 #define READID(sf, var)                                        \
248     do                                                         \
249     {                                                          \
250         if (sf->fcbs->fread(var, 4, sf->sffd) == FLUID_FAILED) \
251             return FALSE;                                      \
252     } while (0)
253
254 #define READSTR(sf, var)                                        \
255     do                                                          \
256     {                                                           \
257         if (sf->fcbs->fread(var, 20, sf->sffd) == FLUID_FAILED) \
258             return FALSE;                                       \
259         (*var)[20] = '\0';                                      \
260     } while (0)
261
262 #define READB(sf, var)                                          \
263     do                                                          \
264     {                                                           \
265         if (sf->fcbs->fread(&var, 1, sf->sffd) == FLUID_FAILED) \
266             return FALSE;                                       \
267     } while (0)
268
269 #define FSKIP(sf, size)                                                \
270     do                                                                 \
271     {                                                                  \
272         if (sf->fcbs->fseek(sf->sffd, size, SEEK_CUR) == FLUID_FAILED) \
273             return FALSE;                                              \
274     } while (0)
275
276 #define FSKIPW(sf)                                                  \
277     do                                                              \
278     {                                                               \
279         if (sf->fcbs->fseek(sf->sffd, 2, SEEK_CUR) == FLUID_FAILED) \
280             return FALSE;                                           \
281     } while (0)
282
283 /* removes and advances a fluid_list_t pointer */
284 #define SLADVREM(list, item)                        \
285     do                                              \
286     {                                               \
287         fluid_list_t *_temp = item;                 \
288         item = fluid_list_next(item);               \
289         list = fluid_list_remove_link(list, _temp); \
290         delete1_fluid_list(_temp);                  \
291     } while (0)
292
293
294 static int load_header(SFData *sf);
295 static int load_body(SFData *sf);
296 static int process_info(SFData *sf, int size);
297 static int process_sdta(SFData *sf, unsigned int size);
298 static int process_pdta(SFData *sf, int size);
299 static int load_phdr(SFData *sf, int size);
300 static int load_pbag(SFData *sf, int size);
301 static int load_pmod(SFData *sf, int size);
302 static int load_pgen(SFData *sf, int size);
303 static int load_ihdr(SFData *sf, int size);
304 static int load_ibag(SFData *sf, int size);
305 static int load_imod(SFData *sf, int size);
306 static int load_igen(SFData *sf, int size);
307 static int load_shdr(SFData *sf, unsigned int size);
308 static int fixup_pgen(SFData *sf);
309 static int fixup_igen(SFData *sf);
310
311 static int chunkid(uint32_t id);
312 static int read_listchunk(SFData *sf, SFChunk *chunk);
313 static int pdtahelper(SFData *sf, unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size);
314 static int preset_compare_func(void *a, void *b);
315 static fluid_list_t *find_gen_by_id(int gen, fluid_list_t *genlist);
316 static int valid_inst_genid(unsigned short genid);
317 static int valid_preset_genid(unsigned short genid);
318
319
320 static void delete_preset(SFPreset *preset);
321 static void delete_inst(SFInst *inst);
322 static void delete_zone(SFZone *zone);
323
324 static int fluid_sffile_read_vorbis(SFData *sf, unsigned int start_byte, unsigned int end_byte, short **data);
325 static int fluid_sffile_read_wav(SFData *sf, unsigned int start, unsigned int end, short **data, char **data24);
326
327 /**
328  * Check if a file is a SoundFont file.
329  * @param filename Path to the file to check
330  * @return TRUE if it could be a SoundFont, FALSE otherwise
331  *
332  * @note The current implementation only checks for the "RIFF" and "sfbk" headers in
333  * the file. It is useful to distinguish between SoundFont and other (e.g. MIDI) files.
334  */
335 int fluid_is_soundfont(const char *filename)
336 {
337     FILE    *fp = FLUID_FOPEN(filename, "rb");
338     uint32_t fcc;
339     int      retcode = FALSE;
340
341     do
342     {
343         if(fp == NULL)
344         {
345             return retcode;
346         }
347
348         if(FLUID_FREAD(&fcc, sizeof(fcc), 1, fp) != 1)
349         {
350             break;
351         }
352
353         if(fcc != RIFF_FCC)
354         {
355             break;
356         }
357
358         if(FLUID_FSEEK(fp, 4, SEEK_CUR))
359         {
360             break;
361         }
362
363         if(FLUID_FREAD(&fcc, sizeof(fcc), 1, fp) != 1)
364         {
365             break;
366         }
367
368         retcode = (fcc == SFBK_FCC);
369     }
370     while(0);
371
372     FLUID_FCLOSE(fp);
373
374     return retcode;
375 }
376
377 /*
378  * Open a SoundFont file and parse it's contents into a SFData structure.
379  *
380  * @param fname filename
381  * @param fcbs file callback structure
382  * @return the partially parsed SoundFont as SFData structure or NULL on error
383  */
384 SFData *fluid_sffile_open(const char *fname, const fluid_file_callbacks_t *fcbs)
385 {
386     SFData *sf;
387     int fsize = 0;
388
389     if(!(sf = FLUID_NEW(SFData)))
390     {
391         FLUID_LOG(FLUID_ERR, "Out of memory");
392         return NULL;
393     }
394
395     FLUID_MEMSET(sf, 0, sizeof(SFData));
396
397     sf->fcbs = fcbs;
398
399     if((sf->sffd = fcbs->fopen(fname)) == NULL)
400     {
401         FLUID_LOG(FLUID_ERR, "Unable to open file '%s'", fname);
402         goto error_exit;
403     }
404
405     sf->fname = FLUID_STRDUP(fname);
406
407     if(sf->fname == NULL)
408     {
409         FLUID_LOG(FLUID_ERR, "Out of memory");
410         goto error_exit;
411     }
412
413     /* get size of file by seeking to end */
414     if(fcbs->fseek(sf->sffd, 0L, SEEK_END) == FLUID_FAILED)
415     {
416         FLUID_LOG(FLUID_ERR, "Seek to end of file failed");
417         goto error_exit;
418     }
419
420     if((fsize = fcbs->ftell(sf->sffd)) == FLUID_FAILED)
421     {
422         FLUID_LOG(FLUID_ERR, "Get end of file position failed");
423         goto error_exit;
424     }
425
426     sf->filesize = fsize;
427
428     if(fcbs->fseek(sf->sffd, 0, SEEK_SET) == FLUID_FAILED)
429     {
430         FLUID_LOG(FLUID_ERR, "Rewind to start of file failed");
431         goto error_exit;
432     }
433
434     if(!load_header(sf))
435     {
436         goto error_exit;
437     }
438
439     return sf;
440
441 error_exit:
442     fluid_sffile_close(sf);
443     return NULL;
444 }
445
446 /*
447  * Parse all preset information from the soundfont
448  *
449  * @return FLUID_OK on success, otherwise FLUID_FAILED
450  */
451 int fluid_sffile_parse_presets(SFData *sf)
452 {
453     if(!load_body(sf))
454     {
455         return FLUID_FAILED;
456     }
457
458     return FLUID_OK;
459 }
460
461 /* Load sample data from the soundfont file
462  *
463  * This function will always return the sample data in WAV format. If the sample_type specifies an
464  * Ogg Vorbis compressed sample, it will be decompressed automatically before returning.
465  *
466  * @param sf SFData instance
467  * @param sample_start index of first sample point in Soundfont sample chunk
468  * @param sample_end index of last sample point in Soundfont sample chunk
469  * @param sample_type type of the sample in Soundfont
470  * @param data pointer to sample data pointer, will point to loaded sample data on success
471  * @param data24 pointer to 24-bit sample data pointer if 24-bit data present, will point to loaded
472  *               24-bit sample data on success or NULL if no 24-bit data is present in file
473  *
474  * @return The number of sample words in returned buffers or -1 on failure
475  */
476 int fluid_sffile_read_sample_data(SFData *sf, unsigned int sample_start, unsigned int sample_end,
477                                   int sample_type, short **data, char **data24)
478 {
479     int num_samples;
480
481     if(sample_type & FLUID_SAMPLETYPE_OGG_VORBIS)
482     {
483         num_samples = fluid_sffile_read_vorbis(sf, sample_start, sample_end, data);
484     }
485     else
486     {
487         num_samples = fluid_sffile_read_wav(sf, sample_start, sample_end, data, data24);
488     }
489
490     return num_samples;
491 }
492
493 /*
494  * Close a SoundFont file and free the SFData structure.
495  *
496  * @param sf pointer to SFData structure
497  * @param fcbs file callback structure
498  */
499 void fluid_sffile_close(SFData *sf)
500 {
501     fluid_list_t *entry;
502     SFPreset *preset;
503     SFInst *inst;
504
505     if(sf->sffd)
506     {
507         sf->fcbs->fclose(sf->sffd);
508     }
509
510     FLUID_FREE(sf->fname);
511
512     entry = sf->info;
513
514     while(entry)
515     {
516         FLUID_FREE(fluid_list_get(entry));
517         entry = fluid_list_next(entry);
518     }
519
520     delete_fluid_list(sf->info);
521
522     entry = sf->preset;
523
524     while(entry)
525     {
526         preset = (SFPreset *)fluid_list_get(entry);
527         delete_preset(preset);
528         entry = fluid_list_next(entry);
529     }
530
531     delete_fluid_list(sf->preset);
532
533     entry = sf->inst;
534
535     while(entry)
536     {
537         inst = (SFInst *)fluid_list_get(entry);
538         delete_inst(inst);
539         entry = fluid_list_next(entry);
540     }
541
542     delete_fluid_list(sf->inst);
543
544     entry = sf->sample;
545
546     while(entry)
547     {
548         FLUID_FREE(fluid_list_get(entry));
549         entry = fluid_list_next(entry);
550     }
551
552     delete_fluid_list(sf->sample);
553
554     FLUID_FREE(sf);
555 }
556
557
558 /*
559  * Private functions
560  */
561
562 /* sound font file load functions */
563 static int chunkid(uint32_t id)
564 {
565     unsigned int i;
566
567     for(i = 0; i < FLUID_N_ELEMENTS(idlist); i++)
568     {
569         if(idlist[i] == id)
570         {
571             break;
572         }
573     }
574
575     /* Return chunk id or UNKN_ID if not found */
576     return i;
577 }
578
579 static int load_header(SFData *sf)
580 {
581     SFChunk chunk;
582
583     READCHUNK(sf, &chunk); /* load RIFF chunk */
584
585     if(chunk.id != RIFF_FCC)
586     {
587         /* error if not RIFF */
588         FLUID_LOG(FLUID_ERR, "Not a RIFF file");
589         return FALSE;
590     }
591
592     READID(sf, &chunk.id); /* load file ID */
593
594     if(chunk.id != SFBK_FCC)
595     {
596         /* error if not SFBK_ID */
597         FLUID_LOG(FLUID_ERR, "Not a SoundFont file");
598         return FALSE;
599     }
600
601     if(chunk.size != sf->filesize - 8)
602     {
603         FLUID_LOG(FLUID_ERR, "SoundFont file size mismatch");
604         return FALSE;
605     }
606
607     /* Process INFO block */
608     if(!read_listchunk(sf, &chunk))
609     {
610         return FALSE;
611     }
612
613     if(chunk.id != INFO_FCC)
614     {
615         FLUID_LOG(FLUID_ERR, "Invalid ID found when expecting INFO chunk");
616         return FALSE;
617     }
618
619     if(!process_info(sf, chunk.size))
620     {
621         return FALSE;
622     }
623
624     /* Process sample chunk */
625     if(!read_listchunk(sf, &chunk))
626     {
627         return FALSE;
628     }
629
630     if(chunk.id != SDTA_FCC)
631     {
632         FLUID_LOG(FLUID_ERR, "Invalid ID found when expecting SAMPLE chunk");
633         return FALSE;
634     }
635
636     if(!process_sdta(sf, chunk.size))
637     {
638         return FALSE;
639     }
640
641     /* process HYDRA chunk */
642     if(!read_listchunk(sf, &chunk))
643     {
644         return FALSE;
645     }
646
647     if(chunk.id != PDTA_FCC)
648     {
649         FLUID_LOG(FLUID_ERR, "Invalid ID found when expecting HYDRA chunk");
650         return FALSE;
651     }
652
653     sf->hydrapos = sf->fcbs->ftell(sf->sffd);
654     sf->hydrasize = chunk.size;
655
656     return TRUE;
657 }
658
659 static int load_body(SFData *sf)
660 {
661     if(sf->fcbs->fseek(sf->sffd, sf->hydrapos, SEEK_SET) == FLUID_FAILED)
662     {
663         FLUID_LOG(FLUID_ERR, "Failed to seek to HYDRA position");
664         return FALSE;
665     }
666
667     if(!process_pdta(sf, sf->hydrasize))
668     {
669         return FALSE;
670     }
671
672     if(!fixup_pgen(sf))
673     {
674         return FALSE;
675     }
676
677     if(!fixup_igen(sf))
678     {
679         return FALSE;
680     }
681
682     /* sort preset list by bank, preset # */
683     sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)preset_compare_func);
684
685     return TRUE;
686 }
687
688 static int read_listchunk(SFData *sf, SFChunk *chunk)
689 {
690     READCHUNK(sf, chunk); /* read list chunk */
691
692     if(chunk->id != LIST_FCC)  /* error if ! list chunk */
693     {
694         FLUID_LOG(FLUID_ERR, "Invalid chunk id in level 0 parse");
695         return FALSE;
696     }
697
698     READID(sf, &chunk->id); /* read id string */
699     chunk->size -= 4;
700     return TRUE;
701 }
702
703 static int process_info(SFData *sf, int size)
704 {
705     SFChunk chunk;
706     union
707     {
708         char *chr;
709         uint32_t *fcc;
710     } item;
711     unsigned short ver;
712
713     while(size > 0)
714     {
715         READCHUNK(sf, &chunk);
716         size -= 8;
717
718         if(chunk.id == IFIL_FCC)
719         {
720             /* sound font version chunk? */
721             if(chunk.size != 4)
722             {
723                 FLUID_LOG(FLUID_ERR, "Sound font version info chunk has invalid size");
724                 return FALSE;
725             }
726
727             READW(sf, ver);
728             sf->version.major = ver;
729             READW(sf, ver);
730             sf->version.minor = ver;
731
732             if(sf->version.major < 2)
733             {
734                 FLUID_LOG(FLUID_ERR, "Sound font version is %d.%d which is not"
735                           " supported, convert to version 2.0x",
736                           sf->version.major, sf->version.minor);
737                 return FALSE;
738             }
739
740             if(sf->version.major == 3)
741             {
742 #if !LIBSNDFILE_SUPPORT
743                 FLUID_LOG(FLUID_WARN,
744                           "Sound font version is %d.%d but fluidsynth was compiled without"
745                           " support for (v3.x)",
746                           sf->version.major, sf->version.minor);
747                 return FALSE;
748 #endif
749             }
750             else if(sf->version.major > 2)
751             {
752                 FLUID_LOG(FLUID_WARN,
753                           "Sound font version is %d.%d which is newer than"
754                           " what this version of fluidsynth was designed for (v2.0x)",
755                           sf->version.major, sf->version.minor);
756                 return FALSE;
757             }
758         }
759         else if(chunk.id == IVER_FCC)
760         {
761             /* ROM version chunk? */
762             if(chunk.size != 4)
763             {
764                 FLUID_LOG(FLUID_ERR, "ROM version info chunk has invalid size");
765                 return FALSE;
766             }
767
768             READW(sf, ver);
769             sf->romver.major = ver;
770             READW(sf, ver);
771             sf->romver.minor = ver;
772         }
773         else if(chunkid(chunk.id) != UNKN_ID)
774         {
775             if((chunk.id != ICMT_FCC && chunk.size > 256) || (chunk.size > 65536) || (chunk.size % 2))
776             {
777                 FLUID_LOG(FLUID_ERR, "INFO sub chunk %.4s has invalid chunk size of %d bytes",
778                           &chunk.id, chunk.size);
779                 return FALSE;
780             }
781
782             /* alloc for chunk fcc and da chunk */
783             if(!(item.fcc = FLUID_MALLOC(chunk.size + sizeof(uint32_t) + 1)))
784             {
785                 FLUID_LOG(FLUID_ERR, "Out of memory");
786                 return FALSE;
787             }
788
789             /* attach to INFO list, fluid_sffile_close will cleanup if FAIL occurs */
790             sf->info = fluid_list_append(sf->info, item.fcc);
791
792             /* save chunk fcc and update pointer to data value */
793             *item.fcc++ = chunk.id;
794
795             if(sf->fcbs->fread(item.chr, chunk.size, sf->sffd) == FLUID_FAILED)
796             {
797                 return FALSE;
798             }
799
800             /* force terminate info item */
801             item.chr[chunk.size] = '\0';
802         }
803         else
804         {
805             FLUID_LOG(FLUID_ERR, "Invalid chunk id in INFO chunk");
806             return FALSE;
807         }
808
809         size -= chunk.size;
810     }
811
812     if(size < 0)
813     {
814         FLUID_LOG(FLUID_ERR, "INFO chunk size mismatch");
815         return FALSE;
816     }
817
818     return TRUE;
819 }
820
821 static int process_sdta(SFData *sf, unsigned int size)
822 {
823     SFChunk chunk;
824
825     if(size == 0)
826     {
827         return TRUE;    /* no sample data? */
828     }
829
830     /* read sub chunk */
831     READCHUNK(sf, &chunk);
832     size -= 8;
833
834     if(chunk.id != SMPL_FCC)
835     {
836         FLUID_LOG(FLUID_ERR, "Expected SMPL chunk found invalid id instead");
837         return FALSE;
838     }
839
840     /* SDTA chunk may also contain sm24 chunk for 24 bit samples
841      * (not yet supported), only an error if SMPL chunk size is
842      * greater than SDTA. */
843     if(chunk.size > size)
844     {
845         FLUID_LOG(FLUID_ERR, "SDTA chunk size mismatch");
846         return FALSE;
847     }
848
849     /* sample data follows */
850     sf->samplepos = sf->fcbs->ftell(sf->sffd);
851
852     /* used to check validity of sample headers */
853     sf->samplesize = chunk.size;
854
855     FSKIP(sf, chunk.size);
856     size -= chunk.size;
857
858     if(sf->version.major >= 2 && sf->version.minor >= 4)
859     {
860         /* any chance to find another chunk here? */
861         if(size > 8)
862         {
863             /* read sub chunk */
864             READCHUNK(sf, &chunk);
865             size -= 8;
866
867             if(chunk.id == SM24_FCC)
868             {
869                 int sm24size, sdtahalfsize;
870
871                 FLUID_LOG(FLUID_DBG, "Found SM24 chunk");
872
873                 if(chunk.size > size)
874                 {
875                     FLUID_LOG(FLUID_WARN, "SM24 exeeds SDTA chunk, ignoring SM24");
876                     goto ret; // no error
877                 }
878
879                 sdtahalfsize = sf->samplesize / 2;
880                 /* + 1 byte in the case that half the size of smpl chunk is an odd value */
881                 sdtahalfsize += sdtahalfsize % 2;
882                 sm24size = chunk.size;
883
884                 if(sdtahalfsize != sm24size)
885                 {
886                     FLUID_LOG(FLUID_WARN, "SM24 not equal to half the size of SMPL chunk (0x%X != "
887                               "0x%X), ignoring SM24",
888                               sm24size, sdtahalfsize);
889                     goto ret; // no error
890                 }
891
892                 /* sample data24 follows */
893                 sf->sample24pos = sf->fcbs->ftell(sf->sffd);
894                 sf->sample24size = sm24size;
895             }
896         }
897     }
898
899 ret:
900     FSKIP(sf, size);
901
902     return TRUE;
903 }
904
905 static int pdtahelper(SFData *sf, unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size)
906 {
907     READCHUNK(sf, chunk);
908     *size -= 8;
909
910     if(chunk->id != expid)
911     {
912         FLUID_LOG(FLUID_ERR, "Expected PDTA sub-chunk '%.4s' found invalid id instead", &expid);
913         return FALSE;
914     }
915
916     if(chunk->size % reclen)  /* valid chunk size? */
917     {
918         FLUID_LOG(FLUID_ERR, "'%.4s' chunk size is not a multiple of %d bytes", &expid, reclen);
919         return FALSE;
920     }
921
922     if((*size -= chunk->size) < 0)
923     {
924         FLUID_LOG(FLUID_ERR, "'%.4s' chunk size exceeds remaining PDTA chunk size", &expid);
925         return FALSE;
926     }
927
928     return TRUE;
929 }
930
931 static int process_pdta(SFData *sf, int size)
932 {
933     SFChunk chunk;
934
935     if(!pdtahelper(sf, PHDR_FCC, SF_PHDR_SIZE, &chunk, &size))
936     {
937         return FALSE;
938     }
939
940     if(!load_phdr(sf, chunk.size))
941     {
942         return FALSE;
943     }
944
945     if(!pdtahelper(sf, PBAG_FCC, SF_BAG_SIZE, &chunk, &size))
946     {
947         return FALSE;
948     }
949
950     if(!load_pbag(sf, chunk.size))
951     {
952         return FALSE;
953     }
954
955     if(!pdtahelper(sf, PMOD_FCC, SF_MOD_SIZE, &chunk, &size))
956     {
957         return FALSE;
958     }
959
960     if(!load_pmod(sf, chunk.size))
961     {
962         return FALSE;
963     }
964
965     if(!pdtahelper(sf, PGEN_FCC, SF_GEN_SIZE, &chunk, &size))
966     {
967         return FALSE;
968     }
969
970     if(!load_pgen(sf, chunk.size))
971     {
972         return FALSE;
973     }
974
975     if(!pdtahelper(sf, IHDR_FCC, SF_IHDR_SIZE, &chunk, &size))
976     {
977         return FALSE;
978     }
979
980     if(!load_ihdr(sf, chunk.size))
981     {
982         return FALSE;
983     }
984
985     if(!pdtahelper(sf, IBAG_FCC, SF_BAG_SIZE, &chunk, &size))
986     {
987         return FALSE;
988     }
989
990     if(!load_ibag(sf, chunk.size))
991     {
992         return FALSE;
993     }
994
995     if(!pdtahelper(sf, IMOD_FCC, SF_MOD_SIZE, &chunk, &size))
996     {
997         return FALSE;
998     }
999
1000     if(!load_imod(sf, chunk.size))
1001     {
1002         return FALSE;
1003     }
1004
1005     if(!pdtahelper(sf, IGEN_FCC, SF_GEN_SIZE, &chunk, &size))
1006     {
1007         return FALSE;
1008     }
1009
1010     if(!load_igen(sf, chunk.size))
1011     {
1012         return FALSE;
1013     }
1014
1015     if(!pdtahelper(sf, SHDR_FCC, SF_SHDR_SIZE, &chunk, &size))
1016     {
1017         return FALSE;
1018     }
1019
1020     if(!load_shdr(sf, chunk.size))
1021     {
1022         return FALSE;
1023     }
1024
1025     return TRUE;
1026 }
1027
1028 /* preset header loader */
1029 static int load_phdr(SFData *sf, int size)
1030 {
1031     int i, i2;
1032     SFPreset *preset, *prev_preset = NULL;
1033     unsigned short pbag_idx, prev_pbag_idx = 0;
1034
1035     if(size % SF_PHDR_SIZE || size == 0)
1036     {
1037         FLUID_LOG(FLUID_ERR, "Preset header chunk size is invalid");
1038         return FALSE;
1039     }
1040
1041     i = size / SF_PHDR_SIZE - 1;
1042
1043     if(i == 0)
1044     {
1045         /* at least one preset + term record */
1046         FLUID_LOG(FLUID_WARN, "File contains no presets");
1047         FSKIP(sf, SF_PHDR_SIZE);
1048         return TRUE;
1049     }
1050
1051     for(; i > 0; i--)
1052     {
1053         /* load all preset headers */
1054         if((preset = FLUID_NEW(SFPreset)) == NULL)
1055         {
1056             FLUID_LOG(FLUID_ERR, "Out of memory");
1057             return FALSE;
1058         }
1059
1060         sf->preset = fluid_list_append(sf->preset, preset);
1061         preset->zone = NULL; /* In case of failure, fluid_sffile_close can cleanup */
1062         READSTR(sf, &preset->name); /* possible read failure ^ */
1063         READW(sf, preset->prenum);
1064         READW(sf, preset->bank);
1065         READW(sf, pbag_idx);
1066         READD(sf, preset->libr);
1067         READD(sf, preset->genre);
1068         READD(sf, preset->morph);
1069
1070         if(prev_preset)
1071         {
1072             /* not first preset? */
1073             if(pbag_idx < prev_pbag_idx)
1074             {
1075                 FLUID_LOG(FLUID_ERR, "Preset header indices not monotonic");
1076                 return FALSE;
1077             }
1078
1079             i2 = pbag_idx - prev_pbag_idx;
1080
1081             while(i2--)
1082             {
1083                 prev_preset->zone = fluid_list_prepend(prev_preset->zone, NULL);
1084             }
1085         }
1086         else if(pbag_idx > 0)  /* 1st preset, warn if ofs >0 */
1087         {
1088             FLUID_LOG(FLUID_WARN, "%d preset zones not referenced, discarding", pbag_idx);
1089         }
1090
1091         prev_preset = preset; /* update preset ptr */
1092         prev_pbag_idx = pbag_idx;
1093     }
1094
1095     FSKIP(sf, 24);
1096     READW(sf, pbag_idx); /* Read terminal generator index */
1097     FSKIP(sf, 12);
1098
1099     if(pbag_idx < prev_pbag_idx)
1100     {
1101         FLUID_LOG(FLUID_ERR, "Preset header indices not monotonic");
1102         return FALSE;
1103     }
1104
1105     i2 = pbag_idx - prev_pbag_idx;
1106
1107     while(i2--)
1108     {
1109         prev_preset->zone = fluid_list_prepend(prev_preset->zone, NULL);
1110     }
1111
1112     return TRUE;
1113 }
1114
1115 /* preset bag loader */
1116 static int load_pbag(SFData *sf, int size)
1117 {
1118     fluid_list_t *p, *p2;
1119     SFZone *z, *pz = NULL;
1120     unsigned short genndx, modndx;
1121     unsigned short pgenndx = 0, pmodndx = 0;
1122     unsigned short i;
1123
1124     if(size % SF_BAG_SIZE || size == 0)  /* size is multiple of SF_BAG_SIZE? */
1125     {
1126         FLUID_LOG(FLUID_ERR, "Preset bag chunk size is invalid");
1127         return FALSE;
1128     }
1129
1130     p = sf->preset;
1131
1132     while(p)
1133     {
1134         /* traverse through presets */
1135         p2 = ((SFPreset *)(p->data))->zone;
1136
1137         while(p2)
1138         {
1139             /* traverse preset's zones */
1140             if((size -= SF_BAG_SIZE) < 0)
1141             {
1142                 FLUID_LOG(FLUID_ERR, "Preset bag chunk size mismatch");
1143                 return FALSE;
1144             }
1145
1146             if((z = FLUID_NEW(SFZone)) == NULL)
1147             {
1148                 FLUID_LOG(FLUID_ERR, "Out of memory");
1149                 return FALSE;
1150             }
1151
1152             p2->data = z;
1153             z->gen = NULL; /* Init gen and mod before possible failure, */
1154             z->mod = NULL; /* to ensure proper cleanup (fluid_sffile_close) */
1155             READW(sf, genndx); /* possible read failure ^ */
1156             READW(sf, modndx);
1157             z->instsamp = NULL;
1158
1159             if(pz)
1160             {
1161                 /* if not first zone */
1162                 if(genndx < pgenndx)
1163                 {
1164                     FLUID_LOG(FLUID_ERR, "Preset bag generator indices not monotonic");
1165                     return FALSE;
1166                 }
1167
1168                 if(modndx < pmodndx)
1169                 {
1170                     FLUID_LOG(FLUID_ERR, "Preset bag modulator indices not monotonic");
1171                     return FALSE;
1172                 }
1173
1174                 i = genndx - pgenndx;
1175
1176                 while(i--)
1177                 {
1178                     pz->gen = fluid_list_prepend(pz->gen, NULL);
1179                 }
1180
1181                 i = modndx - pmodndx;
1182
1183                 while(i--)
1184                 {
1185                     pz->mod = fluid_list_prepend(pz->mod, NULL);
1186                 }
1187             }
1188
1189             pz = z; /* update previous zone ptr */
1190             pgenndx = genndx; /* update previous zone gen index */
1191             pmodndx = modndx; /* update previous zone mod index */
1192             p2 = fluid_list_next(p2);
1193         }
1194
1195         p = fluid_list_next(p);
1196     }
1197
1198     size -= SF_BAG_SIZE;
1199
1200     if(size != 0)
1201     {
1202         FLUID_LOG(FLUID_ERR, "Preset bag chunk size mismatch");
1203         return FALSE;
1204     }
1205
1206     READW(sf, genndx);
1207     READW(sf, modndx);
1208
1209     if(!pz)
1210     {
1211         if(genndx > 0)
1212         {
1213             FLUID_LOG(FLUID_WARN, "No preset generators and terminal index not 0");
1214         }
1215
1216         if(modndx > 0)
1217         {
1218             FLUID_LOG(FLUID_WARN, "No preset modulators and terminal index not 0");
1219         }
1220
1221         return TRUE;
1222     }
1223
1224     if(genndx < pgenndx)
1225     {
1226         FLUID_LOG(FLUID_ERR, "Preset bag generator indices not monotonic");
1227         return FALSE;
1228     }
1229
1230     if(modndx < pmodndx)
1231     {
1232         FLUID_LOG(FLUID_ERR, "Preset bag modulator indices not monotonic");
1233         return FALSE;
1234     }
1235
1236     i = genndx - pgenndx;
1237
1238     while(i--)
1239     {
1240         pz->gen = fluid_list_prepend(pz->gen, NULL);
1241     }
1242
1243     i = modndx - pmodndx;
1244
1245     while(i--)
1246     {
1247         pz->mod = fluid_list_prepend(pz->mod, NULL);
1248     }
1249
1250     return TRUE;
1251 }
1252
1253 /* preset modulator loader */
1254 static int load_pmod(SFData *sf, int size)
1255 {
1256     fluid_list_t *p, *p2, *p3;
1257     SFMod *m;
1258
1259     p = sf->preset;
1260
1261     while(p)
1262     {
1263         /* traverse through all presets */
1264         p2 = ((SFPreset *)(p->data))->zone;
1265
1266         while(p2)
1267         {
1268             /* traverse this preset's zones */
1269             p3 = ((SFZone *)(p2->data))->mod;
1270
1271             while(p3)
1272             {
1273                 /* load zone's modulators */
1274                 if((size -= SF_MOD_SIZE) < 0)
1275                 {
1276                     FLUID_LOG(FLUID_ERR, "Preset modulator chunk size mismatch");
1277                     return FALSE;
1278                 }
1279
1280                 if((m = FLUID_NEW(SFMod)) == NULL)
1281                 {
1282                     FLUID_LOG(FLUID_ERR, "Out of memory");
1283                     return FALSE;
1284                 }
1285
1286                 p3->data = m;
1287                 READW(sf, m->src);
1288                 READW(sf, m->dest);
1289                 READW(sf, m->amount);
1290                 READW(sf, m->amtsrc);
1291                 READW(sf, m->trans);
1292                 p3 = fluid_list_next(p3);
1293             }
1294
1295             p2 = fluid_list_next(p2);
1296         }
1297
1298         p = fluid_list_next(p);
1299     }
1300
1301     /*
1302        If there isn't even a terminal record
1303        Hmmm, the specs say there should be one, but..
1304      */
1305     if(size == 0)
1306     {
1307         return TRUE;
1308     }
1309
1310     size -= SF_MOD_SIZE;
1311
1312     if(size != 0)
1313     {
1314         FLUID_LOG(FLUID_ERR, "Preset modulator chunk size mismatch");
1315         return FALSE;
1316     }
1317
1318     FSKIP(sf, SF_MOD_SIZE); /* terminal mod */
1319
1320     return TRUE;
1321 }
1322
1323 /* -------------------------------------------------------------------
1324  * preset generator loader
1325  * generator (per preset) loading rules:
1326  * Zones with no generators or modulators shall be annihilated
1327  * Global zone must be 1st zone, discard additional ones (instrumentless zones)
1328  *
1329  * generator (per zone) loading rules (in order of decreasing precedence):
1330  * KeyRange is 1st in list (if exists), else discard
1331  * if a VelRange exists only preceded by a KeyRange, else discard
1332  * if a generator follows an instrument discard it
1333  * if a duplicate generator exists replace previous one
1334  * ------------------------------------------------------------------- */
1335 static int load_pgen(SFData *sf, int size)
1336 {
1337     fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
1338     SFZone *z;
1339     SFGen *g;
1340     SFGenAmount genval;
1341     unsigned short genid;
1342     int level, skip, drop, gzone, discarded;
1343
1344     p = sf->preset;
1345
1346     while(p)
1347     {
1348         /* traverse through all presets */
1349         gzone = FALSE;
1350         discarded = FALSE;
1351         p2 = ((SFPreset *)(p->data))->zone;
1352
1353         if(p2)
1354         {
1355             hz = &p2;
1356         }
1357
1358         while(p2)
1359         {
1360             /* traverse preset's zones */
1361             level = 0;
1362             z = (SFZone *)(p2->data);
1363             p3 = z->gen;
1364
1365             while(p3)
1366             {
1367                 /* load zone's generators */
1368                 dup = NULL;
1369                 skip = FALSE;
1370                 drop = FALSE;
1371
1372                 if((size -= SF_GEN_SIZE) < 0)
1373                 {
1374                     FLUID_LOG(FLUID_ERR, "Preset generator chunk size mismatch");
1375                     return FALSE;
1376                 }
1377
1378                 READW(sf, genid);
1379
1380                 if(genid == Gen_KeyRange)
1381                 {
1382                     /* nothing precedes */
1383                     if(level == 0)
1384                     {
1385                         level = 1;
1386                         READB(sf, genval.range.lo);
1387                         READB(sf, genval.range.hi);
1388                     }
1389                     else
1390                     {
1391                         skip = TRUE;
1392                     }
1393                 }
1394                 else if(genid == Gen_VelRange)
1395                 {
1396                     /* only KeyRange precedes */
1397                     if(level <= 1)
1398                     {
1399                         level = 2;
1400                         READB(sf, genval.range.lo);
1401                         READB(sf, genval.range.hi);
1402                     }
1403                     else
1404                     {
1405                         skip = TRUE;
1406                     }
1407                 }
1408                 else if(genid == Gen_Instrument)
1409                 {
1410                     /* inst is last gen */
1411                     level = 3;
1412                     READW(sf, genval.uword);
1413                     ((SFZone *)(p2->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1);
1414                     break; /* break out of generator loop */
1415                 }
1416                 else
1417                 {
1418                     level = 2;
1419
1420                     if(valid_preset_genid(genid))
1421                     {
1422                         /* generator valid? */
1423                         READW(sf, genval.sword);
1424                         dup = find_gen_by_id(genid, z->gen);
1425                     }
1426                     else
1427                     {
1428                         skip = TRUE;
1429                     }
1430                 }
1431
1432                 if(!skip)
1433                 {
1434                     if(!dup)
1435                     {
1436                         /* if gen ! dup alloc new */
1437                         if((g = FLUID_NEW(SFGen)) == NULL)
1438                         {
1439                             FLUID_LOG(FLUID_ERR, "Out of memory");
1440                             return FALSE;
1441                         }
1442
1443                         p3->data = g;
1444                         g->id = genid;
1445                     }
1446                     else
1447                     {
1448                         g = (SFGen *)(dup->data); /* ptr to orig gen */
1449                         drop = TRUE;
1450                     }
1451
1452                     g->amount = genval;
1453                 }
1454                 else
1455                 {
1456                     /* Skip this generator */
1457                     discarded = TRUE;
1458                     drop = TRUE;
1459                     FSKIPW(sf);
1460                 }
1461
1462                 if(!drop)
1463                 {
1464                     p3 = fluid_list_next(p3);    /* next gen */
1465                 }
1466                 else
1467                 {
1468                     SLADVREM(z->gen, p3);    /* drop place holder */
1469                 }
1470
1471             } /* generator loop */
1472
1473             if(level == 3)
1474             {
1475                 SLADVREM(z->gen, p3);    /* zone has inst? */
1476             }
1477             else
1478             {
1479                 /* congratulations its a global zone */
1480                 if(!gzone)
1481                 {
1482                     /* Prior global zones? */
1483                     gzone = TRUE;
1484
1485                     /* if global zone is not 1st zone, relocate */
1486                     if(*hz != p2)
1487                     {
1488                         void *save = p2->data;
1489                         FLUID_LOG(FLUID_WARN, "Preset '%s': Global zone is not first zone",
1490                                   ((SFPreset *)(p->data))->name);
1491                         SLADVREM(*hz, p2);
1492                         *hz = fluid_list_prepend(*hz, save);
1493                         continue;
1494                     }
1495                 }
1496                 else
1497                 {
1498                     /* previous global zone exists, discard */
1499                     FLUID_LOG(FLUID_WARN, "Preset '%s': Discarding invalid global zone",
1500                               ((SFPreset *)(p->data))->name);
1501                     *hz = fluid_list_remove(*hz, p2->data);
1502                     delete_zone((SFZone *)fluid_list_get(p2));
1503                 }
1504             }
1505
1506             while(p3)
1507             {
1508                 /* Kill any zones following an instrument */
1509                 discarded = TRUE;
1510
1511                 if((size -= SF_GEN_SIZE) < 0)
1512                 {
1513                     FLUID_LOG(FLUID_ERR, "Preset generator chunk size mismatch");
1514                     return FALSE;
1515                 }
1516
1517                 FSKIP(sf, SF_GEN_SIZE);
1518                 SLADVREM(z->gen, p3);
1519             }
1520
1521             p2 = fluid_list_next(p2); /* next zone */
1522         }
1523
1524         if(discarded)
1525         {
1526             FLUID_LOG(FLUID_WARN,
1527                       "Preset '%s': Some invalid generators were discarded",
1528                       ((SFPreset *)(p->data))->name);
1529         }
1530
1531         p = fluid_list_next(p);
1532     }
1533
1534     /* in case there isn't a terminal record */
1535     if(size == 0)
1536     {
1537         return TRUE;
1538     }
1539
1540     size -= SF_GEN_SIZE;
1541
1542     if(size != 0)
1543     {
1544         FLUID_LOG(FLUID_ERR, "Preset generator chunk size mismatch");
1545         return FALSE;
1546     }
1547
1548     FSKIP(sf, SF_GEN_SIZE); /* terminal gen */
1549
1550     return TRUE;
1551 }
1552
1553 /* instrument header loader */
1554 static int load_ihdr(SFData *sf, int size)
1555 {
1556     int i, i2;
1557     SFInst *p, *pr = NULL; /* ptr to current & previous instrument */
1558     unsigned short zndx, pzndx = 0;
1559
1560     if(size % SF_IHDR_SIZE || size == 0)  /* chunk size is valid? */
1561     {
1562         FLUID_LOG(FLUID_ERR, "Instrument header has invalid size");
1563         return FALSE;
1564     }
1565
1566     size = size / SF_IHDR_SIZE - 1;
1567
1568     if(size == 0)
1569     {
1570         /* at least one preset + term record */
1571         FLUID_LOG(FLUID_WARN, "File contains no instruments");
1572         FSKIP(sf, SF_IHDR_SIZE);
1573         return TRUE;
1574     }
1575
1576     for(i = 0; i < size; i++)
1577     {
1578         /* load all instrument headers */
1579         if((p = FLUID_NEW(SFInst)) == NULL)
1580         {
1581             FLUID_LOG(FLUID_ERR, "Out of memory");
1582             return FALSE;
1583         }
1584
1585         sf->inst = fluid_list_append(sf->inst, p);
1586         p->zone = NULL; /* For proper cleanup if fail (fluid_sffile_close) */
1587         p->idx = i;
1588         READSTR(sf, &p->name); /* Possible read failure ^ */
1589         READW(sf, zndx);
1590
1591         if(pr)
1592         {
1593             /* not first instrument? */
1594             if(zndx < pzndx)
1595             {
1596                 FLUID_LOG(FLUID_ERR, "Instrument header indices not monotonic");
1597                 return FALSE;
1598             }
1599
1600             i2 = zndx - pzndx;
1601
1602             while(i2--)
1603             {
1604                 pr->zone = fluid_list_prepend(pr->zone, NULL);
1605             }
1606         }
1607         else if(zndx > 0)  /* 1st inst, warn if ofs >0 */
1608         {
1609             FLUID_LOG(FLUID_WARN, "%d instrument zones not referenced, discarding", zndx);
1610         }
1611
1612         pzndx = zndx;
1613         pr = p; /* update instrument ptr */
1614     }
1615
1616     FSKIP(sf, 20);
1617     READW(sf, zndx);
1618
1619     if(zndx < pzndx)
1620     {
1621         FLUID_LOG(FLUID_ERR, "Instrument header indices not monotonic");
1622         return FALSE;
1623     }
1624
1625     i2 = zndx - pzndx;
1626
1627     while(i2--)
1628     {
1629         pr->zone = fluid_list_prepend(pr->zone, NULL);
1630     }
1631
1632     return TRUE;
1633 }
1634
1635 /* instrument bag loader */
1636 static int load_ibag(SFData *sf, int size)
1637 {
1638     fluid_list_t *p, *p2;
1639     SFZone *z, *pz = NULL;
1640     unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0;
1641     int i;
1642
1643     if(size % SF_BAG_SIZE || size == 0)  /* size is multiple of SF_BAG_SIZE? */
1644     {
1645         FLUID_LOG(FLUID_ERR, "Instrument bag chunk size is invalid");
1646         return FALSE;
1647     }
1648
1649     p = sf->inst;
1650
1651     while(p)
1652     {
1653         /* traverse through inst */
1654         p2 = ((SFInst *)(p->data))->zone;
1655
1656         while(p2)
1657         {
1658             /* load this inst's zones */
1659             if((size -= SF_BAG_SIZE) < 0)
1660             {
1661                 FLUID_LOG(FLUID_ERR, "Instrument bag chunk size mismatch");
1662                 return FALSE;
1663             }
1664
1665             if((z = FLUID_NEW(SFZone)) == NULL)
1666             {
1667                 FLUID_LOG(FLUID_ERR, "Out of memory");
1668                 return FALSE;
1669             }
1670
1671             p2->data = z;
1672             z->gen = NULL; /* In case of failure, */
1673             z->mod = NULL; /* fluid_sffile_close can clean up */
1674             READW(sf, genndx); /* READW = possible read failure */
1675             READW(sf, modndx);
1676             z->instsamp = NULL;
1677
1678             if(pz)
1679             {
1680                 /* if not first zone */
1681                 if(genndx < pgenndx)
1682                 {
1683                     FLUID_LOG(FLUID_ERR, "Instrument generator indices not monotonic");
1684                     return FALSE;
1685                 }
1686
1687                 if(modndx < pmodndx)
1688                 {
1689                     FLUID_LOG(FLUID_ERR, "Instrument modulator indices not monotonic");
1690                     return FALSE;
1691                 }
1692
1693                 i = genndx - pgenndx;
1694
1695                 while(i--)
1696                 {
1697                     pz->gen = fluid_list_prepend(pz->gen, NULL);
1698                 }
1699
1700                 i = modndx - pmodndx;
1701
1702                 while(i--)
1703                 {
1704                     pz->mod = fluid_list_prepend(pz->mod, NULL);
1705                 }
1706             }
1707
1708             pz = z; /* update previous zone ptr */
1709             pgenndx = genndx;
1710             pmodndx = modndx;
1711             p2 = fluid_list_next(p2);
1712         }
1713
1714         p = fluid_list_next(p);
1715     }
1716
1717     size -= SF_BAG_SIZE;
1718
1719     if(size != 0)
1720     {
1721         FLUID_LOG(FLUID_ERR, "Instrument chunk size mismatch");
1722         return FALSE;
1723     }
1724
1725     READW(sf, genndx);
1726     READW(sf, modndx);
1727
1728     if(!pz)
1729     {
1730         /* in case that all are no zoners */
1731         if(genndx > 0)
1732         {
1733             FLUID_LOG(FLUID_WARN, "No instrument generators and terminal index not 0");
1734         }
1735
1736         if(modndx > 0)
1737         {
1738             FLUID_LOG(FLUID_WARN, "No instrument modulators and terminal index not 0");
1739         }
1740
1741         return TRUE;
1742     }
1743
1744     if(genndx < pgenndx)
1745     {
1746         FLUID_LOG(FLUID_ERR, "Instrument generator indices not monotonic");
1747         return FALSE;
1748     }
1749
1750     if(modndx < pmodndx)
1751     {
1752         FLUID_LOG(FLUID_ERR, "Instrument modulator indices not monotonic");
1753         return FALSE;
1754     }
1755
1756     i = genndx - pgenndx;
1757
1758     while(i--)
1759     {
1760         pz->gen = fluid_list_prepend(pz->gen, NULL);
1761     }
1762
1763     i = modndx - pmodndx;
1764
1765     while(i--)
1766     {
1767         pz->mod = fluid_list_prepend(pz->mod, NULL);
1768     }
1769
1770     return TRUE;
1771 }
1772
1773 /* instrument modulator loader */
1774 static int load_imod(SFData *sf, int size)
1775 {
1776     fluid_list_t *p, *p2, *p3;
1777     SFMod *m;
1778
1779     p = sf->inst;
1780
1781     while(p)
1782     {
1783         /* traverse through all inst */
1784         p2 = ((SFInst *)(p->data))->zone;
1785
1786         while(p2)
1787         {
1788             /* traverse this inst's zones */
1789             p3 = ((SFZone *)(p2->data))->mod;
1790
1791             while(p3)
1792             {
1793                 /* load zone's modulators */
1794                 if((size -= SF_MOD_SIZE) < 0)
1795                 {
1796                     FLUID_LOG(FLUID_ERR, "Instrument modulator chunk size mismatch");
1797                     return FALSE;
1798                 }
1799
1800                 if((m = FLUID_NEW(SFMod)) == NULL)
1801                 {
1802                     FLUID_LOG(FLUID_ERR, "Out of memory");
1803                     return FALSE;
1804                 }
1805
1806                 p3->data = m;
1807                 READW(sf, m->src);
1808                 READW(sf, m->dest);
1809                 READW(sf, m->amount);
1810                 READW(sf, m->amtsrc);
1811                 READW(sf, m->trans);
1812                 p3 = fluid_list_next(p3);
1813             }
1814
1815             p2 = fluid_list_next(p2);
1816         }
1817
1818         p = fluid_list_next(p);
1819     }
1820
1821     /*
1822        If there isn't even a terminal record
1823        Hmmm, the specs say there should be one, but..
1824      */
1825     if(size == 0)
1826     {
1827         return TRUE;
1828     }
1829
1830     size -= SF_MOD_SIZE;
1831
1832     if(size != 0)
1833     {
1834         FLUID_LOG(FLUID_ERR, "Instrument modulator chunk size mismatch");
1835         return FALSE;
1836     }
1837
1838     FSKIP(sf, SF_MOD_SIZE); /* terminal mod */
1839
1840     return TRUE;
1841 }
1842
1843 /* load instrument generators (see load_pgen for loading rules) */
1844 static int load_igen(SFData *sf, int size)
1845 {
1846     fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
1847     SFZone *z;
1848     SFGen *g;
1849     SFGenAmount genval;
1850     unsigned short genid;
1851     int level, skip, drop, gzone, discarded;
1852
1853     p = sf->inst;
1854
1855     while(p)
1856     {
1857         /* traverse through all instruments */
1858         gzone = FALSE;
1859         discarded = FALSE;
1860         p2 = ((SFInst *)(p->data))->zone;
1861
1862         if(p2)
1863         {
1864             hz = &p2;
1865         }
1866
1867         while(p2)
1868         {
1869             /* traverse this instrument's zones */
1870             level = 0;
1871             z = (SFZone *)(p2->data);
1872             p3 = z->gen;
1873
1874             while(p3)
1875             {
1876                 /* load zone's generators */
1877                 dup = NULL;
1878                 skip = FALSE;
1879                 drop = FALSE;
1880
1881                 if((size -= SF_GEN_SIZE) < 0)
1882                 {
1883                     FLUID_LOG(FLUID_ERR, "IGEN chunk size mismatch");
1884                     return FALSE;
1885                 }
1886
1887                 READW(sf, genid);
1888
1889                 if(genid == Gen_KeyRange)
1890                 {
1891                     /* nothing precedes */
1892                     if(level == 0)
1893                     {
1894                         level = 1;
1895                         READB(sf, genval.range.lo);
1896                         READB(sf, genval.range.hi);
1897                     }
1898                     else
1899                     {
1900                         skip = TRUE;
1901                     }
1902                 }
1903                 else if(genid == Gen_VelRange)
1904                 {
1905                     /* only KeyRange precedes */
1906                     if(level <= 1)
1907                     {
1908                         level = 2;
1909                         READB(sf, genval.range.lo);
1910                         READB(sf, genval.range.hi);
1911                     }
1912                     else
1913                     {
1914                         skip = TRUE;
1915                     }
1916                 }
1917                 else if(genid == Gen_SampleId)
1918                 {
1919                     /* sample is last gen */
1920                     level = 3;
1921                     READW(sf, genval.uword);
1922                     ((SFZone *)(p2->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1);
1923                     break; /* break out of generator loop */
1924                 }
1925                 else
1926                 {
1927                     level = 2;
1928
1929                     if(valid_inst_genid(genid))
1930                     {
1931                         /* gen valid? */
1932                         READW(sf, genval.sword);
1933                         dup = find_gen_by_id(genid, z->gen);
1934                     }
1935                     else
1936                     {
1937                         skip = TRUE;
1938                     }
1939                 }
1940
1941                 if(!skip)
1942                 {
1943                     if(!dup)
1944                     {
1945                         /* if gen ! dup alloc new */
1946                         if((g = FLUID_NEW(SFGen)) == NULL)
1947                         {
1948                             FLUID_LOG(FLUID_ERR, "Out of memory");
1949                             return FALSE;
1950                         }
1951
1952                         p3->data = g;
1953                         g->id = genid;
1954                     }
1955                     else
1956                     {
1957                         g = (SFGen *)(dup->data);
1958                         drop = TRUE;
1959                     }
1960
1961                     g->amount = genval;
1962                 }
1963                 else
1964                 {
1965                     /* skip this generator */
1966                     discarded = TRUE;
1967                     drop = TRUE;
1968                     FSKIPW(sf);
1969                 }
1970
1971                 if(!drop)
1972                 {
1973                     p3 = fluid_list_next(p3);    /* next gen */
1974                 }
1975                 else
1976                 {
1977                     SLADVREM(z->gen, p3);
1978                 }
1979
1980             } /* generator loop */
1981
1982             if(level == 3)
1983             {
1984                 SLADVREM(z->gen, p3);    /* zone has sample? */
1985             }
1986             else
1987             {
1988                 /* its a global zone */
1989                 if(!gzone)
1990                 {
1991                     gzone = TRUE;
1992
1993                     /* if global zone is not 1st zone, relocate */
1994                     if(*hz != p2)
1995                     {
1996                         void *save = p2->data;
1997                         FLUID_LOG(FLUID_WARN, "Instrument '%s': Global zone is not first zone",
1998                                   ((SFPreset *)(p->data))->name);
1999                         SLADVREM(*hz, p2);
2000                         *hz = fluid_list_prepend(*hz, save);
2001                         continue;
2002                     }
2003                 }
2004                 else
2005                 {
2006                     /* previous global zone exists, discard */
2007                     FLUID_LOG(FLUID_WARN, "Instrument '%s': Discarding invalid global zone",
2008                               ((SFInst *)(p->data))->name);
2009                     *hz = fluid_list_remove(*hz, p2->data);
2010                     delete_zone((SFZone *)fluid_list_get(p2));
2011                 }
2012             }
2013
2014             while(p3)
2015             {
2016                 /* Kill any zones following a sample */
2017                 discarded = TRUE;
2018
2019                 if((size -= SF_GEN_SIZE) < 0)
2020                 {
2021                     FLUID_LOG(FLUID_ERR, "Instrument generator chunk size mismatch");
2022                     return FALSE;
2023                 }
2024
2025                 FSKIP(sf, SF_GEN_SIZE);
2026                 SLADVREM(z->gen, p3);
2027             }
2028
2029             p2 = fluid_list_next(p2); /* next zone */
2030         }
2031
2032         if(discarded)
2033         {
2034             FLUID_LOG(FLUID_WARN,
2035                       "Instrument '%s': Some invalid generators were discarded",
2036                       ((SFInst *)(p->data))->name);
2037         }
2038
2039         p = fluid_list_next(p);
2040     }
2041
2042     /* for those non-terminal record cases, grr! */
2043     if(size == 0)
2044     {
2045         return TRUE;
2046     }
2047
2048     size -= SF_GEN_SIZE;
2049
2050     if(size != 0)
2051     {
2052         FLUID_LOG(FLUID_ERR, "IGEN chunk size mismatch");
2053         return FALSE;
2054     }
2055
2056     FSKIP(sf, SF_GEN_SIZE); /* terminal gen */
2057
2058     return TRUE;
2059 }
2060
2061 /* sample header loader */
2062 static int load_shdr(SFData *sf, unsigned int size)
2063 {
2064     unsigned int i;
2065     SFSample *p;
2066
2067     if(size % SF_SHDR_SIZE || size == 0)  /* size is multiple of SHDR size? */
2068     {
2069         FLUID_LOG(FLUID_ERR, "Sample header has invalid size");
2070         return FALSE;
2071     }
2072
2073     size = size / SF_SHDR_SIZE - 1;
2074
2075     if(size == 0)
2076     {
2077         /* at least one sample + term record? */
2078         FLUID_LOG(FLUID_WARN, "File contains no samples");
2079         FSKIP(sf, SF_SHDR_SIZE);
2080         return TRUE;
2081     }
2082
2083     /* load all sample headers */
2084     for(i = 0; i < size; i++)
2085     {
2086         if((p = FLUID_NEW(SFSample)) == NULL)
2087         {
2088             FLUID_LOG(FLUID_ERR, "Out of memory");
2089             return FALSE;
2090         }
2091
2092         sf->sample = fluid_list_append(sf->sample, p);
2093         READSTR(sf, &p->name);
2094         READD(sf, p->start);
2095         READD(sf, p->end);
2096         READD(sf, p->loopstart);
2097         READD(sf, p->loopend);
2098         READD(sf, p->samplerate);
2099         READB(sf, p->origpitch);
2100         READB(sf, p->pitchadj);
2101         FSKIPW(sf); /* skip sample link */
2102         READW(sf, p->sampletype);
2103         p->samfile = 0;
2104     }
2105
2106     FSKIP(sf, SF_SHDR_SIZE); /* skip terminal shdr */
2107
2108     return TRUE;
2109 }
2110
2111 /* "fixup" (inst # -> inst ptr) instrument references in preset list */
2112 static int fixup_pgen(SFData *sf)
2113 {
2114     fluid_list_t *p, *p2, *p3;
2115     SFZone *z;
2116     int i;
2117
2118     p = sf->preset;
2119
2120     while(p)
2121     {
2122         p2 = ((SFPreset *)(p->data))->zone;
2123
2124         while(p2)
2125         {
2126             /* traverse this preset's zones */
2127             z = (SFZone *)(p2->data);
2128
2129             if((i = FLUID_POINTER_TO_INT(z->instsamp)))
2130             {
2131                 /* load instrument # */
2132                 p3 = fluid_list_nth(sf->inst, i - 1);
2133
2134                 if(!p3)
2135                 {
2136                     FLUID_LOG(FLUID_ERR, "Preset %03d %03d: Invalid instrument reference",
2137                               ((SFPreset *)(p->data))->bank, ((SFPreset *)(p->data))->prenum);
2138                     return FALSE;
2139                 }
2140
2141                 z->instsamp = p3;
2142             }
2143             else
2144             {
2145                 z->instsamp = NULL;
2146             }
2147
2148             p2 = fluid_list_next(p2);
2149         }
2150
2151         p = fluid_list_next(p);
2152     }
2153
2154     return TRUE;
2155 }
2156
2157 /* "fixup" (sample # -> sample ptr) sample references in instrument list */
2158 static int fixup_igen(SFData *sf)
2159 {
2160     fluid_list_t *p, *p2, *p3;
2161     SFZone *z;
2162     int i;
2163
2164     p = sf->inst;
2165
2166     while(p)
2167     {
2168         p2 = ((SFInst *)(p->data))->zone;
2169
2170         while(p2)
2171         {
2172             /* traverse instrument's zones */
2173             z = (SFZone *)(p2->data);
2174
2175             if((i = FLUID_POINTER_TO_INT(z->instsamp)))
2176             {
2177                 /* load sample # */
2178                 p3 = fluid_list_nth(sf->sample, i - 1);
2179
2180                 if(!p3)
2181                 {
2182                     FLUID_LOG(FLUID_ERR, "Instrument '%s': Invalid sample reference",
2183                               ((SFInst *)(p->data))->name);
2184                     return FALSE;
2185                 }
2186
2187                 z->instsamp = p3;
2188             }
2189
2190             p2 = fluid_list_next(p2);
2191         }
2192
2193         p = fluid_list_next(p);
2194     }
2195
2196     return TRUE;
2197 }
2198
2199 static void delete_preset(SFPreset *preset)
2200 {
2201     fluid_list_t *entry;
2202     SFZone *zone;
2203
2204     if(!preset)
2205     {
2206         return;
2207     }
2208
2209     entry = preset->zone;
2210
2211     while(entry)
2212     {
2213         zone = (SFZone *)fluid_list_get(entry);
2214         delete_zone(zone);
2215         entry = fluid_list_next(entry);
2216     }
2217
2218     delete_fluid_list(preset->zone);
2219
2220     FLUID_FREE(preset);
2221 }
2222
2223 static void delete_inst(SFInst *inst)
2224 {
2225     fluid_list_t *entry;
2226     SFZone *zone;
2227
2228     if(!inst)
2229     {
2230         return;
2231     }
2232
2233     entry = inst->zone;
2234
2235     while(entry)
2236     {
2237         zone = (SFZone *)fluid_list_get(entry);
2238         delete_zone(zone);
2239         entry = fluid_list_next(entry);
2240     }
2241
2242     delete_fluid_list(inst->zone);
2243
2244     FLUID_FREE(inst);
2245 }
2246
2247
2248 /* Free all elements of a zone (Preset or Instrument) */
2249 static void delete_zone(SFZone *zone)
2250 {
2251     fluid_list_t *entry;
2252
2253     if(!zone)
2254     {
2255         return;
2256     }
2257
2258     entry = zone->gen;
2259
2260     while(entry)
2261     {
2262         FLUID_FREE(fluid_list_get(entry));
2263         entry = fluid_list_next(entry);
2264     }
2265
2266     delete_fluid_list(zone->gen);
2267
2268     entry = zone->mod;
2269
2270     while(entry)
2271     {
2272         FLUID_FREE(fluid_list_get(entry));
2273         entry = fluid_list_next(entry);
2274     }
2275
2276     delete_fluid_list(zone->mod);
2277
2278     FLUID_FREE(zone);
2279 }
2280
2281 /* preset sort function, first by bank, then by preset # */
2282 static int preset_compare_func(void *a, void *b)
2283 {
2284     int aval, bval;
2285
2286     aval = (int)(((SFPreset *)a)->bank) << 16 | ((SFPreset *)a)->prenum;
2287     bval = (int)(((SFPreset *)b)->bank) << 16 | ((SFPreset *)b)->prenum;
2288
2289     return (aval - bval);
2290 }
2291
2292 /* Find a generator by its id in the passed in list.
2293  *
2294  * @return pointer to SFGen if found, otherwise NULL
2295  */
2296 static fluid_list_t *find_gen_by_id(int gen, fluid_list_t *genlist)
2297 {
2298     /* is generator in gen list? */
2299     fluid_list_t *p;
2300
2301     p = genlist;
2302
2303     while(p)
2304     {
2305         if(p->data == NULL)
2306         {
2307             return NULL;
2308         }
2309
2310         if(gen == ((SFGen *)p->data)->id)
2311         {
2312             break;
2313         }
2314
2315         p = fluid_list_next(p);
2316     }
2317
2318     return p;
2319 }
2320
2321 /* check validity of instrument generator */
2322 static int valid_inst_genid(unsigned short genid)
2323 {
2324     int i = 0;
2325
2326     if(genid > Gen_MaxValid)
2327     {
2328         return FALSE;
2329     }
2330
2331     while(invalid_inst_gen[i] && invalid_inst_gen[i] != genid)
2332     {
2333         i++;
2334     }
2335
2336     return (invalid_inst_gen[i] == 0);
2337 }
2338
2339 /* check validity of preset generator */
2340 static int valid_preset_genid(unsigned short genid)
2341 {
2342     int i = 0;
2343
2344     if(!valid_inst_genid(genid))
2345     {
2346         return FALSE;
2347     }
2348
2349     while(invalid_preset_gen[i] && invalid_preset_gen[i] != genid)
2350     {
2351         i++;
2352     }
2353
2354     return (invalid_preset_gen[i] == 0);
2355 }
2356
2357
2358 static int fluid_sffile_read_wav(SFData *sf, unsigned int start, unsigned int end, short **data, char **data24)
2359 {
2360     short *loaded_data = NULL;
2361     char *loaded_data24 = NULL;
2362
2363     int num_samples = (end + 1) - start;
2364     fluid_return_val_if_fail(num_samples > 0, -1);
2365
2366     if((start * sizeof(short) > sf->samplesize) || (end * sizeof(short) > sf->samplesize))
2367     {
2368         FLUID_LOG(FLUID_ERR, "Sample offsets exceed sample data chunk");
2369         goto error_exit;
2370     }
2371
2372     /* Load 16-bit sample data */
2373     if(sf->fcbs->fseek(sf->sffd, sf->samplepos + (start * sizeof(short)), SEEK_SET) == FLUID_FAILED)
2374     {
2375         FLUID_LOG(FLUID_ERR, "Failed to seek to sample position");
2376         goto error_exit;
2377     }
2378
2379     loaded_data = FLUID_ARRAY(short, num_samples);
2380
2381     if(loaded_data == NULL)
2382     {
2383         FLUID_LOG(FLUID_ERR, "Out of memory");
2384         goto error_exit;
2385     }
2386
2387     if(sf->fcbs->fread(loaded_data, num_samples * sizeof(short), sf->sffd) == FLUID_FAILED)
2388     {
2389         FLUID_LOG(FLUID_ERR, "Failed to read sample data");
2390         goto error_exit;
2391     }
2392
2393     /* If this machine is big endian, byte swap the 16 bit samples */
2394     if(FLUID_IS_BIG_ENDIAN)
2395     {
2396         int i;
2397
2398         for(i = 0; i < num_samples; i++)
2399         {
2400             loaded_data[i] = FLUID_LE16TOH(loaded_data[i]);
2401         }
2402     }
2403
2404     *data = loaded_data;
2405
2406     /* Optionally load additional 8 bit sample data for 24-bit support. Any failures while loading
2407      * the 24-bit sample data will be logged as errors but won't prevent the sample reading to
2408      * fail, as sound output is still possible with the 16-bit sample data. */
2409     if(sf->sample24pos)
2410     {
2411         if((start > sf->sample24size) || (end > sf->sample24size))
2412         {
2413             FLUID_LOG(FLUID_ERR, "Sample offsets exceed 24-bit sample data chunk");
2414             goto error24_exit;
2415         }
2416
2417         if(sf->fcbs->fseek(sf->sffd, sf->sample24pos + start, SEEK_SET) == FLUID_FAILED)
2418         {
2419             FLUID_LOG(FLUID_ERR, "Failed to seek position for 24-bit sample data in data file");
2420             goto error24_exit;
2421         }
2422
2423         loaded_data24 = FLUID_ARRAY(char, num_samples);
2424
2425         if(loaded_data24 == NULL)
2426         {
2427             FLUID_LOG(FLUID_ERR, "Out of memory reading 24-bit sample data");
2428             goto error24_exit;
2429         }
2430
2431         if(sf->fcbs->fread(loaded_data24, num_samples, sf->sffd) == FLUID_FAILED)
2432         {
2433             FLUID_LOG(FLUID_ERR, "Failed to read 24-bit sample data");
2434             goto error24_exit;
2435         }
2436     }
2437
2438     *data24 = loaded_data24;
2439
2440     return num_samples;
2441
2442 error24_exit:
2443     FLUID_LOG(FLUID_WARN, "Ignoring 24-bit sample data, sound quality might suffer");
2444     FLUID_FREE(loaded_data24);
2445     *data24 = NULL;
2446     return num_samples;
2447
2448 error_exit:
2449     FLUID_FREE(loaded_data);
2450     FLUID_FREE(loaded_data24);
2451     return -1;
2452 }
2453
2454
2455 /* Ogg Vorbis loading and decompression */
2456 #if LIBSNDFILE_SUPPORT
2457
2458 /* Virtual file access rountines to allow loading individually compressed
2459  * samples from the Soundfont sample data chunk using the file callbacks
2460  * passing in during opening of the file */
2461 typedef struct _sfvio_data_t
2462 {
2463     SFData *sffile;
2464     sf_count_t start;  /* start byte offset of compressed data */
2465     sf_count_t end;    /* end byte offset of compressed data */
2466     sf_count_t offset; /* current virtual file offset from start byte offset */
2467
2468 } sfvio_data_t;
2469
2470 static sf_count_t sfvio_get_filelen(void *user_data)
2471 {
2472     sfvio_data_t *data = user_data;
2473
2474     return (data->end + 1) - data->start;
2475 }
2476
2477 static sf_count_t sfvio_seek(sf_count_t offset, int whence, void *user_data)
2478 {
2479     sfvio_data_t *data = user_data;
2480     SFData *sf = data->sffile;
2481     sf_count_t new_offset;
2482
2483     switch(whence)
2484     {
2485     case SEEK_SET:
2486         new_offset = offset;
2487         break;
2488
2489     case SEEK_CUR:
2490         new_offset = data->offset + offset;
2491         break;
2492
2493     case SEEK_END:
2494         new_offset = sfvio_get_filelen(user_data) + offset;
2495         break;
2496
2497     default:
2498         goto fail; /* proper error handling not possible?? */
2499     }
2500
2501     if(sf->fcbs->fseek(sf->sffd, sf->samplepos + data->start + new_offset, SEEK_SET) != FLUID_FAILED)
2502     {
2503         data->offset = new_offset;
2504     }
2505
2506 fail:
2507     return data->offset;
2508 }
2509
2510 static sf_count_t sfvio_read(void *ptr, sf_count_t count, void *user_data)
2511 {
2512     sfvio_data_t *data = user_data;
2513     SFData *sf = data->sffile;
2514     sf_count_t remain;
2515
2516     remain = sfvio_get_filelen(user_data) - data->offset;
2517
2518     if(count > remain)
2519     {
2520         count = remain;
2521     }
2522
2523     if(count == 0)
2524     {
2525         return count;
2526     }
2527
2528     if(sf->fcbs->fread(ptr, count, sf->sffd) == FLUID_FAILED)
2529     {
2530         FLUID_LOG(FLUID_ERR, "Failed to read compressed sample data");
2531         return 0;
2532     }
2533
2534     data->offset += count;
2535
2536     return count;
2537 }
2538
2539 static sf_count_t sfvio_tell(void *user_data)
2540 {
2541     sfvio_data_t *data = user_data;
2542
2543     return data->offset;
2544 }
2545
2546 /**
2547  * Read Ogg Vorbis compressed data from the Soundfont and decompress it, returning the number of samples
2548  * in the decompressed WAV. Only 16-bit mono samples are supported.
2549  *
2550  * Note that this function takes byte indices for start and end source data. The sample headers in SF3
2551  * files use byte indices, so those pointers can be passed directly to this function.
2552  *
2553  * This function uses a virtual file structure in order to read the Ogg Vorbis
2554  * data from arbitrary locations in the source file.
2555  */
2556 static int fluid_sffile_read_vorbis(SFData *sf, unsigned int start_byte, unsigned int end_byte, short **data)
2557 {
2558     SNDFILE *sndfile;
2559     SF_INFO sfinfo;
2560     SF_VIRTUAL_IO sfvio =
2561     {
2562         sfvio_get_filelen,
2563         sfvio_seek,
2564         sfvio_read,
2565         NULL,
2566         sfvio_tell
2567     };
2568     sfvio_data_t sfdata;
2569     short *wav_data = NULL;
2570
2571     if((start_byte > sf->samplesize) || (end_byte > sf->samplesize))
2572     {
2573         FLUID_LOG(FLUID_ERR, "Ogg Vorbis data offsets exceed sample data chunk");
2574         return -1;
2575     }
2576
2577     // Initialize file position indicator and SF_INFO structure
2578     sfdata.sffile = sf;
2579     sfdata.start = start_byte;
2580     sfdata.end = end_byte;
2581     sfdata.offset = 0;
2582
2583     memset(&sfinfo, 0, sizeof(sfinfo));
2584
2585     /* Seek to beginning of Ogg Vorbis data in Soundfont */
2586     if(sf->fcbs->fseek(sf->sffd, sf->samplepos + start_byte, SEEK_SET) == FLUID_FAILED)
2587     {
2588         FLUID_LOG(FLUID_ERR, "Failed to seek to compressd sample position");
2589         return -1;
2590     }
2591
2592     // Open sample as a virtual file
2593     sndfile = sf_open_virtual(&sfvio, SFM_READ, &sfinfo, &sfdata);
2594
2595     if(!sndfile)
2596     {
2597         FLUID_LOG(FLUID_ERR, sf_strerror(sndfile));
2598         return -1;
2599     }
2600
2601     // Empty sample
2602     if(!sfinfo.frames || !sfinfo.channels)
2603     {
2604         FLUID_LOG(FLUID_DBG, "Empty decompressed sample");
2605         *data = NULL;
2606         sf_close(sndfile);
2607         return 0;
2608     }
2609
2610     /* FIXME: ensure that the decompressed WAV data is 16-bit mono? */
2611
2612     wav_data = FLUID_ARRAY(short, sfinfo.frames * sfinfo.channels);
2613
2614     if(!wav_data)
2615     {
2616         FLUID_LOG(FLUID_ERR, "Out of memory");
2617         goto error_exit;
2618     }
2619
2620     /* Automatically decompresses the Ogg Vorbis data to 16-bit WAV */
2621     if(sf_readf_short(sndfile, wav_data, sfinfo.frames) < sfinfo.frames)
2622     {
2623         FLUID_LOG(FLUID_DBG, "Decompression failed!");
2624         FLUID_LOG(FLUID_ERR, sf_strerror(sndfile));
2625         goto error_exit;
2626     }
2627
2628     sf_close(sndfile);
2629
2630     *data = wav_data;
2631
2632     return sfinfo.frames;
2633
2634 error_exit:
2635     FLUID_FREE(wav_data);
2636     sf_close(sndfile);
2637     return -1;
2638 }
2639 #else
2640 static int fluid_sffile_read_vorbis(SFData *sf, unsigned int start_byte, unsigned int end_byte, short **data)
2641 {
2642     return -1;
2643 }
2644 #endif