1
/* MikMod sound library
2
(c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for
5
This library is free software; you can redistribute it and/or modify
6
it under the terms of the GNU Library General Public License as
7
published by the Free Software Foundation; either version 2 of
8
the License, or (at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public
16
License along with this library; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21
/*==============================================================================
23
$Id: load_xm.c,v 1.6 2001/09/11 18:49:18 slouken Exp $
25
Fasttracker (XM) module loader
27
==============================================================================*/
35
#include "mikmod_internals.h"
37
/*========== Module structure */
39
typedef struct XMHEADER {
40
CHAR id[17]; /* ID text: 'Extended module: ' */
41
CHAR songname[21]; /* Module name */
42
CHAR trackername[20]; /* Tracker name */
43
UWORD version; /* Version number */
44
ULONG headersize; /* Header size */
45
UWORD songlength; /* Song length (in patten order table) */
46
UWORD restart; /* Restart position */
47
UWORD numchn; /* Number of channels (2,4,6,8,10,...,32) */
48
UWORD numpat; /* Number of patterns (max 256) */
49
UWORD numins; /* Number of instruments (max 128) */
51
UWORD tempo; /* Default tempo */
52
UWORD bpm; /* Default BPM */
53
UBYTE orders[256]; /* Pattern order table */
56
typedef struct XMINSTHEADER {
57
ULONG size; /* Instrument size */
58
CHAR name[22]; /* Instrument name */
59
UBYTE type; /* Instrument type (always 0) */
60
UWORD numsmp; /* Number of samples in instrument */
64
#define XMENVCNT (12*2)
65
#define XMNOTECNT (8*OCTAVE)
66
typedef struct XMPATCHHEADER {
67
UBYTE what[XMNOTECNT]; /* Sample number for all notes */
68
UWORD volenv[XMENVCNT]; /* Points for volume envelope */
69
UWORD panenv[XMENVCNT]; /* Points for panning envelope */
70
UBYTE volpts; /* Number of volume points */
71
UBYTE panpts; /* Number of panning points */
72
UBYTE volsus; /* Volume sustain point */
73
UBYTE volbeg; /* Volume loop start point */
74
UBYTE volend; /* Volume loop end point */
75
UBYTE pansus; /* Panning sustain point */
76
UBYTE panbeg; /* Panning loop start point */
77
UBYTE panend; /* Panning loop end point */
78
UBYTE volflg; /* Volume type: bit 0: On; 1: Sustain; 2: Loop */
79
UBYTE panflg; /* Panning type: bit 0: On; 1: Sustain; 2: Loop */
80
UBYTE vibflg; /* Vibrato type */
81
UBYTE vibsweep; /* Vibrato sweep */
82
UBYTE vibdepth; /* Vibrato depth */
83
UBYTE vibrate; /* Vibrato rate */
84
UWORD volfade; /* Volume fadeout */
87
typedef struct XMWAVHEADER {
88
ULONG length; /* Sample length */
89
ULONG loopstart; /* Sample loop start */
90
ULONG looplength; /* Sample loop length */
91
UBYTE volume; /* Volume */
92
SBYTE finetune; /* Finetune (signed byte -128..+127) */
93
UBYTE type; /* Loop type */
94
UBYTE panning; /* Panning (0-255) */
95
SBYTE relnote; /* Relative note number (signed byte) */
97
CHAR samplename[22]; /* Sample name */
98
UBYTE vibtype; /* Vibrato type */
99
UBYTE vibsweep; /* Vibrato sweep */
100
UBYTE vibdepth; /* Vibrato depth */
101
UBYTE vibrate; /* Vibrato rate */
104
typedef struct XMPATHEADER {
105
ULONG size; /* Pattern header length */
106
UBYTE packing; /* Packing type (always 0) */
107
UWORD numrows; /* Number of rows in pattern (1..256) */
108
SWORD packsize; /* Packed patterndata size */
111
typedef struct XMNOTE {
112
UBYTE note,ins,vol,eff,dat;
115
/*========== Loader variables */
117
static XMNOTE *xmpat=NULL;
118
static XMHEADER *mh=NULL;
120
/* increment unit for sample array reallocation */
121
#define XM_SMPINCR 64
122
static ULONG *nextwav=NULL;
123
static XMWAVHEADER *wh=NULL,*s=NULL;
125
/*========== Loader code */
131
if(!_mm_read_UBYTES(id,38,modreader)) return 0;
132
if(memcmp(id,"Extended Module: ",17)) return 0;
133
if(id[37]==0x1a) return 1;
139
if(!(mh=(XMHEADER *)_mm_malloc(sizeof(XMHEADER)))) return 0;
143
void XM_Cleanup(void)
148
static int XM_ReadNote(XMNOTE* n)
152
memset(n,0,sizeof(XMNOTE));
153
cmp=_mm_read_UBYTE(modreader);
156
if(cmp&1) { result++;n->note = _mm_read_UBYTE(modreader); }
157
if(cmp&2) { result++;n->ins = _mm_read_UBYTE(modreader); }
158
if(cmp&4) { result++;n->vol = _mm_read_UBYTE(modreader); }
159
if(cmp&8) { result++;n->eff = _mm_read_UBYTE(modreader); }
160
if(cmp&16) { result++;n->dat = _mm_read_UBYTE(modreader); }
163
n->ins = _mm_read_UBYTE(modreader);
164
n->vol = _mm_read_UBYTE(modreader);
165
n->eff = _mm_read_UBYTE(modreader);
166
n->dat = _mm_read_UBYTE(modreader);
172
static UBYTE* XM_Convert(XMNOTE* xmtrack,UWORD rows)
175
UBYTE note,ins,vol,eff,dat;
178
for(t=0;t<rows;t++) {
179
note = xmtrack->note;
187
UniEffect(UNI_KEYFADE,0);
191
if(ins) UniInstrument(ins-1);
194
case 0x6: /* volslide down */
195
if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol&0xf);
197
case 0x7: /* volslide up */
198
if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol<<4);
201
/* volume-row fine volume slide is compatible with protracker
202
EBx and EAx effects i.e. a zero nibble means DO NOT SLIDE, as
203
opposed to 'take the last sliding value'. */
204
case 0x8: /* finevol down */
205
UniPTEffect(0xe,0xb0|(vol&0xf));
207
case 0x9: /* finevol up */
208
UniPTEffect(0xe,0xa0|(vol&0xf));
210
case 0xa: /* set vibrato speed */
211
UniPTEffect(0x4,vol<<4);
213
case 0xb: /* vibrato */
214
UniPTEffect(0x4,vol&0xf);
216
case 0xc: /* set panning */
217
UniPTEffect(0x8,vol<<4);
219
case 0xd: /* panning slide left (only slide when data not zero) */
220
if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol&0xf);
222
case 0xe: /* panning slide right (only slide when data not zero) */
223
if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol<<4);
225
case 0xf: /* tone porta */
226
UniPTEffect(0x3,vol<<4);
229
if((vol>=0x10)&&(vol<=0x50))
230
UniPTEffect(0xc,vol-0x10);
235
UniEffect(UNI_XMEFFECT4,dat);
238
UniEffect(UNI_XMEFFECTA,dat);
240
case 0xe: /* Extended effects */
242
case 0x1: /* XM fine porta up */
243
UniEffect(UNI_XMEFFECTE1,dat&0xf);
245
case 0x2: /* XM fine porta down */
246
UniEffect(UNI_XMEFFECTE2,dat&0xf);
248
case 0xa: /* XM fine volume up */
249
UniEffect(UNI_XMEFFECTEA,dat&0xf);
251
case 0xb: /* XM fine volume down */
252
UniEffect(UNI_XMEFFECTEB,dat&0xf);
255
UniPTEffect(eff,dat);
258
case 'G'-55: /* G - set global volume */
259
UniEffect(UNI_XMEFFECTG,dat>64?64:dat);
261
case 'H'-55: /* H - global volume slide */
262
UniEffect(UNI_XMEFFECTH,dat);
264
case 'K'-55: /* K - keyOff and KeyFade */
265
UniEffect(UNI_KEYFADE,dat);
267
case 'L'-55: /* L - set envelope position */
268
UniEffect(UNI_XMEFFECTL,dat);
270
case 'P'-55: /* P - panning slide */
271
UniEffect(UNI_XMEFFECTP,dat);
273
case 'R'-55: /* R - multi retrig note */
274
UniEffect(UNI_S3MEFFECTQ,dat);
276
case 'T'-55: /* T - Tremor */
277
UniEffect(UNI_S3MEFFECTI,dat);
281
case 1: /* X1 - Extra Fine Porta up */
282
UniEffect(UNI_XMEFFECTX1,dat&0xf);
284
case 2: /* X2 - Extra Fine Porta down */
285
UniEffect(UNI_XMEFFECTX2,dat&0xf);
289
case 'Z'-55: /* Z - synchro */
290
UniEffect(UNI_XMEFFECTZ,dat);
294
/* the pattern jump destination is written in decimal,
295
but it seems some poor tracker software writes them
296
in hexadecimal... (sigh) */
298
/* don't change anything if we're sure it's in hexa */
299
if ((((dat&0xf0)>>4)<=9)&&((dat&0xf)<=9))
300
/* otherwise, convert from dec to hex */
301
dat=(((dat&0xf0)>>4)*10)+(dat&0xf);
302
UniPTEffect(eff,dat);
312
static BOOL LoadPatterns(BOOL dummypat)
316
if(!AllocTracks()) return 0;
317
if(!AllocPatterns()) return 0;
320
for(t=0;t<mh->numpat;t++) {
323
ph.size =_mm_read_I_ULONG(modreader);
324
if (ph.size<(mh->version==0x0102?8:9)) {
325
_mm_errno=MMERR_LOADING_PATTERN;
328
ph.packing =_mm_read_UBYTE(modreader);
330
_mm_errno=MMERR_LOADING_PATTERN;
333
if(mh->version==0x0102)
334
ph.numrows =_mm_read_UBYTE(modreader)+1;
336
ph.numrows =_mm_read_I_UWORD(modreader);
337
ph.packsize =_mm_read_I_UWORD(modreader);
339
ph.size-=(mh->version==0x0102?8:9);
341
_mm_fseek(modreader,ph.size,SEEK_CUR);
343
of.pattrows[t]=ph.numrows;
346
if(!(xmpat=(XMNOTE*)_mm_calloc(ph.numrows*of.numchn,sizeof(XMNOTE))))
349
/* when packsize is 0, don't try to load a pattern.. it's empty. */
351
for(u=0;u<ph.numrows;u++)
352
for(v=0;v<of.numchn;v++) {
353
if(!ph.packsize) break;
355
ph.packsize-=XM_ReadNote(&xmpat[(v*ph.numrows)+u]);
357
free(xmpat);xmpat=NULL;
358
_mm_errno=MMERR_LOADING_PATTERN;
364
_mm_fseek(modreader,ph.packsize,SEEK_CUR);
367
if(_mm_eof(modreader)) {
368
free(xmpat);xmpat=NULL;
369
_mm_errno=MMERR_LOADING_PATTERN;
373
for(v=0;v<of.numchn;v++)
374
of.tracks[numtrk++]=XM_Convert(&xmpat[v*ph.numrows],ph.numrows);
376
free(xmpat);xmpat=NULL;
378
for(v=0;v<of.numchn;v++)
379
of.tracks[numtrk++]=XM_Convert(NULL,ph.numrows);
385
if(!(xmpat=(XMNOTE*)_mm_calloc(64*of.numchn,sizeof(XMNOTE)))) return 0;
386
for(v=0;v<of.numchn;v++)
387
of.tracks[numtrk++]=XM_Convert(&xmpat[v*64],64);
388
free(xmpat);xmpat=NULL;
394
static BOOL LoadInstruments(void)
401
if(!AllocInstruments()) return 0;
403
for(t=0;t<of.numins;t++,d++) {
407
memset(d->samplenumber,0xff,INSTNOTES*sizeof(UWORD));
409
/* read instrument header */
410
headend = _mm_ftell(modreader);
411
ih.size = _mm_read_I_ULONG(modreader);
413
_mm_read_string(ih.name, 22, modreader);
414
ih.type = _mm_read_UBYTE(modreader);
415
ih.numsmp = _mm_read_I_UWORD(modreader);
417
d->insname = DupStr(ih.name,22,1);
419
if((SWORD)ih.size>29) {
420
ih.ssize = _mm_read_I_ULONG(modreader);
421
if(((SWORD)ih.numsmp>0)&&(ih.numsmp<=XMNOTECNT)) {
425
_mm_read_UBYTES (pth.what,XMNOTECNT,modreader);
426
_mm_read_I_UWORDS (pth.volenv, XMENVCNT, modreader);
427
_mm_read_I_UWORDS (pth.panenv, XMENVCNT, modreader);
428
pth.volpts = _mm_read_UBYTE(modreader);
429
pth.panpts = _mm_read_UBYTE(modreader);
430
pth.volsus = _mm_read_UBYTE(modreader);
431
pth.volbeg = _mm_read_UBYTE(modreader);
432
pth.volend = _mm_read_UBYTE(modreader);
433
pth.pansus = _mm_read_UBYTE(modreader);
434
pth.panbeg = _mm_read_UBYTE(modreader);
435
pth.panend = _mm_read_UBYTE(modreader);
436
pth.volflg = _mm_read_UBYTE(modreader);
437
pth.panflg = _mm_read_UBYTE(modreader);
438
pth.vibflg = _mm_read_UBYTE(modreader);
439
pth.vibsweep = _mm_read_UBYTE(modreader);
440
pth.vibdepth = _mm_read_UBYTE(modreader);
441
pth.vibrate = _mm_read_UBYTE(modreader);
442
pth.volfade = _mm_read_I_UWORD(modreader);
444
/* read the remainder of the header
445
(2 bytes for 1.03, 22 for 1.04) */
446
for(u=headend-_mm_ftell(modreader);u;u--) _mm_read_UBYTE(modreader);
448
/* we can't trust the envelope point count here, as some
449
modules have incorrect values (K_OSPACE.XM reports 32 volume
450
points, for example). */
451
if(pth.volpts>XMENVCNT/2) pth.volpts=XMENVCNT/2;
452
if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2;
454
if((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) {
455
if(nextwav) { free(nextwav);nextwav=NULL; }
456
if(wh) { free(wh);wh=NULL; }
457
_mm_errno = MMERR_LOADING_SAMPLEINFO;
461
for(u=0;u<XMNOTECNT;u++)
462
d->samplenumber[u]=pth.what[u]+of.numsmp;
463
d->volfade = pth.volfade;
465
memcpy(d->volenv,pth.volenv,XMENVCNT);
466
if (pth.volflg&1) d->volflg|=EF_ON;
467
if (pth.volflg&2) d->volflg|=EF_SUSTAIN;
468
if (pth.volflg&4) d->volflg|=EF_LOOP;
469
d->volsusbeg=d->volsusend=pth.volsus;
470
d->volbeg=pth.volbeg;
471
d->volend=pth.volend;
472
d->volpts=pth.volpts;
474
for (p=0;p<XMENVCNT/2;p++)
475
d->volenv[p].val<<=2;
476
if ((d->volflg&EF_ON)&&(d->volpts<2))
478
memcpy(d->panenv,pth.panenv,XMENVCNT);
479
if (pth.panflg&1) d->panflg|=EF_ON;
480
if (pth.panflg&2) d->panflg|=EF_SUSTAIN;
481
if (pth.panflg&4) d->panflg|=EF_LOOP;
482
d->pansusbeg=d->pansusend=pth.pansus;
483
d->panbeg=pth.panbeg;
484
d->panend=pth.panend;
485
d->panpts=pth.panpts;
487
for (p=0;p<XMENVCNT/2;p++)
488
d->panenv[p].val<<=2;
489
if ((d->panflg&EF_ON)&&(d->panpts<2))
491
/* Samples are stored outside the instrument struct now, so we
492
have to load them all into a temp area, count the of.numsmp
493
along the way and then do an AllocSamples() and move
495
if(mh->version>0x0103) next = 0;
496
for(u=0;u<ih.numsmp;u++,s++) {
497
/* Allocate more room for sample information if necessary */
498
if(of.numsmp+u==wavcnt) {
500
if(!(nextwav=realloc(nextwav,wavcnt*sizeof(ULONG)))){
501
if(wh) { free(wh);wh=NULL; }
502
_mm_errno = MMERR_OUT_OF_MEMORY;
505
if(!(wh=realloc(wh,wavcnt*sizeof(XMWAVHEADER)))) {
506
free(nextwav);nextwav=NULL;
507
_mm_errno = MMERR_OUT_OF_MEMORY;
510
s=wh+(wavcnt-XM_SMPINCR);
513
s->length =_mm_read_I_ULONG (modreader);
514
s->loopstart =_mm_read_I_ULONG (modreader);
515
s->looplength =_mm_read_I_ULONG (modreader);
516
s->volume =_mm_read_UBYTE (modreader);
517
s->finetune =_mm_read_SBYTE (modreader);
518
s->type =_mm_read_UBYTE (modreader);
519
s->panning =_mm_read_UBYTE (modreader);
520
s->relnote =_mm_read_SBYTE (modreader);
521
s->vibtype = pth.vibflg;
522
s->vibsweep = pth.vibsweep;
523
s->vibdepth = pth.vibdepth*4;
524
s->vibrate = pth.vibrate;
525
s->reserved =_mm_read_UBYTE (modreader);
526
_mm_read_string(s->samplename, 22, modreader);
528
nextwav[of.numsmp+u]=next;
531
if(_mm_eof(modreader)) {
532
free(nextwav);free(wh);
533
nextwav=NULL;wh=NULL;
534
_mm_errno = MMERR_LOADING_SAMPLEINFO;
539
if(mh->version>0x0103) {
540
for(u=0;u<ih.numsmp;u++)
541
nextwav[of.numsmp++]+=_mm_ftell(modreader);
542
_mm_fseek(modreader,next,SEEK_CUR);
544
of.numsmp+=ih.numsmp;
546
/* read the remainder of the header */
547
for(u=headend-_mm_ftell(modreader);u;u--) _mm_read_UBYTE(modreader);
549
if(_mm_eof(modreader)) {
550
free(nextwav);free(wh);
551
nextwav=NULL;wh=NULL;
552
_mm_errno = MMERR_LOADING_SAMPLEINFO;
561
if(nextwav) { free(nextwav);nextwav=NULL; }
562
if(wh) { free(wh);wh=NULL; }
563
_mm_errno = MMERR_LOADING_SAMPLEINFO;
570
BOOL XM_Load(BOOL curious)
576
char tracker[21],modtype[60];
578
/* try to read module header */
579
_mm_read_string(mh->id,17,modreader);
580
_mm_read_string(mh->songname,21,modreader);
581
_mm_read_string(mh->trackername,20,modreader);
582
mh->version =_mm_read_I_UWORD(modreader);
583
if((mh->version<0x102)||(mh->version>0x104)) {
584
_mm_errno=MMERR_NOT_A_MODULE;
587
mh->headersize =_mm_read_I_ULONG(modreader);
588
mh->songlength =_mm_read_I_UWORD(modreader);
589
mh->restart =_mm_read_I_UWORD(modreader);
590
mh->numchn =_mm_read_I_UWORD(modreader);
591
mh->numpat =_mm_read_I_UWORD(modreader);
592
mh->numins =_mm_read_I_UWORD(modreader);
593
mh->flags =_mm_read_I_UWORD(modreader);
594
mh->tempo =_mm_read_I_UWORD(modreader);
595
mh->bpm =_mm_read_I_UWORD(modreader);
597
_mm_errno=MMERR_NOT_A_MODULE;
600
_mm_read_UBYTES(mh->orders,256,modreader);
602
if(_mm_eof(modreader)) {
603
_mm_errno = MMERR_LOADING_HEADER;
607
/* set module variables */
608
of.initspeed = (UBYTE)mh->tempo;
609
of.inittempo = (UBYTE)mh->bpm;
610
strncpy(tracker,mh->trackername,20);tracker[20]=0;
611
for(t=20;(tracker[t]<=' ')&&(t>=0);t--) tracker[t]=0;
613
/* some modules have the tracker name empty */
615
strcpy(tracker,"Unknown tracker");
618
snprintf(modtype,60,"%s (XM format %d.%02d)",
619
tracker,mh->version>>8,mh->version&0xff);
621
sprintf(modtype,"%s (XM format %d.%02d)",
622
tracker,mh->version>>8,mh->version&0xff);
624
of.modtype = strdup(modtype);
625
of.numchn = mh->numchn;
626
of.numpat = mh->numpat;
627
of.numtrk = (UWORD)of.numpat*of.numchn; /* get number of channels */
628
of.songname = DupStr(mh->songname,20,1);
629
of.numpos = mh->songlength; /* copy the songlength */
630
of.reppos = mh->restart<mh->songlength?mh->restart:0;
631
of.numins = mh->numins;
632
of.flags |= UF_XMPERIODS|UF_INST|UF_NOWRAP|UF_FT2QUIRKS;
633
if(mh->flags&1) of.flags |= UF_LINEAR;
635
memset(of.chanvol,64,of.numchn); /* store channel volumes */
637
if(!AllocPositions(of.numpos+1)) return 0;
638
for(t=0;t<of.numpos;t++)
639
of.positions[t]=mh->orders[t];
641
/* We have to check for any pattern numbers in the order list greater than
642
the number of patterns total. If one or more is found, we set it equal to
643
the pattern total and make a dummy pattern to workaround the problem */
644
for(t=0;t<of.numpos;t++) {
645
if(of.positions[t]>=of.numpat) {
646
of.positions[t]=of.numpat;
651
of.numpat++;of.numtrk+=of.numchn;
654
if(mh->version<0x0104) {
655
if(!LoadInstruments()) return 0;
656
if(!LoadPatterns(dummypat)) return 0;
657
for(t=0;t<of.numsmp;t++)
658
nextwav[t]+=_mm_ftell(modreader);
660
if(!LoadPatterns(dummypat)) return 0;
661
if(!LoadInstruments()) return 0;
664
if(!AllocSamples()) {
665
free(nextwav);free(wh);
666
nextwav=NULL;wh=NULL;
671
for(u=0;u<of.numsmp;u++,q++,s++) {
672
q->samplename = DupStr(s->samplename,22,1);
673
q->length = s->length;
674
q->loopstart = s->loopstart;
675
q->loopend = s->loopstart+s->looplength;
676
q->volume = s->volume;
677
q->speed = s->finetune+128;
678
q->panning = s->panning;
679
q->seekpos = nextwav[u];
680
q->vibtype = s->vibtype;
681
q->vibsweep = s->vibsweep;
682
q->vibdepth = s->vibdepth;
683
q->vibrate = s->vibrate;
692
if(s->type&0x3) q->flags|=SF_LOOP;
693
if(s->type&0x2) q->flags|=SF_BIDI;
694
if(s->type&0x10) q->flags|=SF_16BITS;
695
q->flags|=SF_DELTA|SF_SIGNED;
700
for(u=0;u<of.numins;u++,d++)
701
for(t=0;t<XMNOTECNT;t++) {
702
if (d->samplenumber[t]>=of.numsmp)
703
d->samplenote[t]=255;
705
int note=t+s[d->samplenumber[t]].relnote;
706
d->samplenote[t]=(note<0)?0:note;
710
free(wh);free(nextwav);
711
wh=NULL;nextwav=NULL;
715
CHAR *XM_LoadTitle(void)
719
_mm_fseek(modreader,17,SEEK_SET);
720
if(!_mm_read_UBYTES(s,21,modreader)) return NULL;
722
return(DupStr(s,21,1));
725
/*========== Loader information */
727
MIKMODAPI MLOADER load_xm={
730
"XM (FastTracker 2)",