OSDN Git Service

q: Command not found.
[timidity41/timidity41.git] / libunimod / load_amf.c
1 /*      MikMod sound library
2    (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
3    complete list.
4
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.
9
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.
14
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
18    02111-1307, USA.
19  */
20
21 /*==============================================================================
22
23   $Id$
24
25   DMP Advanced Module Format loader
26
27 ==============================================================================*/
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <string.h>
34
35 #include "unimod_priv.h"
36
37 /*========== Module structure */
38
39 typedef struct AMFHEADER
40   {
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 */
45     UBYTE numorders;
46     UWORD numtracks;            /* number of tracks saved */
47     UBYTE numchannels;          /* number of channels used  */
48     SBYTE panpos[32];           /* voice pan positions */
49     UBYTE songbpm;
50     UBYTE songspd;
51   }
52 AMFHEADER;
53
54 typedef struct AMFSAMPLE
55   {
56     UBYTE type;
57     CHAR samplename[32];
58     CHAR filename[13];
59     ULONG offset;
60     ULONG length;
61     UWORD c2spd;
62     UBYTE volume;
63     ULONG reppos;
64     ULONG repend;
65   }
66 AMFSAMPLE;
67
68 typedef struct AMFNOTE
69   {
70     UBYTE note, instr, volume, fxcnt;
71     UBYTE effect[3];
72     SBYTE parameter[3];
73   }
74 AMFNOTE;
75
76 /*========== Loader variables */
77
78 static AMFHEADER *mh = NULL;
79 #define AMFTEXTLEN 22
80 static CHAR AMF_Version[AMFTEXTLEN + 1] = "DSMI Module Format 0.0";
81 static AMFNOTE *track = NULL;
82
83 /*========== Loader code */
84
85 BOOL 
86 AMF_Test (void)
87 {
88   UBYTE id[3], ver;
89
90   if (!_mm_read_UBYTES (id, 3, modreader))
91     return 0;
92   if (memcmp (id, "AMF", 3))
93     return 0;
94
95   ver = _mm_read_UBYTE (modreader);
96   if ((ver >= 10) && (ver <= 14))
97     return 1;
98   return 0;
99 }
100
101 BOOL 
102 AMF_Init (void)
103 {
104   if (!(mh = (AMFHEADER *) _mm_malloc (sizeof (AMFHEADER))))
105     return 0;
106   if (!(track = (AMFNOTE *) _mm_calloc (64, sizeof (AMFNOTE))))
107     return 0;
108
109   return 1;
110 }
111
112 void 
113 AMF_Cleanup (void)
114 {
115   _mm_free (mh);
116   _mm_free (track);
117 }
118
119 static BOOL 
120 AMF_UnpackTrack (URL modreader)
121 {
122   ULONG tracksize;
123   UBYTE row, cmd;
124   SBYTE arg;
125
126   /* empty track */
127   memset (track, 0, 64 * sizeof (AMFNOTE));
128
129   /* read packed track */
130   if (modreader)
131     {
132       tracksize = _mm_read_I_UWORD (modreader);
133       tracksize += ((ULONG) _mm_read_UBYTE (modreader)) << 16;
134       if (tracksize)
135         while (tracksize--)
136           {
137             row = _mm_read_UBYTE (modreader);
138             cmd = _mm_read_UBYTE (modreader);
139             arg = _mm_read_SBYTE (modreader);
140             /* unexpected end of track */
141             if (!tracksize)
142               {
143                 if ((row == 0xff) && (cmd == 0xff) && (arg == -1))
144                   break;
145                 /* the last triplet should be FF FF FF, but this is not
146                    always the case... maybe a bug in m2amf ? 
147                    else
148                    return 0;
149                  */
150
151               }
152             /* invalid row (probably unexpected end of row) */
153             if (row >= 64)
154               return 0;
155             if (cmd < 0x7f)
156               {
157                 /* note, vol */
158                 track[row].note = cmd;
159                 track[row].volume = (UBYTE) arg + 1;
160               }
161             else if (cmd == 0x7f)
162               {
163                 /* duplicate row */
164                 if ((arg < 0) && (row + arg >= 0))
165                   {
166                     memcpy (track + row, track + (row + arg), sizeof (AMFNOTE));
167                   }
168               }
169             else if (cmd == 0x80)
170               {
171                 /* instr */
172                 track[row].instr = arg + 1;
173               }
174             else if (cmd == 0x83)
175               {
176                 /* volume without note */
177                 track[row].volume = (UBYTE) arg + 1;
178               }
179             else if (track[row].fxcnt < 3)
180               {
181                 /* effect, param */
182                 if (cmd > 0x97)
183                   return 0;
184                 track[row].effect[track[row].fxcnt] = cmd & 0x7f;
185                 track[row].parameter[track[row].fxcnt] = arg;
186                 track[row].fxcnt++;
187               }
188             else
189               return 0;
190           }
191     }
192   return 1;
193 }
194
195 static UBYTE *
196 AMF_ConvertTrack (void)
197 {
198   int row, fx4memory = 0;
199
200   /* convert track */
201   UniReset ();
202   for (row = 0; row < 64; row++)
203     {
204       if (track[row].instr)
205         UniInstrument (track[row].instr - 1);
206       if (track[row].note > OCTAVE)
207         UniNote (track[row].note - OCTAVE);
208
209       /* AMF effects */
210       while (track[row].fxcnt--)
211         {
212           SBYTE inf = track[row].parameter[track[row].fxcnt];
213
214           switch (track[row].effect[track[row].fxcnt])
215             {
216             case 1:             /* Set speed */
217               UniEffect (UNI_S3MEFFECTA, inf);
218               break;
219             case 2:             /* Volume slide */
220               if (inf)
221                 {
222                   UniWriteByte (UNI_S3MEFFECTD);
223                   if (inf >= 0)
224                     UniWriteByte ((inf & 0xf) << 4);
225                   else
226                     UniWriteByte ((-inf) & 0xf);
227                 }
228               break;
229               /* effect 3, set channel volume, done in UnpackTrack */
230             case 4:             /* Porta up/down */
231               if (inf)
232                 {
233                   if (inf > 0)
234                     {
235                       UniEffect (UNI_S3MEFFECTE, inf);
236                       fx4memory = UNI_S3MEFFECTE;
237                     }
238                   else
239                     {
240                       UniEffect (UNI_S3MEFFECTF, -inf);
241                       fx4memory = UNI_S3MEFFECTF;
242                     }
243                 }
244               else if (fx4memory)
245                 UniEffect (fx4memory, 0);
246               break;
247               /* effect 5, "Porta abs", not supported */
248             case 6:             /* Porta to note */
249               UniEffect (UNI_ITEFFECTG, inf);
250               break;
251             case 7:             /* Tremor */
252               UniEffect (UNI_S3MEFFECTI, inf);
253               break;
254             case 8:             /* Arpeggio */
255               UniPTEffect (0x0, inf);
256               break;
257             case 9:             /* Vibrato */
258               UniPTEffect (0x4, inf);
259               break;
260             case 0xa:           /* Porta + Volume slide */
261               UniPTEffect (0x3, 0);
262               if (inf)
263                 {
264                   UniWriteByte (UNI_S3MEFFECTD);
265                   if (inf >= 0)
266                     UniWriteByte ((inf & 0xf) << 4);
267                   else
268                     UniWriteByte ((-inf) & 0xf);
269                 }
270               break;
271             case 0xb:           /* Vibrato + Volume slide */
272               UniPTEffect (0x4, 0);
273               if (inf)
274                 {
275                   UniWriteByte (UNI_S3MEFFECTD);
276                   if (inf >= 0)
277                     UniWriteByte ((inf & 0xf) << 4);
278                   else
279                     UniWriteByte ((-inf) & 0xf);
280                 }
281               break;
282             case 0xc:           /* Pattern break (in hex) */
283               UniPTEffect (0xd, inf);
284               break;
285             case 0xd:           /* Pattern jump */
286               UniPTEffect (0xb, inf);
287               break;
288               /* effect 0xe, "Sync", not supported */
289             case 0xf:           /* Retrig */
290               UniEffect (UNI_S3MEFFECTQ, inf & 0xf);
291               break;
292             case 0x10:          /* Sample offset */
293               UniPTEffect (0x9, inf);
294               break;
295             case 0x11:          /* Fine volume slide */
296               if (inf)
297                 {
298                   UniWriteByte (UNI_S3MEFFECTD);
299                   if (inf >= 0)
300                     UniWriteByte ((inf & 0xf) << 4 | 0xf);
301                   else
302                     UniWriteByte (0xf0 | ((-inf) & 0xf));
303                 }
304               break;
305             case 0x12:          /* Fine portamento */
306               if (inf)
307                 {
308                   if (inf > 0)
309                     {
310                       UniEffect (UNI_S3MEFFECTE, 0xf0 | (inf & 0xf));
311                       fx4memory = UNI_S3MEFFECTE;
312                     }
313                   else
314                     {
315                       UniEffect (UNI_S3MEFFECTF, 0xf0 | ((-inf) & 0xf));
316                       fx4memory = UNI_S3MEFFECTF;
317                     }
318                 }
319               else if (fx4memory)
320                 UniEffect (fx4memory, 0);
321               break;
322             case 0x13:          /* Delay note */
323               UniPTEffect (0xe, 0xd0 | (inf & 0xf));
324               break;
325             case 0x14:          /* Note cut */
326               UniPTEffect (0xc, 0);
327               track[row].volume = 0;
328               break;
329             case 0x15:          /* Set tempo */
330               UniEffect (UNI_S3MEFFECTT, inf);
331               break;
332             case 0x16:          /* Extra fine portamento */
333               if (inf)
334                 {
335                   if (inf > 0)
336                     {
337                       UniEffect (UNI_S3MEFFECTE, 0xe0 | ((inf >> 2) & 0xf));
338                       fx4memory = UNI_S3MEFFECTE;
339                     }
340                   else
341                     {
342                       UniEffect (UNI_S3MEFFECTF, 0xe0 | (((-inf) >> 2) & 0xf));
343                       fx4memory = UNI_S3MEFFECTF;
344                     }
345                 }
346               else if (fx4memory)
347                 UniEffect (fx4memory, 0);
348               break;
349             case 0x17:          /* Panning */
350               if (inf > 64)
351                 UniEffect (UNI_ITEFFECTS0, 0x91);       /* surround */
352               else
353                 UniPTEffect (0x8, (inf == 64) ? 255 : (inf + 64) << 1);
354               break;
355             }
356
357         }
358       if (track[row].volume)
359         UniVolEffect (VOL_VOLUME, track[row].volume - 1);
360       UniNewline ();
361     }
362   return UniDup ();
363 }
364
365 BOOL 
366 AMF_Load (BOOL curious)
367 {
368   int t, u, realtrackcnt, realsmpcnt;
369   AMFSAMPLE s;
370   SAMPLE *q;
371   UWORD *track_remap;
372   ULONG samplepos;
373   int channel_remap[16];
374
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)))
384     {
385       _mm_errno = MMERR_NOT_A_MODULE;
386       return 0;
387     }
388
389   if (mh->version >= 11)
390     {
391       memset (mh->panpos, 0, 32);
392       _mm_read_SBYTES (mh->panpos, (mh->version >= 13) ? 32 : 16, modreader);
393     }
394   else
395     _mm_read_UBYTES (channel_remap, 16, modreader);
396
397   if (mh->version >= 13)
398     {
399       mh->songbpm = _mm_read_UBYTE (modreader);
400       if (mh->songbpm < 32)
401         {
402           _mm_errno = MMERR_NOT_A_MODULE;
403           return 0;
404         }
405       mh->songspd = _mm_read_UBYTE (modreader);
406       if (mh->songspd > 32)
407         {
408           _mm_errno = MMERR_NOT_A_MODULE;
409           return 0;
410         }
411     }
412   else
413     {
414       mh->songbpm = 125;
415       mh->songspd = 6;
416     }
417
418   if (_mm_eof (modreader))
419     {
420       _mm_errno = MMERR_LOADING_HEADER;
421       return 0;
422     }
423
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;
437   of.reppos = 0;
438   of.flags |= UF_S3MSLIDES;
439   for (t = 0; t < 32; t++)
440     {
441       if (mh->panpos[t] > 64)
442         of.panning[t] = PAN_SURROUND;
443       else if (mh->panpos[t] == 64)
444         of.panning[t] = 255;
445       else
446         of.panning[t] = (mh->panpos[t] + 64) << 1;
447     }
448   of.numins = of.numsmp = mh->numsamples;
449
450   if (!AllocPositions (of.numpos))
451     return 0;
452   for (t = 0; t < of.numpos; t++)
453     of.positions[t] = t;
454
455   if (!AllocTracks ())
456     return 0;
457   if (!AllocPatterns ())
458     return 0;
459
460   /* read AMF order table */
461   for (t = 0; t < of.numpat; t++)
462     {
463       if (mh->version >= 14)
464         /* track size */
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);
468       else
469         for (u = 0; u < of.numchn; u++)
470           of.patterns[t * of.numchn + channel_remap[u]] = _mm_read_I_UWORD (modreader);
471     }
472   if (_mm_eof (modreader))
473     {
474       _mm_errno = MMERR_LOADING_HEADER;
475       return 0;
476     }
477
478   /* read sample information */
479   if (!AllocSamples ())
480     return 0;
481   q = of.samples;
482   for (t = 0; t < of.numins; t++)
483     {
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);
491       if (s.c2spd == 8368)
492         s.c2spd = 8363;
493       s.volume = _mm_read_UBYTE (modreader);
494       if (mh->version >= 11)
495         {
496           s.reppos = _mm_read_I_ULONG (modreader);
497           s.repend = _mm_read_I_ULONG (modreader);
498         }
499       else
500         {
501           s.reppos = _mm_read_I_UWORD (modreader);
502           s.repend = s.length;
503         }
504
505       if (_mm_eof (modreader))
506         {
507           _mm_errno = MMERR_LOADING_SAMPLEINFO;
508           return 0;
509         }
510
511       q->samplename = DupStr (s.samplename, 32, 1);
512       q->speed = s.c2spd;
513       q->volume = s.volume;
514       if (s.type)
515         {
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)
521             q->flags |= SF_LOOP;
522         }
523       q++;
524     }
525
526   /* read track table */
527   if (!(track_remap = _mm_calloc (mh->numtracks + 1, sizeof (UWORD))))
528     return 0;
529   _mm_read_I_UWORDS (track_remap + 1, mh->numtracks, modreader);
530   if (_mm_eof (modreader))
531     {
532       free (track_remap);
533       _mm_errno = MMERR_LOADING_TRACK;
534       return 0;
535     }
536
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;
543
544   free (track_remap);
545
546   /* unpack tracks */
547   for (t = 0; t < realtrackcnt; t++)
548     {
549       if (_mm_eof (modreader))
550         {
551           _mm_errno = MMERR_LOADING_TRACK;
552           return 0;
553         }
554       if (!AMF_UnpackTrack (modreader))
555         {
556           _mm_errno = MMERR_LOADING_TRACK;
557           return 0;
558         }
559       if (!(of.tracks[t] = AMF_ConvertTrack ()))
560         return 0;
561     }
562   /* add en extra void track */
563   UniReset ();
564   for (t = 0; t < 64; t++)
565     UniNewline ();
566   of.tracks[realtrackcnt++] = UniDup ();
567   for (t = realtrackcnt; t < of.numtrk; t++)
568     of.tracks[t] = NULL;
569
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++)
576     {
577       q = of.samples;
578       while (q->seekpos != t)
579         q++;
580       q->seekpos = samplepos;
581       samplepos += q->length;
582     }
583
584   return 1;
585 }
586
587 CHAR *
588 AMF_LoadTitle (void)
589 {
590   CHAR s[32];
591
592   _mm_fseek (modreader, 4, SEEK_SET);
593   if (!_mm_read_UBYTES (s, 32, modreader))
594     return NULL;
595
596   return (DupStr (s, 32, 1));
597 }
598
599 /*========== Loader information */
600
601 MLOADER load_amf =
602 {
603   NULL,
604   "AMF",
605   "AMF (DSMI Advanced Module Format)",
606   AMF_Init,
607   AMF_Test,
608   AMF_Load,
609   AMF_Cleanup,
610   AMF_LoadTitle
611 };
612
613 /* ex:set ts=4: */