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