1
/*================================================================
4
*================================================================*/
12
/*----------------------------------------------------------------
14
*----------------------------------------------------------------*/
16
#define NEW(type,nums) (type*)malloc(sizeof(type) * (nums))
18
static int READCHUNK(tchunk *vp, FILE *fd)
20
if (fread(vp, 8, 1, fd) != 1) return -1;
21
vp->size = LE_LONG(vp->size);
25
static int READDW(uint32 *vp, FILE *fd)
27
if (fread(vp, 4, 1, fd) != 1) return -1;
32
static int READW(uint16 *vp, FILE *fd)
34
if (fread(vp, 2, 1, fd) != 1) return -1;
39
#define READSTR(var,fd) fread(var, 20, 1, fd)
42
static int READSTR(char *str, FILE *fd)
46
if(fread(str, 20, 1, fd) != 1) return -1;
49
while(n > 0 && str[n - 1] == ' ')
56
#define READID(var,fd) fread(var, 1, 4, fd)
57
#define READB(var,fd) fread(var, 1, 1, fd)
58
#define SKIPB(fd) {uint8 dummy; fread(&dummy, 1, 1, fd);}
59
#define SKIPW(fd) {uint16 dummy; fread(&dummy, 2, 1, fd);}
60
#define SKIPDW(fd) {uint32 dummy; fread(&dummy, 4, 1, fd);}
62
static int getchunk(const char *id);
63
static void process_chunk(int id, int s, SFInfo *sf, FILE *fd);
64
static void load_sample_names(int size, SFInfo *sf, FILE *fd);
65
static void load_preset_header(int size, SFInfo *sf, FILE *fd);
66
static void load_inst_header(int size, SFInfo *sf, FILE *fd);
67
static void load_bag(int size, SFInfo *sf, FILE *fd, int *totalp, unsigned short **bufp);
68
static void load_gen(int size, SFInfo *sf, FILE *fd, int *totalp, tgenrec **bufp);
69
static void load_sample_info(int size, SFInfo *sf, FILE *fd);
75
UNKN_ID, RIFF_ID, LIST_ID,
77
INFO_ID, SDTA_ID, PDTA_ID,
79
IFIL_ID, ISNG_ID, IROM_ID, INAM_ID, IVER_ID, IPRD_ID, ICOP_ID,
81
ICRD_ID, IENG_ID, ISFT_ID, ICMT_ID,
83
/* sample data stuff */
86
PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID,
88
INST_ID, IBAG_ID, IMOD_ID, IGEN_ID,
94
/*----------------------------------------------------------------
96
*----------------------------------------------------------------*/
99
static void debugid(char *tag, char *p)
101
char buf[5]; strncpy(buf, p, 4); buf[4]=0;
102
fprintf(stderr,"[%s:%s]\n", tag, buf);
105
static void debugname(char *tag, char *p)
107
char buf[21]; strncpy(buf, p, 20); buf[20]=0;
108
fprintf(stderr,"[%s:%s]\n", tag, buf);
111
static void debugval(char *tag, int v)
113
fprintf(stderr, "[%s:%d]\n", tag, v);
116
#define debugid(t,s) /**/
117
#define debugname(t,s) /**/
118
#define debugval(t,v) /**/
122
/*----------------------------------------------------------------
124
*----------------------------------------------------------------*/
126
void load_sbk(FILE *fd, SFInfo *sf)
128
tchunk chunk, subchunk;
130
READID(sf->sbkh.riff, fd);
131
READDW(&sf->sbkh.size, fd);
132
READID(sf->sbkh.sfbk, fd);
136
READID(chunk.id, fd);
137
switch (getchunk(chunk.id)) {
139
READDW(&chunk.size, fd);
140
READID(subchunk.id, fd);
141
process_chunk(getchunk(subchunk.id), chunk.size - 4, sf, fd);
148
/*----------------------------------------------------------------
150
*----------------------------------------------------------------*/
152
void free_sbk(SFInfo *sf)
154
free(sf->samplenames);
156
free(sf->sampleinfo);
162
/* if (sf->sf_name) free(sf->sf_name); */
163
memset(sf, 0, sizeof(*sf));
168
/*----------------------------------------------------------------
170
*----------------------------------------------------------------*/
172
static int getchunk(const char *id)
174
static struct idstring {
213
for (i = 0; i < sizeof(idlist)/sizeof(idlist[0]); i++) {
214
if (strncmp(id, idlist[i].str, 4) == 0) {
225
static void load_sample_names(int size, SFInfo *sf, FILE *fd)
228
sf->nrsamples = size / 20;
229
sf->samplenames = NEW(tsamplenames, sf->nrsamples);
230
for (i = 0; i < sf->nrsamples; i++) {
231
READSTR(sf->samplenames[i].name, fd);
232
sf->samplenames[i].name[20] = 0;
236
static void load_preset_header(int size, SFInfo *sf, FILE *fd)
239
sf->nrpresets = size / 38;
240
sf->presethdr = NEW(tpresethdr, sf->nrpresets);
241
for (i = 0; i < sf->nrpresets; i++) {
242
READSTR(sf->presethdr[i].name, fd);
243
READW(&sf->presethdr[i].preset, fd);
244
sf->presethdr[i].sub_preset = sf->presethdr[i].preset;
245
READW(&sf->presethdr[i].bank, fd);
246
sf->presethdr[i].sub_bank = sf->presethdr[i].bank;
247
READW(&sf->presethdr[i].bagNdx, fd);
248
SKIPDW(fd); /* lib */
249
SKIPDW(fd); /* genre */
250
SKIPDW(fd); /* morph */
254
static void load_inst_header(int size, SFInfo *sf, FILE *fd)
258
sf->nrinsts = size / 22;
259
sf->insthdr = NEW(tinsthdr, sf->nrinsts);
260
for (i = 0; i < sf->nrinsts; i++) {
261
READSTR(sf->insthdr[i].name, fd);
262
READW(&sf->insthdr[i].bagNdx, fd);
267
static void load_bag(int size, SFInfo *sf, FILE *fd, int *totalp, unsigned short **bufp)
272
debugval("bagsize", size);
274
buf = NEW(unsigned short, size);
275
for (i = 0; i < size; i++) {
283
static void load_gen(int size, SFInfo *sf, FILE *fd, int *totalp, tgenrec **bufp)
288
debugval("gensize", size);
290
buf = NEW(tgenrec, size);
291
for (i = 0; i < size; i++) {
292
READW(&buf[i].oper, fd);
293
READW(&buf[i].amount, fd);
299
static void load_sample_info(int size, SFInfo *sf, FILE *fd)
303
debugval("infosize", size);
304
if (sf->version > 1) {
305
sf->nrinfos = size / 46;
306
sf->nrsamples = sf->nrinfos;
307
sf->sampleinfo = NEW(tsampleinfo, sf->nrinfos);
308
sf->samplenames = NEW(tsamplenames, sf->nrsamples);
311
sf->nrinfos = size / 16;
312
sf->sampleinfo = NEW(tsampleinfo, sf->nrinfos);
316
for (i = 0; i < sf->nrinfos; i++) {
318
READSTR(sf->samplenames[i].name, fd);
319
READDW(&sf->sampleinfo[i].startsample, fd);
320
READDW(&sf->sampleinfo[i].endsample, fd);
321
READDW(&sf->sampleinfo[i].startloop, fd);
322
READDW(&sf->sampleinfo[i].endloop, fd);
323
if (sf->version > 1) {
324
READDW(&sf->sampleinfo[i].samplerate, fd);
325
READB(&sf->sampleinfo[i].originalPitch, fd);
326
READB(&sf->sampleinfo[i].pitchCorrection, fd);
327
READW(&sf->sampleinfo[i].samplelink, fd);
328
READW(&sf->sampleinfo[i].sampletype, fd);
330
if (sf->sampleinfo[i].startsample == 0)
332
sf->sampleinfo[i].startloop++;
333
sf->sampleinfo[i].endloop += 2;
334
sf->sampleinfo[i].samplerate = 44100;
335
sf->sampleinfo[i].originalPitch = 60;
336
sf->sampleinfo[i].pitchCorrection = 0;
337
sf->sampleinfo[i].samplelink = 0;
339
sf->sampleinfo[i].sampletype = 0x8001;
341
sf->sampleinfo[i].sampletype = 1;
350
static void process_chunk(int id, int s, SFInfo *sf, FILE *fd)
357
READCHUNK(&subchunk, fd);
358
while ((cid = getchunk(subchunk.id)) != LIST_ID) {
361
READW(&sf->version, fd);
362
READW(&sf->minorversion, fd);
366
sf->sf_name = (char*)malloc(subchunk.size);
367
if (sf->sf_name == NULL) {
368
fprintf(stderr, "can't malloc\n");
371
fread(sf->sf_name, 1, subchunk.size, fd);
375
fseek(fd, subchunk.size, SEEK_CUR);
378
READCHUNK(&subchunk, fd);
382
fseek(fd, -8, SEEK_CUR); /* seek back */
386
READCHUNK(&subchunk, fd);
387
while ((cid = getchunk(subchunk.id)) != LIST_ID) {
390
if (sf->version > 1) {
391
printf("**** version 2 has obsolete format??\n");
392
fseek(fd, subchunk.size, SEEK_CUR);
394
load_sample_names(subchunk.size, sf, fd);
397
sf->samplepos = ftell(fd);
398
sf->samplesize = subchunk.size;
399
fseek(fd, subchunk.size, SEEK_CUR);
401
READCHUNK(&subchunk, fd);
405
fseek(fd, -8, SEEK_CUR); /* seek back */
409
READCHUNK(&subchunk, fd);
410
while ((cid = getchunk(subchunk.id)) != LIST_ID) {
413
load_preset_header(subchunk.size, sf, fd);
417
load_bag(subchunk.size, sf, fd,
418
&sf->nrpbags, &sf->presetbag);
421
case PMOD_ID: /* ignored */
422
fseek(fd, subchunk.size, SEEK_CUR);
426
load_gen(subchunk.size, sf, fd,
427
&sf->nrpgens, &sf->presetgen);
431
load_inst_header(subchunk.size, sf, fd);
435
load_bag(subchunk.size, sf, fd,
436
&sf->nribags, &sf->instbag);
439
case IMOD_ID: /* ingored */
440
fseek(fd, subchunk.size, SEEK_CUR);
444
load_gen(subchunk.size, sf, fd,
445
&sf->nrigens, &sf->instgen);
449
load_sample_info(subchunk.size, sf, fd);
453
fprintf(stderr, "unknown id\n");
454
fseek(fd, subchunk.size, SEEK_CUR);
457
READCHUNK(&subchunk, fd);
459
debugid("file", "EOF");
463
fseek(fd, -8, SEEK_CUR); /* rewind */