1 /*
2 TiMidity++ -- MIDI to WAVE converter and player
3 Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4 Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 /*================================================================
22 * sffile.c
23 * read SoundFont file (SBK/SF2) and store the layer lists
24 *
25 * Copyright (C) 1996,1997 Takashi Iwai
26 *
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
31 *
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 *
37 * You should have received a copy of the GNU General Public License
38 * along with this program; if not, write to the Free Software
39 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 *================================================================*/
41
42 /*
43 * Modified by Masanao Izumo <mo@goice.co.jp>
44 */
45
46 #ifdef HAVE_CONFIG_H
47 #include "config.h"
48 #endif /* HAVE_CONFIG_H */
49 #include <stdio.h>
50 #ifndef NO_STRING_H
51 #include <string.h>
52 #else
53 #include <strings.h>
54 #endif
55 #include <stdlib.h>
56 #include "timidity.h"
57 #include "common.h"
58 #include "controls.h"
59 #include "sffile.h"
60
61 extern int progbase;
62
63 /*================================================================
64 * preset / instrument bag record
65 *================================================================*/
66
67 typedef struct _SFBags {
68 int nbags;
69 uint16 *bag;
70 int ngens;
71 SFGenRec *gen;
72 } SFBags;
73
74 static SFBags prbags, inbags;
75
76
77 /*----------------------------------------------------------------
78 * function prototypes
79 *----------------------------------------------------------------*/
80
81 #define NEW(type,nums) (type*)safe_malloc(sizeof(type) * (nums))
82
READCHUNK(SFChunk * vp,struct timidity_file * tf)83 static int READCHUNK(SFChunk *vp, struct timidity_file *tf)
84 {
85 if(tf_read(vp, 8, 1, tf) != 1)
86 return -1;
87 vp->size = LE_LONG(vp->size);
88 return 1;
89 }
90
READDW(uint32 * vp,struct timidity_file * tf)91 static int READDW(uint32 *vp, struct timidity_file *tf)
92 {
93 if(tf_read(vp, 4, 1, tf) != 1)
94 return -1;
95 *vp = LE_LONG(*vp);
96 return 1;
97 }
98
READW(uint16 * vp,struct timidity_file * tf)99 static int READW(uint16 *vp, struct timidity_file *tf)
100 {
101 if(tf_read(vp, 2, 1, tf) != 1)
102 return -1;
103 *vp = LE_SHORT(*vp);
104 return 1;
105 }
106
READSTR(char * str,struct timidity_file * tf)107 static int READSTR(char *str, struct timidity_file *tf)
108 {
109 int n;
110
111 if(tf_read(str, 20, 1, tf) != 1)
112 return -1;
113 str[19] = '\0';
114 n = strlen(str);
115 while(n > 0 && str[n - 1] == ' ')
116 n--;
117 str[n] = '\0';
118 return n;
119 }
120
121 #define READID(var,tf) tf_read(var, 4, 1, tf)
122 #define READB(var,tf) tf_read(&var, 1, 1, tf)
123 #define SKIPB(tf) skip(tf, 1)
124 #define SKIPW(tf) skip(tf, 2)
125 #define SKIPDW(tf) skip(tf, 4)
126
127 #define FSKIP(size,tf) skip(tf, size)
128
129
130 /*----------------------------------------------------------------*/
131
132 static int chunkid(char *id);
133 static int process_list(int size, SFInfo *sf, struct timidity_file *fd);
134 static int process_info(int size, SFInfo *sf, struct timidity_file *fd);
135 static int process_sdta(int size, SFInfo *sf, struct timidity_file *fd);
136 static int process_pdta(int size, SFInfo *sf, struct timidity_file *fd);
137 static void load_sample_names(int size, SFInfo *sf, struct timidity_file *fd);
138 static void load_preset_header(int size, SFInfo *sf, struct timidity_file *fd);
139 static void load_inst_header(int size, SFInfo *sf, struct timidity_file *fd);
140 static void load_bag(int size, SFBags *bagp, struct timidity_file *fd);
141 static void load_gen(int size, SFBags *bagp, struct timidity_file *fd);
142 static void load_sample_info(int size, SFInfo *sf, struct timidity_file *fd);
143 static void convert_layers(SFInfo *sf);
144 static void generate_layers(SFHeader *hdr, SFHeader *next, SFBags *bags);
145 static void free_layer(SFHeader *hdr);
146
147
148 /*----------------------------------------------------------------
149 * id numbers
150 *----------------------------------------------------------------*/
151
152 enum {
153 /* level 0; chunk */
154 UNKN_ID, RIFF_ID, LIST_ID, SFBK_ID,
155 /* level 1; id only */
156 INFO_ID, SDTA_ID, PDTA_ID,
157 /* info stuff; chunk */
158 IFIL_ID, ISNG_ID, IROM_ID, INAM_ID, IVER_ID, IPRD_ID, ICOP_ID,
159 ICRD_ID, IENG_ID, ISFT_ID, ICMT_ID,
160 /* sample data stuff; chunk */
161 SNAM_ID, SMPL_ID,
162 /* preset stuff; chunk */
163 PHDR_ID, PBAG_ID, PMOD_ID, PGEN_ID,
164 /* inst stuff; chunk */
165 INST_ID, IBAG_ID, IMOD_ID, IGEN_ID,
166 /* sample header; chunk */
167 SHDR_ID
168 };
169
170
171 /*================================================================
172 * load a soundfont file
173 *================================================================*/
174
load_soundfont(SFInfo * sf,struct timidity_file * fd)175 int load_soundfont(SFInfo *sf, struct timidity_file *fd)
176 {
177 SFChunk chunk;
178
179 sf->preset = NULL;
180 sf->sample = NULL;
181 sf->inst = NULL;
182 sf->sf_name = NULL;
183
184 prbags.bag = inbags.bag = NULL;
185 prbags.gen = inbags.gen = NULL;
186
187 /* check RIFF file header */
188 READCHUNK(&chunk, fd);
189 if (chunkid(chunk.id) != RIFF_ID) {
190 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
191 "%s: *** not a RIFF file", current_filename);
192 return -1;
193 }
194 /* check file id */
195 READID(chunk.id, fd);
196 if (chunkid(chunk.id) != SFBK_ID) {
197 ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
198 "%s: *** not a SoundFont file", current_filename);
199 return -1;
200 }
201
202 for (;;) {
203 if(READCHUNK(&chunk, fd) <= 0)
204 break;
205 else if (chunkid(chunk.id) == LIST_ID) {
206 if (process_list(chunk.size, sf, fd))
207 break;
208 } else {
209 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
210 "%s: *** illegal id in level 0: %4.4s %4d",
211 current_filename, chunk.id, chunk.size);
212 FSKIP(chunk.size, fd);
213 }
214 }
215
216 /* parse layer structure */
217 convert_layers(sf);
218
219 /* free private tables */
220 if (prbags.bag) free(prbags.bag);
221 if (prbags.gen) free(prbags.gen);
222 if (inbags.bag) free(inbags.bag);
223 if (inbags.gen) free(inbags.gen);
224
225 return 0;
226 }
227
228
229 /*================================================================
230 * free buffer
231 *================================================================*/
232
free_soundfont(SFInfo * sf)233 void free_soundfont(SFInfo *sf)
234 {
235 int i;
236 if (sf->preset) {
237 for (i = 0; i < sf->npresets; i++)
238 free_layer(&sf->preset[i].hdr);
239 free(sf->preset);
240 }
241 if (sf->inst) {
242 for (i = 0; i < sf->ninsts; i++)
243 free_layer(&sf->inst[i].hdr);
244 free(sf->inst);
245 }
246 if (sf->sample) free(sf->sample);
247 if (sf->sf_name) free(sf->sf_name);
248 }
249
250
251 /*----------------------------------------------------------------
252 * get id value from 4bytes ID string
253 *----------------------------------------------------------------*/
254
chunkid(char * id)255 static int chunkid(char *id)
256 {
257 static struct idstring {
258 char *str;
259 int id;
260 } idlist[] = {
261 {"RIFF", RIFF_ID},
262 {"LIST", LIST_ID},
263 {"sfbk", SFBK_ID},
264 {"INFO", INFO_ID},
265 {"sdta", SDTA_ID},
266 {"snam", SNAM_ID},
267 {"smpl", SMPL_ID},
268 {"pdta", PDTA_ID},
269 {"phdr", PHDR_ID},
270 {"pbag", PBAG_ID},
271 {"pmod", PMOD_ID},
272 {"pgen", PGEN_ID},
273 {"inst", INST_ID},
274 {"ibag", IBAG_ID},
275 {"imod", IMOD_ID},
276 {"igen", IGEN_ID},
277 {"shdr", SHDR_ID},
278 {"ifil", IFIL_ID},
279 {"isng", ISNG_ID},
280 {"irom", IROM_ID},
281 {"iver", IVER_ID},
282 {"INAM", INAM_ID},
283 {"IPRD", IPRD_ID},
284 {"ICOP", ICOP_ID},
285 {"ICRD", ICRD_ID},
286 {"IENG", IENG_ID},
287 {"ISFT", ISFT_ID},
288 {"ICMT", ICMT_ID},
289 };
290
291 int i;
292
293 for (i = 0; i < sizeof(idlist)/sizeof(idlist[0]); i++) {
294 if (strncmp(id, idlist[i].str, 4) == 0)
295 return idlist[i].id;
296 }
297
298 return UNKN_ID;
299 }
300
301
302 /*================================================================
303 * process a list chunk
304 *================================================================*/
305
process_list(int size,SFInfo * sf,struct timidity_file * fd)306 static int process_list(int size, SFInfo *sf, struct timidity_file *fd)
307 {
308 SFChunk chunk;
309
310 /* read the following id string */
311 READID(chunk.id, fd); size -= 4;
312 ctl->cmsg(CMSG_INFO, VERB_DEBUG, "%c%c%c%c:",
313 chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);
314 switch (chunkid(chunk.id)) {
315 case INFO_ID:
316 return process_info(size, sf, fd);
317 case SDTA_ID:
318 return process_sdta(size, sf, fd);
319 case PDTA_ID:
320 return process_pdta(size, sf, fd);
321 default:
322 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
323 "%s: *** illegal id in level 1: %4.4s",
324 current_filename, chunk.id);
325 FSKIP(size, fd); /* skip it */
326 return 0;
327 }
328 }
329
330
331 /*================================================================
332 * process info list
333 *================================================================*/
334
process_info(int size,SFInfo * sf,struct timidity_file * fd)335 static int process_info(int size, SFInfo *sf, struct timidity_file *fd)
336 {
337 sf->infopos = tf_tell(fd);
338 sf->infosize = size;
339
340 /* parse the buffer */
341 while (size > 0) {
342 SFChunk chunk;
343
344 /* read a sub chunk */
345 if(READCHUNK(&chunk, fd) <= 0)
346 return -1;
347 size -= 8;
348
349 ctl->cmsg(CMSG_INFO, VERB_DEBUG, " %c%c%c%c:",
350 chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);
351 switch (chunkid(chunk.id)) {
352 case IFIL_ID:
353 /* soundfont file version */
354 READW(&sf->version, fd);
355 READW(&sf->minorversion, fd);
356 ctl->cmsg(CMSG_INFO, VERB_DEBUG,
357 " version %d, minor %d",
358 sf->version, sf->minorversion);
359 break;
360 case INAM_ID:
361 /* name of the font */
362 sf->sf_name = (char*)safe_malloc(chunk.size + 1);
363 tf_read(sf->sf_name, 1, chunk.size, fd);
364 sf->sf_name[chunk.size] = 0;
365 ctl->cmsg(CMSG_INFO, VERB_DEBUG,
366 " name %s", sf->sf_name);
367 break;
368
369 default:
370 if(ctl->verbosity >= VERB_DEBUG)
371 {
372 char buff[100];
373 if(chunk.size < sizeof(buff) - 1)
374 {
375 tf_read(buff, chunk.size, 1, fd);
376 buff[chunk.size] = '\0';
377 }
378 else
379 {
380 int i = sizeof(buff) - 4;
381 tf_read(buff, i, 1, fd);
382 FSKIP(chunk.size - i, fd);
383 buff[i++] = '.';
384 buff[i++] = '.';
385 buff[i++] = '.';
386 buff[i] = '\0';
387 }
388 ctl->cmsg(CMSG_INFO, VERB_DEBUG, " %s", buff);
389 }
390 else
391 FSKIP(chunk.size, fd);
392 break;
393 }
394 size -= chunk.size;
395 }
396 return 0;
397 }
398
399
400 /*================================================================
401 * process sample data list
402 *================================================================*/
403
process_sdta(int size,SFInfo * sf,struct timidity_file * fd)404 static int process_sdta(int size, SFInfo *sf, struct timidity_file *fd)
405 {
406 while (size > 0) {
407 SFChunk chunk;
408
409 /* read a sub chunk */
410 if(READCHUNK(&chunk, fd) <= 0)
411 return -1;
412 size -= 8;
413
414 ctl->cmsg(CMSG_INFO, VERB_DEBUG, " %c%c%c%c:",
415 chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);
416 switch (chunkid(chunk.id)) {
417 case SNAM_ID:
418 /* sample name list */
419 load_sample_names(chunk.size, sf, fd);
420 break;
421 case SMPL_ID:
422 /* sample data starts from here */
423 sf->samplepos = tf_tell(fd);
424 sf->samplesize = chunk.size;
425 FSKIP(chunk.size, fd);
426 break;
427 default:
428 FSKIP(chunk.size, fd);
429 break;
430 }
431 size -= chunk.size;
432 }
433 return 0;
434 }
435
436
437 /*================================================================
438 * process preset data list
439 *================================================================*/
440
process_pdta(int size,SFInfo * sf,struct timidity_file * fd)441 static int process_pdta(int size, SFInfo *sf, struct timidity_file *fd)
442 {
443 while (size > 0) {
444 SFChunk chunk;
445
446 /* read a subchunk */
447 if(READCHUNK(&chunk, fd) <= 0)
448 return -1;
449 size -= 8;
450
451 ctl->cmsg(CMSG_INFO, VERB_DEBUG, " %c%c%c%c:",
452 chunk.id[0], chunk.id[1], chunk.id[2], chunk.id[3]);
453 switch (chunkid(chunk.id)) {
454 case PHDR_ID:
455 load_preset_header(chunk.size, sf, fd);
456 break;
457 case PBAG_ID:
458 load_bag(chunk.size, &prbags, fd);
459 break;
460 case PGEN_ID:
461 load_gen(chunk.size, &prbags, fd);
462 break;
463 case INST_ID:
464 load_inst_header(chunk.size, sf, fd);
465 break;
466 case IBAG_ID:
467 load_bag(chunk.size, &inbags, fd);
468 break;
469 case IGEN_ID:
470 load_gen(chunk.size, &inbags, fd);
471 break;
472 case SHDR_ID:
473 load_sample_info(chunk.size, sf, fd);
474 break;
475 case PMOD_ID: /* ignored */
476 case IMOD_ID: /* ingored */
477 default:
478 FSKIP(chunk.size, fd);
479 break;
480 }
481 size -= chunk.size;
482 }
483 return 0;
484 }
485
486
487 /*----------------------------------------------------------------
488 * store sample name list; sf1 only
489 *----------------------------------------------------------------*/
490
load_sample_names(int size,SFInfo * sf,struct timidity_file * fd)491 static void load_sample_names(int size, SFInfo *sf, struct timidity_file *fd)
492 {
493 int i, nsamples;
494 if (sf->version > 1) {
495 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
496 "%s: *** version 2 has obsolete format??",
497 current_filename);
498 FSKIP(size, fd);
499 return;
500 }
501
502 /* each sample name has a fixed lentgh (20 bytes) */
503 nsamples = size / 20;
504 if (sf->sample == NULL) {
505 sf->nsamples = nsamples;
506 sf->sample = NEW(SFSampleInfo, sf->nsamples);
507 } else if (sf->nsamples != nsamples) {
508 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
509 "%s: *** different # of samples ?? (%d : %d)\n",
510 current_filename, sf->nsamples, nsamples);
511 FSKIP(size, fd);
512 return;
513 }
514
515 /* read each name from file */
516 for (i = 0; i < sf->nsamples; i++) {
517 READSTR(sf->sample[i].name, fd);
518 }
519 }
520
521
522 /*----------------------------------------------------------------
523 * preset header list
524 *----------------------------------------------------------------*/
525
load_preset_header(int size,SFInfo * sf,struct timidity_file * fd)526 static void load_preset_header(int size, SFInfo *sf, struct timidity_file *fd)
527 {
528 int i;
529
530 sf->npresets = size / 38;
531 sf->preset = NEW(SFPresetHdr, sf->npresets);
532 for (i = 0; i < sf->npresets; i++) {
533 READSTR(sf->preset[i].hdr.name, fd);
534 READW(&sf->preset[i].preset, fd);
535 READW(&sf->preset[i].bank, fd);
536 READW(&sf->preset[i].hdr.bagNdx, fd);
537 SKIPDW(fd); /* lib; ignored*/
538 SKIPDW(fd); /* genre; ignored */
539 SKIPDW(fd); /* morph; ignored */
540 /* initialize layer table; it'll be parsed later */
541 sf->preset[i].hdr.nlayers = 0;
542 sf->preset[i].hdr.layer = NULL;
543
544 ctl->cmsg(CMSG_INFO, VERB_DEBUG,
545 " Preset %d (%s) index=%d bank=%d preset=%d",
546 i, sf->preset[i].hdr.name,
547 sf->preset[i].hdr.bagNdx,
548 sf->preset[i].bank,
549 sf->preset[i].preset + progbase);
550 }
551 }
552
553
554 /*----------------------------------------------------------------
555 * instrument header list
556 *----------------------------------------------------------------*/
557
load_inst_header(int size,SFInfo * sf,struct timidity_file * fd)558 static void load_inst_header(int size, SFInfo *sf, struct timidity_file *fd)
559 {
560 int i;
561
562 sf->ninsts = size / 22;
563 sf->inst = NEW(SFInstHdr, sf->ninsts);
564 for (i = 0; i < sf->ninsts; i++) {
565 READSTR(sf->inst[i].hdr.name, fd);
566 READW(&sf->inst[i].hdr.bagNdx, fd);
567 /* iniitialize layer table; it'll be parsed later */
568 sf->inst[i].hdr.nlayers = 0;
569 sf->inst[i].hdr.layer = NULL;
570
571 ctl->cmsg(CMSG_INFO, VERB_DEBUG,
572 " InstHdr %d (%s) bagNdx=%d",
573 i, sf->inst[i].hdr.name, sf->inst[i].hdr.bagNdx);
574 }
575 }
576
577
578 /*----------------------------------------------------------------
579 * load preset/instrument bag list on the private table
580 *----------------------------------------------------------------*/
581
load_bag(int size,SFBags * bagp,struct timidity_file * fd)582 static void load_bag(int size, SFBags *bagp, struct timidity_file *fd)
583 {
584 int i;
585
586 size /= 4;
587 bagp->bag = NEW(uint16, size);
588 for (i = 0; i < size; i++) {
589 READW(&bagp->bag[i], fd);
590 SKIPW(fd); /* mod; ignored */
591 }
592 bagp->nbags = size;
593 }
594
595
596 /*----------------------------------------------------------------
597 * load preset/instrument generator list on the private table
598 *----------------------------------------------------------------*/
599
load_gen(int size,SFBags * bagp,struct timidity_file * fd)600 static void load_gen(int size, SFBags *bagp, struct timidity_file *fd)
601 {
602 int i;
603
604 size /= 4;
605 bagp->gen = NEW(SFGenRec, size);
606 for (i = 0; i < size; i++) {
607 READW((uint16 *)&bagp->gen[i].oper, fd);
608 READW((uint16 *)&bagp->gen[i].amount, fd);
609 }
610 bagp->ngens = size;
611 }
612
613
614 /*----------------------------------------------------------------
615 * load sample info list
616 *----------------------------------------------------------------*/
617
load_sample_info(int size,SFInfo * sf,struct timidity_file * fd)618 static void load_sample_info(int size, SFInfo *sf, struct timidity_file *fd)
619 {
620 int i;
621 int in_rom;
622
623 /* the record size depends on the soundfont version */
624 if (sf->version > 1) {
625 /* SF2 includes sample name and other infos */
626 sf->nsamples = size / 46;
627 sf->sample = NEW(SFSampleInfo, sf->nsamples);
628 } else {
629 /* SBK; sample name may be read already */
630 int nsamples = size / 16;
631 if (sf->sample == NULL) {
632 sf->nsamples = nsamples;
633 sf->sample = NEW(SFSampleInfo, sf->nsamples);
634 } else if (sf->nsamples != nsamples) {
635 #if 0
636 fprintf(stderr, "*** different # of infos ?? (%d : %d)\n",
637 sf->nsamples, nsamples);
638 FSKIP(size, fd);
639 return;
640 #endif
641 /* overwrite it */
642 sf->nsamples = nsamples;
643 }
644 }
645
646 in_rom = 1; /* data may start from ROM samples */
647 for (i = 0; i < sf->nsamples; i++) {
648 if (sf->version > 1) /* SF2 only */
649 READSTR(sf->sample[i].name, fd);
650 READDW((uint32 *)&sf->sample[i].startsample, fd);
651 READDW((uint32 *)&sf->sample[i].endsample, fd);
652 READDW((uint32 *)&sf->sample[i].startloop, fd);
653 READDW((uint32 *)&sf->sample[i].endloop, fd);
654 if (sf->version > 1) { /* SF2 only */
655 READDW((uint32 *)&sf->sample[i].samplerate, fd);
656 READB(sf->sample[i].originalPitch, fd);
657 READB(sf->sample[i].pitchCorrection, fd);
658 READW(&sf->sample[i].samplelink, fd);
659 READW(&sf->sample[i].sampletype, fd);
660 } else { /* for SBK; set missing infos */
661 sf->sample[i].samplerate = 44100;
662 sf->sample[i].originalPitch = 60;
663 sf->sample[i].pitchCorrection = 0;
664 sf->sample[i].samplelink = 0;
665 /* the first RAM data starts from address 0 */
666 if (sf->sample[i].startsample == 0)
667 in_rom = 0;
668 if (in_rom)
669 sf->sample[i].sampletype = 0x8001;
670 else
671 sf->sample[i].sampletype = 1;
672 }
673 }
674 }
675
676
677 /*================================================================
678 * convert from bags to layers
679 *================================================================*/
680
convert_layers(SFInfo * sf)681 static void convert_layers(SFInfo *sf)
682 {
683 int i;
684
685 if (prbags.bag == NULL || prbags.gen == NULL ||
686 inbags.bag == NULL || inbags.gen == NULL) {
687 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
688 "%s: *** illegal bags / gens", current_filename);
689 return;
690 }
691
692 for (i = 0; i < sf->npresets - 1; i++) {
693 generate_layers(&sf->preset[i].hdr,
694 &sf->preset[i+1].hdr,
695 &prbags);
696 }
697 for (i = 0; i < sf->ninsts - 1; i++) {
698 generate_layers(&sf->inst[i].hdr,
699 &sf->inst[i+1].hdr,
700 &inbags);
701 }
702 }
703
704
705 /*----------------------------------------------------------------
706 * generate layer lists from stored bags
707 *----------------------------------------------------------------*/
708
generate_layers(SFHeader * hdr,SFHeader * next,SFBags * bags)709 static void generate_layers(SFHeader *hdr, SFHeader *next, SFBags *bags)
710 {
711 int i;
712 SFGenLayer *layp;
713
714 hdr->nlayers = next->bagNdx - hdr->bagNdx;
715 if (hdr->nlayers < 0) {
716 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
717 "%s: illegal layer numbers %d",
718 current_filename, hdr->nlayers);
719 return;
720 }
721 if (hdr->nlayers == 0)
722 return;
723 hdr->layer = (SFGenLayer*)safe_malloc(sizeof(SFGenLayer) * hdr->nlayers);
724 layp = hdr->layer;
725 for (layp = hdr->layer, i = hdr->bagNdx; i < next->bagNdx; layp++, i++) {
726 int genNdx = bags->bag[i];
727 layp->nlists = bags->bag[i+1] - genNdx;
728 if (layp->nlists < 0) {
729 ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
730 "%s: illegal list numbers %d",
731 current_filename, layp->nlists);
732 return;
733 }
734 layp->list = (SFGenRec*)safe_malloc(sizeof(SFGenRec) * layp->nlists);
735 memcpy(layp->list, &bags->gen[genNdx],
736 sizeof(SFGenRec) * layp->nlists);
737 }
738 }
739
740 /*----------------------------------------------------------------
741 * free a layer
742 *----------------------------------------------------------------*/
743
free_layer(SFHeader * hdr)744 static void free_layer(SFHeader *hdr)
745 {
746 int i;
747 for (i = 0; i < hdr->nlayers; i++) {
748 SFGenLayer *layp = &hdr->layer[i];
749 if (layp->nlists >= 0)
750 free(layp->list);
751 }
752 if (hdr->nlayers > 0)
753 free(hdr->layer);
754 }
755
756 /* add blank loop for each data */
757 int auto_add_blank = 0;
correct_samples(SFInfo * sf)758 void correct_samples(SFInfo *sf)
759 {
760 int i;
761 SFSampleInfo *sp;
762 int prev_end;
763
764 prev_end = 0;
765 for (sp = sf->sample, i = 0; i < sf->nsamples; i++, sp++) {
766 /* correct sample positions for SBK file */
767 if (sf->version == 1) {
768 sp->startloop++;
769 sp->endloop += 2;
770 }
771
772 /* calculate sample data size */
773 if (sp->sampletype & 0x8000)
774 sp->size = 0;
775 else if (sp->startsample < prev_end && sp->startsample != 0)
776 sp->size = 0;
777 else {
778 sp->size = -1;
779 if (!auto_add_blank && i != sf->nsamples-1)
780 sp->size = sp[1].startsample - sp->startsample;
781 if (sp->size < 0)
782 sp->size = sp->endsample - sp->startsample + 48; }
783 prev_end = sp->endsample;
784
785 /* calculate short-shot loop size */
786 if (auto_add_blank || i == sf->nsamples-1)
787 sp->loopshot = 48;
788 else {
789 sp->loopshot = sp[1].startsample - sp->endsample;
790 if (sp->loopshot < 0 || sp->loopshot > 48)
791 sp->loopshot = 48;
792 }
793 }
794 }
795