1 /* MikMod sound library
2 (c) 1998, 1999 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 /*==============================================================================
25 DMP Advanced Module Format loader
27 ==============================================================================*/
35 #include "unimod_priv.h"
37 /*========== Module structure */
39 typedef struct AMFHEADER
41 UBYTE id[3]; /* AMF file marker */
42 UBYTE version; /* upper major, lower nibble minor version number */
43 CHAR songname[32]; /* ASCIIZ songname */
44 UBYTE numsamples; /* number of samples saved */
46 UWORD numtracks; /* number of tracks saved */
47 UBYTE numchannels; /* number of channels used */
48 SBYTE panpos[32]; /* voice pan positions */
54 typedef struct AMFSAMPLE
68 typedef struct AMFNOTE
70 UBYTE note, instr, volume, fxcnt;
76 /*========== Loader variables */
78 static AMFHEADER *mh = NULL;
80 static CHAR AMF_Version[AMFTEXTLEN + 1] = "DSMI Module Format 0.0";
81 static AMFNOTE *track = NULL;
83 /*========== Loader code */
90 if (!_mm_read_UBYTES (id, 3, modreader))
92 if (memcmp (id, "AMF", 3))
95 ver = _mm_read_UBYTE (modreader);
96 if ((ver >= 10) && (ver <= 14))
104 if (!(mh = (AMFHEADER *) _mm_malloc (sizeof (AMFHEADER))))
106 if (!(track = (AMFNOTE *) _mm_calloc (64, sizeof (AMFNOTE))))
120 AMF_UnpackTrack (URL modreader)
127 memset (track, 0, 64 * sizeof (AMFNOTE));
129 /* read packed track */
132 tracksize = _mm_read_I_UWORD (modreader);
133 tracksize += ((ULONG) _mm_read_UBYTE (modreader)) << 16;
137 row = _mm_read_UBYTE (modreader);
138 cmd = _mm_read_UBYTE (modreader);
139 arg = _mm_read_SBYTE (modreader);
140 /* unexpected end of track */
143 if ((row == 0xff) && (cmd == 0xff) && (arg == -1))
145 /* the last triplet should be FF FF FF, but this is not
146 always the case... maybe a bug in m2amf ?
152 /* invalid row (probably unexpected end of row) */
158 track[row].note = cmd;
159 track[row].volume = (UBYTE) arg + 1;
161 else if (cmd == 0x7f)
164 if ((arg < 0) && (row + arg >= 0))
166 memcpy (track + row, track + (row + arg), sizeof (AMFNOTE));
169 else if (cmd == 0x80)
172 track[row].instr = arg + 1;
174 else if (cmd == 0x83)
176 /* volume without note */
177 track[row].volume = (UBYTE) arg + 1;
179 else if (track[row].fxcnt < 3)
184 track[row].effect[track[row].fxcnt] = cmd & 0x7f;
185 track[row].parameter[track[row].fxcnt] = arg;
196 AMF_ConvertTrack (void)
198 int row, fx4memory = 0;
202 for (row = 0; row < 64; row++)
204 if (track[row].instr)
205 UniInstrument (track[row].instr - 1);
206 if (track[row].note > OCTAVE)
207 UniNote (track[row].note - OCTAVE);
210 while (track[row].fxcnt--)
212 SBYTE inf = track[row].parameter[track[row].fxcnt];
214 switch (track[row].effect[track[row].fxcnt])
216 case 1: /* Set speed */
217 UniEffect (UNI_S3MEFFECTA, inf);
219 case 2: /* Volume slide */
222 UniWriteByte (UNI_S3MEFFECTD);
224 UniWriteByte ((inf & 0xf) << 4);
226 UniWriteByte ((-inf) & 0xf);
229 /* effect 3, set channel volume, done in UnpackTrack */
230 case 4: /* Porta up/down */
235 UniEffect (UNI_S3MEFFECTE, inf);
236 fx4memory = UNI_S3MEFFECTE;
240 UniEffect (UNI_S3MEFFECTF, -inf);
241 fx4memory = UNI_S3MEFFECTF;
245 UniEffect (fx4memory, 0);
247 /* effect 5, "Porta abs", not supported */
248 case 6: /* Porta to note */
249 UniEffect (UNI_ITEFFECTG, inf);
252 UniEffect (UNI_S3MEFFECTI, inf);
254 case 8: /* Arpeggio */
255 UniPTEffect (0x0, inf);
257 case 9: /* Vibrato */
258 UniPTEffect (0x4, inf);
260 case 0xa: /* Porta + Volume slide */
261 UniPTEffect (0x3, 0);
264 UniWriteByte (UNI_S3MEFFECTD);
266 UniWriteByte ((inf & 0xf) << 4);
268 UniWriteByte ((-inf) & 0xf);
271 case 0xb: /* Vibrato + Volume slide */
272 UniPTEffect (0x4, 0);
275 UniWriteByte (UNI_S3MEFFECTD);
277 UniWriteByte ((inf & 0xf) << 4);
279 UniWriteByte ((-inf) & 0xf);
282 case 0xc: /* Pattern break (in hex) */
283 UniPTEffect (0xd, inf);
285 case 0xd: /* Pattern jump */
286 UniPTEffect (0xb, inf);
288 /* effect 0xe, "Sync", not supported */
289 case 0xf: /* Retrig */
290 UniEffect (UNI_S3MEFFECTQ, inf & 0xf);
292 case 0x10: /* Sample offset */
293 UniPTEffect (0x9, inf);
295 case 0x11: /* Fine volume slide */
298 UniWriteByte (UNI_S3MEFFECTD);
300 UniWriteByte ((inf & 0xf) << 4 | 0xf);
302 UniWriteByte (0xf0 | ((-inf) & 0xf));
305 case 0x12: /* Fine portamento */
310 UniEffect (UNI_S3MEFFECTE, 0xf0 | (inf & 0xf));
311 fx4memory = UNI_S3MEFFECTE;
315 UniEffect (UNI_S3MEFFECTF, 0xf0 | ((-inf) & 0xf));
316 fx4memory = UNI_S3MEFFECTF;
320 UniEffect (fx4memory, 0);
322 case 0x13: /* Delay note */
323 UniPTEffect (0xe, 0xd0 | (inf & 0xf));
325 case 0x14: /* Note cut */
326 UniPTEffect (0xc, 0);
327 track[row].volume = 0;
329 case 0x15: /* Set tempo */
330 UniEffect (UNI_S3MEFFECTT, inf);
332 case 0x16: /* Extra fine portamento */
337 UniEffect (UNI_S3MEFFECTE, 0xe0 | ((inf >> 2) & 0xf));
338 fx4memory = UNI_S3MEFFECTE;
342 UniEffect (UNI_S3MEFFECTF, 0xe0 | (((-inf) >> 2) & 0xf));
343 fx4memory = UNI_S3MEFFECTF;
347 UniEffect (fx4memory, 0);
349 case 0x17: /* Panning */
351 UniEffect (UNI_ITEFFECTS0, 0x91); /* surround */
353 UniPTEffect (0x8, (inf == 64) ? 255 : (inf + 64) << 1);
358 if (track[row].volume)
359 UniVolEffect (VOL_VOLUME, track[row].volume - 1);
366 AMF_Load (BOOL curious)
368 int t, u, realtrackcnt, realsmpcnt;
373 int channel_remap[16];
375 /* try to read module header */
376 _mm_read_UBYTES (mh->id, 3, modreader);
377 mh->version = _mm_read_UBYTE (modreader);
378 _mm_read_string (mh->songname, 32, modreader);
379 mh->numsamples = _mm_read_UBYTE (modreader);
380 mh->numorders = _mm_read_UBYTE (modreader);
381 mh->numtracks = _mm_read_I_UWORD (modreader);
382 mh->numchannels = _mm_read_UBYTE (modreader);
383 if ((!mh->numchannels) || (mh->numchannels > (mh->version >= 12 ? 32 : 16)))
385 _mm_errno = MMERR_NOT_A_MODULE;
389 if (mh->version >= 11)
391 memset (mh->panpos, 0, 32);
392 _mm_read_SBYTES (mh->panpos, (mh->version >= 13) ? 32 : 16, modreader);
395 _mm_read_UBYTES (channel_remap, 16, modreader);
397 if (mh->version >= 13)
399 mh->songbpm = _mm_read_UBYTE (modreader);
400 if (mh->songbpm < 32)
402 _mm_errno = MMERR_NOT_A_MODULE;
405 mh->songspd = _mm_read_UBYTE (modreader);
406 if (mh->songspd > 32)
408 _mm_errno = MMERR_NOT_A_MODULE;
418 if (_mm_eof (modreader))
420 _mm_errno = MMERR_LOADING_HEADER;
424 /* set module variables */
425 of.initspeed = mh->songspd;
426 of.inittempo = mh->songbpm;
427 AMF_Version[AMFTEXTLEN - 3] = '0' + (mh->version / 10);
428 AMF_Version[AMFTEXTLEN - 1] = '0' + (mh->version % 10);
429 of.modtype = strdup (AMF_Version);
430 of.numchn = mh->numchannels;
431 of.numtrk = mh->numorders * mh->numchannels;
432 if (mh->numtracks > of.numtrk)
433 of.numtrk = mh->numtracks;
434 of.songname = DupStr (mh->songname, 32, 1);
435 of.numpos = mh->numorders;
436 of.numpat = mh->numorders;
438 of.flags |= UF_S3MSLIDES;
439 for (t = 0; t < 32; t++)
441 if (mh->panpos[t] > 64)
442 of.panning[t] = PAN_SURROUND;
443 else if (mh->panpos[t] == 64)
446 of.panning[t] = (mh->panpos[t] + 64) << 1;
448 of.numins = of.numsmp = mh->numsamples;
450 if (!AllocPositions (of.numpos))
452 for (t = 0; t < of.numpos; t++)
457 if (!AllocPatterns ())
460 /* read AMF order table */
461 for (t = 0; t < of.numpat; t++)
463 if (mh->version >= 14)
465 of.pattrows[t] = _mm_read_I_UWORD (modreader);
466 if (mh->version >= 10)
467 _mm_read_I_UWORDS (of.patterns + (t * of.numchn), of.numchn, modreader);
469 for (u = 0; u < of.numchn; u++)
470 of.patterns[t * of.numchn + channel_remap[u]] = _mm_read_I_UWORD (modreader);
472 if (_mm_eof (modreader))
474 _mm_errno = MMERR_LOADING_HEADER;
478 /* read sample information */
479 if (!AllocSamples ())
482 for (t = 0; t < of.numins; t++)
484 /* try to read sample info */
485 s.type = _mm_read_UBYTE (modreader);
486 _mm_read_string (s.samplename, 32, modreader);
487 _mm_read_string (s.filename, 13, modreader);
488 s.offset = _mm_read_I_ULONG (modreader);
489 s.length = _mm_read_I_ULONG (modreader);
490 s.c2spd = _mm_read_I_UWORD (modreader);
493 s.volume = _mm_read_UBYTE (modreader);
494 if (mh->version >= 11)
496 s.reppos = _mm_read_I_ULONG (modreader);
497 s.repend = _mm_read_I_ULONG (modreader);
501 s.reppos = _mm_read_I_UWORD (modreader);
505 if (_mm_eof (modreader))
507 _mm_errno = MMERR_LOADING_SAMPLEINFO;
511 q->samplename = DupStr (s.samplename, 32, 1);
513 q->volume = s.volume;
516 q->seekpos = s.offset;
517 q->length = s.length;
518 q->loopstart = s.reppos;
519 q->loopend = s.repend;
520 if ((s.repend - s.reppos) > 2)
526 /* read track table */
527 if (!(track_remap = _mm_calloc (mh->numtracks + 1, sizeof (UWORD))))
529 _mm_read_I_UWORDS (track_remap + 1, mh->numtracks, modreader);
530 if (_mm_eof (modreader))
533 _mm_errno = MMERR_LOADING_TRACK;
537 for (realtrackcnt = t = 0; t <= mh->numtracks; t++)
538 if (realtrackcnt < track_remap[t])
539 realtrackcnt = track_remap[t];
540 for (t = 0; t < of.numpat * of.numchn; t++)
541 of.patterns[t] = (of.patterns[t] <= mh->numtracks) ?
542 track_remap[of.patterns[t]] - 1 : realtrackcnt;
547 for (t = 0; t < realtrackcnt; t++)
549 if (_mm_eof (modreader))
551 _mm_errno = MMERR_LOADING_TRACK;
554 if (!AMF_UnpackTrack (modreader))
556 _mm_errno = MMERR_LOADING_TRACK;
559 if (!(of.tracks[t] = AMF_ConvertTrack ()))
562 /* add en extra void track */
564 for (t = 0; t < 64; t++)
566 of.tracks[realtrackcnt++] = UniDup ();
567 for (t = realtrackcnt; t < of.numtrk; t++)
570 /* compute sample offsets */
571 samplepos = _mm_ftell (modreader);
572 for (realsmpcnt = t = 0; t < of.numsmp; t++)
573 if (realsmpcnt < of.samples[t].seekpos)
574 realsmpcnt = of.samples[t].seekpos;
575 for (t = 1; t <= realsmpcnt; t++)
578 while (q->seekpos != t)
580 q->seekpos = samplepos;
581 samplepos += q->length;
592 _mm_fseek (modreader, 4, SEEK_SET);
593 if (!_mm_read_UBYTES (s, 32, modreader))
596 return (DupStr (s, 32, 1));
599 /*========== Loader information */
605 "AMF (DSMI Advanced Module Format)",