Add more to the gitignores
[platform/upstream/gstreamer.git] / gst / modplug / libmodplug / load_it.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 #include "it_defs.h"
15
16 #ifdef MSC_VER
17 #pragma warning(disable:4244)
18 #endif
19
20 BYTE autovibit2xm[8] =
21 { 0, 3, 1, 4, 2, 0, 0, 0 };
22
23 BYTE autovibxm2it[8] =
24 { 0, 2, 4, 1, 3, 0, 0, 0 };
25
26 //////////////////////////////////////////////////////////
27 // Impulse Tracker IT file support (import only)
28
29
30 static inline UINT ConvertVolParam(UINT value)
31 //--------------------------------------------
32 {
33         return (value > 9)  ? 9 : value;
34 }
35
36
37 BOOL CSoundFile::ITInstrToMPT(const void *p, INSTRUMENTHEADER *penv, UINT trkvers)
38 //--------------------------------------------------------------------------------
39 {
40         if (trkvers < 0x0200)
41         {
42                 const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p;
43                 memcpy(penv->name, pis->name, 26);
44                 memcpy(penv->filename, pis->filename, 12);
45                 penv->nFadeOut = bswapLE16(pis->fadeout) << 6;
46                 penv->nGlobalVol = 64;
47                 for (UINT j=0; j<120; j++)
48                 {
49                         UINT note = pis->keyboard[j*2];
50                         UINT ins = pis->keyboard[j*2+1];
51                         if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins;
52                         if (note < 128) penv->NoteMap[j] = note+1;
53                         else if (note >= 0xFE) penv->NoteMap[j] = note;
54                 }
55                 if (pis->flags & 0x01) penv->dwFlags |= ENV_VOLUME;
56                 if (pis->flags & 0x02) penv->dwFlags |= ENV_VOLLOOP;
57                 if (pis->flags & 0x04) penv->dwFlags |= ENV_VOLSUSTAIN;
58                 penv->nVolLoopStart = pis->vls;
59                 penv->nVolLoopEnd = pis->vle;
60                 penv->nVolSustainBegin = pis->sls;
61                 penv->nVolSustainEnd = pis->sle;
62                 penv->nVolEnv = 25;
63                 for (UINT ev=0; ev<25; ev++)
64                 {
65                         if ((penv->VolPoints[ev] = pis->nodes[ev*2]) == 0xFF)
66                         {
67                                 penv->nVolEnv = ev;
68                                 break;
69                         }
70                         penv->VolEnv[ev] = pis->nodes[ev*2+1];
71                 }
72                 penv->nNNA = pis->nna;
73                 penv->nDCT = pis->dnc;
74                 penv->nPan = 0x80;
75         } else
76         {
77                 const ITINSTRUMENT *pis = (const ITINSTRUMENT *)p;
78                 memcpy(penv->name, pis->name, 26);
79                 memcpy(penv->filename, pis->filename, 12);
80                 penv->nMidiProgram = pis->mpr;
81                 penv->nMidiChannel = pis->mch;
82                 penv->wMidiBank = bswapLE16(pis->mbank);
83                 penv->nFadeOut = bswapLE16(pis->fadeout) << 5;
84                 penv->nGlobalVol = pis->gbv >> 1;
85                 if (penv->nGlobalVol > 64) penv->nGlobalVol = 64;
86                 for (UINT j=0; j<120; j++)
87                 {
88                         UINT note = pis->keyboard[j*2];
89                         UINT ins = pis->keyboard[j*2+1];
90                         if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins;
91                         if (note < 128) penv->NoteMap[j] = note+1;
92                         else if (note >= 0xFE) penv->NoteMap[j] = note;
93                 }
94                 // Volume Envelope
95                 if (pis->volenv.flags & 1) penv->dwFlags |= ENV_VOLUME;
96                 if (pis->volenv.flags & 2) penv->dwFlags |= ENV_VOLLOOP;
97                 if (pis->volenv.flags & 4) penv->dwFlags |= ENV_VOLSUSTAIN;
98                 if (pis->volenv.flags & 8) penv->dwFlags |= ENV_VOLCARRY;
99                 penv->nVolEnv = pis->volenv.num;
100                 if (penv->nVolEnv > 25) penv->nVolEnv = 25;
101
102                 penv->nVolLoopStart = pis->volenv.lpb;
103                 penv->nVolLoopEnd = pis->volenv.lpe;
104                 penv->nVolSustainBegin = pis->volenv.slb;
105                 penv->nVolSustainEnd = pis->volenv.sle;
106                 // Panning Envelope
107                 if (pis->panenv.flags & 1) penv->dwFlags |= ENV_PANNING;
108                 if (pis->panenv.flags & 2) penv->dwFlags |= ENV_PANLOOP;
109                 if (pis->panenv.flags & 4) penv->dwFlags |= ENV_PANSUSTAIN;
110                 if (pis->panenv.flags & 8) penv->dwFlags |= ENV_PANCARRY;
111                 penv->nPanEnv = pis->panenv.num;
112                 if (penv->nPanEnv > 25) penv->nPanEnv = 25;
113                 penv->nPanLoopStart = pis->panenv.lpb;
114                 penv->nPanLoopEnd = pis->panenv.lpe;
115                 penv->nPanSustainBegin = pis->panenv.slb;
116                 penv->nPanSustainEnd = pis->panenv.sle;
117                 // Pitch Envelope
118                 if (pis->pitchenv.flags & 1) penv->dwFlags |= ENV_PITCH;
119                 if (pis->pitchenv.flags & 2) penv->dwFlags |= ENV_PITCHLOOP;
120                 if (pis->pitchenv.flags & 4) penv->dwFlags |= ENV_PITCHSUSTAIN;
121                 if (pis->pitchenv.flags & 8) penv->dwFlags |= ENV_PITCHCARRY;
122                 if (pis->pitchenv.flags & 0x80) penv->dwFlags |= ENV_FILTER;
123                 penv->nPitchEnv = pis->pitchenv.num;
124                 if (penv->nPitchEnv > 25) penv->nPitchEnv = 25;
125                 penv->nPitchLoopStart = pis->pitchenv.lpb;
126                 penv->nPitchLoopEnd = pis->pitchenv.lpe;
127                 penv->nPitchSustainBegin = pis->pitchenv.slb;
128                 penv->nPitchSustainEnd = pis->pitchenv.sle;
129                 // Envelopes Data
130                 for (UINT ev=0; ev<25; ev++)
131                 {
132                         penv->VolEnv[ev] = pis->volenv.data[ev*3];
133                         penv->VolPoints[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]);
134                         penv->PanEnv[ev] = pis->panenv.data[ev*3] + 32;
135                         penv->PanPoints[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]);
136                         penv->PitchEnv[ev] = pis->pitchenv.data[ev*3] + 32;
137                         penv->PitchPoints[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]);
138                 }
139                 penv->nNNA = pis->nna;
140                 penv->nDCT = pis->dct;
141                 penv->nDNA = pis->dca;
142                 penv->nPPS = pis->pps;
143                 penv->nPPC = pis->ppc;
144                 penv->nIFC = pis->ifc;
145                 penv->nIFR = pis->ifr;
146                 penv->nVolSwing = pis->rv;
147                 penv->nPanSwing = pis->rp;
148                 penv->nPan = (pis->dfp & 0x7F) << 2;
149                 if (penv->nPan > 256) penv->nPan = 128;
150                 if (pis->dfp < 0x80) penv->dwFlags |= ENV_SETPANNING;
151         }
152         if ((penv->nVolLoopStart >= 25) || (penv->nVolLoopEnd >= 25)) penv->dwFlags &= ~ENV_VOLLOOP;
153         if ((penv->nVolSustainBegin >= 25) || (penv->nVolSustainEnd >= 25)) penv->dwFlags &= ~ENV_VOLSUSTAIN;
154         return TRUE;
155 }
156
157
158 BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength)
159 //--------------------------------------------------------------
160 {
161         ITFILEHEADER pifh = *(ITFILEHEADER *)lpStream;
162         DWORD dwMemPos = sizeof(ITFILEHEADER);
163         DWORD inspos[MAX_INSTRUMENTS];
164         DWORD smppos[MAX_SAMPLES];
165         DWORD patpos[MAX_PATTERNS];
166         BYTE chnmask[64], channels_used[64];
167         MODCOMMAND lastvalue[64];
168
169         pifh.id = bswapLE32(pifh.id);
170         pifh.reserved1 = bswapLE16(pifh.reserved1);
171         pifh.ordnum = bswapLE16(pifh.ordnum);
172         pifh.insnum = bswapLE16(pifh.insnum);
173         pifh.smpnum = bswapLE16(pifh.smpnum);
174         pifh.patnum = bswapLE16(pifh.patnum);
175         pifh.cwtv = bswapLE16(pifh.cwtv);
176         pifh.cmwt = bswapLE16(pifh.cmwt);
177         pifh.flags = bswapLE16(pifh.flags);
178         pifh.special = bswapLE16(pifh.special);
179         pifh.msglength = bswapLE16(pifh.msglength);
180         pifh.msgoffset = bswapLE32(pifh.msgoffset);
181         pifh.reserved2 = bswapLE32(pifh.reserved2);
182
183         if ((!lpStream) || (dwMemLength < 0x100)) return FALSE;
184         if ((pifh.id != 0x4D504D49) || (pifh.insnum >= MAX_INSTRUMENTS)
185          || (!pifh.smpnum) || (pifh.smpnum >= MAX_INSTRUMENTS) || (!pifh.ordnum)) return FALSE;
186         if (dwMemPos + pifh.ordnum + pifh.insnum*4
187          + pifh.smpnum*4 + pifh.patnum*4 > dwMemLength) return FALSE;
188         m_nType = MOD_TYPE_IT;
189         if (pifh.flags & 0x08) m_dwSongFlags |= SONG_LINEARSLIDES;
190         if (pifh.flags & 0x10) m_dwSongFlags |= SONG_ITOLDEFFECTS;
191         if (pifh.flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATMODE;
192         if (pifh.flags & 0x80) m_dwSongFlags |= SONG_EMBEDMIDICFG;
193         if (pifh.flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE;
194         memcpy(m_szNames[0], pifh.songname, 26);
195         m_szNames[0][26] = 0;
196         // Global Volume
197         if (pifh.globalvol)
198         {
199                 m_nDefaultGlobalVolume = pifh.globalvol << 1;
200                 if (!m_nDefaultGlobalVolume) m_nDefaultGlobalVolume = 256;
201                 if (m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256;
202         }
203         if (pifh.speed) m_nDefaultSpeed = pifh.speed;
204         if (pifh.tempo) m_nDefaultTempo = pifh.tempo;
205         m_nSongPreAmp = pifh.mv & 0x7F;
206         // Reading Channels Pan Positions
207         for (int ipan=0; ipan<64; ipan++) if (pifh.chnpan[ipan] != 0xFF)
208         {
209                 ChnSettings[ipan].nVolume = pifh.chnvol[ipan];
210                 ChnSettings[ipan].nPan = 128;
211                 if (pifh.chnpan[ipan] & 0x80) ChnSettings[ipan].dwFlags |= CHN_MUTE;
212                 UINT n = pifh.chnpan[ipan] & 0x7F;
213                 if (n <= 64) ChnSettings[ipan].nPan = n << 2;
214                 if (n == 100) ChnSettings[ipan].dwFlags |= CHN_SURROUND;
215         }
216         if (m_nChannels < 4) m_nChannels = 4;
217         // Reading Song Message
218         if ((pifh.special & 0x01) && (pifh.msglength) && (pifh.msgoffset + pifh.msglength < dwMemLength))
219         {
220                 m_lpszSongComments = new char[pifh.msglength+1];
221                 if (m_lpszSongComments)
222                 {
223                         memcpy(m_lpszSongComments, lpStream+pifh.msgoffset, pifh.msglength);
224                         m_lpszSongComments[pifh.msglength] = 0;
225                 }
226         }
227         // Reading orders
228         UINT nordsize = pifh.ordnum;
229         if (nordsize > MAX_ORDERS) nordsize = MAX_ORDERS;
230         memcpy(Order, lpStream+dwMemPos, nordsize);
231         dwMemPos += pifh.ordnum;
232         // Reading Instrument Offsets
233         memset(inspos, 0, sizeof(inspos));
234         UINT inspossize = pifh.insnum;
235         if (inspossize > MAX_INSTRUMENTS) inspossize = MAX_INSTRUMENTS;
236         inspossize <<= 2;
237         memcpy(inspos, lpStream+dwMemPos, inspossize);
238         for (UINT j=0; j < (inspossize>>2); j++)
239         {
240                inspos[j] = bswapLE32(inspos[j]);
241         }
242         dwMemPos += pifh.insnum * 4;
243         // Reading Samples Offsets
244         memset(smppos, 0, sizeof(smppos));
245         UINT smppossize = pifh.smpnum;
246         if (smppossize > MAX_SAMPLES) smppossize = MAX_SAMPLES;
247         smppossize <<= 2;
248         memcpy(smppos, lpStream+dwMemPos, smppossize);
249         for (UINT j=0; j < (smppossize>>2); j++)
250         {
251                smppos[j] = bswapLE32(smppos[j]);
252         }
253         dwMemPos += pifh.smpnum * 4;
254         // Reading Patterns Offsets
255         memset(patpos, 0, sizeof(patpos));
256         UINT patpossize = pifh.patnum;
257         if (patpossize > MAX_PATTERNS) patpossize = MAX_PATTERNS;
258         patpossize <<= 2;
259         memcpy(patpos, lpStream+dwMemPos, patpossize);
260         for (UINT j=0; j < (patpossize>>2); j++)
261         {
262                patpos[j] = bswapLE32(patpos[j]);
263         }
264         dwMemPos += pifh.patnum * 4;
265         // Reading IT Extra Info
266         if (dwMemPos + 2 < dwMemLength)
267         {
268                 UINT nflt = bswapLE16(*((WORD *)(lpStream + dwMemPos)));
269                 dwMemPos += 2;
270                 if (dwMemPos + nflt * 8 < dwMemLength) dwMemPos += nflt * 8;
271         }
272         // Reading Midi Output & Macros
273         if (m_dwSongFlags & SONG_EMBEDMIDICFG)
274         {
275                 if (dwMemPos + sizeof(MODMIDICFG) < dwMemLength)
276                 {
277                         memcpy(&m_MidiCfg, lpStream+dwMemPos, sizeof(MODMIDICFG));
278                         dwMemPos += sizeof(MODMIDICFG);
279                 }
280         }
281         // Read pattern names: "PNAM"
282         if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50))
283         {
284                 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4)));
285                 dwMemPos += 8;
286                 if ((dwMemPos + len <= dwMemLength) && (len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME))
287                 {
288                         m_lpszPatternNames = new char[len];
289                         if (m_lpszPatternNames)
290                         {
291                                 m_nPatternNames = len / MAX_PATTERNNAME;
292                                 memcpy(m_lpszPatternNames, lpStream+dwMemPos, len);
293                         }
294                         dwMemPos += len;
295                 }
296         }
297         // 4-channels minimum
298         m_nChannels = 4;
299         // Read channel names: "CNAM"
300         if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43))
301         {
302                 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4)));
303                 dwMemPos += 8;
304                 if ((dwMemPos + len <= dwMemLength) && (len <= 64*MAX_CHANNELNAME))
305                 {
306                         UINT n = len / MAX_CHANNELNAME;
307                         if (n > m_nChannels) m_nChannels = n;
308                         for (UINT i=0; i<n; i++)
309                         {
310                                 memcpy(ChnSettings[i].szName, (lpStream+dwMemPos+i*MAX_CHANNELNAME), MAX_CHANNELNAME);
311                                 ChnSettings[i].szName[MAX_CHANNELNAME-1] = 0;
312                         }
313                         dwMemPos += len;
314                 }
315         }
316         // Read mix plugins information
317         if (dwMemPos + 8 < dwMemLength)
318         {
319                 dwMemPos += LoadMixPlugins(lpStream+dwMemPos, dwMemLength-dwMemPos);
320         }
321         // Checking for unused channels
322         UINT npatterns = pifh.patnum;
323         if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS;
324         for (UINT patchk=0; patchk<npatterns; patchk++)
325         {
326                 memset(chnmask, 0, sizeof(chnmask));
327                 if ((!patpos[patchk]) || ((DWORD)patpos[patchk] + 4 >= dwMemLength)) continue;
328                 UINT len = bswapLE16(*((WORD *)(lpStream+patpos[patchk])));
329                 UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[patchk]+2)));
330                 if ((rows < 4) || (rows > 256)) continue;
331                 if (patpos[patchk]+8+len > dwMemLength) continue;
332                 UINT i = 0;
333                 const BYTE *p = lpStream+patpos[patchk]+8;
334                 UINT nrow = 0;
335                 while (nrow<rows)
336                 {
337                         if (i >= len) break;
338                         BYTE b = p[i++];
339                         if (!b)
340                         {
341                                 nrow++;
342                                 continue;
343                         }
344                         UINT ch = b & 0x7F;
345                         if (ch) ch = (ch - 1) & 0x3F;
346                         if (b & 0x80)
347                         {
348                                 if (i >= len) break;
349                                 chnmask[ch] = p[i++];
350                         }
351                         // Channel used
352                         if (chnmask[ch] & 0x0F)
353                         {
354                                 if ((ch >= m_nChannels) && (ch < 64)) m_nChannels = ch+1;
355                         }
356                         // Note
357                         if (chnmask[ch] & 1) i++;
358                         // Instrument
359                         if (chnmask[ch] & 2) i++;
360                         // Volume
361                         if (chnmask[ch] & 4) i++;
362                         // Effect
363                         if (chnmask[ch] & 8) i += 2;
364                         if (i >= len) break;
365                 }
366         }
367         // Reading Instruments
368         m_nInstruments = 0;
369         if (pifh.flags & 0x04) m_nInstruments = pifh.insnum;
370         if (m_nInstruments >= MAX_INSTRUMENTS) m_nInstruments = MAX_INSTRUMENTS-1;
371         for (UINT nins=0; nins<m_nInstruments; nins++)
372         {
373                 if ((inspos[nins] > 0) && (inspos[nins] < dwMemLength - sizeof(ITOLDINSTRUMENT)))
374                 {
375                         INSTRUMENTHEADER *penv = new INSTRUMENTHEADER;
376                         if (!penv) continue;
377                         Headers[nins+1] = penv;
378                         memset(penv, 0, sizeof(INSTRUMENTHEADER));
379                         ITInstrToMPT(lpStream + inspos[nins], penv, pifh.cmwt);
380                 }
381         }
382         // Reading Samples
383         m_nSamples = pifh.smpnum;
384         if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1;
385         for (UINT nsmp=0; nsmp<pifh.smpnum; nsmp++) if ((smppos[nsmp]) && (smppos[nsmp] + sizeof(ITSAMPLESTRUCT) <= dwMemLength))
386         {
387                 ITSAMPLESTRUCT pis = *(ITSAMPLESTRUCT *)(lpStream+smppos[nsmp]);
388                 pis.id = bswapLE32(pis.id);
389                 pis.length = bswapLE32(pis.length);
390                 pis.loopbegin = bswapLE32(pis.loopbegin);
391                 pis.loopend = bswapLE32(pis.loopend);
392                 pis.C5Speed = bswapLE32(pis.C5Speed);
393                 pis.susloopbegin = bswapLE32(pis.susloopbegin);
394                 pis.susloopend = bswapLE32(pis.susloopend);
395                 pis.samplepointer = bswapLE32(pis.samplepointer);
396
397                 if (pis.id == 0x53504D49)
398                 {
399                         MODINSTRUMENT *pins = &Ins[nsmp+1];
400                         memcpy(pins->name, pis.filename, 12);
401                         pins->uFlags = 0;
402                         pins->nLength = 0;
403                         pins->nLoopStart = pis.loopbegin;
404                         pins->nLoopEnd = pis.loopend;
405                         pins->nSustainStart = pis.susloopbegin;
406                         pins->nSustainEnd = pis.susloopend;
407                         pins->nC4Speed = pis.C5Speed;
408                         if (!pins->nC4Speed) pins->nC4Speed = 8363;
409                         if (pis.C5Speed < 256) pins->nC4Speed = 256;
410                         pins->nVolume = pis.vol << 2;
411                         if (pins->nVolume > 256) pins->nVolume = 256;
412                         pins->nGlobalVol = pis.gvl;
413                         if (pins->nGlobalVol > 64) pins->nGlobalVol = 64;
414                         if (pis.flags & 0x10) pins->uFlags |= CHN_LOOP;
415                         if (pis.flags & 0x20) pins->uFlags |= CHN_SUSTAINLOOP;
416                         if (pis.flags & 0x40) pins->uFlags |= CHN_PINGPONGLOOP;
417                         if (pis.flags & 0x80) pins->uFlags |= CHN_PINGPONGSUSTAIN;
418                         pins->nPan = (pis.dfp & 0x7F) << 2;
419                         if (pins->nPan > 256) pins->nPan = 256;
420                         if (pis.dfp & 0x80) pins->uFlags |= CHN_PANNING;
421                         pins->nVibType = autovibit2xm[pis.vit & 7];
422                         pins->nVibRate = pis.vis;
423                         pins->nVibDepth = pis.vid & 0x7F;
424                         pins->nVibSweep = (pis.vir + 3) / 4;
425                         if ((pis.samplepointer) && (pis.samplepointer < dwMemLength) && (pis.length))
426                         {
427                                 pins->nLength = pis.length;
428                                 if (pins->nLength > MAX_SAMPLE_LENGTH) pins->nLength = MAX_SAMPLE_LENGTH;
429                                 UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U;
430                                 if (pis.flags & 2)
431                                 {
432                                         flags += 5;
433                                         if (pis.flags & 4) flags |= RSF_STEREO;
434                                         pins->uFlags |= CHN_16BIT;
435                                         // IT 2.14 16-bit packed sample ?
436                                         if (pis.flags & 8) flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT21516 : RS_IT21416;
437                                 } else
438                                 {
439                                         if (pis.flags & 4) flags |= RSF_STEREO;
440                                         if (pis.cvt == 0xFF) flags = RS_ADPCM4; else
441                                         // IT 2.14 8-bit packed sample ?
442                                         if (pis.flags & 8)      flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT2158 : RS_IT2148;
443                                 }
444                                 ReadSample(&Ins[nsmp+1], flags, (LPSTR)(lpStream+pis.samplepointer), dwMemLength - pis.samplepointer);
445                         }
446                 }
447                 memcpy(m_szNames[nsmp+1], pis.name, 26);
448         }
449         // Reading Patterns
450         for (UINT npat=0; npat<npatterns; npat++)
451         {
452                 if ((!patpos[npat]) || ((DWORD)patpos[npat] + 4 >= dwMemLength))
453                 {
454                         PatternSize[npat] = 64;
455                         Patterns[npat] = AllocatePattern(64, m_nChannels);
456                         continue;
457                 }
458
459                 UINT len = bswapLE16(*((WORD *)(lpStream+patpos[npat])));
460                 UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[npat]+2)));
461                 if ((rows < 4) || (rows > 256)) continue;
462                 if (patpos[npat]+8+len > dwMemLength) continue;
463                 PatternSize[npat] = rows;
464                 if ((Patterns[npat] = AllocatePattern(rows, m_nChannels)) == NULL) continue;
465                 memset(lastvalue, 0, sizeof(lastvalue));
466                 memset(chnmask, 0, sizeof(chnmask));
467                 MODCOMMAND *m = Patterns[npat];
468                 UINT i = 0;
469                 const BYTE *p = lpStream+patpos[npat]+8;
470                 UINT nrow = 0;
471                 while (nrow<rows)
472                 {
473                         if (i >= len) break;
474                         BYTE b = p[i++];
475                         if (!b)
476                         {
477                                 nrow++;
478                                 m+=m_nChannels;
479                                 continue;
480                         }
481                         UINT ch = b & 0x7F;
482                         if (ch) ch = (ch - 1) & 0x3F;
483                         if (b & 0x80)
484                         {
485                                 if (i >= len) break;
486                                 chnmask[ch] = p[i++];
487                         }
488                         if ((chnmask[ch] & 0x10) && (ch < m_nChannels))
489                         {
490                                 m[ch].note = lastvalue[ch].note;
491                         }
492                         if ((chnmask[ch] & 0x20) && (ch < m_nChannels))
493                         {
494                                 m[ch].instr = lastvalue[ch].instr;
495                         }
496                         if ((chnmask[ch] & 0x40) && (ch < m_nChannels))
497                         {
498                                 m[ch].volcmd = lastvalue[ch].volcmd;
499                                 m[ch].vol = lastvalue[ch].vol;
500                         }
501                         if ((chnmask[ch] & 0x80) && (ch < m_nChannels))
502                         {
503                                 m[ch].command = lastvalue[ch].command;
504                                 m[ch].param = lastvalue[ch].param;
505                         }
506                         if (chnmask[ch] & 1)    // Note
507                         {
508                                 if (i >= len) break;
509                                 UINT note = p[i++];
510                                 if (ch < m_nChannels)
511                                 {
512                                         if (note < 0x80) note++;
513                                         m[ch].note = note;
514                                         lastvalue[ch].note = note;
515                                         channels_used[ch] = TRUE;
516                                 }
517                         }
518                         if (chnmask[ch] & 2)
519                         {
520                                 if (i >= len) break;
521                                 UINT instr = p[i++];
522                                 if (ch < m_nChannels)
523                                 {
524                                         m[ch].instr = instr;
525                                         lastvalue[ch].instr = instr;
526                                 }
527                         }
528                         if (chnmask[ch] & 4)
529                         {
530                                 if (i >= len) break;
531                                 UINT vol = p[i++];
532                                 if (ch < m_nChannels)
533                                 {
534                                         // 0-64: Set Volume
535                                         if (vol <= 64) { m[ch].volcmd = VOLCMD_VOLUME; m[ch].vol = vol; } else
536                                         // 128-192: Set Panning
537                                         if ((vol >= 128) && (vol <= 192)) { m[ch].volcmd = VOLCMD_PANNING; m[ch].vol = vol - 128; } else
538                                         // 65-74: Fine Volume Up
539                                         if (vol < 75) { m[ch].volcmd = VOLCMD_FINEVOLUP; m[ch].vol = vol - 65; } else
540                                         // 75-84: Fine Volume Down
541                                         if (vol < 85) { m[ch].volcmd = VOLCMD_FINEVOLDOWN; m[ch].vol = vol - 75; } else
542                                         // 85-94: Volume Slide Up
543                                         if (vol < 95) { m[ch].volcmd = VOLCMD_VOLSLIDEUP; m[ch].vol = vol - 85; } else
544                                         // 95-104: Volume Slide Down
545                                         if (vol < 105) { m[ch].volcmd = VOLCMD_VOLSLIDEDOWN; m[ch].vol = vol - 95; } else
546                                         // 105-114: Pitch Slide Up
547                                         if (vol < 115) { m[ch].volcmd = VOLCMD_PORTADOWN; m[ch].vol = vol - 105; } else
548                                         // 115-124: Pitch Slide Down
549                                         if (vol < 125) { m[ch].volcmd = VOLCMD_PORTAUP; m[ch].vol = vol - 115; } else
550                                         // 193-202: Portamento To
551                                         if ((vol >= 193) && (vol <= 202)) { m[ch].volcmd = VOLCMD_TONEPORTAMENTO; m[ch].vol = vol - 193; } else
552                                         // 203-212: Vibrato
553                                         if ((vol >= 203) && (vol <= 212)) { m[ch].volcmd = VOLCMD_VIBRATOSPEED; m[ch].vol = vol - 203; }
554                                         lastvalue[ch].volcmd = m[ch].volcmd;
555                                         lastvalue[ch].vol = m[ch].vol;
556                                 }
557                         }
558                         // Reading command/param
559                         if (chnmask[ch] & 8)
560                         {
561                                 if (i > len - 2) break;
562                                 UINT cmd = p[i++];
563                                 UINT param = p[i++];
564                                 if (ch < m_nChannels)
565                                 {
566                                         if (cmd)
567                                         {
568                                                 m[ch].command = cmd;
569                                                 m[ch].param = param;
570                                                 S3MConvert(&m[ch], TRUE);
571                                                 lastvalue[ch].command = m[ch].command;
572                                                 lastvalue[ch].param = m[ch].param;
573                                         }
574                                 }
575                         }
576                 }
577         }
578         for (UINT ncu=0; ncu<MAX_BASECHANNELS; ncu++)
579         {
580                 if (ncu>=m_nChannels)
581                 {
582                         ChnSettings[ncu].nVolume = 64;
583                         ChnSettings[ncu].dwFlags &= ~CHN_MUTE;
584                 }
585         }
586         m_nMinPeriod = 8;
587         m_nMaxPeriod = 0xF000;
588         return TRUE;
589 }
590
591
592 #ifndef MODPLUG_NO_FILESAVE
593 //#define SAVEITTIMESTAMP
594 #pragma warning(disable:4100)
595
596 BOOL CSoundFile::SaveIT(LPCSTR lpszFileName, UINT nPacking)
597 //---------------------------------------------------------
598 {
599         DWORD dwPatNamLen, dwChnNamLen;
600         ITFILEHEADER header;
601         ITINSTRUMENT iti;
602         ITSAMPLESTRUCT itss;
603         BYTE smpcount[MAX_SAMPLES];
604         DWORD inspos[MAX_INSTRUMENTS];
605         DWORD patpos[MAX_PATTERNS];
606         DWORD smppos[MAX_SAMPLES];
607         DWORD dwPos = 0, dwHdrPos = 0, dwExtra = 2;
608         WORD patinfo[4];
609         BYTE chnmask[64];
610         BYTE buf[512];
611         MODCOMMAND lastvalue[64];
612         FILE *f;
613
614
615         if ((!lpszFileName) || ((f = fopen(lpszFileName, "wb")) == NULL)) return FALSE;
616         memset(inspos, 0, sizeof(inspos));
617         memset(patpos, 0, sizeof(patpos));
618         memset(smppos, 0, sizeof(smppos));
619         // Writing Header
620         memset(&header, 0, sizeof(header));
621         dwPatNamLen = 0;
622         dwChnNamLen = 0;
623         header.id = 0x4D504D49;
624         lstrcpyn(header.songname, m_szNames[0], 27);
625         header.reserved1 = 0x1004;
626         header.ordnum = 0;
627         while ((header.ordnum < MAX_ORDERS) && (Order[header.ordnum] < 0xFF)) header.ordnum++;
628         if (header.ordnum < MAX_ORDERS) Order[header.ordnum++] = 0xFF;
629         header.insnum = m_nInstruments;
630         header.smpnum = m_nSamples;
631         header.patnum = MAX_PATTERNS;
632         while ((header.patnum > 0) && (!Patterns[header.patnum-1])) header.patnum--;
633         header.cwtv = 0x217;
634         header.cmwt = 0x200;
635         header.flags = 0x0001;
636         header.special = 0x0006;
637         if (m_nInstruments) header.flags |= 0x04;
638         if (m_dwSongFlags & SONG_LINEARSLIDES) header.flags |= 0x08;
639         if (m_dwSongFlags & SONG_ITOLDEFFECTS) header.flags |= 0x10;
640         if (m_dwSongFlags & SONG_ITCOMPATMODE) header.flags |= 0x20;
641         if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000;
642         header.globalvol = m_nDefaultGlobalVolume >> 1;
643         header.mv = m_nSongPreAmp;
644         if (header.mv < 0x20) header.mv = 0x20;
645         if (header.mv > 0x7F) header.mv = 0x7F;
646         header.speed = m_nDefaultSpeed;
647         header.tempo = m_nDefaultTempo;
648         header.sep = 128;
649         dwHdrPos = sizeof(header) + header.ordnum;
650         // Channel Pan and Volume
651         memset(header.chnpan, 0xFF, 64);
652         memset(header.chnvol, 64, 64);
653         for (UINT ich=0; ich<m_nChannels; ich++)
654         {
655                 header.chnpan[ich] = ChnSettings[ich].nPan >> 2;
656                 if (ChnSettings[ich].dwFlags & CHN_SURROUND) header.chnpan[ich] = 100;
657                 header.chnvol[ich] = ChnSettings[ich].nVolume;
658                 if (ChnSettings[ich].dwFlags & CHN_MUTE) header.chnpan[ich] |= 0x80;
659                 if (ChnSettings[ich].szName[0])
660                 {
661                         dwChnNamLen = (ich+1) * MAX_CHANNELNAME;
662                 }
663         }
664         if (dwChnNamLen) dwExtra += dwChnNamLen + 8;
665 #ifdef SAVEITTIMESTAMP
666         dwExtra += 8; // Time Stamp
667 #endif
668         if (m_dwSongFlags & SONG_EMBEDMIDICFG)
669         {
670                 header.flags |= 0x80;
671                 header.special |= 0x08;
672                 dwExtra += sizeof(MODMIDICFG);
673         }
674         // Pattern Names
675         if ((m_nPatternNames) && (m_lpszPatternNames))
676         {
677                 dwPatNamLen = m_nPatternNames * MAX_PATTERNNAME;
678                 while ((dwPatNamLen >= MAX_PATTERNNAME) && (!m_lpszPatternNames[dwPatNamLen-MAX_PATTERNNAME])) dwPatNamLen -= MAX_PATTERNNAME;
679                 if (dwPatNamLen < MAX_PATTERNNAME) dwPatNamLen = 0;
680                 if (dwPatNamLen) dwExtra += dwPatNamLen + 8;
681         }
682         // Mix Plugins
683         dwExtra += SaveMixPlugins(NULL, TRUE);
684         // Comments
685         if (m_lpszSongComments)
686         {
687                 header.special |= 1;
688                 header.msglength = strlen(m_lpszSongComments)+1;
689                 header.msgoffset = dwHdrPos + dwExtra + header.insnum*4 + header.patnum*4 + header.smpnum*4;
690         }
691         // Write file header
692         fwrite(&header, 1, sizeof(header), f);
693         fwrite(Order, 1, header.ordnum, f);
694         if (header.insnum) fwrite(inspos, 4, header.insnum, f);
695         if (header.smpnum) fwrite(smppos, 4, header.smpnum, f);
696         if (header.patnum) fwrite(patpos, 4, header.patnum, f);
697         // Writing editor history information
698         {
699 #ifdef SAVEITTIMESTAMP
700                 SYSTEMTIME systime;
701                 FILETIME filetime;
702                 WORD timestamp[4];
703                 WORD nInfoEx = 1;
704                 memset(timestamp, 0, sizeof(timestamp));
705                 fwrite(&nInfoEx, 1, 2, f);
706                 GetSystemTime(&systime);
707                 SystemTimeToFileTime(&systime, &filetime);
708                 FileTimeToDosDateTime(&filetime, &timestamp[0], &timestamp[1]);
709                 fwrite(timestamp, 1, 8, f);
710 #else
711                 WORD nInfoEx = 0;
712                 fwrite(&nInfoEx, 1, 2, f);
713 #endif
714         }
715         // Writing midi cfg
716         if (header.flags & 0x80)
717         {
718                 fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f);
719         }
720         // Writing pattern names
721         if (dwPatNamLen)
722         {
723                 DWORD d = 0x4d414e50;
724                 fwrite(&d, 1, 4, f);
725                 fwrite(&dwPatNamLen, 1, 4, f);
726                 fwrite(m_lpszPatternNames, 1, dwPatNamLen, f);
727         }
728         // Writing channel Names
729         if (dwChnNamLen)
730         {
731                 DWORD d = 0x4d414e43;
732                 fwrite(&d, 1, 4, f);
733                 fwrite(&dwChnNamLen, 1, 4, f);
734                 UINT nChnNames = dwChnNamLen / MAX_CHANNELNAME;
735                 for (UINT inam=0; inam<nChnNames; inam++)
736                 {
737                         fwrite(ChnSettings[inam].szName, 1, MAX_CHANNELNAME, f);
738                 }
739         }
740         // Writing mix plugins info
741         SaveMixPlugins(f, FALSE);
742         // Writing song message
743         dwPos = dwHdrPos + dwExtra + (header.insnum + header.smpnum + header.patnum) * 4;
744         if (header.special & 1)
745         {
746                 dwPos += strlen(m_lpszSongComments) + 1;
747                 fwrite(m_lpszSongComments, 1, strlen(m_lpszSongComments)+1, f);
748         }
749         // Writing instruments
750         for (UINT nins=1; nins<=header.insnum; nins++)
751         {
752                 memset(&iti, 0, sizeof(iti));
753                 iti.id = 0x49504D49;    // "IMPI"
754                 iti.trkvers = 0x211;
755                 if (Headers[nins])
756                 {
757                         INSTRUMENTHEADER *penv = Headers[nins];
758                         memset(smpcount, 0, sizeof(smpcount));
759                         memcpy(iti.filename, penv->filename, 12);
760                         memcpy(iti.name, penv->name, 26);
761                         iti.mbank = penv->wMidiBank;
762                         iti.mpr = penv->nMidiProgram;
763                         iti.mch = penv->nMidiChannel;
764                         iti.nna = penv->nNNA;
765                         iti.dct = penv->nDCT;
766                         iti.dca = penv->nDNA;
767                         iti.fadeout = penv->nFadeOut >> 5;
768                         iti.pps = penv->nPPS;
769                         iti.ppc = penv->nPPC;
770                         iti.gbv = (BYTE)(penv->nGlobalVol << 1);
771                         iti.dfp = (BYTE)penv->nPan >> 2;
772                         if (!(penv->dwFlags & ENV_SETPANNING)) iti.dfp |= 0x80;
773                         iti.rv = penv->nVolSwing;
774                         iti.rp = penv->nPanSwing;
775                         iti.ifc = penv->nIFC;
776                         iti.ifr = penv->nIFR;
777                         iti.nos = 0;
778                         for (UINT i=0; i<120; i++) if (penv->Keyboard[i] < MAX_SAMPLES)
779                         {
780                                 UINT smp = penv->Keyboard[i];
781                                 if ((smp) && (!smpcount[smp]))
782                                 {
783                                         smpcount[smp] = 1;
784                                         iti.nos++;
785                                 }
786                                 iti.keyboard[i*2] = penv->NoteMap[i] - 1;
787                                 iti.keyboard[i*2+1] = smp;
788                         }
789                         // Writing Volume envelope
790                         if (penv->dwFlags & ENV_VOLUME) iti.volenv.flags |= 0x01;
791                         if (penv->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02;
792                         if (penv->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04;
793                         if (penv->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08;
794                         iti.volenv.num = (BYTE)penv->nVolEnv;
795                         iti.volenv.lpb = (BYTE)penv->nVolLoopStart;
796                         iti.volenv.lpe = (BYTE)penv->nVolLoopEnd;
797                         iti.volenv.slb = penv->nVolSustainBegin;
798                         iti.volenv.sle = penv->nVolSustainEnd;
799                         // Writing Panning envelope
800                         if (penv->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01;
801                         if (penv->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02;
802                         if (penv->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04;
803                         if (penv->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08;
804                         iti.panenv.num = (BYTE)penv->nPanEnv;
805                         iti.panenv.lpb = (BYTE)penv->nPanLoopStart;
806                         iti.panenv.lpe = (BYTE)penv->nPanLoopEnd;
807                         iti.panenv.slb = penv->nPanSustainBegin;
808                         iti.panenv.sle = penv->nPanSustainEnd;
809                         // Writing Pitch Envelope
810                         if (penv->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01;
811                         if (penv->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02;
812                         if (penv->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04;
813                         if (penv->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08;
814                         if (penv->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80;
815                         iti.pitchenv.num = (BYTE)penv->nPitchEnv;
816                         iti.pitchenv.lpb = (BYTE)penv->nPitchLoopStart;
817                         iti.pitchenv.lpe = (BYTE)penv->nPitchLoopEnd;
818                         iti.pitchenv.slb = (BYTE)penv->nPitchSustainBegin;
819                         iti.pitchenv.sle = (BYTE)penv->nPitchSustainEnd;
820                         // Writing Envelopes data
821                         for (UINT ev=0; ev<25; ev++)
822                         {
823                                 iti.volenv.data[ev*3] = penv->VolEnv[ev];
824                                 iti.volenv.data[ev*3+1] = penv->VolPoints[ev] & 0xFF;
825                                 iti.volenv.data[ev*3+2] = penv->VolPoints[ev] >> 8;
826                                 iti.panenv.data[ev*3] = penv->PanEnv[ev] - 32;
827                                 iti.panenv.data[ev*3+1] = penv->PanPoints[ev] & 0xFF;
828                                 iti.panenv.data[ev*3+2] = penv->PanPoints[ev] >> 8;
829                                 iti.pitchenv.data[ev*3] = penv->PitchEnv[ev] - 32;
830                                 iti.pitchenv.data[ev*3+1] = penv->PitchPoints[ev] & 0xFF;
831                                 iti.pitchenv.data[ev*3+2] = penv->PitchPoints[ev] >> 8;
832                         }
833                 } else
834                 // Save Empty Instrument
835                 {
836                         for (UINT i=0; i<120; i++) iti.keyboard[i*2] = i;
837                         iti.ppc = 5*12;
838                         iti.gbv = 128;
839                         iti.dfp = 0x20;
840                         iti.ifc = 0xFF;
841                 }
842                 if (!iti.nos) iti.trkvers = 0;
843                 // Writing instrument
844                 inspos[nins-1] = dwPos;
845                 dwPos += sizeof(ITINSTRUMENT);
846                 fwrite(&iti, 1, sizeof(ITINSTRUMENT), f);
847         }
848         // Writing sample headers
849         memset(&itss, 0, sizeof(itss));
850         for (UINT hsmp=0; hsmp<header.smpnum; hsmp++)
851         {
852                 smppos[hsmp] = dwPos;
853                 dwPos += sizeof(ITSAMPLESTRUCT);
854                 fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f);
855         }
856         // Writing Patterns
857         for (UINT npat=0; npat<header.patnum; npat++)
858         {
859                 DWORD dwPatPos = dwPos;
860                 UINT len;
861                 if (!Patterns[npat]) continue;
862                 patpos[npat] = dwPos;
863                 patinfo[0] = 0;
864                 patinfo[1] = PatternSize[npat];
865                 patinfo[2] = 0;
866                 patinfo[3] = 0;
867                 // Check for empty pattern
868                 if (PatternSize[npat] == 64)
869                 {
870                         MODCOMMAND *pzc = Patterns[npat];
871                         UINT nz = PatternSize[npat] * m_nChannels;
872             INT iz;
873                         for (iz=0; iz<nz; iz++)
874                         {
875                                 if ((pzc[iz].note) || (pzc[iz].instr)
876                                  || (pzc[iz].volcmd) || (pzc[iz].command)) break;
877                         }
878                         if (iz == nz)
879                         {
880                                 patpos[npat] = 0;
881                                 continue;
882                         }
883                 }
884                 fwrite(patinfo, 8, 1, f);
885                 dwPos += 8;
886                 memset(chnmask, 0xFF, sizeof(chnmask));
887                 memset(lastvalue, 0, sizeof(lastvalue));
888                 MODCOMMAND *m = Patterns[npat];
889                 for (UINT row=0; row<PatternSize[npat]; row++)
890                 {
891                         len = 0;
892                         for (UINT ch=0; ch<m_nChannels; ch++, m++)
893                         {
894                                 BYTE b = 0;
895                                 UINT command = m->command;
896                                 UINT param = m->param;
897                                 UINT vol = 0xFF;
898                                 UINT note = m->note;
899                                 if (note) b |= 1;
900                                 if ((note) && (note < 0xFE)) note--;
901                                 if (m->instr) b |= 2;
902                                 if (m->volcmd)
903                                 {
904                                         UINT volcmd = m->volcmd;
905                                         switch(volcmd)
906                                         {
907                                         case VOLCMD_VOLUME:                     vol = m->vol; if (vol > 64) vol = 64; break;
908                                         case VOLCMD_PANNING:            vol = m->vol + 128; if (vol > 192) vol = 192; break;
909                                         case VOLCMD_VOLSLIDEUP:         vol = 85 + ConvertVolParam(m->vol); break;
910                                         case VOLCMD_VOLSLIDEDOWN:       vol = 95 + ConvertVolParam(m->vol); break;
911                                         case VOLCMD_FINEVOLUP:          vol = 65 + ConvertVolParam(m->vol); break;
912                                         case VOLCMD_FINEVOLDOWN:        vol = 75 + ConvertVolParam(m->vol); break;
913                                         case VOLCMD_VIBRATO:            vol = 203; break;
914                                         case VOLCMD_VIBRATOSPEED:       vol = 203 + ConvertVolParam(m->vol); break;
915                                         case VOLCMD_TONEPORTAMENTO:     vol = 193 + ConvertVolParam(m->vol); break;
916                                         case VOLCMD_PORTADOWN:          vol = 105 + ConvertVolParam(m->vol); break;
917                                         case VOLCMD_PORTAUP:            vol = 115 + ConvertVolParam(m->vol); break;
918                                         default:                                        vol = 0xFF;
919                                         }
920                                 }
921                                 if (vol != 0xFF) b |= 4;
922                                 if (command)
923                                 {
924                                         S3MSaveConvert(&command, &param, TRUE);
925                                         if (command) b |= 8;
926                                 }
927                                 // Packing information
928                                 if (b)
929                                 {
930                                         // Same note ?
931                                         if (b & 1)
932                                         {
933                                                 if ((note == lastvalue[ch].note) && (lastvalue[ch].volcmd & 1))
934                                                 {
935                                                         b &= ~1;
936                                                         b |= 0x10;
937                                                 } else
938                                                 {
939                                                         lastvalue[ch].note = note;
940                                                         lastvalue[ch].volcmd |= 1;
941                                                 }
942                                         }
943                                         // Same instrument ?
944                                         if (b & 2)
945                                         {
946                                                 if ((m->instr == lastvalue[ch].instr) && (lastvalue[ch].volcmd & 2))
947                                                 {
948                                                         b &= ~2;
949                                                         b |= 0x20;
950                                                 } else
951                                                 {
952                                                         lastvalue[ch].instr = m->instr;
953                                                         lastvalue[ch].volcmd |= 2;
954                                                 }
955                                         }
956                                         // Same volume column byte ?
957                                         if (b & 4)
958                                         {
959                                                 if ((vol == lastvalue[ch].vol) && (lastvalue[ch].volcmd & 4))
960                                                 {
961                                                         b &= ~4;
962                                                         b |= 0x40;
963                                                 } else
964                                                 {
965                                                         lastvalue[ch].vol = vol;
966                                                         lastvalue[ch].volcmd |= 4;
967                                                 }
968                                         }
969                                         // Same command / param ?
970                                         if (b & 8)
971                                         {
972                                                 if ((command == lastvalue[ch].command) && (param == lastvalue[ch].param) && (lastvalue[ch].volcmd & 8))
973                                                 {
974                                                         b &= ~8;
975                                                         b |= 0x80;
976                                                 } else
977                                                 {
978                                                         lastvalue[ch].command = command;
979                                                         lastvalue[ch].param = param;
980                                                         lastvalue[ch].volcmd |= 8;
981                                                 }
982                                         }
983                                         if (b != chnmask[ch])
984                                         {
985                                                 chnmask[ch] = b;
986                                                 buf[len++] = (ch+1) | 0x80;
987                                                 buf[len++] = b;
988                                         } else
989                                         {
990                                                 buf[len++] = ch+1;
991                                         }
992                                         if (b & 1) buf[len++] = note;
993                                         if (b & 2) buf[len++] = m->instr;
994                                         if (b & 4) buf[len++] = vol;
995                                         if (b & 8)
996                                         {
997                                                 buf[len++] = command;
998                                                 buf[len++] = param;
999                                         }
1000                                 }
1001                         }
1002                         buf[len++] = 0;
1003                         dwPos += len;
1004                         patinfo[0] += len;
1005                         fwrite(buf, 1, len, f);
1006                 }
1007                 fseek(f, dwPatPos, SEEK_SET);
1008                 fwrite(patinfo, 8, 1, f);
1009                 fseek(f, dwPos, SEEK_SET);
1010         }
1011         // Writing Sample Data
1012         for (UINT nsmp=1; nsmp<=header.smpnum; nsmp++)
1013         {
1014                 MODINSTRUMENT *psmp = &Ins[nsmp];
1015                 memset(&itss, 0, sizeof(itss));
1016                 memcpy(itss.filename, psmp->name, 12);
1017                 memcpy(itss.name, m_szNames[nsmp], 26);
1018                 itss.id = 0x53504D49;
1019                 itss.gvl = (BYTE)psmp->nGlobalVol;
1020                 if (m_nInstruments)
1021                 {
1022                         for (UINT iu=1; iu<=m_nInstruments; iu++) if (Headers[iu])
1023                         {
1024                                 INSTRUMENTHEADER *penv = Headers[iu];
1025                                 for (UINT ju=0; ju<128; ju++) if (penv->Keyboard[ju] == nsmp)
1026                                 {
1027                                         itss.flags = 0x01;
1028                                         break;
1029                                 }
1030                         }
1031                 } else
1032                 {
1033                         itss.flags = 0x01;
1034                 }
1035                 if (psmp->uFlags & CHN_LOOP) itss.flags |= 0x10;
1036                 if (psmp->uFlags & CHN_SUSTAINLOOP) itss.flags |= 0x20;
1037                 if (psmp->uFlags & CHN_PINGPONGLOOP) itss.flags |= 0x40;
1038                 if (psmp->uFlags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80;
1039                 itss.C5Speed = psmp->nC4Speed;
1040                 if (!itss.C5Speed) itss.C5Speed = 8363;
1041                 itss.length = psmp->nLength;
1042                 itss.loopbegin = psmp->nLoopStart;
1043                 itss.loopend = psmp->nLoopEnd;
1044                 itss.susloopbegin = psmp->nSustainStart;
1045                 itss.susloopend = psmp->nSustainEnd;
1046                 itss.vol = psmp->nVolume >> 2;
1047                 itss.dfp = psmp->nPan >> 2;
1048                 itss.vit = autovibxm2it[psmp->nVibType & 7];
1049                 itss.vis = psmp->nVibRate;
1050                 itss.vid = psmp->nVibDepth;
1051                 itss.vir = (psmp->nVibSweep < 64) ? psmp->nVibSweep * 4 : 255;
1052                 if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80;
1053                 if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01;
1054                 UINT flags = RS_PCM8S;
1055 #ifndef NO_PACKING
1056                 if (nPacking)
1057                 {
1058                         if ((!(psmp->uFlags & (CHN_16BIT|CHN_STEREO)))
1059                          && (CanPackSample(psmp->pSample, psmp->nLength, nPacking)))
1060                         {
1061                                 flags = RS_ADPCM4;
1062                                 itss.cvt = 0xFF;
1063                         }
1064                 } else
1065 #endif // NO_PACKING
1066                 {
1067                         if (psmp->uFlags & CHN_STEREO)
1068                         {
1069                                 flags = RS_STPCM8S;
1070                                 itss.flags |= 0x04;
1071                         }
1072                         if (psmp->uFlags & CHN_16BIT)
1073                         {
1074                                 itss.flags |= 0x02;
1075                                 flags = (psmp->uFlags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S;
1076                         }
1077                 }
1078                 itss.samplepointer = dwPos;
1079                 fseek(f, smppos[nsmp-1], SEEK_SET);
1080                 fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f);
1081                 fseek(f, dwPos, SEEK_SET);
1082                 if ((psmp->pSample) && (psmp->nLength))
1083                 {
1084                         dwPos += WriteSample(f, psmp, flags);
1085                 }
1086         }
1087         // Updating offsets
1088         fseek(f, dwHdrPos, SEEK_SET);
1089         if (header.insnum) fwrite(inspos, 4, header.insnum, f);
1090         if (header.smpnum) fwrite(smppos, 4, header.smpnum, f);
1091         if (header.patnum) fwrite(patpos, 4, header.patnum, f);
1092         fclose(f);
1093         return TRUE;
1094 }
1095
1096 #pragma warning(default:4100)
1097 #endif // MODPLUG_NO_FILESAVE
1098
1099 //////////////////////////////////////////////////////////////////////////////
1100 // IT 2.14 compression
1101
1102 DWORD ITReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n)
1103 //-----------------------------------------------------------------
1104 {
1105         DWORD retval = 0;
1106         UINT i = n;
1107
1108         if (n > 0)
1109         {
1110                 do
1111                 {
1112                         if (!bitnum)
1113                         {
1114                                 bitbuf = *ibuf++;
1115                                 bitnum = 8;
1116                         }
1117                         retval >>= 1;
1118                         retval |= bitbuf << 31;
1119                         bitbuf >>= 1;
1120                         bitnum--;
1121                         i--;
1122                 } while (i);
1123                 i = n;
1124         }
1125         return (retval >> (32-i));
1126 }
1127
1128 #define IT215_SUPPORT
1129 void ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215)
1130 //-------------------------------------------------------------------------------------------
1131 {
1132         signed char *pDst = pSample;
1133         LPBYTE pSrc = lpMemFile;
1134         DWORD wHdr = 0;
1135         DWORD wCount = 0;
1136         DWORD bitbuf = 0;
1137         UINT bitnum = 0;
1138         BYTE bLeft = 0, bTemp = 0, bTemp2 = 0;
1139
1140         while (dwLen)
1141         {
1142                 if (!wCount)
1143                 {
1144                         wCount = 0x8000;
1145                         wHdr = bswapLE16(*((LPWORD)pSrc));
1146                         pSrc += 2;
1147                         bLeft = 9;
1148                         bTemp = bTemp2 = 0;
1149                         bitbuf = bitnum = 0;
1150                 }
1151                 DWORD d = wCount;
1152                 if (d > dwLen) d = dwLen;
1153                 // Unpacking
1154                 DWORD dwPos = 0;
1155                 do
1156                 {
1157                         WORD wBits = (WORD)ITReadBits(bitbuf, bitnum, pSrc, bLeft);
1158                         if (bLeft < 7)
1159                         {
1160                                 DWORD i = 1 << (bLeft-1);
1161                                 DWORD j = wBits & 0xFFFF;
1162                                 if (i != j) goto UnpackByte;
1163                                 wBits = (WORD)(ITReadBits(bitbuf, bitnum, pSrc, 3) + 1) & 0xFF;
1164                                 bLeft = ((BYTE)wBits < bLeft) ? (BYTE)wBits : (BYTE)((wBits+1) & 0xFF);
1165                                 goto Next;
1166                         }
1167                         if (bLeft < 9)
1168                         {
1169                                 WORD i = (0xFF >> (9 - bLeft)) + 4;
1170                                 WORD j = i - 8;
1171                                 if ((wBits <= j) || (wBits > i)) goto UnpackByte;
1172                                 wBits -= j;
1173                                 bLeft = ((BYTE)(wBits & 0xFF) < bLeft) ? (BYTE)(wBits & 0xFF) : (BYTE)((wBits+1) & 0xFF);
1174                                 goto Next;
1175                         }
1176                         if (bLeft >= 10) goto SkipByte;
1177                         if (wBits >= 256)
1178                         {
1179                                 bLeft = (BYTE)(wBits + 1) & 0xFF;
1180                                 goto Next;
1181                         }
1182                 UnpackByte:
1183                         if (bLeft < 8)
1184                         {
1185                                 BYTE shift = 8 - bLeft;
1186                                 signed char c = (signed char)(wBits << shift);
1187                                 c >>= shift;
1188                                 wBits = (WORD)c;
1189                         }
1190                         wBits += bTemp;
1191                         bTemp = (BYTE)wBits;
1192                         bTemp2 += bTemp;
1193 #ifdef IT215_SUPPORT
1194                         pDst[dwPos] = (b215) ? bTemp2 : bTemp;
1195 #else
1196                         pDst[dwPos] = bTemp;
1197 #endif
1198                 SkipByte:
1199                         dwPos++;
1200                 Next:
1201                         if (pSrc >= lpMemFile+dwMemLength+1) return;
1202                 } while (dwPos < d);
1203                 // Move On
1204                 wCount -= d;
1205                 dwLen -= d;
1206                 pDst += d;
1207         }
1208 }
1209
1210
1211 void ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dwMemLength, BOOL b215)
1212 //--------------------------------------------------------------------------------------------
1213 {
1214         signed short *pDst = (signed short *)pSample;
1215         LPBYTE pSrc = lpMemFile;
1216         DWORD wHdr = 0;
1217         DWORD wCount = 0;
1218         DWORD bitbuf = 0;
1219         UINT bitnum = 0;
1220         BYTE bLeft = 0;
1221         signed short wTemp = 0, wTemp2 = 0;
1222
1223         while (dwLen)
1224         {
1225                 if (!wCount)
1226                 {
1227                         wCount = 0x4000;
1228                         wHdr = bswapLE16(*((LPWORD)pSrc));
1229                         pSrc += 2;
1230                         bLeft = 17;
1231                         wTemp = wTemp2 = 0;
1232                         bitbuf = bitnum = 0;
1233                 }
1234                 DWORD d = wCount;
1235                 if (d > dwLen) d = dwLen;
1236                 // Unpacking
1237                 DWORD dwPos = 0;
1238                 do
1239                 {
1240                         DWORD dwBits = ITReadBits(bitbuf, bitnum, pSrc, bLeft);
1241                         if (bLeft < 7)
1242                         {
1243                                 DWORD i = 1 << (bLeft-1);
1244                                 DWORD j = dwBits;
1245                                 if (i != j) goto UnpackByte;
1246                                 dwBits = ITReadBits(bitbuf, bitnum, pSrc, 4) + 1;
1247                                 bLeft = ((BYTE)(dwBits & 0xFF) < bLeft) ? (BYTE)(dwBits & 0xFF) : (BYTE)((dwBits+1) & 0xFF);
1248                                 goto Next;
1249                         }
1250                         if (bLeft < 17)
1251                         {
1252                                 DWORD i = (0xFFFF >> (17 - bLeft)) + 8;
1253                                 DWORD j = (i - 16) & 0xFFFF;
1254                                 if ((dwBits <= j) || (dwBits > (i & 0xFFFF))) goto UnpackByte;
1255                                 dwBits -= j;
1256                                 bLeft = ((BYTE)(dwBits & 0xFF) < bLeft) ? (BYTE)(dwBits & 0xFF) : (BYTE)((dwBits+1) & 0xFF);
1257                                 goto Next;
1258                         }
1259                         if (bLeft >= 18) goto SkipByte;
1260                         if (dwBits >= 0x10000)
1261                         {
1262                                 bLeft = (BYTE)(dwBits + 1) & 0xFF;
1263                                 goto Next;
1264                         }
1265                 UnpackByte:
1266                         if (bLeft < 16)
1267                         {
1268                                 BYTE shift = 16 - bLeft;
1269                                 signed short c = (signed short)(dwBits << shift);
1270                                 c >>= shift;
1271                                 dwBits = (DWORD)c;
1272                         }
1273                         dwBits += wTemp;
1274                         wTemp = (signed short)dwBits;
1275                         wTemp2 += wTemp;
1276 #ifdef IT215_SUPPORT
1277                         pDst[dwPos] = (b215) ? wTemp2 : wTemp;
1278 #else
1279                         pDst[dwPos] = wTemp;
1280 #endif
1281                 SkipByte:
1282                         dwPos++;
1283                 Next:
1284                         if (pSrc >= lpMemFile+dwMemLength+1) return;
1285                 } while (dwPos < d);
1286                 // Move On
1287                 wCount -= d;
1288                 dwLen -= d;
1289                 pDst += d;
1290                 if (pSrc >= lpMemFile+dwMemLength) break;
1291         }
1292 }
1293
1294 #ifndef MODPLUG_NO_FILESAVE
1295
1296 UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate)
1297 //----------------------------------------------------
1298 {
1299         DWORD chinfo[64];
1300         CHAR s[32];
1301         DWORD nPluginSize;
1302         UINT nTotalSize = 0;
1303         UINT nChInfo = 0;
1304
1305         for (UINT i=0; i<MAX_MIXPLUGINS; i++)
1306         {
1307                 PSNDMIXPLUGIN p = &m_MixPlugins[i];
1308                 if ((p->Info.dwPluginId1) || (p->Info.dwPluginId2))
1309                 {
1310                         nPluginSize = sizeof(SNDMIXPLUGININFO)+4; // plugininfo+4 (datalen)
1311                         if ((p->pMixPlugin) && (bUpdate))
1312                         {
1313                                 p->pMixPlugin->SaveAllParameters();
1314                         }
1315                         if (p->pPluginData)
1316                         {
1317                                 nPluginSize += p->nPluginDataSize;
1318                         }
1319                         if (f)
1320                         {
1321                                 s[0] = 'F';
1322                                 s[1] = 'X';
1323                                 s[2] = '0' + (i/10);
1324                                 s[3] = '0' + (i%10);
1325                                 fwrite(s, 1, 4, f);
1326                                 fwrite(&nPluginSize, 1, 4, f);
1327                                 fwrite(&p->Info, 1, sizeof(SNDMIXPLUGININFO), f);
1328                                 fwrite(&m_MixPlugins[i].nPluginDataSize, 1, 4, f);
1329                                 if (m_MixPlugins[i].pPluginData)
1330                                 {
1331                                         fwrite(m_MixPlugins[i].pPluginData, 1, m_MixPlugins[i].nPluginDataSize, f);
1332                                 }
1333                         }
1334                         nTotalSize += nPluginSize + 8;
1335                 }
1336         }
1337         for (UINT j=0; j<m_nChannels; j++)
1338         {
1339                 if (j < 64)
1340                 {
1341                         if ((chinfo[j] = ChnSettings[j].nMixPlugin) != 0)
1342                         {
1343                                 nChInfo = j+1;
1344                         }
1345                 }
1346         }
1347         if (nChInfo)
1348         {
1349                 if (f)
1350                 {
1351                         nPluginSize = 0x58464843;
1352                         fwrite(&nPluginSize, 1, 4, f);
1353                         nPluginSize = nChInfo*4;
1354                         fwrite(&nPluginSize, 1, 4, f);
1355                         fwrite(chinfo, 1, nPluginSize, f);
1356                 }
1357                 nTotalSize += nChInfo*4 + 8;
1358         }
1359         return nTotalSize;
1360 }
1361
1362 #endif /* MODPLUG_NO_FILESAVE */
1363
1364 UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen)
1365 //-----------------------------------------------------------
1366 {
1367         const BYTE *p = (const BYTE *)pData;
1368         UINT nPos = 0;
1369
1370         while (nPos+8 < nLen)
1371         {
1372                 DWORD nPluginSize;
1373                 UINT nPlugin;
1374
1375                 nPluginSize = bswapLE32(*(DWORD *)(p+nPos+4));
1376                 if (nPluginSize > nLen-nPos-8) break;;
1377                 if ((bswapLE32(*(DWORD *)(p+nPos))) == 0x58464843)
1378                 {
1379                         for (UINT ch=0; ch<64; ch++) if (ch*4 < nPluginSize)
1380                         {
1381                                 ChnSettings[ch].nMixPlugin = bswapLE32(*(DWORD *)(p+nPos+8+ch*4));
1382                         }
1383                 } else
1384                 {
1385                         if ((p[nPos] != 'F') || (p[nPos+1] != 'X')
1386                          || (p[nPos+2] < '0') || (p[nPos+3] < '0'))
1387                         {
1388                                 break;
1389                         }
1390                         nPlugin = (p[nPos+2]-'0')*10 + (p[nPos+3]-'0');
1391                         if ((nPlugin < MAX_MIXPLUGINS) && (nPluginSize >= sizeof(SNDMIXPLUGININFO)+4))
1392                         {
1393                                 DWORD dwExtra = bswapLE32(*(DWORD *)(p+nPos+8+sizeof(SNDMIXPLUGININFO)));
1394                                 m_MixPlugins[nPlugin].Info = *(const SNDMIXPLUGININFO *)(p+nPos+8);
1395                                 m_MixPlugins[nPlugin].Info.dwPluginId1 = bswapLE32(m_MixPlugins[nPlugin].Info.dwPluginId1);
1396                                 m_MixPlugins[nPlugin].Info.dwPluginId2 = bswapLE32(m_MixPlugins[nPlugin].Info.dwPluginId2);
1397                                 m_MixPlugins[nPlugin].Info.dwInputRouting = bswapLE32(m_MixPlugins[nPlugin].Info.dwInputRouting);
1398                                 m_MixPlugins[nPlugin].Info.dwOutputRouting = bswapLE32(m_MixPlugins[nPlugin].Info.dwOutputRouting);
1399                                 for (UINT j=0; j<4; j++)
1400                                 {
1401                                         m_MixPlugins[nPlugin].Info.dwReserved[j] = bswapLE32(m_MixPlugins[nPlugin].Info.dwReserved[j]);
1402                                 }
1403                                 if ((dwExtra) && (dwExtra <= nPluginSize-sizeof(SNDMIXPLUGININFO)-4))
1404                                 {
1405                                         m_MixPlugins[nPlugin].nPluginDataSize = 0;
1406                                         m_MixPlugins[nPlugin].pPluginData = new signed char [dwExtra];
1407                                         if (m_MixPlugins[nPlugin].pPluginData)
1408                                         {
1409                                                 m_MixPlugins[nPlugin].nPluginDataSize = dwExtra;
1410                                                 memcpy(m_MixPlugins[nPlugin].pPluginData, p+nPos+8+sizeof(SNDMIXPLUGININFO)+4, dwExtra);
1411                                         }
1412                                 }
1413                         }
1414                 }
1415                 nPos += nPluginSize + 8;
1416         }
1417         return nPos;
1418 }
1419