76eafe5158f429b52d7c1dd522efab83e34a48e0
[platform/upstream/gstreamer.git] / gst / modplug / libmodplug / load_med.cpp
1 /*
2  * This source code is public domain.
3  *
4  * Authors: Olivier Lapicque <olivierl@jps.net>,
5  *          Adam Goode       <adam@evdebs.org> (endian and char fixes for PPC)
6 */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "stdafx.h"
13 #include "sndfile.h"
14
15 //#define MED_LOG
16
17 #ifdef MED_LOG
18 extern void Log(LPCSTR s, ...);
19 #endif
20
21 //////////////////////////////////////////////////////////
22 // OctaMed MED file support (import only)
23
24 // flags
25 #define MMD_FLAG_FILTERON       0x1
26 #define MMD_FLAG_JUMPINGON      0x2
27 #define MMD_FLAG_JUMP8TH        0x4
28 #define MMD_FLAG_INSTRSATT      0x8 // instruments are attached (this is a module)
29 #define MMD_FLAG_VOLHEX         0x10
30 #define MMD_FLAG_STSLIDE        0x20 // SoundTracker mode for slides
31 #define MMD_FLAG_8CHANNEL       0x40 // OctaMED 8 channel song
32 #define MMD_FLAG_SLOWHQ         0x80 // HQ slows playing speed (V2-V4 compatibility)
33 // flags2
34 #define MMD_FLAG2_BMASK         0x1F
35 #define MMD_FLAG2_BPM           0x20
36 #define MMD_FLAG2_MIX           0x80 // uses Mixing (V7+)
37 // flags3:
38 #define MMD_FLAG3_STEREO        0x1     // mixing in Stereo mode
39 #define MMD_FLAG3_FREEPAN       0x2     // free panning
40 #define MMD_FLAG3_GM            0x4 // module designed for GM/XG compatibility
41
42
43 // generic MMD tags
44 #define MMDTAG_END              0
45 #define MMDTAG_PTR              0x80000000      // data needs relocation
46 #define MMDTAG_MUSTKNOW 0x40000000      // loader must fail if this isn't recognized
47 #define MMDTAG_MUSTWARN 0x20000000      // loader must warn if this isn't recognized
48
49 // ExpData tags
50 // # of effect groups, including the global group (will
51 // override settings in MMDSong struct), default = 1
52 #define MMDTAG_EXP_NUMFXGROUPS  1
53 #define MMDTAG_TRK_NAME         (MMDTAG_PTR|1)  // trackinfo tags
54 #define MMDTAG_TRK_NAMELEN      2                               // namelen includes zero term.
55 #define MMDTAG_TRK_FXGROUP      3
56 // effectinfo tags
57 #define MMDTAG_FX_ECHOTYPE      1
58 #define MMDTAG_FX_ECHOLEN       2
59 #define MMDTAG_FX_ECHODEPTH     3
60 #define MMDTAG_FX_STEREOSEP     4
61 #define MMDTAG_FX_GROUPNAME     (MMDTAG_PTR|5)  // the Global Effects group shouldn't have name saved!
62 #define MMDTAG_FX_GRPNAMELEN 6  // namelen includes zero term.
63
64 #pragma pack(1)
65
66 typedef struct tagMEDMODULEHEADER
67 {
68         DWORD id;               // MMD1-MMD3
69         DWORD modlen;   // Size of file
70         DWORD song;             // Position in file for this song
71         WORD psecnum;
72         WORD pseq;
73         DWORD blockarr; // Position in file for blocks
74         DWORD mmdflags;
75         DWORD smplarr;  // Position in file for samples
76         DWORD reserved;
77         DWORD expdata;  // Absolute offset in file for ExpData (0 if not present)
78         DWORD reserved2;
79         WORD pstate;
80         WORD pblock;
81         WORD pline;
82         WORD pseqnum;
83         WORD actplayline;
84         BYTE counter;
85         BYTE extra_songs;       // # of songs - 1
86 } MEDMODULEHEADER;
87
88
89 typedef struct tagMMD0SAMPLE
90 {
91         WORD rep, replen;
92         BYTE midich;
93         BYTE midipreset;
94         BYTE svol;
95         signed char strans;
96 } MMD0SAMPLE;
97
98
99 // Sample header is immediately followed by sample data...
100 typedef struct tagMMDSAMPLEHEADER
101 {
102         DWORD length;     // length of *one* *unpacked* channel in *bytes*
103         WORD type;   
104                                 // if non-negative
105                                         // bits 0-3 reserved for multi-octave instruments, not supported on the PC
106                                         // 0x10: 16 bit (otherwise 8 bit)
107                                         // 0x20: Stereo (otherwise mono)
108                                         // 0x40: Uses DeltaCode
109                                         // 0x80: Packed data
110                                 // -1: Synth
111                                 // -2: Hybrid
112         // if type indicates packed data, these fields follow, otherwise we go right to the data
113         WORD packtype;  // Only 1 = ADPCM is supported
114         WORD subtype;   // Packing subtype
115                 // ADPCM subtype
116                 // 1: g723_40
117                 // 2: g721
118                 // 3: g723_24
119         BYTE commonflags;       // flags common to all packtypes (none defined so far)
120         BYTE packerflags;       // flags for the specific packtype
121         ULONG leftchlen;        // packed length of left channel in bytes
122         ULONG rightchlen;       // packed length of right channel in bytes (ONLY PRESENT IN STEREO SAMPLES)
123         BYTE SampleData[1];     // Sample Data
124 } MMDSAMPLEHEADER;
125
126
127 // MMD0/MMD1 song header
128 typedef struct tagMMD0SONGHEADER
129 {
130         MMD0SAMPLE sample[63];
131         WORD numblocks;         // # of blocks
132         WORD songlen;           // # of entries used in playseq
133         BYTE playseq[256];      // Play sequence
134         WORD deftempo;          // BPM tempo
135         signed char playtransp; // Play transpose
136         BYTE flags;                     // 0x10: Hex Volumes | 0x20: ST/NT/PT Slides | 0x40: 8 Channels song
137         BYTE flags2;            // [b4-b0]+1: Tempo LPB, 0x20: tempo mode, 0x80: mix_conv=on
138         BYTE tempo2;            // tempo TPL
139         BYTE trkvol[16];        // track volumes
140         BYTE mastervol;         // master volume
141         BYTE numsamples;        // # of samples (max=63)
142 } MMD0SONGHEADER;
143
144
145 // MMD2/MMD3 song header
146 typedef struct tagMMD2SONGHEADER
147 {
148         MMD0SAMPLE sample[63];
149         WORD numblocks;         // # of blocks
150         WORD numsections;       // # of sections
151         DWORD playseqtable;     // filepos of play sequence
152         DWORD sectiontable;     // filepos of sections table (WORD array)
153         DWORD trackvols;        // filepos of tracks volume (BYTE array)
154         WORD numtracks;         // # of tracks (max 64)
155         WORD numpseqs;          // # of play sequences
156         DWORD trackpans;        // filepos of tracks pan values (BYTE array)
157         LONG flags3;            // 0x1:stereo_mix, 0x2:free_panning, 0x4:GM/XG compatibility
158         WORD voladj;            // vol_adjust (set to 100 if 0)
159         WORD channels;          // # of channels (4 if =0)
160         BYTE mix_echotype;      // 1:normal,2:xecho
161         BYTE mix_echodepth;     // 1..6
162         WORD mix_echolen;       // > 0
163         signed char mix_stereosep;      // -4..4
164         BYTE pad0[223];
165         WORD deftempo;          // BPM tempo
166         signed char playtransp; // play transpose
167         BYTE flags;                     // 0x1:filteron, 0x2:jumpingon, 0x4:jump8th, 0x8:instr_attached, 0x10:hex_vol, 0x20:PT_slides, 0x40:8ch_conv,0x80:hq slows playing speed
168         BYTE flags2;            // 0x80:mix_conv=on, [b4-b0]+1:tempo LPB, 0x20:tempo_mode
169         BYTE tempo2;            // tempo TPL
170         BYTE pad1[16];
171         BYTE mastervol;         // master volume
172         BYTE numsamples;        // # of samples (max 63)
173 } MMD2SONGHEADER;
174
175 // For MMD0 the note information is held in 3 bytes, byte0, byte1, byte2.  For reference we 
176 // number the bits in each byte 0..7, where 0 is the low bit.
177 // The note is held as bits 5..0 of byte0
178 // The instrument is encoded in 6 bits,  bits 7 and 6 of byte0 and bits 7,6,5,4 of byte1
179 // The command number is bits 3,2,1,0 of byte1, command data is in byte2:
180 // For command 0, byte2 represents the second data byte, otherwise byte2
181 // represents the first data byte.
182 typedef struct tagMMD0BLOCK
183 {
184         BYTE numtracks;
185         BYTE lines;             // File value is 1 less than actual, so 0 -> 1 line
186 } MMD0BLOCK;            // BYTE data[lines+1][tracks][3];
187
188
189 // For MMD1,MMD2,MMD3 the note information is carried in 4 bytes, byte0, byte1,
190 // byte2 and byte3
191 // The note is held as byte0 (values above 0x84 are ignored)
192 // The instrument is held as byte1
193 // The command number is held as byte2, command data is in byte3
194 // For commands 0 and 0x19 byte3 represents the second data byte,
195 // otherwise byte2 represents the first data byte.
196 typedef struct tagMMD1BLOCK
197 {
198         WORD numtracks; // Number of tracks, may be > 64, but then that data is skipped.
199         WORD lines;             // Stored value is 1 less than actual, so 0 -> 1 line
200         DWORD info;             // Offset of BlockInfo (if 0, no block_info is present)
201 } MMD1BLOCK;
202
203
204 typedef struct tagMMD1BLOCKINFO
205 {
206         DWORD hlmask;           // Unimplemented - ignore
207         DWORD blockname;        // file offset of block name
208         DWORD blocknamelen;     // length of block name (including term. 0)
209         DWORD pagetable;        // file offset of command page table
210         DWORD cmdexttable;      // file offset of command extension table
211         DWORD reserved[4];      // future expansion
212 } MMD1BLOCKINFO;
213
214
215 // A set of play sequences is stored as an array of ULONG files offsets
216 // Each offset points to the play sequence itself.
217 typedef struct tagMMD2PLAYSEQ
218 {
219         CHAR name[32];
220         DWORD command_offs;     // filepos of command table
221         DWORD reserved;
222         WORD length;
223         WORD seq[512];  // skip if > 0x8000
224 } MMD2PLAYSEQ;
225
226
227 // A command table contains commands that effect a particular play sequence
228 // entry.  The only commands read in are STOP or POSJUMP, all others are ignored
229 // POSJUMP is presumed to have extra bytes containing a WORD for the position
230 typedef struct tagMMDCOMMAND
231 {
232         WORD offset;            // Offset within current sequence entry
233         BYTE cmdnumber;         // STOP (537) or POSJUMP (538) (others skipped)
234         BYTE extra_count;
235         BYTE extra_bytes[4];// [extra_count];
236 } MMDCOMMAND;  // Last entry has offset == 0xFFFF, cmd_number == 0 and 0 extrabytes
237
238
239 typedef struct tagMMD0EXP
240 {
241         DWORD nextmod;                  // File offset of next Hdr
242         DWORD exp_smp;                  // Pointer to extra instrument data
243         WORD s_ext_entries;             // Number of extra instrument entries
244         WORD s_ext_entrsz;              // Size of extra instrument data
245         DWORD annotxt;
246         DWORD annolen;
247         DWORD iinfo;                    // Instrument names
248         WORD i_ext_entries;     
249         WORD i_ext_entrsz;
250         DWORD jumpmask;
251         DWORD rgbtable;
252         BYTE channelsplit[4];   // Only used if 8ch_conv (extra channel for every nonzero entry)
253         DWORD n_info;
254         DWORD songname;                 // Song name
255         DWORD songnamelen;
256         DWORD dumps;
257         DWORD mmdinfo;
258         DWORD mmdrexx;
259         DWORD mmdcmd3x;
260         DWORD trackinfo_ofs;    // ptr to song->numtracks ptrs to tag lists
261         DWORD effectinfo_ofs;   // ptr to group ptrs
262         DWORD tag_end;
263 } MMD0EXP;
264
265 #pragma pack()
266
267
268
269 static void MedConvert(MODCOMMAND *p, const MMD0SONGHEADER *pmsh)
270 //---------------------------------------------------------------
271 {
272         const BYTE bpmvals[9] = { 179,164,152,141,131,123,116,110,104};
273
274         UINT command = p->command;
275         UINT param = p->param;
276         switch(command)
277         {
278         case 0x00:      if (param) command = CMD_ARPEGGIO; else command = 0; break;
279         case 0x01:      command = CMD_PORTAMENTOUP; break;
280         case 0x02:      command = CMD_PORTAMENTODOWN; break;
281         case 0x03:      command = CMD_TONEPORTAMENTO; break;
282         case 0x04:      command = CMD_VIBRATO; break;
283         case 0x05:      command = CMD_TONEPORTAVOL; break;
284         case 0x06:      command = CMD_VIBRATOVOL; break;
285         case 0x07:      command = CMD_TREMOLO; break;
286         case 0x0A:      if (param & 0xF0) param &= 0xF0; command = CMD_VOLUMESLIDE; if (!param) command = 0; break;
287         case 0x0B:      command = CMD_POSITIONJUMP; break;
288         case 0x0C:      command = CMD_VOLUME;
289                                 if (pmsh->flags & MMD_FLAG_VOLHEX)
290                                 {
291                                         if (param < 0x80)
292                                         {
293                                                 param = (param+1) / 2;
294                                         } else command = 0;
295                                 } else
296                                 {
297                                         if (param <= 0x99)
298                                         {
299                                                 param = (param >> 4)*10+((param & 0x0F) % 10);
300                                                 if (param > 64) param = 64;
301                                         } else command = 0;
302                                 }
303                                 break;
304         case 0x09:      command = (param < 0x20) ? CMD_SPEED : CMD_TEMPO; break;
305         case 0x0D:      if (param & 0xF0) param &= 0xF0; command = CMD_VOLUMESLIDE; if (!param) command = 0; break;
306         case 0x0F:      // Set Tempo / Special
307                 // F.00 = Pattern Break
308                 if (!param)     command = CMD_PATTERNBREAK;     else
309                 // F.01 - F.F0: Set tempo/speed
310                 if (param <= 0xF0)
311                 {
312                         if (pmsh->flags & MMD_FLAG_8CHANNEL)
313                         {
314                                 param = (param > 10) ? 99 : bpmvals[param-1];
315                         } else
316                         // F.01 - F.0A: Set Speed
317                         if (param <= 0x0A)
318                         {
319                                 command = CMD_SPEED;
320                         } else
321                         // Old tempo
322                         if (!(pmsh->flags2 & MMD_FLAG2_BPM))
323                         {
324                                 param = _muldiv(param, 5*715909, 2*474326);
325                         }
326                         // F.0B - F.F0: Set Tempo (assumes LPB=4)
327                         if (param > 0x0A)
328                         {
329                                 command = CMD_TEMPO;
330                                 if (param < 0x21) param = 0x21;
331                                 if (param > 240) param = 240;
332                         }
333                 } else
334                 switch(param)
335                 {
336                 // F.F1: Retrig 2x
337                 case 0xF1:
338                         command = CMD_MODCMDEX;
339                         param = 0x93;
340                         break;
341                 // F.F2: Note Delay 2x
342                 case 0xF2:
343                         command = CMD_MODCMDEX;
344                         param = 0xD3;
345                         break;
346                 // F.F3: Retrig 3x
347                 case 0xF3:
348                         command = CMD_MODCMDEX;
349                         param = 0x92;
350                         break;
351                 // F.F4: Note Delay 1/3
352                 case 0xF4:
353                         command = CMD_MODCMDEX;
354                         param = 0xD2;
355                         break;
356                 // F.F5: Note Delay 2/3
357                 case 0xF5:
358                         command = CMD_MODCMDEX;
359                         param = 0xD4;
360                         break;
361                 // F.F8: Filter Off
362                 case 0xF8:
363                         command = CMD_MODCMDEX;
364                         param = 0x00;
365                         break;
366                 // F.F9: Filter On
367                 case 0xF9:
368                         command = CMD_MODCMDEX;
369                         param = 0x01;
370                         break;
371                 // F.FD: Very fast tone-portamento
372                 case 0xFD:
373                         command = CMD_TONEPORTAMENTO;
374                         param = 0xFF;
375                         break;
376                 // F.FE: End Song
377                 case 0xFE:
378                         command = CMD_SPEED;
379                         param = 0;
380                         break;
381                 // F.FF: Note Cut
382                 case 0xFF:
383                         command = CMD_MODCMDEX;
384                         param = 0xC0;
385                         break;
386                 default:
387 #ifdef MED_LOG
388                         Log("Unknown Fxx command: cmd=0x%02X param=0x%02X\n", command, param);
389 #endif
390                         param = command = 0;
391                 }
392                 break;
393         // 11.0x: Fine Slide Up
394         case 0x11:
395                 command = CMD_MODCMDEX;
396                 if (param > 0x0F) param = 0x0F;
397                 param |= 0x10;
398                 break;
399         // 12.0x: Fine Slide Down
400         case 0x12:
401                 command = CMD_MODCMDEX;
402                 if (param > 0x0F) param = 0x0F;
403                 param |= 0x20;
404                 break;
405         // 14.xx: Vibrato
406         case 0x14:
407                 command = CMD_VIBRATO;
408                 break;
409         // 15.xx: FineTune
410         case 0x15:
411                 command = CMD_MODCMDEX;
412                 param &= 0x0F;
413                 param |= 0x50;
414                 break;
415         // 16.xx: Pattern Loop
416         case 0x16:
417                 command = CMD_MODCMDEX;
418                 if (param > 0x0F) param = 0x0F;
419                 param |= 0x60;
420                 break;
421         // 18.xx: Note Cut
422         case 0x18:
423                 command = CMD_MODCMDEX;
424                 if (param > 0x0F) param = 0x0F;
425                 param |= 0xC0;
426                 break;
427         // 19.xx: Sample Offset
428         case 0x19:
429                 command = CMD_OFFSET;
430                 break;
431         // 1A.0x: Fine Volume Up
432         case 0x1A:
433                 command = CMD_MODCMDEX;
434                 if (param > 0x0F) param = 0x0F;
435                 param |= 0xA0;
436                 break;
437         // 1B.0x: Fine Volume Down
438         case 0x1B:
439                 command = CMD_MODCMDEX;
440                 if (param > 0x0F) param = 0x0F;
441                 param |= 0xB0;
442                 break;
443         // 1D.xx: Pattern Break
444         case 0x1D:
445                 command = CMD_PATTERNBREAK;
446                 break;
447         // 1E.0x: Pattern Delay
448         case 0x1E:
449                 command = CMD_MODCMDEX;
450                 if (param > 0x0F) param = 0x0F;
451                 param |= 0xE0;
452                 break;
453         // 1F.xy: Retrig
454         case 0x1F:
455                 command = CMD_RETRIG;
456                 param &= 0x0F;
457                 break;
458         // 2E.xx: set panning
459         case 0x2E:
460                 command = CMD_MODCMDEX;
461                 param = ((param + 0x10) & 0xFF) >> 1;
462                 if (param > 0x0F) param = 0x0F;
463                 param |= 0x80;
464                 break;
465         default:
466 #ifdef MED_LOG
467                 // 0x2E ?
468                 Log("Unknown command: cmd=0x%02X param=0x%02X\n", command, param);
469 #endif
470                 command = param = 0;
471         }
472         p->command = command;
473         p->param = param;
474 }
475
476
477 BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength)
478 //---------------------------------------------------------------
479 {
480         const MEDMODULEHEADER *pmmh;
481         const MMD0SONGHEADER *pmsh;
482         const MMD2SONGHEADER *pmsh2;
483         const MMD0EXP *pmex;
484         DWORD dwBlockArr, dwSmplArr, dwExpData, wNumBlocks;
485         LPDWORD pdwTable;
486         CHAR version;
487         UINT deftempo;
488         int playtransp = 0;
489
490         if ((!lpStream) || (dwMemLength < 0x200)) return FALSE;
491         pmmh = (MEDMODULEHEADER *)lpStream;
492         if (((pmmh->id & 0x00FFFFFF) != 0x444D4D) || (!pmmh->song)) return FALSE;
493         // Check for 'MMDx'
494         DWORD dwSong = bswapBE32(pmmh->song);
495         if ((dwSong >= dwMemLength) || (dwSong + sizeof(MMD0SONGHEADER) >= dwMemLength)) return FALSE;
496         version = (signed char)((pmmh->id >> 24) & 0xFF);
497         if ((version < '0') || (version > '3')) return FALSE;
498 #ifdef MED_LOG
499         Log("\nLoading MMD%c module (flags=0x%02X)...\n", version, bswapBE32(pmmh->mmdflags));
500         Log("  modlen   = %d\n", bswapBE32(pmmh->modlen));
501         Log("  song     = 0x%08X\n", bswapBE32(pmmh->song));
502         Log("  psecnum  = %d\n", bswapBE16(pmmh->psecnum));
503         Log("  pseq     = %d\n", bswapBE16(pmmh->pseq));
504         Log("  blockarr = 0x%08X\n", bswapBE32(pmmh->blockarr));
505         Log("  mmdflags = 0x%08X\n", bswapBE32(pmmh->mmdflags));
506         Log("  smplarr  = 0x%08X\n", bswapBE32(pmmh->smplarr));
507         Log("  reserved = 0x%08X\n", bswapBE32(pmmh->reserved));
508         Log("  expdata  = 0x%08X\n", bswapBE32(pmmh->expdata));
509         Log("  reserved2= 0x%08X\n", bswapBE32(pmmh->reserved2));
510         Log("  pstate   = %d\n", bswapBE16(pmmh->pstate));
511         Log("  pblock   = %d\n", bswapBE16(pmmh->pblock));
512         Log("  pline    = %d\n", bswapBE16(pmmh->pline));
513         Log("  pseqnum  = %d\n", bswapBE16(pmmh->pseqnum));
514         Log("  actplayline=%d\n", bswapBE16(pmmh->actplayline));
515         Log("  counter  = %d\n", pmmh->counter);
516         Log("  extra_songs = %d\n", pmmh->extra_songs);
517         Log("\n");
518 #endif
519         m_nType = MOD_TYPE_MED;
520         m_nSongPreAmp = 0x20;
521         dwBlockArr = bswapBE32(pmmh->blockarr);
522         dwSmplArr = bswapBE32(pmmh->smplarr);
523         dwExpData = bswapBE32(pmmh->expdata);
524         if ((dwExpData) && (dwExpData+sizeof(MMD0EXP) < dwMemLength))
525                 pmex = (MMD0EXP *)(lpStream+dwExpData);
526         else
527                 pmex = NULL;
528         pmsh = (MMD0SONGHEADER *)(lpStream + dwSong);
529         pmsh2 = (MMD2SONGHEADER *)pmsh;
530 #ifdef MED_LOG
531         if (version < '2')
532         {
533                 Log("MMD0 Header:\n");
534                 Log("  numblocks  = %d\n", bswapBE16(pmsh->numblocks));
535                 Log("  songlen    = %d\n", bswapBE16(pmsh->songlen));
536                 Log("  playseq    = ");
537                 for (UINT idbg1=0; idbg1<16; idbg1++) Log("%2d, ", pmsh->playseq[idbg1]);
538                 Log("...\n");
539                 Log("  deftempo   = 0x%04X\n", bswapBE16(pmsh->deftempo));
540                 Log("  playtransp = %d\n", (signed char)pmsh->playtransp);
541                 Log("  flags(1,2) = 0x%02X, 0x%02X\n", pmsh->flags, pmsh->flags2);
542                 Log("  tempo2     = %d\n", pmsh->tempo2);
543                 Log("  trkvol     = ");
544                 for (UINT idbg2=0; idbg2<16; idbg2++) Log("0x%02X, ", pmsh->trkvol[idbg2]);
545                 Log("...\n");
546                 Log("  mastervol  = 0x%02X\n", pmsh->mastervol);
547                 Log("  numsamples = %d\n", pmsh->numsamples);
548         } else
549         {
550                 Log("MMD2 Header:\n");
551                 Log("  numblocks  = %d\n", bswapBE16(pmsh2->numblocks));
552                 Log("  numsections= %d\n", bswapBE16(pmsh2->numsections));
553                 Log("  playseqptr = 0x%04X\n", bswapBE32(pmsh2->playseqtable));
554                 Log("  sectionptr = 0x%04X\n", bswapBE32(pmsh2->sectiontable));
555                 Log("  trackvols  = 0x%04X\n", bswapBE32(pmsh2->trackvols));
556                 Log("  numtracks  = %d\n", bswapBE16(pmsh2->numtracks));
557                 Log("  numpseqs   = %d\n", bswapBE16(pmsh2->numpseqs));
558                 Log("  trackpans  = 0x%04X\n", bswapBE32(pmsh2->trackpans));
559                 Log("  flags3     = 0x%08X\n", bswapBE32(pmsh2->flags3));
560                 Log("  voladj     = %d\n", bswapBE16(pmsh2->voladj));
561                 Log("  channels   = %d\n", bswapBE16(pmsh2->channels));
562                 Log("  echotype   = %d\n", pmsh2->mix_echotype);
563                 Log("  echodepth  = %d\n", pmsh2->mix_echodepth);
564                 Log("  echolen    = %d\n", bswapBE16(pmsh2->mix_echolen));
565                 Log("  stereosep  = %d\n", (signed char)pmsh2->mix_stereosep);
566                 Log("  deftempo   = 0x%04X\n", bswapBE16(pmsh2->deftempo));
567                 Log("  playtransp = %d\n", (signed char)pmsh2->playtransp);
568                 Log("  flags(1,2) = 0x%02X, 0x%02X\n", pmsh2->flags, pmsh2->flags2);
569                 Log("  tempo2     = %d\n", pmsh2->tempo2);
570                 Log("  mastervol  = 0x%02X\n", pmsh2->mastervol);
571                 Log("  numsamples = %d\n", pmsh->numsamples);
572         }
573         Log("\n");
574 #endif
575         wNumBlocks = bswapBE16(pmsh->numblocks);
576         m_nChannels = 4;
577         m_nSamples = pmsh->numsamples;
578         if (m_nSamples > 63) m_nSamples = 63;
579         // Tempo
580         m_nDefaultTempo = 125;
581         deftempo = bswapBE16(pmsh->deftempo);
582         if (!deftempo) deftempo = 125;
583         if (pmsh->flags2 & MMD_FLAG2_BPM)
584         {
585                 UINT tempo_tpl = (pmsh->flags2 & MMD_FLAG2_BMASK) + 1;
586                 if (!tempo_tpl) tempo_tpl = 4;
587                 deftempo *= tempo_tpl;
588                 deftempo /= 4;
589         #ifdef MED_LOG
590                 Log("newtempo: %3d bpm (bpm=%3d lpb=%2d)\n", deftempo, bswapBE16(pmsh->deftempo), (pmsh->flags2 & MMD_FLAG2_BMASK)+1);
591         #endif
592         } else
593         {
594                 deftempo = _muldiv(deftempo, 5*715909, 2*474326);
595         #ifdef MED_LOG
596                 Log("oldtempo: %3d bpm (bpm=%3d)\n", deftempo, bswapBE16(pmsh->deftempo));
597         #endif
598         }
599         // Speed
600         m_nDefaultSpeed = pmsh->tempo2;
601         if (!m_nDefaultSpeed) m_nDefaultSpeed = 6;
602         if (deftempo < 0x21) deftempo = 0x21;
603         if (deftempo > 255)
604         {
605                 while ((m_nDefaultSpeed > 3) && (deftempo > 260))
606                 {
607                         deftempo = (deftempo * (m_nDefaultSpeed - 1)) / m_nDefaultSpeed;
608                         m_nDefaultSpeed--;
609                 }
610                 if (deftempo > 255) deftempo = 255;
611         }
612         m_nDefaultTempo = deftempo;
613         // Reading Samples
614         for (UINT iSHdr=0; iSHdr<m_nSamples; iSHdr++)
615         {
616                 MODINSTRUMENT *pins = &Ins[iSHdr+1];
617                 pins->nLoopStart = bswapBE16(pmsh->sample[iSHdr].rep) << 1;
618                 pins->nLoopEnd = pins->nLoopStart + (bswapBE16(pmsh->sample[iSHdr].replen) << 1);
619                 pins->nVolume = (pmsh->sample[iSHdr].svol << 2);
620                 pins->nGlobalVol = 64;
621                 if (pins->nVolume > 256) pins->nVolume = 256;
622                 pins->RelativeTone = -12 * pmsh->sample[iSHdr].strans;
623                 pins->nPan = 128;
624                 if (pins->nLoopEnd) pins->uFlags |= CHN_LOOP;
625         }
626         // Common Flags
627         if (!(pmsh->flags & 0x20)) m_dwSongFlags |= SONG_FASTVOLSLIDES;
628         // Reading play sequence
629         if (version < '2')
630         {
631                 UINT nbo = pmsh->songlen >> 8;
632                 if (nbo >= MAX_ORDERS) nbo = MAX_ORDERS-1;
633                 if (!nbo) nbo = 1;
634                 memcpy(Order, pmsh->playseq, nbo);
635                 playtransp = pmsh->playtransp;
636         } else
637         {
638                 UINT nOrders, nSections;
639                 UINT nTrks = bswapBE16(pmsh2->numtracks);
640                 if ((nTrks >= 4) && (nTrks <= 32)) m_nChannels = nTrks;
641                 DWORD playseqtable = bswapBE32(pmsh2->playseqtable);
642                 UINT numplayseqs = bswapBE16(pmsh2->numpseqs);
643                 if (!numplayseqs) numplayseqs = 1;
644                 nOrders = 0;
645                 nSections = bswapBE16(pmsh2->numsections);
646                 DWORD sectiontable = bswapBE32(pmsh2->sectiontable);
647                 if ((!nSections) || (!sectiontable) || (sectiontable >= dwMemLength-2)) nSections = 1;
648                 nOrders = 0;
649                 for (UINT iSection=0; iSection<nSections; iSection++)
650                 {
651                         UINT nplayseq = 0;
652                         if ((sectiontable) && (sectiontable < dwMemLength-2))
653                         {
654                                 nplayseq = lpStream[sectiontable+1];
655                                 sectiontable += 2; // WORDs
656                         } else
657                         {
658                                 nSections = 0;
659                         }
660                         UINT pseq = 0;
661                         
662                         if ((playseqtable) && (playseqtable + nplayseq*4 < dwMemLength))
663                         {
664                                 pseq = bswapBE32(((LPDWORD)(lpStream+playseqtable))[nplayseq]);
665                         }
666                         if ((pseq) && (pseq < dwMemLength - sizeof(MMD2PLAYSEQ)))
667                         {
668                                 MMD2PLAYSEQ *pmps = (MMD2PLAYSEQ *)(lpStream + pseq);
669                                 if (!m_szNames[0][0]) memcpy(m_szNames[0], pmps->name, 31);
670                                 UINT n = bswapBE16(pmps->length);
671                                 if (pseq+n <= dwMemLength)
672                                 {
673                                         for (UINT i=0; i<n; i++)
674                                         {
675                                                 UINT seqval = pmps->seq[i] >> 8;
676                                                 if ((seqval < wNumBlocks) && (nOrders < MAX_ORDERS-1))
677                                                 {
678                                                         Order[nOrders++] = seqval;
679                                                 }
680                                         }
681                                 }
682                         }
683                 }
684                 playtransp = pmsh2->playtransp;
685                 while (nOrders < MAX_ORDERS) Order[nOrders++] = 0xFF;
686         }
687         // Reading Expansion structure
688         if (pmex)
689         {
690                 // Channel Split
691                 if ((m_nChannels == 4) && (pmsh->flags & 0x40))
692                 {
693                         for (UINT i8ch=0; i8ch<4; i8ch++)
694                         {
695                                 if (pmex->channelsplit[i8ch]) m_nChannels++;
696                         }
697                 }
698                 // Song Comments
699                 UINT annotxt = bswapBE32(pmex->annotxt);
700                 UINT annolen = bswapBE32(pmex->annolen);
701                 if ((annotxt) && (annolen) && (annotxt+annolen <= dwMemLength))
702                 {
703                         m_lpszSongComments = new char[annolen+1];
704                         memcpy(m_lpszSongComments, lpStream+annotxt, annolen);
705                         m_lpszSongComments[annolen] = 0;
706                 }
707                 // Song Name
708                 UINT songname = bswapBE32(pmex->songname);
709                 UINT songnamelen = bswapBE32(pmex->songnamelen);
710                 if ((songname) && (songnamelen) && (songname+songnamelen <= dwMemLength))
711                 {
712                         if (songnamelen > 31) songnamelen = 31;
713                         memcpy(m_szNames[0], lpStream+songname, songnamelen);
714                 }
715                 // Sample Names
716                 DWORD smpinfoex = bswapBE32(pmex->iinfo);
717                 if (smpinfoex)
718                 {
719                         DWORD iinfoptr = bswapBE32(pmex->iinfo);
720                         UINT ientries = bswapBE16(pmex->i_ext_entries);
721                         UINT ientrysz = bswapBE16(pmex->i_ext_entrsz);
722
723                         if ((iinfoptr) && (ientrysz < 256) && (iinfoptr + ientries*ientrysz < dwMemLength))
724                         {
725                                 LPCSTR psznames = (LPCSTR)(lpStream + iinfoptr);
726                                 UINT maxnamelen = ientrysz;
727                                 if (maxnamelen > 32) maxnamelen = 32;
728                                 for (UINT i=0; i<ientries; i++) if (i < m_nSamples)
729                                 {
730                                         lstrcpyn(m_szNames[i+1], psznames + i*ientrysz, maxnamelen);
731                                 }
732                         }
733                 }
734                 // Track Names
735                 DWORD trackinfo_ofs = bswapBE32(pmex->trackinfo_ofs);
736                 if ((trackinfo_ofs) && (trackinfo_ofs + m_nChannels * 4 < dwMemLength))
737                 {
738                         DWORD *ptrktags = (DWORD *)(lpStream + trackinfo_ofs);
739                         for (UINT i=0; i<m_nChannels; i++)
740                         {
741                                 DWORD trknameofs = 0, trknamelen = 0;
742                                 DWORD trktagofs = bswapBE32(ptrktags[i]);
743                                 if (trktagofs)
744                                 {
745                                         while (trktagofs+8 < dwMemLength)
746                                         {
747                                                 DWORD ntag = bswapBE32(*(DWORD *)(lpStream + trktagofs));
748                                                 if (ntag == MMDTAG_END) break;
749                                                 DWORD tagdata = bswapBE32(*(DWORD *)(lpStream + trktagofs + 4));
750                                                 switch(ntag)
751                                                 {
752                                                 case MMDTAG_TRK_NAMELEN:        trknamelen = tagdata; break;
753                                                 case MMDTAG_TRK_NAME:           trknameofs = tagdata; break;
754                                                 }
755                                                 trktagofs += 8;
756                                         }
757                                         if (trknamelen > MAX_CHANNELNAME) trknamelen = MAX_CHANNELNAME;
758                                         if ((trknameofs) && (trknameofs + trknamelen < dwMemLength))
759                                         {
760                                                 lstrcpyn(ChnSettings[i].szName, (LPCSTR)(lpStream+trknameofs), MAX_CHANNELNAME);
761                                         }
762                                 }
763                         }
764                 }
765         }
766         // Reading samples
767         if (dwSmplArr > dwMemLength - 4*m_nSamples) return TRUE;
768         pdwTable = (LPDWORD)(lpStream + dwSmplArr);
769         for (UINT iSmp=0; iSmp<m_nSamples; iSmp++) if (pdwTable[iSmp])
770         {
771                 UINT dwPos = bswapBE32(pdwTable[iSmp]);
772                 if ((dwPos >= dwMemLength) || (dwPos + sizeof(MMDSAMPLEHEADER) >= dwMemLength)) continue;
773                 MMDSAMPLEHEADER *psdh = (MMDSAMPLEHEADER *)(lpStream + dwPos);
774                 UINT len = bswapBE32(psdh->length);
775         #ifdef MED_LOG
776                 Log("SampleData %d: stype=0x%02X len=%d\n", iSmp, bswapBE16(psdh->type), len);
777         #endif
778                 if ((len > MAX_SAMPLE_LENGTH) || (dwPos + len + 6 > dwMemLength)) len = 0;
779                 UINT flags = RS_PCM8S, stype = bswapBE16(psdh->type);
780                 LPSTR psdata = (LPSTR)(lpStream + dwPos + 6);
781                 if (stype & 0x80)
782                 {
783                         psdata += (stype & 0x20) ? 14 : 6;
784                 } else
785                 {
786                         if (stype & 0x10)
787                         {
788                                 Ins[iSmp+1].uFlags |= CHN_16BIT;
789                                 len /= 2;
790                                 flags = (stype & 0x20) ? RS_STPCM16M : RS_PCM16M;
791                         } else
792                         {
793                                 flags = (stype & 0x20) ? RS_STPCM8S : RS_PCM8S;
794                         }
795                         if (stype & 0x20) len /= 2;
796                 }
797                 Ins[iSmp+1].nLength = len;
798                 ReadSample(&Ins[iSmp+1], flags, psdata, dwMemLength - dwPos - 6);
799         }
800         // Reading patterns (blocks)
801         if (wNumBlocks > MAX_PATTERNS) wNumBlocks = MAX_PATTERNS;
802         if ((!dwBlockArr) || (dwBlockArr > dwMemLength - 4*wNumBlocks)) return TRUE;
803         pdwTable = (LPDWORD)(lpStream + dwBlockArr);
804         playtransp += (version == '3') ? 24 : 48;
805         for (UINT iBlk=0; iBlk<wNumBlocks; iBlk++)
806         {
807                 UINT dwPos = bswapBE32(pdwTable[iBlk]);
808                 if ((!dwPos) || (dwPos >= dwMemLength) || (dwPos >= dwMemLength - 8)) continue;
809                 UINT lines = 64, tracks = 4;
810                 if (version == '0')
811                 {
812                         const MMD0BLOCK *pmb = (const MMD0BLOCK *)(lpStream + dwPos);
813                         lines = pmb->lines + 1;
814                         tracks = pmb->numtracks;
815                         if (!tracks) tracks = m_nChannels;
816                         if ((Patterns[iBlk] = AllocatePattern(lines, m_nChannels)) == NULL) continue;
817                         PatternSize[iBlk] = lines;
818                         MODCOMMAND *p = Patterns[iBlk];
819                         LPBYTE s = (LPBYTE)(lpStream + dwPos + 2);
820                         UINT maxlen = tracks*lines*3;
821                         if (maxlen + dwPos > dwMemLength - 2) break;
822                         for (UINT y=0; y<lines; y++)
823                         {
824                                 for (UINT x=0; x<tracks; x++, s+=3) if (x < m_nChannels)
825                                 {
826                                         BYTE note = s[0] & 0x3F;
827                                         BYTE instr = s[1] >> 4;
828                                         if (s[0] & 0x80) instr |= 0x10;
829                                         if (s[0] & 0x40) instr |= 0x20;
830                                         if ((note) && (note <= 132)) p->note = note + playtransp;
831                                         p->instr = instr;
832                                         p->command = s[1] & 0x0F;
833                                         p->param = s[2];
834                                         // if (!iBlk) Log("%02X.%02X.%02X | ", s[0], s[1], s[2]);
835                                         MedConvert(p, pmsh);
836                                         p++;
837                                 }
838                                 //if (!iBlk) Log("\n");
839                         }
840                 } else
841                 {
842                         MMD1BLOCK *pmb = (MMD1BLOCK *)(lpStream + dwPos);
843                 #ifdef MED_LOG
844                         Log("MMD1BLOCK:   lines=%2d, tracks=%2d, offset=0x%04X\n",
845                                 bswapBE16(pmb->lines), bswapBE16(pmb->numtracks), bswapBE32(pmb->info));
846                 #endif
847                         MMD1BLOCKINFO *pbi = NULL;
848                         BYTE *pcmdext = NULL;
849                         lines = (pmb->lines >> 8) + 1;
850                         tracks = pmb->numtracks >> 8;
851                         if (!tracks) tracks = m_nChannels;
852                         if ((Patterns[iBlk] = AllocatePattern(lines, m_nChannels)) == NULL) continue;
853                         PatternSize[iBlk] = (WORD)lines;
854                         DWORD dwBlockInfo = bswapBE32(pmb->info);
855                         if ((dwBlockInfo) && (dwBlockInfo < dwMemLength - sizeof(MMD1BLOCKINFO)))
856                         {
857                                 pbi = (MMD1BLOCKINFO *)(lpStream + dwBlockInfo);
858                         #ifdef MED_LOG
859                                 Log("  BLOCKINFO: blockname=0x%04X namelen=%d pagetable=0x%04X &cmdexttable=0x%04X\n",
860                                         bswapBE32(pbi->blockname), bswapBE32(pbi->blocknamelen), bswapBE32(pbi->pagetable), bswapBE32(pbi->cmdexttable));
861                         #endif
862                                 if ((pbi->blockname) && (pbi->blocknamelen))
863                                 {
864                                         DWORD nameofs = bswapBE32(pbi->blockname);
865                                         UINT namelen = bswapBE32(pbi->blocknamelen);
866                                         if ((nameofs < dwMemLength) && (nameofs+namelen < dwMemLength))
867                                         {
868                                                 SetPatternName(iBlk, (LPCSTR)(lpStream+nameofs));
869                                         }
870                                 }
871                                 if (pbi->cmdexttable)
872                                 {
873                                         DWORD cmdexttable = bswapBE32(pbi->cmdexttable);
874                                         if (cmdexttable < dwMemLength - 4)
875                                         {
876                                                 cmdexttable = bswapBE32(*(DWORD *)(lpStream + cmdexttable));
877                                                 if ((cmdexttable) && (cmdexttable <= dwMemLength - lines*tracks))
878                                                 {
879                                                         pcmdext = (BYTE *)(lpStream + cmdexttable);
880                                                 }
881                                         }
882                                 }
883                         }
884                         MODCOMMAND *p = Patterns[iBlk];
885                         LPBYTE s = (LPBYTE)(lpStream + dwPos + 8);
886                         UINT maxlen = tracks*lines*4;
887                         if (maxlen + dwPos > dwMemLength - 8) break;
888                         for (UINT y=0; y<lines; y++)
889                         {
890                                 for (UINT x=0; x<tracks; x++, s+=4) if (x < m_nChannels)
891                                 {
892                                         BYTE note = s[0];
893                                         if ((note) && (note <= 132))
894                                         {
895                                                 int rnote = note + playtransp;
896                                                 if (rnote < 1) rnote = 1;
897                                                 if (rnote > 120) rnote = 120;
898                                                 p->note = (BYTE)rnote;
899                                         }
900                                         p->instr = s[1];
901                                         p->command = s[2];
902                                         p->param = s[3];
903                                         if (pcmdext) p->vol = pcmdext[x];
904                                         MedConvert(p, pmsh);
905                                         p++;
906                                 }
907                                 if (pcmdext) pcmdext += tracks;
908                         }
909                 }
910         }
911         // Setup channel pan positions
912         for (UINT iCh=0; iCh<m_nChannels; iCh++)
913         {
914                 ChnSettings[iCh].nPan = (((iCh&3) == 1) || ((iCh&3) == 2)) ? 0xC0 : 0x40;
915                 ChnSettings[iCh].nVolume = 64;
916         }
917         return TRUE;
918 }
919
920