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