1 /* FluidSynth - A Software Synthesizer
3 * Copyright (C) 2003 Peter Hanappe and others.
5 * SoundFont file loading code borrowed from Smurf SoundFont Editor
6 * Copyright (C) 1999-2001 Josh Green
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.
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.
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
25 #include "fluid_sffile.h"
26 #include "fluid_sfont.h"
27 #include "fluid_sys.h"
29 #if LIBSNDFILE_SUPPORT
33 /*=================================sfload.c========================
34 Borrowed from Smurf SoundFont Editor by Josh Green
35 =================================================================*/
38 functions for loading data from sfont files, with appropriate byte swapping
39 on big endian machines. Sfont IDs are not swapped because the ID read is
40 equivalent to the matching ID list in memory regardless of LE/BE machine
43 /* sf file chunk IDs */
52 PDTA_ID, /* info/sample/preset */
57 IROM_ID, /* info ids (1st byte of info strings) */
61 IPRD_ID, /* more info ids */
64 ISFT_ID, /* and yet more info ids */
67 SMPL_ID, /* sample ids */
71 PGEN_ID, /* preset ids */
75 IGEN_ID, /* instrument ids */
76 SHDR_ID, /* sample info */
80 static const char idlist[] = {"RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD"
81 "ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdrsm24"
92 Gen_StartAddrCoarseOfs,
100 Gen_EndAddrCoarseOfs,
133 Gen_StartLoopAddrCoarseOfs,
138 Gen_EndLoopAddrCoarseOfs,
150 #define Gen_MaxValid Gen_Dummy - 1 /* maximum valid generator */
151 #define Gen_Count Gen_Dummy /* count of generators */
152 #define GenArrSize sizeof(SFGenAmount) * Gen_Count /* gen array size */
155 static const unsigned short invalid_inst_gen[] =
167 static const unsigned short invalid_preset_gen[] =
171 Gen_StartLoopAddrOfs,
173 Gen_StartAddrCoarseOfs,
174 Gen_EndAddrCoarseOfs,
175 Gen_StartLoopAddrCoarseOfs,
178 Gen_EndLoopAddrCoarseOfs,
186 #define CHNKIDSTR(id) &idlist[(id - 1) * 4]
188 /* sfont file chunk sizes */
189 #define SF_PHDR_SIZE (38)
190 #define SF_BAG_SIZE (4)
191 #define SF_MOD_SIZE (10)
192 #define SF_GEN_SIZE (4)
193 #define SF_IHDR_SIZE (22)
194 #define SF_SHDR_SIZE (46)
197 #define READCHUNK(sf, var) \
200 if (sf->fcbs->fread(var, 8, sf->sffd) == FLUID_FAILED) \
202 ((SFChunk *)(var))->size = FLUID_LE32TOH(((SFChunk *)(var))->size); \
205 #define READD(sf, var) \
209 if (sf->fcbs->fread(&_temp, 4, sf->sffd) == FLUID_FAILED) \
211 var = FLUID_LE32TOH(_temp); \
214 #define READW(sf, var) \
218 if (sf->fcbs->fread(&_temp, 2, sf->sffd) == FLUID_FAILED) \
220 var = FLUID_LE16TOH(_temp); \
223 #define READID(sf, var) \
226 if (sf->fcbs->fread(var, 4, sf->sffd) == FLUID_FAILED) \
230 #define READSTR(sf, var) \
233 if (sf->fcbs->fread(var, 20, sf->sffd) == FLUID_FAILED) \
238 #define READB(sf, var) \
241 if (sf->fcbs->fread(&var, 1, sf->sffd) == FLUID_FAILED) \
245 #define FSKIP(sf, size) \
248 if (sf->fcbs->fseek(sf->sffd, size, SEEK_CUR) == FLUID_FAILED) \
255 if (sf->fcbs->fseek(sf->sffd, 2, SEEK_CUR) == FLUID_FAILED) \
259 /* removes and advances a fluid_list_t pointer */
260 #define SLADVREM(list, item) \
263 fluid_list_t *_temp = item; \
264 item = fluid_list_next(item); \
265 list = fluid_list_remove_link(list, _temp); \
266 delete1_fluid_list(_temp); \
270 static int load_header(SFData *sf);
271 static int load_body(SFData *sf);
272 static int process_info(SFData *sf, int size);
273 static int process_sdta(SFData *sf, unsigned int size);
274 static int process_pdta(SFData *sf, int size);
275 static int load_phdr(SFData *sf, int size);
276 static int load_pbag(SFData *sf, int size);
277 static int load_pmod(SFData *sf, int size);
278 static int load_pgen(SFData *sf, int size);
279 static int load_ihdr(SFData *sf, int size);
280 static int load_ibag(SFData *sf, int size);
281 static int load_imod(SFData *sf, int size);
282 static int load_igen(SFData *sf, int size);
283 static int load_shdr(SFData *sf, unsigned int size);
284 static int fixup_pgen(SFData *sf);
285 static int fixup_igen(SFData *sf);
287 static int chunkid(unsigned int id);
288 static int read_listchunk(SFData *sf, SFChunk *chunk);
289 static int pdtahelper(SFData *sf, unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size);
290 static int preset_compare_func(void *a, void *b);
291 static fluid_list_t *find_gen_by_id(int gen, fluid_list_t *genlist);
292 static int valid_inst_genid(unsigned short genid);
293 static int valid_preset_genid(unsigned short genid);
296 static void delete_preset(SFPreset *preset);
297 static void delete_inst(SFInst *inst);
298 static void delete_zone(SFZone *zone);
300 static int fluid_sffile_read_vorbis(SFData *sf, unsigned int start_byte, unsigned int end_byte, short **data);
301 static int fluid_sffile_read_wav(SFData *sf, unsigned int start, unsigned int end, short **data, char **data24);
304 * Open a SoundFont file and parse it's contents into a SFData structure.
306 * @param fname filename
307 * @param fcbs file callback structure
308 * @return the partially parsed SoundFont as SFData structure or NULL on error
310 SFData *fluid_sffile_open(const char *fname, const fluid_file_callbacks_t *fcbs)
315 if(!(sf = FLUID_NEW(SFData)))
317 FLUID_LOG(FLUID_ERR, "Out of memory");
321 FLUID_MEMSET(sf, 0, sizeof(SFData));
325 if((sf->sffd = fcbs->fopen(fname)) == NULL)
327 FLUID_LOG(FLUID_ERR, "Unable to open file '%s'", fname);
331 sf->fname = FLUID_STRDUP(fname);
333 if(sf->fname == NULL)
335 FLUID_LOG(FLUID_ERR, "Out of memory");
339 /* get size of file by seeking to end */
340 if(fcbs->fseek(sf->sffd, 0L, SEEK_END) == FLUID_FAILED)
342 FLUID_LOG(FLUID_ERR, "Seek to end of file failed");
346 if((fsize = fcbs->ftell(sf->sffd)) == FLUID_FAILED)
348 FLUID_LOG(FLUID_ERR, "Get end of file position failed");
352 sf->filesize = fsize;
354 if(fcbs->fseek(sf->sffd, 0, SEEK_SET) == FLUID_FAILED)
356 FLUID_LOG(FLUID_ERR, "Rewind to start of file failed");
368 fluid_sffile_close(sf);
373 * Parse all preset information from the soundfont
375 * @return FLUID_OK on success, otherwise FLUID_FAILED
377 int fluid_sffile_parse_presets(SFData *sf)
387 /* Load sample data from the soundfont file
389 * This function will always return the sample data in WAV format. If the sample_type specifies an
390 * Ogg Vorbis compressed sample, it will be decompressed automatically before returning.
392 * @param sf SFData instance
393 * @param sample_start index of first sample point in Soundfont sample chunk
394 * @param sample_end index of last sample point in Soundfont sample chunk
395 * @param sample_type type of the sample in Soundfont
396 * @param data pointer to sample data pointer, will point to loaded sample data on success
397 * @param data24 pointer to 24-bit sample data pointer if 24-bit data present, will point to loaded
398 * 24-bit sample data on success or NULL if no 24-bit data is present in file
400 * @return The number of sample words in returned buffers or -1 on failure
402 int fluid_sffile_read_sample_data(SFData *sf, unsigned int sample_start, unsigned int sample_end,
403 int sample_type, short **data, char **data24)
407 if(sample_type & FLUID_SAMPLETYPE_OGG_VORBIS)
409 num_samples = fluid_sffile_read_vorbis(sf, sample_start, sample_end, data);
413 num_samples = fluid_sffile_read_wav(sf, sample_start, sample_end, data, data24);
420 * Close a SoundFont file and free the SFData structure.
422 * @param sf pointer to SFData structure
423 * @param fcbs file callback structure
425 void fluid_sffile_close(SFData *sf)
433 sf->fcbs->fclose(sf->sffd);
436 FLUID_FREE(sf->fname);
442 FLUID_FREE(fluid_list_get(entry));
443 entry = fluid_list_next(entry);
446 delete_fluid_list(sf->info);
452 preset = (SFPreset *)fluid_list_get(entry);
453 delete_preset(preset);
454 entry = fluid_list_next(entry);
457 delete_fluid_list(sf->preset);
463 inst = (SFInst *)fluid_list_get(entry);
465 entry = fluid_list_next(entry);
468 delete_fluid_list(sf->inst);
474 FLUID_FREE(fluid_list_get(entry));
475 entry = fluid_list_next(entry);
478 delete_fluid_list(sf->sample);
488 /* sound font file load functions */
489 static int chunkid(unsigned int id)
492 const unsigned int *p;
494 p = (const unsigned int *)&idlist;
496 for(i = 0; i < sizeof(idlist) / sizeof(int); i++, p += 1)
507 static int load_header(SFData *sf)
511 READCHUNK(sf, &chunk); /* load RIFF chunk */
513 if(chunkid(chunk.id) != RIFF_ID)
515 /* error if not RIFF */
516 FLUID_LOG(FLUID_ERR, "Not a RIFF file");
520 READID(sf, &chunk.id); /* load file ID */
522 if(chunkid(chunk.id) != SFBK_ID)
524 /* error if not SFBK_ID */
525 FLUID_LOG(FLUID_ERR, "Not a SoundFont file");
529 if(chunk.size != sf->filesize - 8)
531 FLUID_LOG(FLUID_ERR, "SoundFont file size mismatch");
535 /* Process INFO block */
536 if(!read_listchunk(sf, &chunk))
541 if(chunkid(chunk.id) != INFO_ID)
543 FLUID_LOG(FLUID_ERR, "Invalid ID found when expecting INFO chunk");
547 if(!process_info(sf, chunk.size))
552 /* Process sample chunk */
553 if(!read_listchunk(sf, &chunk))
558 if(chunkid(chunk.id) != SDTA_ID)
560 FLUID_LOG(FLUID_ERR, "Invalid ID found when expecting SAMPLE chunk");
564 if(!process_sdta(sf, chunk.size))
569 /* process HYDRA chunk */
570 if(!read_listchunk(sf, &chunk))
575 if(chunkid(chunk.id) != PDTA_ID)
577 FLUID_LOG(FLUID_ERR, "Invalid ID found when expecting HYDRA chunk");
581 sf->hydrapos = sf->fcbs->ftell(sf->sffd);
582 sf->hydrasize = chunk.size;
587 static int load_body(SFData *sf)
589 if(sf->fcbs->fseek(sf->sffd, sf->hydrapos, SEEK_SET) == FLUID_FAILED)
591 FLUID_LOG(FLUID_ERR, "Failed to seek to HYDRA position");
595 if(!process_pdta(sf, sf->hydrasize))
610 /* sort preset list by bank, preset # */
611 sf->preset = fluid_list_sort(sf->preset, (fluid_compare_func_t)preset_compare_func);
616 static int read_listchunk(SFData *sf, SFChunk *chunk)
618 READCHUNK(sf, chunk); /* read list chunk */
620 if(chunkid(chunk->id) != LIST_ID) /* error if ! list chunk */
622 FLUID_LOG(FLUID_ERR, "Invalid chunk id in level 0 parse");
626 READID(sf, &chunk->id); /* read id string */
631 static int process_info(SFData *sf, int size)
640 READCHUNK(sf, &chunk);
643 id = chunkid(chunk.id);
647 /* sound font version chunk? */
650 FLUID_LOG(FLUID_ERR, "Sound font version info chunk has invalid size");
655 sf->version.major = ver;
657 sf->version.minor = ver;
659 if(sf->version.major < 2)
661 FLUID_LOG(FLUID_ERR, "Sound font version is %d.%d which is not"
662 " supported, convert to version 2.0x",
663 sf->version.major, sf->version.minor);
667 if(sf->version.major == 3)
669 #if !LIBSNDFILE_SUPPORT
670 FLUID_LOG(FLUID_WARN,
671 "Sound font version is %d.%d but fluidsynth was compiled without"
672 " support for (v3.x)",
673 sf->version.major, sf->version.minor);
677 else if(sf->version.major > 2)
679 FLUID_LOG(FLUID_WARN,
680 "Sound font version is %d.%d which is newer than"
681 " what this version of fluidsynth was designed for (v2.0x)",
682 sf->version.major, sf->version.minor);
686 else if(id == IVER_ID)
688 /* ROM version chunk? */
691 FLUID_LOG(FLUID_ERR, "ROM version info chunk has invalid size");
696 sf->romver.major = ver;
698 sf->romver.minor = ver;
700 else if(id != UNKN_ID)
702 if((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536) || (chunk.size % 2))
704 FLUID_LOG(FLUID_ERR, "INFO sub chunk %.4s has invalid chunk size of %d bytes",
705 &chunk.id, chunk.size);
709 /* alloc for chunk id and da chunk */
710 if(!(item = FLUID_MALLOC(chunk.size + 1)))
712 FLUID_LOG(FLUID_ERR, "Out of memory");
716 /* attach to INFO list, fluid_sffile_close will cleanup if FAIL occurs */
717 sf->info = fluid_list_append(sf->info, item);
719 *(unsigned char *)item = id;
721 if(sf->fcbs->fread(&item[1], chunk.size, sf->sffd) == FLUID_FAILED)
726 /* force terminate info item (don't forget uint8 info ID) */
727 *(item + chunk.size) = '\0';
731 FLUID_LOG(FLUID_ERR, "Invalid chunk id in INFO chunk");
740 FLUID_LOG(FLUID_ERR, "INFO chunk size mismatch");
747 static int process_sdta(SFData *sf, unsigned int size)
753 return TRUE; /* no sample data? */
757 READCHUNK(sf, &chunk);
760 if(chunkid(chunk.id) != SMPL_ID)
762 FLUID_LOG(FLUID_ERR, "Expected SMPL chunk found invalid id instead");
766 /* SDTA chunk may also contain sm24 chunk for 24 bit samples
767 * (not yet supported), only an error if SMPL chunk size is
768 * greater than SDTA. */
769 if(chunk.size > size)
771 FLUID_LOG(FLUID_ERR, "SDTA chunk size mismatch");
775 /* sample data follows */
776 sf->samplepos = sf->fcbs->ftell(sf->sffd);
778 /* used to check validity of sample headers */
779 sf->samplesize = chunk.size;
781 FSKIP(sf, chunk.size);
784 if(sf->version.major >= 2 && sf->version.minor >= 4)
786 /* any chance to find another chunk here? */
790 READCHUNK(sf, &chunk);
793 if(chunkid(chunk.id) == SM24_ID)
795 int sm24size, sdtahalfsize;
797 FLUID_LOG(FLUID_DBG, "Found SM24 chunk");
799 if(chunk.size > size)
801 FLUID_LOG(FLUID_WARN, "SM24 exeeds SDTA chunk, ignoring SM24");
802 goto ret; // no error
805 sdtahalfsize = sf->samplesize / 2;
806 /* + 1 byte in the case that half the size of smpl chunk is an odd value */
807 sdtahalfsize += sdtahalfsize % 2;
808 sm24size = chunk.size;
810 if(sdtahalfsize != sm24size)
812 FLUID_LOG(FLUID_WARN, "SM24 not equal to half the size of SMPL chunk (0x%X != "
813 "0x%X), ignoring SM24",
814 sm24size, sdtahalfsize);
815 goto ret; // no error
818 /* sample data24 follows */
819 sf->sample24pos = sf->fcbs->ftell(sf->sffd);
820 sf->sample24size = sm24size;
831 static int pdtahelper(SFData *sf, unsigned int expid, unsigned int reclen, SFChunk *chunk, int *size)
836 expstr = CHNKIDSTR(expid); /* in case we need it */
838 READCHUNK(sf, chunk);
841 if((id = chunkid(chunk->id)) != expid)
843 FLUID_LOG(FLUID_ERR, "Expected PDTA sub-chunk '%.4s' found invalid id instead", expstr);
847 if(chunk->size % reclen) /* valid chunk size? */
849 FLUID_LOG(FLUID_ERR, "'%.4s' chunk size is not a multiple of %d bytes", expstr, reclen);
853 if((*size -= chunk->size) < 0)
855 FLUID_LOG(FLUID_ERR, "'%.4s' chunk size exceeds remaining PDTA chunk size", expstr);
862 static int process_pdta(SFData *sf, int size)
866 if(!pdtahelper(sf, PHDR_ID, SF_PHDR_SIZE, &chunk, &size))
871 if(!load_phdr(sf, chunk.size))
876 if(!pdtahelper(sf, PBAG_ID, SF_BAG_SIZE, &chunk, &size))
881 if(!load_pbag(sf, chunk.size))
886 if(!pdtahelper(sf, PMOD_ID, SF_MOD_SIZE, &chunk, &size))
891 if(!load_pmod(sf, chunk.size))
896 if(!pdtahelper(sf, PGEN_ID, SF_GEN_SIZE, &chunk, &size))
901 if(!load_pgen(sf, chunk.size))
906 if(!pdtahelper(sf, IHDR_ID, SF_IHDR_SIZE, &chunk, &size))
911 if(!load_ihdr(sf, chunk.size))
916 if(!pdtahelper(sf, IBAG_ID, SF_BAG_SIZE, &chunk, &size))
921 if(!load_ibag(sf, chunk.size))
926 if(!pdtahelper(sf, IMOD_ID, SF_MOD_SIZE, &chunk, &size))
931 if(!load_imod(sf, chunk.size))
936 if(!pdtahelper(sf, IGEN_ID, SF_GEN_SIZE, &chunk, &size))
941 if(!load_igen(sf, chunk.size))
946 if(!pdtahelper(sf, SHDR_ID, SF_SHDR_SIZE, &chunk, &size))
951 if(!load_shdr(sf, chunk.size))
959 /* preset header loader */
960 static int load_phdr(SFData *sf, int size)
963 SFPreset *preset, *prev_preset = NULL;
964 unsigned short pbag_idx, prev_pbag_idx = 0;
966 if(size % SF_PHDR_SIZE || size == 0)
968 FLUID_LOG(FLUID_ERR, "Preset header chunk size is invalid");
972 i = size / SF_PHDR_SIZE - 1;
976 /* at least one preset + term record */
977 FLUID_LOG(FLUID_WARN, "File contains no presets");
978 FSKIP(sf, SF_PHDR_SIZE);
984 /* load all preset headers */
985 if((preset = FLUID_NEW(SFPreset)) == NULL)
987 FLUID_LOG(FLUID_ERR, "Out of memory");
990 sf->preset = fluid_list_append(sf->preset, preset);
991 preset->zone = NULL; /* In case of failure, fluid_sffile_close can cleanup */
992 READSTR(sf, &preset->name); /* possible read failure ^ */
993 READW(sf, preset->prenum);
994 READW(sf, preset->bank);
996 READD(sf, preset->libr);
997 READD(sf, preset->genre);
998 READD(sf, preset->morph);
1002 /* not first preset? */
1003 if(pbag_idx < prev_pbag_idx)
1005 FLUID_LOG(FLUID_ERR, "Preset header indices not monotonic");
1009 i2 = pbag_idx - prev_pbag_idx;
1013 prev_preset->zone = fluid_list_prepend(prev_preset->zone, NULL);
1016 else if(pbag_idx > 0) /* 1st preset, warn if ofs >0 */
1018 FLUID_LOG(FLUID_WARN, "%d preset zones not referenced, discarding", pbag_idx);
1021 prev_preset = preset; /* update preset ptr */
1022 prev_pbag_idx = pbag_idx;
1026 READW(sf, pbag_idx); /* Read terminal generator index */
1029 if(pbag_idx < prev_pbag_idx)
1031 FLUID_LOG(FLUID_ERR, "Preset header indices not monotonic");
1035 i2 = pbag_idx - prev_pbag_idx;
1039 prev_preset->zone = fluid_list_prepend(prev_preset->zone, NULL);
1045 /* preset bag loader */
1046 static int load_pbag(SFData *sf, int size)
1048 fluid_list_t *p, *p2;
1049 SFZone *z, *pz = NULL;
1050 unsigned short genndx, modndx;
1051 unsigned short pgenndx = 0, pmodndx = 0;
1054 if(size % SF_BAG_SIZE || size == 0) /* size is multiple of SF_BAG_SIZE? */
1056 FLUID_LOG(FLUID_ERR, "Preset bag chunk size is invalid");
1064 /* traverse through presets */
1065 p2 = ((SFPreset *)(p->data))->zone;
1069 /* traverse preset's zones */
1070 if((size -= SF_BAG_SIZE) < 0)
1072 FLUID_LOG(FLUID_ERR, "Preset bag chunk size mismatch");
1076 if((z = FLUID_NEW(SFZone)) == NULL)
1078 FLUID_LOG(FLUID_ERR, "Out of memory");
1082 z->gen = NULL; /* Init gen and mod before possible failure, */
1083 z->mod = NULL; /* to ensure proper cleanup (fluid_sffile_close) */
1084 READW(sf, genndx); /* possible read failure ^ */
1090 /* if not first zone */
1091 if(genndx < pgenndx)
1093 FLUID_LOG(FLUID_ERR, "Preset bag generator indices not monotonic");
1097 if(modndx < pmodndx)
1099 FLUID_LOG(FLUID_ERR, "Preset bag modulator indices not monotonic");
1103 i = genndx - pgenndx;
1107 pz->gen = fluid_list_prepend(pz->gen, NULL);
1110 i = modndx - pmodndx;
1114 pz->mod = fluid_list_prepend(pz->mod, NULL);
1118 pz = z; /* update previous zone ptr */
1119 pgenndx = genndx; /* update previous zone gen index */
1120 pmodndx = modndx; /* update previous zone mod index */
1121 p2 = fluid_list_next(p2);
1124 p = fluid_list_next(p);
1127 size -= SF_BAG_SIZE;
1131 FLUID_LOG(FLUID_ERR, "Preset bag chunk size mismatch");
1142 FLUID_LOG(FLUID_WARN, "No preset generators and terminal index not 0");
1147 FLUID_LOG(FLUID_WARN, "No preset modulators and terminal index not 0");
1153 if(genndx < pgenndx)
1155 FLUID_LOG(FLUID_ERR, "Preset bag generator indices not monotonic");
1159 if(modndx < pmodndx)
1161 FLUID_LOG(FLUID_ERR, "Preset bag modulator indices not monotonic");
1165 i = genndx - pgenndx;
1169 pz->gen = fluid_list_prepend(pz->gen, NULL);
1172 i = modndx - pmodndx;
1176 pz->mod = fluid_list_prepend(pz->mod, NULL);
1182 /* preset modulator loader */
1183 static int load_pmod(SFData *sf, int size)
1185 fluid_list_t *p, *p2, *p3;
1192 /* traverse through all presets */
1193 p2 = ((SFPreset *)(p->data))->zone;
1197 /* traverse this preset's zones */
1198 p3 = ((SFZone *)(p2->data))->mod;
1202 /* load zone's modulators */
1203 if((size -= SF_MOD_SIZE) < 0)
1205 FLUID_LOG(FLUID_ERR, "Preset modulator chunk size mismatch");
1209 if((m = FLUID_NEW(SFMod)) == NULL)
1211 FLUID_LOG(FLUID_ERR, "Out of memory");
1217 READW(sf, m->amount);
1218 READW(sf, m->amtsrc);
1219 READW(sf, m->trans);
1220 p3 = fluid_list_next(p3);
1223 p2 = fluid_list_next(p2);
1226 p = fluid_list_next(p);
1230 If there isn't even a terminal record
1231 Hmmm, the specs say there should be one, but..
1238 size -= SF_MOD_SIZE;
1242 FLUID_LOG(FLUID_ERR, "Preset modulator chunk size mismatch");
1246 FSKIP(sf, SF_MOD_SIZE); /* terminal mod */
1251 /* -------------------------------------------------------------------
1252 * preset generator loader
1253 * generator (per preset) loading rules:
1254 * Zones with no generators or modulators shall be annihilated
1255 * Global zone must be 1st zone, discard additional ones (instrumentless zones)
1257 * generator (per zone) loading rules (in order of decreasing precedence):
1258 * KeyRange is 1st in list (if exists), else discard
1259 * if a VelRange exists only preceded by a KeyRange, else discard
1260 * if a generator follows an instrument discard it
1261 * if a duplicate generator exists replace previous one
1262 * ------------------------------------------------------------------- */
1263 static int load_pgen(SFData *sf, int size)
1265 fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
1269 unsigned short genid;
1270 int level, skip, drop, gzone, discarded;
1276 /* traverse through all presets */
1279 p2 = ((SFPreset *)(p->data))->zone;
1288 /* traverse preset's zones */
1290 z = (SFZone *)(p2->data);
1295 /* load zone's generators */
1300 if((size -= SF_GEN_SIZE) < 0)
1302 FLUID_LOG(FLUID_ERR, "Preset generator chunk size mismatch");
1308 if(genid == Gen_KeyRange)
1310 /* nothing precedes */
1314 READB(sf, genval.range.lo);
1315 READB(sf, genval.range.hi);
1322 else if(genid == Gen_VelRange)
1324 /* only KeyRange precedes */
1328 READB(sf, genval.range.lo);
1329 READB(sf, genval.range.hi);
1336 else if(genid == Gen_Instrument)
1338 /* inst is last gen */
1340 READW(sf, genval.uword);
1341 ((SFZone *)(p2->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1);
1342 break; /* break out of generator loop */
1348 if(valid_preset_genid(genid))
1350 /* generator valid? */
1351 READW(sf, genval.sword);
1352 dup = find_gen_by_id(genid, z->gen);
1364 /* if gen ! dup alloc new */
1365 if((g = FLUID_NEW(SFGen)) == NULL)
1367 FLUID_LOG(FLUID_ERR, "Out of memory");
1375 g = (SFGen *)(dup->data); /* ptr to orig gen */
1383 /* Skip this generator */
1391 p3 = fluid_list_next(p3); /* next gen */
1395 SLADVREM(z->gen, p3); /* drop place holder */
1398 } /* generator loop */
1402 SLADVREM(z->gen, p3); /* zone has inst? */
1406 /* congratulations its a global zone */
1409 /* Prior global zones? */
1412 /* if global zone is not 1st zone, relocate */
1415 void *save = p2->data;
1416 FLUID_LOG(FLUID_WARN, "Preset '%s': Global zone is not first zone",
1417 ((SFPreset *)(p->data))->name);
1419 *hz = fluid_list_prepend(*hz, save);
1425 /* previous global zone exists, discard */
1426 FLUID_LOG(FLUID_WARN, "Preset '%s': Discarding invalid global zone",
1427 ((SFPreset *)(p->data))->name);
1428 *hz = fluid_list_remove(*hz, p2->data);
1429 delete_zone((SFZone *)fluid_list_get(p2));
1435 /* Kill any zones following an instrument */
1438 if((size -= SF_GEN_SIZE) < 0)
1440 FLUID_LOG(FLUID_ERR, "Preset generator chunk size mismatch");
1444 FSKIP(sf, SF_GEN_SIZE);
1445 SLADVREM(z->gen, p3);
1448 p2 = fluid_list_next(p2); /* next zone */
1453 FLUID_LOG(FLUID_WARN,
1454 "Preset '%s': Some invalid generators were discarded",
1455 ((SFPreset *)(p->data))->name);
1458 p = fluid_list_next(p);
1461 /* in case there isn't a terminal record */
1467 size -= SF_GEN_SIZE;
1471 FLUID_LOG(FLUID_ERR, "Preset generator chunk size mismatch");
1475 FSKIP(sf, SF_GEN_SIZE); /* terminal gen */
1480 /* instrument header loader */
1481 static int load_ihdr(SFData *sf, int size)
1484 SFInst *p, *pr = NULL; /* ptr to current & previous instrument */
1485 unsigned short zndx, pzndx = 0;
1487 if(size % SF_IHDR_SIZE || size == 0) /* chunk size is valid? */
1489 FLUID_LOG(FLUID_ERR, "Instrument header has invalid size");
1493 size = size / SF_IHDR_SIZE - 1;
1497 /* at least one preset + term record */
1498 FLUID_LOG(FLUID_WARN, "File contains no instruments");
1499 FSKIP(sf, SF_IHDR_SIZE);
1503 for(i = 0; i < size; i++)
1505 /* load all instrument headers */
1506 if((p = FLUID_NEW(SFInst)) == NULL)
1508 FLUID_LOG(FLUID_ERR, "Out of memory");
1511 sf->inst = fluid_list_append(sf->inst, p);
1512 p->zone = NULL; /* For proper cleanup if fail (fluid_sffile_close) */
1514 READSTR(sf, &p->name); /* Possible read failure ^ */
1519 /* not first instrument? */
1522 FLUID_LOG(FLUID_ERR, "Instrument header indices not monotonic");
1530 pr->zone = fluid_list_prepend(pr->zone, NULL);
1533 else if(zndx > 0) /* 1st inst, warn if ofs >0 */
1535 FLUID_LOG(FLUID_WARN, "%d instrument zones not referenced, discarding", zndx);
1539 pr = p; /* update instrument ptr */
1547 FLUID_LOG(FLUID_ERR, "Instrument header indices not monotonic");
1555 pr->zone = fluid_list_prepend(pr->zone, NULL);
1561 /* instrument bag loader */
1562 static int load_ibag(SFData *sf, int size)
1564 fluid_list_t *p, *p2;
1565 SFZone *z, *pz = NULL;
1566 unsigned short genndx, modndx, pgenndx = 0, pmodndx = 0;
1569 if(size % SF_BAG_SIZE || size == 0) /* size is multiple of SF_BAG_SIZE? */
1571 FLUID_LOG(FLUID_ERR, "Instrument bag chunk size is invalid");
1579 /* traverse through inst */
1580 p2 = ((SFInst *)(p->data))->zone;
1584 /* load this inst's zones */
1585 if((size -= SF_BAG_SIZE) < 0)
1587 FLUID_LOG(FLUID_ERR, "Instrument bag chunk size mismatch");
1591 if((z = FLUID_NEW(SFZone)) == NULL)
1593 FLUID_LOG(FLUID_ERR, "Out of memory");
1597 z->gen = NULL; /* In case of failure, */
1598 z->mod = NULL; /* fluid_sffile_close can clean up */
1599 READW(sf, genndx); /* READW = possible read failure */
1605 /* if not first zone */
1606 if(genndx < pgenndx)
1608 FLUID_LOG(FLUID_ERR, "Instrument generator indices not monotonic");
1612 if(modndx < pmodndx)
1614 FLUID_LOG(FLUID_ERR, "Instrument modulator indices not monotonic");
1618 i = genndx - pgenndx;
1622 pz->gen = fluid_list_prepend(pz->gen, NULL);
1625 i = modndx - pmodndx;
1629 pz->mod = fluid_list_prepend(pz->mod, NULL);
1633 pz = z; /* update previous zone ptr */
1636 p2 = fluid_list_next(p2);
1639 p = fluid_list_next(p);
1642 size -= SF_BAG_SIZE;
1646 FLUID_LOG(FLUID_ERR, "Instrument chunk size mismatch");
1655 /* in case that all are no zoners */
1658 FLUID_LOG(FLUID_WARN, "No instrument generators and terminal index not 0");
1663 FLUID_LOG(FLUID_WARN, "No instrument modulators and terminal index not 0");
1669 if(genndx < pgenndx)
1671 FLUID_LOG(FLUID_ERR, "Instrument generator indices not monotonic");
1675 if(modndx < pmodndx)
1677 FLUID_LOG(FLUID_ERR, "Instrument modulator indices not monotonic");
1681 i = genndx - pgenndx;
1685 pz->gen = fluid_list_prepend(pz->gen, NULL);
1688 i = modndx - pmodndx;
1692 pz->mod = fluid_list_prepend(pz->mod, NULL);
1698 /* instrument modulator loader */
1699 static int load_imod(SFData *sf, int size)
1701 fluid_list_t *p, *p2, *p3;
1708 /* traverse through all inst */
1709 p2 = ((SFInst *)(p->data))->zone;
1713 /* traverse this inst's zones */
1714 p3 = ((SFZone *)(p2->data))->mod;
1718 /* load zone's modulators */
1719 if((size -= SF_MOD_SIZE) < 0)
1721 FLUID_LOG(FLUID_ERR, "Instrument modulator chunk size mismatch");
1725 if((m = FLUID_NEW(SFMod)) == NULL)
1727 FLUID_LOG(FLUID_ERR, "Out of memory");
1733 READW(sf, m->amount);
1734 READW(sf, m->amtsrc);
1735 READW(sf, m->trans);
1736 p3 = fluid_list_next(p3);
1739 p2 = fluid_list_next(p2);
1742 p = fluid_list_next(p);
1746 If there isn't even a terminal record
1747 Hmmm, the specs say there should be one, but..
1754 size -= SF_MOD_SIZE;
1758 FLUID_LOG(FLUID_ERR, "Instrument modulator chunk size mismatch");
1762 FSKIP(sf, SF_MOD_SIZE); /* terminal mod */
1767 /* load instrument generators (see load_pgen for loading rules) */
1768 static int load_igen(SFData *sf, int size)
1770 fluid_list_t *p, *p2, *p3, *dup, **hz = NULL;
1774 unsigned short genid;
1775 int level, skip, drop, gzone, discarded;
1781 /* traverse through all instruments */
1784 p2 = ((SFInst *)(p->data))->zone;
1793 /* traverse this instrument's zones */
1795 z = (SFZone *)(p2->data);
1800 /* load zone's generators */
1805 if((size -= SF_GEN_SIZE) < 0)
1807 FLUID_LOG(FLUID_ERR, "IGEN chunk size mismatch");
1813 if(genid == Gen_KeyRange)
1815 /* nothing precedes */
1819 READB(sf, genval.range.lo);
1820 READB(sf, genval.range.hi);
1827 else if(genid == Gen_VelRange)
1829 /* only KeyRange precedes */
1833 READB(sf, genval.range.lo);
1834 READB(sf, genval.range.hi);
1841 else if(genid == Gen_SampleId)
1843 /* sample is last gen */
1845 READW(sf, genval.uword);
1846 ((SFZone *)(p2->data))->instsamp = FLUID_INT_TO_POINTER(genval.uword + 1);
1847 break; /* break out of generator loop */
1853 if(valid_inst_genid(genid))
1856 READW(sf, genval.sword);
1857 dup = find_gen_by_id(genid, z->gen);
1869 /* if gen ! dup alloc new */
1870 if((g = FLUID_NEW(SFGen)) == NULL)
1872 FLUID_LOG(FLUID_ERR, "Out of memory");
1880 g = (SFGen *)(dup->data);
1888 /* skip this generator */
1896 p3 = fluid_list_next(p3); /* next gen */
1900 SLADVREM(z->gen, p3);
1903 } /* generator loop */
1907 SLADVREM(z->gen, p3); /* zone has sample? */
1911 /* its a global zone */
1916 /* if global zone is not 1st zone, relocate */
1919 void *save = p2->data;
1920 FLUID_LOG(FLUID_WARN, "Instrument '%s': Global zone is not first zone",
1921 ((SFPreset *)(p->data))->name);
1923 *hz = fluid_list_prepend(*hz, save);
1929 /* previous global zone exists, discard */
1930 FLUID_LOG(FLUID_WARN, "Instrument '%s': Discarding invalid global zone",
1931 ((SFInst *)(p->data))->name);
1932 *hz = fluid_list_remove(*hz, p2->data);
1933 delete_zone((SFZone *)fluid_list_get(p2));
1939 /* Kill any zones following a sample */
1942 if((size -= SF_GEN_SIZE) < 0)
1944 FLUID_LOG(FLUID_ERR, "Instrument generator chunk size mismatch");
1948 FSKIP(sf, SF_GEN_SIZE);
1949 SLADVREM(z->gen, p3);
1952 p2 = fluid_list_next(p2); /* next zone */
1957 FLUID_LOG(FLUID_WARN,
1958 "Instrument '%s': Some invalid generators were discarded",
1959 ((SFInst *)(p->data))->name);
1962 p = fluid_list_next(p);
1965 /* for those non-terminal record cases, grr! */
1971 size -= SF_GEN_SIZE;
1975 FLUID_LOG(FLUID_ERR, "IGEN chunk size mismatch");
1979 FSKIP(sf, SF_GEN_SIZE); /* terminal gen */
1984 /* sample header loader */
1985 static int load_shdr(SFData *sf, unsigned int size)
1990 if(size % SF_SHDR_SIZE || size == 0) /* size is multiple of SHDR size? */
1992 FLUID_LOG(FLUID_ERR, "Sample header has invalid size");
1996 size = size / SF_SHDR_SIZE - 1;
2000 /* at least one sample + term record? */
2001 FLUID_LOG(FLUID_WARN, "File contains no samples");
2002 FSKIP(sf, SF_SHDR_SIZE);
2006 /* load all sample headers */
2007 for(i = 0; i < size; i++)
2009 if((p = FLUID_NEW(SFSample)) == NULL)
2011 FLUID_LOG(FLUID_ERR, "Out of memory");
2014 sf->sample = fluid_list_append(sf->sample, p);
2015 READSTR(sf, &p->name);
2016 READD(sf, p->start);
2018 READD(sf, p->loopstart);
2019 READD(sf, p->loopend);
2020 READD(sf, p->samplerate);
2021 READB(sf, p->origpitch);
2022 READB(sf, p->pitchadj);
2023 FSKIPW(sf); /* skip sample link */
2024 READW(sf, p->sampletype);
2028 FSKIP(sf, SF_SHDR_SIZE); /* skip terminal shdr */
2033 /* "fixup" (inst # -> inst ptr) instrument references in preset list */
2034 static int fixup_pgen(SFData *sf)
2036 fluid_list_t *p, *p2, *p3;
2044 p2 = ((SFPreset *)(p->data))->zone;
2048 /* traverse this preset's zones */
2049 z = (SFZone *)(p2->data);
2051 if((i = FLUID_POINTER_TO_INT(z->instsamp)))
2053 /* load instrument # */
2054 p3 = fluid_list_nth(sf->inst, i - 1);
2058 FLUID_LOG(FLUID_ERR, "Preset %03d %03d: Invalid instrument reference",
2059 ((SFPreset *)(p->data))->bank, ((SFPreset *)(p->data))->prenum);
2070 p2 = fluid_list_next(p2);
2073 p = fluid_list_next(p);
2079 /* "fixup" (sample # -> sample ptr) sample references in instrument list */
2080 static int fixup_igen(SFData *sf)
2082 fluid_list_t *p, *p2, *p3;
2090 p2 = ((SFInst *)(p->data))->zone;
2094 /* traverse instrument's zones */
2095 z = (SFZone *)(p2->data);
2097 if((i = FLUID_POINTER_TO_INT(z->instsamp)))
2100 p3 = fluid_list_nth(sf->sample, i - 1);
2104 FLUID_LOG(FLUID_ERR, "Instrument '%s': Invalid sample reference",
2105 ((SFInst *)(p->data))->name);
2112 p2 = fluid_list_next(p2);
2115 p = fluid_list_next(p);
2121 static void delete_preset(SFPreset *preset)
2123 fluid_list_t *entry;
2131 entry = preset->zone;
2135 zone = (SFZone *)fluid_list_get(entry);
2137 entry = fluid_list_next(entry);
2140 delete_fluid_list(preset->zone);
2145 static void delete_inst(SFInst *inst)
2147 fluid_list_t *entry;
2159 zone = (SFZone *)fluid_list_get(entry);
2161 entry = fluid_list_next(entry);
2164 delete_fluid_list(inst->zone);
2170 /* Free all elements of a zone (Preset or Instrument) */
2171 static void delete_zone(SFZone *zone)
2173 fluid_list_t *entry;
2184 FLUID_FREE(fluid_list_get(entry));
2185 entry = fluid_list_next(entry);
2188 delete_fluid_list(zone->gen);
2194 FLUID_FREE(fluid_list_get(entry));
2195 entry = fluid_list_next(entry);
2198 delete_fluid_list(zone->mod);
2203 /* preset sort function, first by bank, then by preset # */
2204 static int preset_compare_func(void *a, void *b)
2208 aval = (int)(((SFPreset *)a)->bank) << 16 | ((SFPreset *)a)->prenum;
2209 bval = (int)(((SFPreset *)b)->bank) << 16 | ((SFPreset *)b)->prenum;
2211 return (aval - bval);
2214 /* Find a generator by its id in the passed in list.
2216 * @return pointer to SFGen if found, otherwise NULL
2218 static fluid_list_t *find_gen_by_id(int gen, fluid_list_t *genlist)
2220 /* is generator in gen list? */
2232 if(gen == ((SFGen *)p->data)->id)
2237 p = fluid_list_next(p);
2243 /* check validity of instrument generator */
2244 static int valid_inst_genid(unsigned short genid)
2248 if(genid > Gen_MaxValid)
2253 while(invalid_inst_gen[i] && invalid_inst_gen[i] != genid)
2258 return (invalid_inst_gen[i] == 0);
2261 /* check validity of preset generator */
2262 static int valid_preset_genid(unsigned short genid)
2266 if(!valid_inst_genid(genid))
2271 while(invalid_preset_gen[i] && invalid_preset_gen[i] != genid)
2276 return (invalid_preset_gen[i] == 0);
2280 static int fluid_sffile_read_wav(SFData *sf, unsigned int start, unsigned int end, short **data, char **data24)
2282 short *loaded_data = NULL;
2283 char *loaded_data24 = NULL;
2285 int num_samples = (end + 1) - start;
2286 fluid_return_val_if_fail(num_samples > 0, -1);
2288 if((start * sizeof(short) > sf->samplesize) || (end * sizeof(short) > sf->samplesize))
2290 FLUID_LOG(FLUID_ERR, "Sample offsets exceed sample data chunk");
2294 /* Load 16-bit sample data */
2295 if(sf->fcbs->fseek(sf->sffd, sf->samplepos + (start * sizeof(short)), SEEK_SET) == FLUID_FAILED)
2297 FLUID_LOG(FLUID_ERR, "Failed to seek to sample position");
2301 loaded_data = FLUID_ARRAY(short, num_samples);
2303 if(loaded_data == NULL)
2305 FLUID_LOG(FLUID_ERR, "Out of memory");
2309 if(sf->fcbs->fread(loaded_data, num_samples * sizeof(short), sf->sffd) == FLUID_FAILED)
2311 FLUID_LOG(FLUID_ERR, "Failed to read sample data");
2315 /* If this machine is big endian, byte swap the 16 bit samples */
2316 if(FLUID_IS_BIG_ENDIAN)
2320 for(i = 0; i < num_samples; i++)
2322 loaded_data[i] = FLUID_LE16TOH(loaded_data[i]);
2326 *data = loaded_data;
2328 /* Optionally load additional 8 bit sample data for 24-bit support. Any failures while loading
2329 * the 24-bit sample data will be logged as errors but won't prevent the sample reading to
2330 * fail, as sound output is still possible with the 16-bit sample data. */
2333 if((start > sf->sample24size) || (end > sf->sample24size))
2335 FLUID_LOG(FLUID_ERR, "Sample offsets exceed 24-bit sample data chunk");
2339 if(sf->fcbs->fseek(sf->sffd, sf->sample24pos + start, SEEK_SET) == FLUID_FAILED)
2341 FLUID_LOG(FLUID_ERR, "Failed to seek position for 24-bit sample data in data file");
2345 loaded_data24 = FLUID_ARRAY(char, num_samples);
2347 if(loaded_data24 == NULL)
2349 FLUID_LOG(FLUID_ERR, "Out of memory reading 24-bit sample data");
2353 if(sf->fcbs->fread(loaded_data24, num_samples, sf->sffd) == FLUID_FAILED)
2355 FLUID_LOG(FLUID_ERR, "Failed to read 24-bit sample data");
2360 *data24 = loaded_data24;
2365 FLUID_LOG(FLUID_WARN, "Ignoring 24-bit sample data, sound quality might suffer");
2366 FLUID_FREE(loaded_data24);
2371 FLUID_FREE(loaded_data);
2372 FLUID_FREE(loaded_data24);
2377 /* Ogg Vorbis loading and decompression */
2378 #if LIBSNDFILE_SUPPORT
2380 /* Virtual file access rountines to allow loading individually compressed
2381 * samples from the Soundfont sample data chunk using the file callbacks
2382 * passing in during opening of the file */
2383 typedef struct _sfvio_data_t
2386 sf_count_t start; /* start byte offset of compressed data */
2387 sf_count_t end; /* end byte offset of compressed data */
2388 sf_count_t offset; /* current virtual file offset from start byte offset */
2392 static sf_count_t sfvio_get_filelen(void *user_data)
2394 sfvio_data_t *data = user_data;
2396 return (data->end + 1) - data->start;
2399 static sf_count_t sfvio_seek(sf_count_t offset, int whence, void *user_data)
2401 sfvio_data_t *data = user_data;
2402 SFData *sf = data->sffile;
2403 sf_count_t new_offset;
2408 new_offset = offset;
2412 new_offset = data->offset + offset;
2416 new_offset = sfvio_get_filelen(user_data) + offset;
2420 goto fail; /* proper error handling not possible?? */
2423 if(sf->fcbs->fseek(sf->sffd, sf->samplepos + data->start + new_offset, SEEK_SET) != FLUID_FAILED)
2425 data->offset = new_offset;
2429 return data->offset;
2432 static sf_count_t sfvio_read(void *ptr, sf_count_t count, void *user_data)
2434 sfvio_data_t *data = user_data;
2435 SFData *sf = data->sffile;
2438 remain = sfvio_get_filelen(user_data) - data->offset;
2450 if(sf->fcbs->fread(ptr, count, sf->sffd) == FLUID_FAILED)
2452 FLUID_LOG(FLUID_ERR, "Failed to read compressed sample data");
2456 data->offset += count;
2461 static sf_count_t sfvio_tell(void *user_data)
2463 sfvio_data_t *data = user_data;
2465 return data->offset;
2469 * Read Ogg Vorbis compressed data from the Soundfont and decompress it, returning the number of samples
2470 * in the decompressed WAV. Only 16-bit mono samples are supported.
2472 * Note that this function takes byte indices for start and end source data. The sample headers in SF3
2473 * files use byte indices, so those pointers can be passed directly to this function.
2475 * This function uses a virtual file structure in order to read the Ogg Vorbis
2476 * data from arbitrary locations in the source file.
2478 static int fluid_sffile_read_vorbis(SFData *sf, unsigned int start_byte, unsigned int end_byte, short **data)
2482 SF_VIRTUAL_IO sfvio =
2490 sfvio_data_t sfdata;
2491 short *wav_data = NULL;
2493 if((start_byte > sf->samplesize) || (end_byte > sf->samplesize))
2495 FLUID_LOG(FLUID_ERR, "Ogg Vorbis data offsets exceed sample data chunk");
2499 // Initialize file position indicator and SF_INFO structure
2501 sfdata.start = start_byte;
2502 sfdata.end = end_byte;
2505 memset(&sfinfo, 0, sizeof(sfinfo));
2507 /* Seek to beginning of Ogg Vorbis data in Soundfont */
2508 if(sf->fcbs->fseek(sf->sffd, sf->samplepos + start_byte, SEEK_SET) == FLUID_FAILED)
2510 FLUID_LOG(FLUID_ERR, "Failed to seek to compressd sample position");
2514 // Open sample as a virtual file
2515 sndfile = sf_open_virtual(&sfvio, SFM_READ, &sfinfo, &sfdata);
2519 FLUID_LOG(FLUID_ERR, sf_strerror(sndfile));
2524 if(!sfinfo.frames || !sfinfo.channels)
2526 FLUID_LOG(FLUID_DBG, "Empty decompressed sample");
2532 /* FIXME: ensure that the decompressed WAV data is 16-bit mono? */
2534 wav_data = FLUID_ARRAY(short, sfinfo.frames * sfinfo.channels);
2538 FLUID_LOG(FLUID_ERR, "Out of memory");
2542 /* Automatically decompresses the Ogg Vorbis data to 16-bit WAV */
2543 if(sf_readf_short(sndfile, wav_data, sfinfo.frames) < sfinfo.frames)
2545 FLUID_LOG(FLUID_DBG, "Decompression failed!");
2546 FLUID_LOG(FLUID_ERR, sf_strerror(sndfile));
2554 return sfinfo.frames;
2557 FLUID_FREE(wav_data);
2562 static int fluid_sffile_read_vorbis(SFData *sf, unsigned int start_byte, unsigned int end_byte, short **data)