1 /*
2  * This source code is public domain.
3  *
4  * Authors: Olivier Lapicque <olivierl@jps.net>
5 */
6 
7 //////////////////////////////////////////////
8 // DigiTracker (MDL) module loader          //
9 //////////////////////////////////////////////
10 #include "stdafx.h"
11 #include "sndfile.h"
12 
13 //#pragma warning(disable:4244)
14 
15 typedef struct MDLSONGHEADER
16 {
17 	DWORD id;	// "DMDL" = 0x4C444D44
18 	BYTE version;
19 } MDLSONGHEADER;
20 
21 
22 typedef struct MDLINFOBLOCK
23 {
24 	CHAR songname[32];
25 	CHAR composer[20];
26 	WORD norders;
27 	WORD repeatpos;
28 	BYTE globalvol;
29 	BYTE speed;
30 	BYTE tempo;
31 	BYTE channelinfo[32];
32 	BYTE seq[256];
33 } MDLINFOBLOCK;
34 
35 
36 typedef struct MDLPATTERNDATA
37 {
38 	BYTE channels;
39 	BYTE lastrow;	// nrows = lastrow+1
40 	CHAR name[16];
41 	WORD data[1];
42 } MDLPATTERNDATA;
43 
44 
45 static void ConvertMDLCommand(MODCOMMAND *m, UINT eff, UINT data)
46 //--------------------------------------------------------
47 {
48 	UINT command = 0, param = data;
49 	switch(eff)
50 	{
51 	case 0x01:	command = CMD_PORTAMENTOUP; break;
52 	case 0x02:	command = CMD_PORTAMENTODOWN; break;
53 	case 0x03:	command = CMD_TONEPORTAMENTO; break;
54 	case 0x04:	command = CMD_VIBRATO; break;
55 	case 0x05:	command = CMD_ARPEGGIO; break;
56 	case 0x07:	command = (param < 0x20) ? CMD_SPEED : CMD_TEMPO; break;
57 	case 0x08:	command = CMD_PANNING8; param <<= 1; break;
58 	case 0x0B:	command = CMD_POSITIONJUMP; break;
59 	case 0x0C:	command = CMD_GLOBALVOLUME; break;
60 	case 0x0D:	command = CMD_PATTERNBREAK; param = (data & 0x0F) + (data>>4)*10; break;
61 	case 0x0E:
62 		command = CMD_S3MCMDEX;
63 		switch(data & 0xF0)
64 		{
65 		case 0x00:	command = 0; break; // What is E0x in MDL (there is a bunch) ?
66 		case 0x10:	if (param & 0x0F) { param |= 0xF0; command = CMD_PANNINGSLIDE; } else command = 0; break;
67 		case 0x20:	if (param & 0x0F) { param = (param << 4) | 0x0F; command = CMD_PANNINGSLIDE; } else command = 0; break;
68 		case 0x30:	param = (data & 0x0F) | 0x10; break; // glissando
69 		case 0x40:	param = (data & 0x0F) | 0x30; break; // vibrato waveform
70 		case 0x60:	param = (data & 0x0F) | 0xB0; break;
71 		case 0x70:	param = (data & 0x0F) | 0x40; break; // tremolo waveform
72 		case 0x90:	command = CMD_RETRIG; param &= 0x0F; break;
73 		case 0xA0:	param = (data & 0x0F) << 4; command = CMD_GLOBALVOLSLIDE; break;
74 		case 0xB0:	param = data & 0x0F; command = CMD_GLOBALVOLSLIDE; break;
75 		case 0xF0:	param = ((data >> 8) & 0x0F) | 0xA0; break;
76 		}
77 		break;
78 	case 0x0F:	command = CMD_SPEED; break;
79 	case 0x10:	if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) == 0xF0) param = ((param << 4) | 0x0F); else param >>= 2; } break;
80 	case 0x20:	if ((param & 0xF0) != 0xE0) { command = CMD_VOLUMESLIDE; if ((param & 0xF0) != 0xF0) param >>= 2; } break;
81 	case 0x30:	command = CMD_RETRIG; break;
82 	case 0x40:	command = CMD_TREMOLO; break;
83 	case 0x50:	command = CMD_TREMOR; break;
84 	case 0xEF:	if (param > 0xFF) param = 0xFF; command = CMD_OFFSET; break;
85 	}
86 	if (command)
87 	{
88 		m->command = command;
89 		m->param = param;
90 	}
91 }
92 
93 
94 static void UnpackMDLTrack(MODCOMMAND *pat, UINT nChannels, UINT nRows, UINT nTrack, const BYTE *lpTracks, UINT len)
95 //-------------------------------------------------------------------------------------------------
96 {
97 	MODCOMMAND cmd, *m = pat;
98 	UINT pos = 0, row = 0, i;
99 
100 	cmd.note = cmd.instr = 0;
101 	cmd.volcmd = cmd.vol = 0;
102 	cmd.command = cmd.param = 0;
103 	while ((row < nRows) && (pos < len))
104 	{
105 		UINT xx;
106 		BYTE b = lpTracks[pos++];
107 		xx = b >> 2;
108 		switch(b & 0x03)
109 		{
110 		case 0x01:
111 			for (i=0; i<=xx; i++)
112 			{
113 				if (row) *m = *(m-nChannels);
114 				m += nChannels;
115 				row++;
116 				if (row >= nRows) break;
117 			}
118 			break;
119 
120 		case 0x02:
121 			if (xx < row) *m = pat[nChannels*xx];
122 			m += nChannels;
123 			row++;
124 			break;
125 
126 		case 0x03:
127 			{
128 				cmd.note = (xx & 0x01) ? lpTracks[pos++] : 0;
129 				cmd.instr = (xx & 0x02) ? lpTracks[pos++] : 0;
130 				cmd.volcmd = cmd.vol = 0;
131 				cmd.command = cmd.param = 0;
132 				if ((cmd.note < NOTE_MAX-12) && (cmd.note)) cmd.note += 12;
133 				UINT volume = (xx & 0x04) ? lpTracks[pos++] : 0;
134 				UINT commands = (xx & 0x08) ? lpTracks[pos++] : 0;
135 				UINT command1 = commands & 0x0F;
136 				UINT command2 = commands & 0xF0;
137 				UINT param1 = (xx & 0x10) ? lpTracks[pos++] : 0;
138 				UINT param2 = (xx & 0x20) ? lpTracks[pos++] : 0;
139 				if ((command1 == 0x0E) && ((param1 & 0xF0) == 0xF0) && (!command2))
140 				{
141 					param1 = ((param1 & 0x0F) << 8) | param2;
142 					command1 = 0xEF;
143 					command2 = param2 = 0;
144 				}
145 				if (volume)
146 				{
147 					cmd.volcmd = VOLCMD_VOLUME;
148 					cmd.vol = (volume+1) >> 2;
149 				}
150 				ConvertMDLCommand(&cmd, command1, param1);
151 				if ((cmd.command != CMD_SPEED)
152 				 && (cmd.command != CMD_TEMPO)
153 				 && (cmd.command != CMD_PATTERNBREAK))
154 					ConvertMDLCommand(&cmd, command2, param2);
155 				*m = cmd;
156 				m += nChannels;
157 				row++;
158 			}
159 			break;
160 
161 		// Empty Slots
162 		default:
163 			row += xx+1;
164 			m += (xx+1)*nChannels;
165 			if (row >= nRows) break;
166 		}
167 	}
168 }
169 
170 
171 BOOL CSoundFile::ReadMDL(const BYTE *lpStream, DWORD dwMemLength)
172 //---------------------------------------------------------------
173 {
174 	DWORD dwMemPos, dwPos, blocklen, dwTrackPos;
175 	const MDLSONGHEADER *pmsh = (const MDLSONGHEADER *)lpStream;
176 	const MDLINFOBLOCK *pmib;
177 	UINT i,j, norders = 0, npatterns = 0, ntracks = 0;
178 	UINT ninstruments = 0, nsamples = 0;
179 	WORD block;
180 	WORD patterntracks[MAX_PATTERNS*32];
181 	BYTE smpinfo[MAX_SAMPLES];
182 	BYTE insvolenv[MAX_INSTRUMENTS];
183 	BYTE inspanenv[MAX_INSTRUMENTS];
184 	LPCBYTE pvolenv, ppanenv, ppitchenv;
185 	UINT nvolenv, npanenv, npitchenv;
186 
187 	if ((!lpStream) || (dwMemLength < 1024)) return FALSE;
188 	if ((pmsh->id != 0x4C444D44) || ((pmsh->version & 0xF0) > 0x10)) return FALSE;
189 	const UINT hdrLen = (pmsh->version>0)? 59 : 57;
190 	memset(patterntracks, 0, sizeof(patterntracks));
191 	memset(smpinfo, 0, sizeof(smpinfo));
192 	memset(insvolenv, 0, sizeof(insvolenv));
193 	memset(inspanenv, 0, sizeof(inspanenv));
194 	dwMemPos = 5;
195 	dwTrackPos = 0;
196 	pvolenv = ppanenv = ppitchenv = NULL;
197 	nvolenv = npanenv = npitchenv = 0;
198 	m_nSamples = m_nInstruments = 0;
199 	while (dwMemPos+6 < dwMemLength)
200 	{
201 		const BYTE *pp = lpStream + dwMemPos;
202 		block = pp[0] | (pp[1] << 8);
203 		blocklen = pp[2] | (pp[3] << 8) | (pp[4] << 16) | (pp[5] << 24);
204 		dwMemPos += 6;
205 		if (blocklen > dwMemLength - dwMemPos)
206 		{
207 			if (dwMemPos == 11) return FALSE;
208 			break;
209 		}
210 		switch(block)
211 		{
212 		// IN: infoblock
213 		case 0x4E49:
214 			pmib = (const MDLINFOBLOCK *)(lpStream+dwMemPos);
215 			memcpy(m_szNames[0], pmib->songname, 32);
216 			m_szNames[0][31] = 0;
217 			norders = pmib->norders;
218 			if (norders > MAX_ORDERS) norders = MAX_ORDERS;
219 			m_nRestartPos = pmib->repeatpos;
220 			m_nDefaultGlobalVolume = pmib->globalvol;
221 			m_nDefaultTempo = pmib->tempo;
222 			m_nDefaultSpeed = pmib->speed;
223 			m_nChannels = 4;
224 			for (i=0; i<32; i++)
225 			{
226 				ChnSettings[i].nVolume = 64;
227 				ChnSettings[i].nPan = (pmib->channelinfo[i] & 0x7F) << 1;
228 				if (pmib->channelinfo[i] & 0x80)
229 					ChnSettings[i].dwFlags |= CHN_MUTE;
230 				else
231 					m_nChannels = i+1;
232 			}
233 			for (j=0; j<norders; j++) Order[j] = pmib->seq[j];
234 			break;
235 		// ME: song message
236 		case 0x454D:
237 			if (blocklen)
238 			{
239 				if (m_lpszSongComments) delete [] m_lpszSongComments;
240 				m_lpszSongComments = new char[blocklen];
241 				if (m_lpszSongComments)
242 				{
243 					memcpy(m_lpszSongComments, lpStream+dwMemPos, blocklen);
244 					m_lpszSongComments[blocklen-1] = 0;
245 				}
246 			}
247 			break;
248 		// PA: Pattern Data
249 		case 0x4150:
250 			npatterns = lpStream[dwMemPos];
251 			if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS;
252 			dwPos = dwMemPos + 1;
253 			for (i=0; i<npatterns; i++)
254 			{
255 				const BYTE *data;
256 				UINT ch;
257 				if (pmsh->version == 0) {
258 					if (m_nChannels < 32) m_nChannels = 32;
259 					ch = 32;
260 				} else {
261 					if (dwPos+18 >= dwMemLength) break;
262 					const MDLPATTERNDATA *pmpd = (const MDLPATTERNDATA *)(lpStream + dwPos);
263 					if (pmpd->channels > 32) break;
264 					PatternSize[i] = pmpd->lastrow+1;
265 					if (m_nChannels < pmpd->channels) m_nChannels = pmpd->channels;
266 					ch = pmpd->channels;
267 				}
268 
269 				if (2 * ch >= dwMemLength - dwPos) break;
270 				data = lpStream + dwPos;
271 				dwPos += 2 * ch;
272 				for (j=0; j<ch && j<m_nChannels; j++, data+=2)
273 				{
274 					patterntracks[i*32+j] = data[0] | (data[1] << 8);
275 				}
276 			}
277 			break;
278 		// TR: Track Data
279 		case 0x5254:
280 			if (dwTrackPos) break;
281 			pp = lpStream + dwMemPos;
282 			ntracks = pp[0] | (pp[1] << 8);
283 			dwTrackPos = dwMemPos+2;
284 			break;
285 		// II: Instruments
286 		case 0x4949:
287 			ninstruments = lpStream[dwMemPos];
288 			dwPos = dwMemPos+1;
289 			for (i=0; i<ninstruments; i++)
290 			{
291 				UINT nins = lpStream[dwPos];
292 				if ((nins >= MAX_INSTRUMENTS) || (!nins)) break;
293 				if (m_nInstruments < nins) m_nInstruments = nins;
294 				if (!Headers[nins])
295 				{
296 					UINT note = 12;
297 					if ((Headers[nins] = new INSTRUMENTHEADER) == NULL) break;
298 					INSTRUMENTHEADER *penv = Headers[nins];
299 					memset(penv, 0, sizeof(INSTRUMENTHEADER));
300 					memcpy(penv->name, lpStream+dwPos+2, 32);
301 					penv->nGlobalVol = 64;
302 					penv->nPPC = 5*12;
303 					for (j=0; j<lpStream[dwPos+1]; j++)
304 					{
305 						const BYTE *ps = lpStream+dwPos+34+14*j;
306 						while ((note < (UINT)(ps[1]+12)) && (note < NOTE_MAX))
307 						{
308 							penv->NoteMap[note] = note+1;
309 							if (ps[0] < MAX_SAMPLES)
310 							{
311 								int ismp = ps[0];
312 								penv->Keyboard[note] = ps[0];
313 								Ins[ismp].nVolume = ps[2];
314 								Ins[ismp].nPan = ps[4] << 1;
315 								Ins[ismp].nVibType = ps[11];
316 								Ins[ismp].nVibSweep = ps[10];
317 								Ins[ismp].nVibDepth = ps[9];
318 								Ins[ismp].nVibRate = ps[8];
319 							}
320 							penv->nFadeOut = (ps[7] << 8) | ps[6];
321 							if (penv->nFadeOut == 0xFFFF) penv->nFadeOut = 0;
322 							note++;
323 						}
324 						// Use volume envelope ?
325 						if (ps[3] & 0x80)
326 						{
327 							penv->dwFlags |= ENV_VOLUME;
328 							insvolenv[nins] = (ps[3] & 0x3F) + 1;
329 						}
330 						// Use panning envelope ?
331 						if (ps[5] & 0x80)
332 						{
333 							penv->dwFlags |= ENV_PANNING;
334 							inspanenv[nins] = (ps[5] & 0x3F) + 1;
335 						}
336 					}
337 				}
338 				dwPos += 34 + 14*lpStream[dwPos+1];
339 			}
340 			for (j=1; j<=m_nInstruments; j++) if (!Headers[j])
341 			{
342 				Headers[j] = new INSTRUMENTHEADER;
343 				if (Headers[j]) memset(Headers[j], 0, sizeof(INSTRUMENTHEADER));
344 			}
345 			break;
346 		// VE: Volume Envelope
347 		case 0x4556:
348 			if ((nvolenv = lpStream[dwMemPos]) == 0) break;
349 			if (dwMemPos + nvolenv*32 + 1 <= dwMemLength) pvolenv = lpStream + dwMemPos + 1;
350 			break;
351 		// PE: Panning Envelope
352 		case 0x4550:
353 			if ((npanenv = lpStream[dwMemPos]) == 0) break;
354 			if (dwMemPos + npanenv*32 + 1 <= dwMemLength) ppanenv = lpStream + dwMemPos + 1;
355 			break;
356 		// FE: Pitch Envelope
357 		case 0x4546:
358 			if ((npitchenv = lpStream[dwMemPos]) == 0) break;
359 			if (dwMemPos + npitchenv*32 + 1 <= dwMemLength) ppitchenv = lpStream + dwMemPos + 1;
360 			break;
361 		// IS: Sample Infoblock
362 		case 0x5349:
363 			nsamples = lpStream[dwMemPos];
364 			i = blocklen / hdrLen;
365 			if (i< nsamples) nsamples = i;
366 			dwPos = dwMemPos+1;
367 			for (i=0; i<nsamples; i++, dwPos += hdrLen)
368 			{
369 				UINT nins = lpStream[dwPos];
370 				if ((nins >= MAX_SAMPLES) || (!nins)) continue;
371 				if (m_nSamples < nins) m_nSamples = nins;
372 				MODINSTRUMENT *pins = &Ins[nins];
373 				memcpy(m_szNames[nins], lpStream+dwPos+1, 32);
374 				m_szNames[nins][31] = 0;
375 				memcpy(pins->name, lpStream+dwPos+33, 8);
376 				pp = lpStream + dwPos + 41;
377 				pins->nC4Speed = pp[0] | (pp[1] << 8); pp += 2;
378 				if (pmsh->version > 0) {
379 					pins->nC4Speed |= (pp[0] << 16) | (pp[1] << 24); pp += 2;
380 				}
381 				pins->nLength = pp[0] | (pp[1] << 8) | (pp[2] << 16) | (pp[3] << 24); pp += 4;
382 				pins->nLoopStart = pp[0] | (pp[1] << 8) | (pp[2] << 16) | (pp[3] << 24); pp += 4;
383 				pins->nLoopEnd = pins->nLoopStart + (pp[0] | (pp[1] << 8) | (pp[2] << 16) | (pp[3] << 24));
384 				if (pins->nLoopEnd > pins->nLoopStart) pins->uFlags |= CHN_LOOP;
385 				pins->nGlobalVol = 64;
386 				if (pmsh->version == 0) pins->nVolume = pp[4];
387 				if (lpStream[dwPos+hdrLen-1] & 0x01)
388 				{
389 					pins->uFlags |= CHN_16BIT;
390 					pins->nLength >>= 1;
391 					pins->nLoopStart >>= 1;
392 					pins->nLoopEnd >>= 1;
393 				}
394 				if (lpStream[dwPos+hdrLen-1] & 0x02) pins->uFlags |= CHN_PINGPONGLOOP;
395 				smpinfo[nins] = (lpStream[dwPos+hdrLen-1] >> 2) & 3;
396 			}
397 			break;
398 		// SA: Sample Data
399 		case 0x4153:
400 			dwPos = dwMemPos;
401 			for (i=1; i<=m_nSamples; i++) if ((Ins[i].nLength) && (!Ins[i].pSample) && (smpinfo[i] != 3) && (dwPos < dwMemLength))
402 			{
403 				const BYTE *pp = lpStream + dwPos;
404 				MODINSTRUMENT *pins = &Ins[i];
405 				UINT flags = (pins->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S;
406 				if (!smpinfo[i])
407 				{
408 					dwPos += ReadSample(pins, flags, (LPSTR)pp, dwMemLength - dwPos);
409 				} else
410 				{
411 					DWORD dwLen = pp[0] | (pp[1] << 8) | (pp[2] << 16) | (pp[3] << 24); pp += 4;
412 					dwPos += 4;
413 					if ((dwLen <= dwMemLength) && (dwPos <= dwMemLength - dwLen) && (dwLen > 4))
414 					{
415 						flags = (pins->uFlags & CHN_16BIT) ? RS_MDL16 : RS_MDL8;
416 						ReadSample(pins, flags, (LPSTR)pp, dwLen);
417 					}
418 					dwPos += dwLen;
419 				}
420 			}
421 			break;
422 		}
423 		dwMemPos += blocklen;
424 	}
425 	// Unpack Patterns
426 	if ((dwTrackPos) && (npatterns) && (m_nChannels) && (ntracks))
427 	{
428 		for (UINT ipat=0; ipat<npatterns; ipat++)
429 		{
430 			if ((Patterns[ipat] = AllocatePattern(PatternSize[ipat], m_nChannels)) == NULL) break;
431 			for (UINT chn=0; chn<m_nChannels; chn++) if ((patterntracks[ipat*32+chn]) && (patterntracks[ipat*32+chn] <= ntracks))
432 			{
433 			    const BYTE *lpTracks = lpStream + dwTrackPos;
434 			    UINT len = lpTracks[0] | (lpTracks[1] << 8);
435 			    if (len < dwMemLength-dwTrackPos) {
436 				MODCOMMAND *m = Patterns[ipat] + chn;
437 				UINT nTrack = patterntracks[ipat*32+chn];
438 
439 				lpTracks += 2;
440 				for (UINT ntrk=1; ntrk<nTrack && lpTracks < (dwMemLength + lpStream - len); ntrk++)
441 				{
442 					lpTracks += len;
443 					len = lpTracks[0] | (lpTracks[1] << 8);
444 					lpTracks += 2;
445 				}
446 
447 				if ( len > dwMemLength - dwTrackPos ) len = 0;
448 
449 				UnpackMDLTrack(m, m_nChannels, PatternSize[ipat], nTrack, lpTracks, len);
450 			    }
451 			}
452 		}
453 	}
454 	// Set up envelopes
455 	for (UINT iIns=1; iIns<=m_nInstruments; iIns++) if (Headers[iIns])
456 	{
457 		INSTRUMENTHEADER *penv = Headers[iIns];
458 		// Setup volume envelope
459 		if ((nvolenv) && (pvolenv) && (insvolenv[iIns]))
460 		{
461 			LPCBYTE pve = pvolenv;
462 			for (UINT nve=0; nve<nvolenv; nve++, pve+=33) if (pve[0]+1 == insvolenv[iIns])
463 			{
464 				WORD vtick = 1;
465 				penv->nVolEnv = 15;
466 				for (UINT iv=0; iv<15; iv++)
467 				{
468 					if (iv) vtick += pve[iv*2+1];
469 					penv->VolPoints[iv] = vtick;
470 					penv->VolEnv[iv] = pve[iv*2+2];
471 					if (!pve[iv*2+1])
472 					{
473 						penv->nVolEnv = iv+1;
474 						break;
475 					}
476 				}
477 				penv->nVolSustainBegin = penv->nVolSustainEnd = pve[31] & 0x0F;
478 				if (pve[31] & 0x10) penv->dwFlags |= ENV_VOLSUSTAIN;
479 				if (pve[31] & 0x20) penv->dwFlags |= ENV_VOLLOOP;
480 				penv->nVolLoopStart = pve[32] & 0x0F;
481 				penv->nVolLoopEnd = pve[32] >> 4;
482 			}
483 		}
484 		// Setup panning envelope
485 		if ((npanenv) && (ppanenv) && (inspanenv[iIns]))
486 		{
487 			LPCBYTE ppe = ppanenv;
488 			for (UINT npe=0; npe<npanenv; npe++, ppe+=33) if (ppe[0]+1 == inspanenv[iIns])
489 			{
490 				WORD vtick = 1;
491 				penv->nPanEnv = 15;
492 				for (UINT iv=0; iv<15; iv++)
493 				{
494 					if (iv) vtick += ppe[iv*2+1];
495 					penv->PanPoints[iv] = vtick;
496 					penv->PanEnv[iv] = ppe[iv*2+2];
497 					if (!ppe[iv*2+1])
498 					{
499 						penv->nPanEnv = iv+1;
500 						break;
501 					}
502 				}
503 				if (ppe[31] & 0x10) penv->dwFlags |= ENV_PANSUSTAIN;
504 				if (ppe[31] & 0x20) penv->dwFlags |= ENV_PANLOOP;
505 				penv->nPanLoopStart = ppe[32] & 0x0F;
506 				penv->nPanLoopEnd = ppe[32] >> 4;
507 			}
508 		}
509 	}
510 	m_dwSongFlags |= SONG_LINEARSLIDES;
511 	m_nType = MOD_TYPE_MDL;
512 	return TRUE;
513 }
514 
515 
516 /////////////////////////////////////////////////////////////////////////
517 // MDL Sample Unpacking
518 
519 // MDL Huffman ReadBits compression
520 WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n)
521 //-----------------------------------------------------------------
522 {
523 	WORD v = (WORD)(bitbuf & ((1 << n) - 1) );
524 	bitbuf >>= n;
525 	bitnum -= n;
526 	if (bitnum <= 24)
527 	{
528 		bitbuf |= (((DWORD)(*ibuf++)) << bitnum);
529 		bitnum += 8;
530 	}
531 	return v;
532 }
533