OSDN Git Service

Merge unkotim227
[timidity41/timidity41.git] / libunimod / load_m15.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   15 instrument MOD loader
26   Also supports Ultimate Sound Tracker (old M15 format)
27
28 ==============================================================================*/
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <string.h>
35
36 #include "unimod_priv.h"
37
38 /*========== Module Structure */
39
40 typedef struct MSAMPINFO
41   {
42     CHAR samplename[23];        /* 22 in module, 23 in memory */
43     UWORD length;
44     UBYTE finetune;
45     UBYTE volume;
46     UWORD reppos;
47     UWORD replen;
48   }
49 MSAMPINFO;
50
51 typedef struct MODULEHEADER
52   {
53     CHAR songname[21];          /* the songname.., 20 in module, 21 in memory */
54     MSAMPINFO samples[15];      /* all sampleinfo */
55     UBYTE songlength;           /* number of patterns used */
56     UBYTE magic1;               /* should be 127 */
57     UBYTE positions[128];       /* which pattern to play at pos */
58   }
59 MODULEHEADER;
60
61 typedef struct MODNOTE
62   {
63     UBYTE a, b, c, d;
64   }
65 MODNOTE;
66
67 /*========== Loader variables */
68
69 static MODULEHEADER *mh = NULL;
70 static MODNOTE *patbuf = NULL;
71 static BOOL ust_loader = 0;     /* if TRUE, load as an ust module. */
72
73 /* known file formats which can confuse the loader */
74 #define REJECT 2
75 static char *signatures[REJECT] =
76 {
77   "CAKEWALK",                   /* cakewalk midi files */
78   "SZDD"                        /* Microsoft compressed files */
79 };
80 static int siglen[REJECT] =
81 {8, 4};
82
83 /*========== Loader code */
84
85 static BOOL 
86 LoadModuleHeader (MODULEHEADER * mh)
87 {
88   int t, u;
89
90   _mm_read_string (mh->songname, 20, modreader);
91   mh->songname[20] = 0;         /* just in case */
92
93   /* sanity check : title should contain printable characters and a bunch
94      of null chars */
95   for (t = 0; t < 20; t++)
96     if ((mh->songname[t]) && (mh->songname[t] < 32))
97       return 0;
98   for (t = 0; (mh->songname[t]) && (t < 20); t++);
99   if (t < 20)
100     for (; t < 20; t++)
101       if (mh->songname[t])
102         return 0;
103
104   for (t = 0; t < 15; t++)
105     {
106       MSAMPINFO *s = &mh->samples[t];
107
108       _mm_read_string (s->samplename, 22, modreader);
109       s->samplename[22] = 0;    /* just in case */
110       s->length = _mm_read_M_UWORD (modreader);
111       s->finetune = _mm_read_UBYTE (modreader);
112       s->volume = _mm_read_UBYTE (modreader);
113       s->reppos = _mm_read_M_UWORD (modreader);
114       s->replen = _mm_read_M_UWORD (modreader);
115
116       /* sanity check : sample title should contain printable characters and
117          a bunch of null chars */
118       for (u = 0; u < 20; u++)
119         if ((s->samplename[u]) && (s->samplename[u] < /*32 */ 14))
120           return 0;
121       for (u = 0; (s->samplename[u]) && (u < 20); u++);
122       if (u < 20)
123         for (; u < 20; u++)
124           if (s->samplename[u])
125             return 0;
126
127       /* sanity check : finetune values */
128       if (s->finetune >> 4)
129         return 0;
130     }
131
132   mh->songlength = _mm_read_UBYTE (modreader);
133   mh->magic1 = _mm_read_UBYTE (modreader);      /* should be 127 */
134
135   /* sanity check : no more than 128 positions, restart position in range */
136   if ((!mh->songlength) || (mh->songlength > 128))
137     return 0;
138   /* values encountered so far are 0x6a and 0x78 */
139   if (((mh->magic1 & 0xf8) != 0x78) && (mh->magic1 != 0x6a) && (mh->magic1 > mh->songlength))
140     return 0;
141
142   _mm_read_UBYTES (mh->positions, 128, modreader);
143
144   /* sanity check : pattern range is 0..63 */
145   for (t = 0; t < 128; t++)
146     if (mh->positions[t] > 63)
147       return 0;
148
149   return (!_mm_eof (modreader));
150 }
151
152 /* Checks the patterns in the modfile for UST / 15-inst indications.
153    For example, if an effect 3xx is found, it is assumed that the song 
154    is 15-inst.  If a 1xx effect has dat greater than 0x20, it is UST.   
155
156    Returns:  0 indecisive; 1 = UST; 2 = 15-inst                               */
157 static int 
158 CheckPatternType (int numpat)
159 {
160   int t;
161   UBYTE eff, dat;
162
163   for (t = 0; t < numpat * (64U * 4); t++)
164     {
165       /* Load the pattern into the temp buffer and scan it */
166       _mm_read_UBYTE (modreader);
167       _mm_read_UBYTE (modreader);
168       eff = _mm_read_UBYTE (modreader);
169       dat = _mm_read_UBYTE (modreader);
170
171       switch (eff)
172         {
173         case 1:
174           if (dat > 0x1f)
175             return 1;
176           if (dat < 0x3)
177             return 2;
178           break;
179         case 2:
180           if (dat > 0x1f)
181             return 1;
182           return 2;
183         case 3:
184           if (dat)
185             return 2;
186           break;
187         default:
188           return 2;
189         }
190     }
191   return 0;
192 }
193
194 static BOOL 
195 M15_Test (void)
196 {
197   int t, numpat;
198   MODULEHEADER mh;
199
200   ust_loader = 0;
201   if (!LoadModuleHeader (&mh))
202     return 0;
203
204   /* reject other file types */
205   for (t = 0; t < REJECT; t++)
206     if (!memcmp (mh.songname, signatures[t], siglen[t]))
207       return 0;
208
209   if (mh.magic1 > 127)
210     return 0;
211   if ((!mh.songlength) || (mh.songlength > mh.magic1))
212     return 0;
213
214   for (t = 0; t < 15; t++)
215     {
216       /* all finetunes should be zero */
217       if (mh.samples[t].finetune)
218         return 0;
219
220       /* all volumes should be <= 64 */
221       if (mh.samples[t].volume > 64)
222         return 0;
223
224       /* all instrument names should begin with s, st-, or a number */
225       if (mh.samples[t].samplename[0] == 's')
226         {
227           if ((memcmp (mh.samples[t].samplename, "st-", 3)) &&
228               (memcmp (mh.samples[t].samplename, "ST-", 3)) &&
229               (*mh.samples[t].samplename))
230             ust_loader = 1;
231         }
232       else if ((mh.samples[t].samplename[0] < '0') ||
233                (mh.samples[t].samplename[0] > '9'))
234         ust_loader = 1;
235
236       if (mh.samples[t].length > 4999 || mh.samples[t].reppos > 9999)
237         {
238           ust_loader = 0;
239           if (mh.samples[t].length > 32768)
240             return 0;
241         }
242
243       /* if loop information is incorrect as words, but correct as bytes,
244          this is likely to be an ust-style module */
245       if((mh.samples[t].reppos + mh.samples[t].replen > mh.samples[t].length) &&
246          (mh.samples[t].reppos + mh.samples[t].replen < (mh.samples[t].length << 1)))
247         {
248           ust_loader = 1;
249           return 1;
250         }
251     }
252
253   for (numpat = 0, t = 0; t < mh.songlength; t++)
254     if (mh.positions[t] > numpat)
255       numpat = mh.positions[t];
256   numpat++;
257   switch (CheckPatternType (numpat))
258     {
259     case 0:                     /* indecisive, so check more clues... */
260       break;
261     case 1:
262       ust_loader = 1;
263       break;
264     case 2:
265       ust_loader = 0;
266       break;
267     }
268   return 1;
269 }
270
271 static BOOL 
272 M15_Init (void)
273 {
274   if (!(mh = (MODULEHEADER *) _mm_malloc (sizeof (MODULEHEADER))))
275     return 0;
276   return 1;
277 }
278
279 static void 
280 M15_Cleanup (void)
281 {
282   _mm_free (mh);
283   _mm_free (patbuf);
284 }
285
286 /*
287    Old (amiga) noteinfo:
288
289    _____byte 1_____   byte2_    _____byte 3_____   byte4_
290    /                \ /      \  /                \ /      \
291    0000          0000-00000000  0000          0000-00000000
292
293    Upper four    12 bits for    Lower four    Effect command.
294    bits of sam-  note period.   bits of sam-
295    ple number.                  ple number.
296  */
297
298 static UWORD npertab[7 * OCTAVE] =
299 {
300         /* -> Tuning 0 */
301   1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 906,
302   856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
303   428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
304   214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
305   107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56,
306
307   53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28,
308   27, 25, 24, 22, 21, 20, 19, 18, 17, 16, 15, 14
309 };
310
311
312 static void 
313 M15_ConvertNote (MODNOTE * n)
314 {
315   UBYTE instrument, effect, effdat, note;
316   UWORD period;
317   UBYTE lastnote = 0;
318
319   /* decode the 4 bytes that make up a single note */
320   instrument = n->c >> 4;
321   period = (((UWORD) n->a & 0xf) << 8) + n->b;
322   effect = n->c & 0xf;
323   effdat = n->d;
324
325   /* Convert the period to a note number */
326   note = 0;
327   if (period)
328     {
329       for (note = 0; note < 7 * OCTAVE; note++)
330         if (period >= npertab[note])
331           break;
332       if (note == 7 * OCTAVE)
333         note = 0;
334       else
335         note++;
336     }
337
338   if (instrument)
339     {
340       /* if instrument does not exist, note cut */
341       if ((instrument > 15) || (!mh->samples[instrument - 1].length))
342         {
343           UniPTEffect (0xc, 0);
344           if (effect == 0xc)
345             effect = effdat = 0;
346         }
347       else
348         {
349           /* if we had a note, then change instrument... */
350           if (note)
351             UniInstrument (instrument - 1);
352           /* ...otherwise, only adjust volume... */
353           else
354             {
355               /* ...unless an effect was specified, which forces a new note
356                  to be played */
357               if (effect || effdat)
358                 {
359                   UniInstrument (instrument - 1);
360                   note = lastnote;
361                 }
362               else
363                 UniPTEffect (0xc, mh->samples[instrument - 1].volume & 0x7f);
364             }
365         }
366     }
367   if (note)
368     {
369       UniNote (note + 2 * OCTAVE - 1);
370       lastnote = note;
371     }
372
373   /* Handle ``heavy'' volumes correctly */
374   if ((effect == 0xc) && (effdat > 0x40))
375     effdat = 0x40;
376
377   /* Convert pattern jump from Dec to Hex */
378   if (effect == 0xd)
379     effdat = (((effdat & 0xf0) >> 4) * 10) + (effdat & 0xf);
380
381   /* Volume slide, up has priority */
382   if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0))
383     effdat &= 0xf0;
384
385   if (ust_loader)
386     {
387       switch (effect)
388         {
389         case 0:
390         case 3:
391           break;
392         case 1:
393           UniPTEffect (0, effdat);
394           break;
395         case 2:
396           if (effdat & 0xf)
397             UniPTEffect (1, effdat & 0xf);
398           if (effdat >> 2)
399             UniPTEffect (2, effdat >> 2);
400           break;
401         default:
402           UniPTEffect (effect, effdat);
403           break;
404         }
405     }
406   else {
407     /* Ignore 100, 200 and 300 (there is no porta memory in mod files) */
408     if ((!effdat) && ((effect == 1)||(effect == 2)||(effect == 3)))
409       effect = 0;
410
411     UniPTEffect (effect, effdat);
412   }
413 }
414
415 static UBYTE *
416 M15_ConvertTrack (MODNOTE * n)
417 {
418   int t;
419
420   UniReset ();
421   for (t = 0; t < 64; t++)
422     {
423       M15_ConvertNote (n);
424       UniNewline ();
425       n += 4;
426     }
427   return UniDup ();
428 }
429
430 /* Loads all patterns of a modfile and converts them into the 3 byte format. */
431 static BOOL 
432 M15_LoadPatterns (void)
433 {
434   int t, s, tracks = 0;
435
436   if (!AllocPatterns ())
437     return 0;
438   if (!AllocTracks ())
439     return 0;
440
441   /* Allocate temporary buffer for loading and converting the patterns */
442   if (!(patbuf = (MODNOTE *) _mm_calloc (64U * 4, sizeof (MODNOTE))))
443     return 0;
444
445   for (t = 0; t < of.numpat; t++)
446     {
447       /* Load the pattern into the temp buffer and convert it */
448       for (s = 0; s < (64U * 4); s++)
449         {
450           patbuf[s].a = _mm_read_UBYTE (modreader);
451           patbuf[s].b = _mm_read_UBYTE (modreader);
452           patbuf[s].c = _mm_read_UBYTE (modreader);
453           patbuf[s].d = _mm_read_UBYTE (modreader);
454         }
455
456       for (s = 0; s < 4; s++)
457         if (!(of.tracks[tracks++] = M15_ConvertTrack (patbuf + s)))
458           return 0;
459     }
460   return 1;
461 }
462
463 static BOOL 
464 M15_Load (BOOL curious)
465 {
466   int t, scan;
467   SAMPLE *q;
468   MSAMPINFO *s;
469
470   /* try to read module header */
471   if (!LoadModuleHeader (mh))
472     {
473       _mm_errno = MMERR_LOADING_HEADER;
474       return 0;
475     }
476
477   if (ust_loader)
478     of.modtype = strdup ("Ultimate Soundtracker");
479   else
480     of.modtype = strdup ("Soundtracker");
481
482   /* set module variables */
483   of.initspeed = 6;
484   of.inittempo = 125;
485   of.numchn = 4;
486   of.songname = DupStr (mh->songname, 21, 1);
487   of.numpos = mh->songlength;
488   of.reppos = 0;
489
490   /* Count the number of patterns */
491   of.numpat = 0;
492   for (t = 0; t < of.numpos; t++)
493     if (mh->positions[t] > of.numpat)
494       of.numpat = mh->positions[t];
495   /* since some old modules embed extra patterns, we have to check the
496      whole list to get the samples' file offsets right - however we can find
497      garbage here, so check carefully */
498   scan = 1;
499   for (t = of.numpos; t < 128; t++)
500     if (mh->positions[t] >= 0x80)
501       scan = 0;
502   if (scan)
503     for (t = of.numpos; t < 128; t++)
504       {
505         if (mh->positions[t] > of.numpat)
506           of.numpat = mh->positions[t];
507         if ((curious) && (mh->positions[t]))
508           of.numpos = t + 1;
509       }
510   of.numpat++;
511   of.numtrk = of.numpat * of.numchn;
512
513   if (!AllocPositions (of.numpos))
514     return 0;
515   for (t = 0; t < of.numpos; t++)
516     of.positions[t] = mh->positions[t];
517
518   /* Finally, init the sampleinfo structures */
519   of.numins = of.numsmp = 15;
520   if (!AllocSamples ())
521     return 0;
522
523   s = mh->samples;
524   q = of.samples;
525
526   for (t = 0; t < of.numins; t++)
527     {
528       /* convert the samplename */
529       q->samplename = DupStr (s->samplename, 23, 1);
530
531       /* init the sampleinfo variables and convert the size pointers */
532       q->speed = finetune[s->finetune & 0xf];
533       q->volume = s->volume;
534       if (ust_loader)
535         q->loopstart = s->reppos;
536       else
537         q->loopstart = s->reppos << 1;
538       q->loopend = q->loopstart + (s->replen << 1);
539       q->length = s->length << 1;
540
541       q->flags = SF_SIGNED;
542       if(ust_loader)
543         q->flags |= SF_UST_LOOP;
544       if(s->replen > 2)
545         q->flags |= SF_LOOP;
546
547       /* fix replen if repend>length */
548       if (q->loopend > q->length)
549         q->loopend = q->length;
550
551       s++;
552       q++;
553     }
554
555   if (!M15_LoadPatterns ())
556     return 0;
557   ust_loader = 0;
558
559   return 1;
560 }
561
562 static CHAR *
563 M15_LoadTitle (void)
564 {
565   CHAR s[21];
566
567   _mm_fseek (modreader, 0, SEEK_SET);
568   if (!_mm_read_UBYTES (s, 20, modreader))
569     return NULL;
570   s[20] = 0;                    /* just in case */
571   return (DupStr (s, 21, 1));
572 }
573
574 /*========== Loader information */
575
576 MLOADER load_m15 =
577 {
578   NULL,
579   "15-instrument module",
580   "MOD (15 instruments)",
581   M15_Init,
582   M15_Test,
583   M15_Load,
584   M15_Cleanup,
585   M15_LoadTitle
586 };
587
588 /* ex:set ts=4: */