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