1
//=========================================================
4
// $Id: sfont.cpp,v 1.1 2002/01/30 12:08:39 muse Exp $
6
// This file is derived from IIWU Synth and modified
8
// Parts of IIWU are derived from Smurf Sound Font Editor.
9
// Parts of Smurf Sound Font Editor are derived from
11
// Smurf: Copyright (C) 1999-2000 Josh Green
12
// IIWU: Copyright (C) 2001 Peter Hanappe
13
// MusE: Copyright (C) 2001 Werner Schweer
14
// awesfx: Copyright (C) 1996-1999 Takashi Iwai
15
//=========================================================
24
UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID,
25
INFO_ID, SDTA_ID, PDTA_ID, /* info/sample/preset */
27
IFIL_ID, ISNG_ID, INAM_ID, IROM_ID, /* info ids (1st byte of info strings) */
28
IVER_ID, ICRD_ID, IENG_ID, IPRD_ID, /* more info ids */
29
ICOP_ID, ICMT_ID, ISFT_ID, /* and yet more info ids */
31
SNAM_ID, SMPL_ID, /* sample ids */
32
PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID, /* preset ids */
33
IHDR_ID, IBAG_ID, IMOD_ID, IGEN_ID, /* instrument ids */
34
SHDR_ID /* sample info */
37
//---------------------------------------------------------
39
// Set an array of generators to their initial value
40
//---------------------------------------------------------
42
void gen_init_array(Gen* gen)
45
for (i = 0; i < GEN_LAST; i++) {
46
gen[i].flags = GEN_UNUSED;
50
gen[GEN_FILTERFC].val = 13500;
51
gen[GEN_MODLFODELAY].val = -12000;
52
gen[GEN_VIBLFODELAY].val = -12000;
53
gen[GEN_MODENVDELAY].val = -12000;
54
gen[GEN_MODENVATTACK].val = -12000;
55
gen[GEN_MODENVHOLD].val = -12000;
56
gen[GEN_MODENVDECAY].val = -12000;
57
gen[GEN_MODENVRELEASE].val = -12000;
58
gen[GEN_VOLENVDELAY].val = -12000;
59
gen[GEN_VOLENVATTACK].val = -12000;
60
gen[GEN_VOLENVHOLD].val = -12000;
61
gen[GEN_VOLENVDECAY].val = -12000;
62
gen[GEN_VOLENVRELEASE].val = -12000;
63
gen[GEN_KEYNUM].val = -1;
64
gen[GEN_VELOCITY].val = -1;
65
gen[GEN_SCALETUNE].val = 100;
66
gen[GEN_OVERRIDEROOTKEY].val = -1;
69
//---------------------------------------------------------
71
//---------------------------------------------------------
73
int Zone::inside_range(int key, int vel)
75
return ((keylo <= key) && (keyhi >= key) && (vello <= vel) && (velhi >= vel));
78
//---------------------------------------------------------
80
//---------------------------------------------------------
93
//---------------------------------------------------------
95
//---------------------------------------------------------
107
//---------------------------------------------------------
109
//---------------------------------------------------------
125
//---------------------------------------------------------
127
//---------------------------------------------------------
132
while (m) { // Free mod chunks for this zone
139
//---------------------------------------------------------
141
//---------------------------------------------------------
143
static int chunkid(unsigned id)
145
static char idlist[] = {
146
"RIFFLISTsfbkINFOsdtapdtaifilisngINAMiromiverICRDIENGIPRD"
147
"ICOPICMTISFTsnamsmplphdrpbagpmodpgeninstibagimodigenshdr"
149
unsigned* p = (unsigned *) & idlist;
151
for (unsigned i = 0; i < sizeof (idlist) / sizeof (int); ++i, ++p)
157
//---------------------------------------------------------
159
// check validity of instrument generator
160
// return true if valid
161
//---------------------------------------------------------
163
static bool gen_valid(unsigned gen)
165
static unsigned badgen[] = {
166
Gen_Unused1, Gen_Unused2, Gen_Unused3, Gen_Unused4,
167
Gen_Reserved1, Gen_Reserved2, Gen_Reserved3, 0
170
if (gen > Gen_MaxValid)
173
for (i = 0; i < sizeof(badgen)/sizeof(*badgen); ++i)
174
if (badgen[i] == gen)
179
//---------------------------------------------------------
181
// check validity of preset generator
182
//---------------------------------------------------------
184
static bool gen_validp(unsigned int gen)
185
{ /* is preset generator valid? */
186
static unsigned badpgen[] = {
187
Gen_StartAddrOfs, Gen_EndAddrOfs, Gen_StartLoopAddrOfs,
188
Gen_EndLoopAddrOfs, Gen_StartAddrCoarseOfs, Gen_EndAddrCoarseOfs,
189
Gen_StartLoopAddrCoarseOfs, Gen_Keynum, Gen_Velocity,
190
Gen_EndLoopAddrCoarseOfs, Gen_SampleModes, Gen_ExclusiveClass,
191
Gen_OverrideRootKey, 0
194
if (!gen_valid (gen))
197
while (badpgen[i] && badpgen[i] != (unsigned) gen)
199
return (badpgen[i] == 0);
202
//---------------------------------------------------------
205
//---------------------------------------------------------
207
static void gerr(char * fmt, ...)
211
va_start (args, fmt);
218
//---------------------------------------------------------
220
// delete zone from zone list
221
//---------------------------------------------------------
223
static void sfont_zone_delete(Zone** zlist, Zone* zone)
228
for (Zone* tmp = *zlist; tmp; tmp = tmp->next) {
231
prev->next = tmp->next;
233
*zlist = (*zlist)->next;
242
static void SLADVREMZ(Zone*& list, Zone*& item)
247
sfont_zone_delete(&list, _temp);
251
//---------------------------------------------------------
253
//---------------------------------------------------------
255
void SFont::safe_fread(void *buf, int count)
257
if (fread (buf, count, 1, fd) != 1) { // size_t = count, nmemb = 1
265
//---------------------------------------------------------
267
//---------------------------------------------------------
269
void SFont::readid(unsigned* var)
274
//---------------------------------------------------------
276
//---------------------------------------------------------
278
void SFont::readstr(char* var)
284
//---------------------------------------------------------
286
//---------------------------------------------------------
288
void SFont::read_listchunk(SFChunk* chunk)
290
safe_fread(chunk, 8);
291
if (chunkid (chunk->id) != LIST_ID) /* error if ! list chunk */
293
readid(&chunk->id); /* read id string */
297
//---------------------------------------------------------
299
//---------------------------------------------------------
308
//---------------------------------------------------------
310
//---------------------------------------------------------
312
unsigned int SFont::readWord()
319
//---------------------------------------------------------
321
//---------------------------------------------------------
330
//---------------------------------------------------------
332
//---------------------------------------------------------
341
//---------------------------------------------------------
343
// read unsigned char
344
//---------------------------------------------------------
346
unsigned int SFont::readByte()
353
//---------------------------------------------------------
355
//---------------------------------------------------------
357
void SFont::fskip(int size)
359
if (fseek (fd, size, SEEK_CUR) == -1)
363
//---------------------------------------------------------
365
//---------------------------------------------------------
380
//---------------------------------------------------------
382
//---------------------------------------------------------
389
Sample* s = sample->next;
396
for (SFInfo* i = info; i; ) {
397
SFInfo* ni = i->next;
403
Preset* nz = preset->next;
409
Inst* ni = inst->next;
415
//---------------------------------------------------------
417
//---------------------------------------------------------
419
void SFont::process_info(int size)
425
safe_fread(&chunk, 8);
428
unsigned char id = chunkid(chunk.id);
430
if (id == IFIL_ID) { // sound font version chunk?
434
version.major = readw();
435
version.minor = readw();
437
if (version.major < 2)
439
if (version.major > 2)
440
gerr ("Sound font version is %d.%d which is newer than"
441
" what this version of Smurf was designed for (v2.0x)");
443
else if (id == IVER_ID) { // ROM version chunk?
446
romver.major = readw();
447
romver.minor = readw();
449
else if (id != UNKN_ID) {
450
if ((id != ICMT_ID && chunk.size > 256) || (chunk.size > 65536)
454
/* alloc for chunk id and da chunk */
455
SFInfo* item = new SFInfo;
457
item->data = new char[chunk.size+1];
459
/* attach to INFO list, sfont_close will cleanup if FAIL occurs */
468
safe_fread (&item->data[1], chunk.size);
470
/* force terminate info item (don't forget uchar info ID) */
471
*(item->data + chunk.size) = '\0';
482
//---------------------------------------------------------
484
//---------------------------------------------------------
486
void SFont::load_body()
490
safe_fread(&chunk, 8);
491
if (chunkid (chunk.id) != RIFF_ID) { /* error if not RIFF */
495
readid(&chunk.id); // load file ID */
496
if (chunkid (chunk.id) != SFBK_ID)
498
if (chunk.size != unsigned(fsize - 8))
501
// Process INFO block
502
read_listchunk(&chunk);
503
if (chunkid (chunk.id) != INFO_ID)
505
process_info(chunk.size);
507
// Process sample chunk
508
read_listchunk(&chunk);
509
if (chunkid (chunk.id) != SDTA_ID)
511
process_sdta(chunk.size);
513
// process HYDRA chunk
514
read_listchunk(&chunk);
515
if (chunkid (chunk.id) != PDTA_ID)
517
process_pdta(chunk.size);
523
/* sort preset list by bank, preset # */
524
//TODO preset = g_slist_sort(preset, (GCompareFunc) sfont_preset_compare_func);
528
//---------------------------------------------------------
530
//---------------------------------------------------------
532
void SFont::process_sdta(int size)
537
return; /* no sample data? */
540
safe_fread(&chunk, 8);
543
if (chunkid (chunk.id) != SMPL_ID)
546
if ((size - chunk.size) != 0)
549
/* sample data follows */
550
samplepos = ftell(fd);
552
/* used in fixup_sample() to check validity of sample headers */
553
sdtachunk_size = chunk.size;
554
samplesize = chunk.size;
558
//---------------------------------------------------------
560
//---------------------------------------------------------
562
void SFont::pdtahelper(unsigned expid, unsigned reclen, SFChunk* chunk, int* size)
566
safe_fread(chunk, 8);
569
if ((id = chunkid (chunk->id)) != expid)
571
if (chunk->size % reclen) /* valid chunk size? */
573
if ((*size -= chunk->size) < 0)
577
//---------------------------------------------------------
579
// preset header loader
580
//---------------------------------------------------------
582
void SFont::load_phdr(int size)
586
if (size % SFPHDRSIZE || size == 0)
589
int i = size / SFPHDRSIZE - 1;
590
if (i == 0) { /* at least one preset + term record */
591
gerr("File contains no presets");
596
Preset* pr = preset; // ptr to previous preset
600
Preset* p = new Preset();
604
p->name = strdup(buffer);
605
p->prog = readWord();
606
int lbank = readWord();
607
if (lbank == 128) { // drum set
613
int zndx = readWord();
619
if (pr) { /* not first preset? */
632
if (zndx > 0) /* 1st preset, warn if ofs >0 */
635
pr = p; /* update preset ptr */
640
int zndx = readWord(); /* Read terminal generator index */
653
//---------------------------------------------------------
655
//---------------------------------------------------------
657
void SFont::process_pdta(int size)
661
pdtahelper(PHDR_ID, SFPHDRSIZE, &chunk, &size);
662
load_phdr(chunk.size);
664
pdtahelper(PBAG_ID, SFBAGSIZE, &chunk, &size);
665
load_pbag(chunk.size);
667
pdtahelper(PMOD_ID, SFMODSIZE, &chunk, &size);
668
load_pmod(chunk.size);
670
pdtahelper(PGEN_ID, SFGENSIZE, &chunk, &size);
671
load_pgen(chunk.size);
673
pdtahelper(IHDR_ID, SFIHDRSIZE, &chunk, &size);
674
load_ihdr(chunk.size);
676
pdtahelper(IBAG_ID, SFBAGSIZE, &chunk, &size);
677
load_ibag(chunk.size);
679
pdtahelper(IMOD_ID, SFMODSIZE, &chunk, &size);
680
load_imod(chunk.size);
682
pdtahelper(IGEN_ID, SFGENSIZE, &chunk, &size);
683
load_igen(chunk.size);
685
pdtahelper(SHDR_ID, SFSHDRSIZE, &chunk, &size);
686
load_shdr(chunk.size);
689
//---------------------------------------------------------
692
//---------------------------------------------------------
694
void SFont::load_pbag(int size)
697
unsigned genndx, modndx;
698
unsigned pgenndx=0, pmodndx = 0;
700
if ((size % SFBAGSIZE) || size == 0) // size is multiple of SFBAGSIZE?
703
for (Preset* p = preset; p; p = p->next) {
704
for (Zone* z = p->zone; z; z = z->next) {
711
if (pz) { /* if not first zone */
712
if (genndx < pgenndx)
714
if (modndx < pmodndx)
716
// printf("preset <%s> Gen:%d Mod:%d\n", p->name, genndx-pgenndx, modndx-pmodndx);
717
int i = genndx - pgenndx;
719
i = modndx - pmodndx;
721
SFMod* m = new SFMod;
726
pz = z; // update previous zone ptr
727
pgenndx = genndx; /* update previous zone gen index */
728
pmodndx = modndx; /* update previous zone mod index */
746
if (genndx < pgenndx)
748
if (modndx < pmodndx)
750
int i = genndx - pgenndx;
753
i = modndx - pmodndx;
755
SFMod* m = new SFMod;
761
//---------------------------------------------------------
763
// preset modulator loader
764
//---------------------------------------------------------
766
void SFont::load_pmod(int size)
768
for (Preset* p = preset; p; p = p->next) {
769
for (Zone* z = p->zone; z; z = z->next) {
770
for (SFMod* m = z->mod; m; m = m->next) {
771
if ((size -= SFMODSIZE) < 0)
774
m->dest = readWord();
776
m->amtsrc = readWord();
777
m->trans = readWord();
782
* If there isn't even a terminal record
783
* Hmmm, the specs say there should be one, but..
791
fskip(SFMODSIZE); /* terminal mod */
794
//---------------------------------------------------------
796
// instrument header loader
797
//---------------------------------------------------------
799
void SFont::load_ihdr(int size)
801
if (size % SFIHDRSIZE || size == 0) /* chunk size is valid? */
804
size = size / SFIHDRSIZE - 1;
805
if (size == 0) { /* at least one preset + term record */
806
gerr ("File contains no instruments");
810
Inst *pr = inst; // ptr to current & previous instrument
813
for (int i = 0; i < size; i++) { /* load all instrument headers */
816
p->zone = 0; /* For proper cleanup if fail (sfont_close) */
818
int zndx = readWord();
819
if (pr) { /* not first instrument? */
823
int i2 = zndx - pzndx;
832
if (zndx > 0) /* 1st inst, warn if ofs >0 */
833
gerr ("%d instrument zones not referenced, discarding", zndx);
836
pr = p; /* update instrument ptr */
840
int zndx = readWord();
844
int i2 = zndx - pzndx;
852
//---------------------------------------------------------
854
// instrument bag loader
855
//---------------------------------------------------------
857
void SFont::load_ibag(int size)
860
unsigned int genndx, modndx;
861
unsigned int pgenndx=0, pmodndx=0;
863
if (size % SFBAGSIZE || size == 0) /* size is multiple of SFBAGSIZE? */
866
for (Inst* p = inst; p; p = p->next) {
867
for (Zone* z = p->zone; z; z = z->next) {
868
if ((size -= SFBAGSIZE) < 0)
873
if (pz) { /* if not first zone */
874
if (genndx < pgenndx)
876
if (modndx < pmodndx)
878
pz->sfgen += genndx - pgenndx;
879
for (unsigned i = pmodndx; i < modndx; ++i) {
880
SFMod* m = new SFMod;
885
pz = z; /* update previous zone ptr */
898
if (!pz) { /* in case that all are no zoners */
900
gerr ("No instrument generators and terminal index not 0");
902
gerr ("No instrument modulators and terminal index not 0");
906
if (genndx < pgenndx)
908
if (modndx < pmodndx)
911
pz->sfgen += genndx - pgenndx;
912
for (unsigned i = pmodndx; i < modndx; ++i) {
913
SFMod* m = new SFMod;
919
//---------------------------------------------------------
921
// instrument modulator loader
922
//---------------------------------------------------------
924
void SFont::load_imod(int size)
926
for (Inst* p = inst; p; p = p->next) {
927
for (Zone* p2 = p->zone; p2; p2 = p2->next) {
928
for (SFMod* m = p2->mod; m; m = m->next) {
929
if ((size -= SFMODSIZE) < 0)
932
m->dest = readWord();
934
m->amtsrc = readWord();
935
m->trans = readWord();
940
If there isn't even a terminal record
941
Hmmm, the specs say there should be one, but..
949
fskip(SFMODSIZE); /* terminal mod */
952
//---------------------------------------------------------
954
// preset generator loader
955
// generator (per preset) loading rules:
956
// Zones with no generators or modulators shall be annihilated
957
// Global zone must be 1st zone, discard additional ones (instrumentless zones)
959
// generator (per zone) loading rules (in order of decreasing precedence):
960
// KeyRange is 1st in list (if exists), else discard
961
// if a VelRange exists only
962
// preceded by a KeyRange, else discard
963
// if a generator follows an instrument
965
// if a duplicate generator exists
966
// replace previous one
967
//---------------------------------------------------------
969
void SFont::load_pgen(int size)
971
for (Preset* p = preset; p; p = p->next) {
977
for (Zone* zone = p->zone; zone; zone = zone->next) {
979
for (int gen = 0; gen < zone->sfgen; ++gen) {
980
if ((size -= SFGENSIZE) < 0)
988
unsigned genid = readw();
990
if (genid == Gen_KeyRange) {
991
unsigned char a = readByte();
992
unsigned char b = readByte();
999
else if (genid == Gen_VelRange) {
1000
unsigned char a = readByte();
1001
unsigned char b = readByte();
1008
else if (genid == Gen_Instrument) { // inst is last gen
1010
zone->instsampno = readWord() + 1;
1015
if (gen_validp(genid)) {
1016
zone->gen[genid].val = double(data);
1017
zone->gen[genid].flags = GEN_SET;
1023
if (!gzone) { // Prior global zones?
1026
// if global zone is not 1st zone, relocate
1031
sfont_zone_delete(hz, pp);
1037
else { // previous global zone exists, discard
1038
sfont_zone_delete(hz, zone);
1043
// in case there isn't a terminal record
1053
//---------------------------------------------------------
1055
// load instrument generators
1056
// (see load_pgen for loading rules)
1057
//---------------------------------------------------------
1059
void SFont::load_igen(int size)
1061
for (Inst* ip = inst; ip; ip = ip->next) {
1067
for (Zone* zone = ip->zone; zone; zone = zone->next) {
1069
for (int gen = 0; gen < zone->sfgen; ++gen) {
1070
if ((size -= SFGENSIZE) < 0)
1078
unsigned genid = readWord();
1080
if (genid == Gen_KeyRange) {
1081
unsigned char a = readByte();
1082
unsigned char b = readByte();
1089
else if (genid == Gen_VelRange) {
1090
unsigned char a = readByte();
1091
unsigned char b = readByte();
1098
else if (genid == Gen_SampleId) {
1100
zone->instsampno = readWord() + 1;
1105
if (gen_valid(genid)) { /* gen valid? */
1106
zone->gen[genid].val = double(data);
1107
zone->gen[genid].flags = GEN_SET;
1116
/* if global zone is not 1st zone, relocate */
1119
SLADVREMZ (*hz, zone);
1126
sfont_zone_delete (hz, zone);
1132
/* for those non-terminal record cases, grr! */
1139
fskip(SFGENSIZE); /* terminal gen */
1142
//---------------------------------------------------------
1144
// sample header loader
1145
//---------------------------------------------------------
1147
void SFont::load_shdr(int size)
1149
if (size % SFSHDRSIZE || size == 0) /* size is multiple of SHDR size? */
1152
size = size / SFSHDRSIZE - 1;
1153
if (size == 0) { /* at least one sample + term record? */
1154
gerr ("File contains no samples");
1158
/* load all sample headers */
1159
Sample* ps = sample;
1160
while (ps && ps->next)
1163
for (int i = 0; i < size; i++) {
1164
Sample* p = new Sample;
1174
p->end = readd(); // end, loopstart and loopend
1175
p->loopstart = readd(); // will be checked and turned into
1176
p->loopend = readd(); // offsets in fixup_sample()
1177
p->samplerate = readd();
1179
p->origpitch = readByte();
1180
p->pitchadj = readb();
1181
fskip(2); // skip sample link
1182
p->sampletype = readWord();
1184
fskip(SFSHDRSIZE); /* skip terminal shdr */
1187
//---------------------------------------------------------
1189
// "fixup" (inst # -> inst ptr) instrument
1190
// references in preset list
1191
//---------------------------------------------------------
1193
void SFont::fixup_pgen()
1195
for (Preset* p = preset; p; p = p->next) {
1196
for (Zone* z = p->zone; z; z = z->next) {
1197
int i = z->instsampno;
1198
if (i) { /* load instrument # */
1213
//---------------------------------------------------------
1215
// "fixup" (sample # -> sample ptr) sample references
1216
// in instrument list
1217
//---------------------------------------------------------
1219
void SFont::fixup_igen()
1221
for (Inst* p = inst; p; p = p->next) {
1222
for (Zone* z = p->zone; z; z = z->next) {
1223
int i = z->instsampno;
1224
if (i) { /* load sample # */
1225
Sample* ii = sample;
1232
// printf("invalid sample %d\n", z->instsampno);
1241
//---------------------------------------------------------
1243
// convert sample end, loopstart and loopend to offsets
1244
// and check if valid
1245
//---------------------------------------------------------
1247
void SFont::fixup_sample()
1249
for (Sample* sam = sample; sam; sam = sam->next) {
1250
/* if sample is not a ROM sample and end is over the sample data chunk
1251
or sam start is greater than 4 less than the end (at least 4 samples) */
1252
if ((!(sam->sampletype & SF_SAMPLETYPE_ROM) && sam->end
1253
> unsigned(sdtachunk_size)) || sam->start > (sam->end - 4)) {
1254
gerr ("Sample '%s' start/end file positions are invalid,"
1255
" disabling and will not be saved", sam->name());
1257
/* disable sample by setting all sample markers to 0 */
1258
sam->start = sam->end = sam->loopstart = sam->loopend = 0;
1261
else if (sam->loopend > sam->end || sam->loopstart >= sam->loopend
1262
|| sam->loopstart <= sam->start) { /* loop is fowled?? (cluck cluck :) */
1263
/* can pad loop by 8 samples and ensure at least 4 for loop (2*8+4) */
1264
if ((sam->end - sam->start) >= 20) {
1265
sam->loopstart = sam->start + 8;
1266
sam->loopend = sam->end - 8;
1268
else { /* loop is fowled, sample is tiny (can't pad 8 samples) */
1269
sam->loopstart = sam->start + 1;
1270
sam->loopend = sam->end - 1;
1273
sam->end -= 1; /* marks last sample, contrary to SF spec. */
1277
//---------------------------------------------------------
1279
//---------------------------------------------------------
1281
void SFont::load_sampledata()
1283
if (fseek(fd, samplepos, SEEK_SET) == -1)
1285
sampledata = new short[samplesize];
1286
safe_fread(sampledata, samplesize);
1287
for (Sample* s = sample; s; s = s->next)
1288
s->setData(sampledata);
1291
//---------------------------------------------------------
1293
//---------------------------------------------------------
1295
Sample* SFont::get_sample(const char *s) const
1297
for (Sample* sp = sample; sp; sp = sp->next) {
1298
if (strcmp(sp->name(), s) == 0)
1304
//---------------------------------------------------------
1306
//---------------------------------------------------------
1308
int SFont::load(const char* fn)
1310
static char* errMsg = "iiwu: load soundfont: %s failed: %s\n";
1314
if (!(fd = fopen (file, "rb"))) {
1315
fprintf(stderr, errMsg, "open", strerror(errno));
1319
if (fstat(fileno(fd), &buf) == -1) {
1320
fprintf(stderr, errMsg, "stat", strerror(errno));
1323
fsize = buf.st_size;
1326
int error = setjmp(env);
1331
const char* s = "??";
1334
case 1: s = "Sound font version info chunk has invalid size"; break;
1335
case 2: s = "Sound font version unsupported, convert to version 2.0x"; break;
1336
case 3: s = "ROM version info chunk has invalid size"; break;
1337
case 4: s = "INFO sub chunk has invalid chunk size"; break;
1338
case 5: s = "Invalid chunk id in INFO chunk"; break;
1339
case 6: s = "INFO chunk size mismatch"; break;
1340
case 7: s = "Invalid chunk id in level 0 parse"; break;
1341
case 8: s = "Not a RIFF file"; break;
1342
case 9: s = "Not a sound font file"; break;
1343
case 10: s = "Sound font file size mismatch"; break;
1344
case 11: s = "Invalid ID found when expecting INFO chunk"; break;
1345
case 12: s = "Invalid ID found when expecting SAMPLE chunk"; break;
1346
case 13: s = "Invalid ID found when expecting HYDRA chunk"; break;
1347
case 14: s = "Expected SMPL chunk found invalid id instead"; break;
1348
case 15: s = "SDTA chunk size mismatch"; break;
1349
case 16: s = "Unexpected PDTA sub-chunk"; break;
1350
case 17: s = "chunk size is not a multiple of xxx bytes"; break;
1351
case 18: s = "chunk size exceeds remaining PDTA chunk size"; break;
1352
case 19: s = "Preset header chunk size is invalid"; break;
1353
case 20: s = "Preset header indices not monotonic"; break;
1354
case 21: s = "xx preset zones not referenced, discarding"; break;
1355
case 22: s = "Preset header indices not monotonic"; break;
1356
case 23: s = "Preset bag chunk size is invalid"; break;
1357
case 24: s = "Preset bag chunk size mismatch"; break;
1358
case 25: s = "Preset bag generator indices not monotonic"; break;
1359
case 26: s = "Preset bag modulator indices not monotonic"; break;
1360
case 27: s = "No preset generators and terminal index not 0"; break;
1361
case 28: s = "No preset modulators and terminal index not 0"; break;
1362
case 29: s = "Preset bag generator indices not monotonic"; break;
1363
case 30: s = "Preset bag modulator indices not monotonic"; break;
1364
case 31: s = "Preset modulator chunk size mismatch"; break;
1365
case 32: s = "Preset modulator chunk size mismatch"; break;
1366
case 33: s = "Preset generator chunk size mismatch"; break;
1367
case 34: s = "Instrument header has invalid size"; break;
1368
case 35: s = "Instrument header indices not monotonic"; break;
1369
case 36: s = "Instrument bag chunk size is invalid"; break;
1370
case 37: s = "Instrument bag chunk size mismatch"; break;
1371
case 38: s = "Instrument generator indices not monotonic"; break;
1372
case 39: s = "Instrument modulator indices not monotonic"; break;
1373
case 40: s = "Instrument chunk size mismatch"; break;
1374
case 41: s = "Instrument generator indices not monotonic"; break;
1375
case 42: s = "Instrument modulator indices not monotonic"; break;
1376
case 43: s = "Instrument modulator chunk size mismatch"; break;
1377
case 44: s = "Instrument modulator chunk size mismatch"; break;
1378
case 45: s = "IGEN chunk size mismatch"; break;
1379
case 46: s = "Instrument generator chunk size mismatch"; break;
1380
case 47: s = "IGEN chunk size mismatch"; break;
1381
case 48: s = "Sample header has invalid size"; break;
1382
case 49: s = "Preset xx xx: Invalid instrument reference"; break;
1383
case 50: s = "Instrument xxx: Invalid sample reference"; break;
1384
case 51: s = "File read: EOF"; break;
1385
case 52: s = "File read"; break;
1386
case 53: s = "seek"; break;
1388
fprintf(stderr, errMsg, "", s);
1396
//---------------------------------------------------------
1398
//---------------------------------------------------------
1415
//---------------------------------------------------------
1417
//---------------------------------------------------------
1419
Preset* SFont::get_preset(char hbank, char lbank, char prog)
1424
if (p->hbank == hbank && p->lbank == lbank && (p->prog == prog)) {
1431
return next->get_preset(hbank, lbank, prog);
1435
//---------------------------------------------------------
1437
//---------------------------------------------------------
1439
void SFont::append_sfont(SFont* sfont2)
1444
next->append_sfont(sfont2);
1451
//=========================================================
1453
//=========================================================
1456
void SFont::dump() const
1458
printf("Sfont <%s> Version %d.%d, size %d\n", file,
1459
version.major, version.minor, fsize);
1460
for (Preset* p = preset; p; p = p->next)
1462
for (Inst* i = inst; i; i = i->next)
1466
void Preset::dump() const
1468
printf("Preset <%s> idx %d sfont %p\n", name, zoneIndex, _sfont);
1469
for (Zone* z = zone; z; z = z->next) {
1473
void Zone::dump() const
1475
printf(" Zone %d-%d %d-%d\n", keylo,keyhi,vello,velhi);
1476
printf(" inst %p, samp %p, sfgen %p, mod %p\n",
1477
inst, samp, sfgen, mod);
1478
for (SFGen* g = sfgen; g; g = g->next)
1480
for (SFMod* m = mod; m; m = m->next)
1485
void Inst::dump() const
1487
printf("Instrument <%s>\n", name);
1488
for (Zone* z = zone; z; z = z->next)
1492
void SFGen::dump() const
1494
printf(" SFGen: id %d\n", id);
1497
void SFMod::dump() const
1499
printf(" SFMod: %d %d %d %d %d\n",
1500
src, dest, amount, amtsrc, trans);