Mercurial > audlegacy-plugins
comparison src/modplug/load_it.cxx @ 2216:3673c7ec4ea2
Sync with schism's modplug engine. Suggested by G¸«ärkan Seng¸«än.
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Fri, 07 Dec 2007 12:08:47 -0600 |
parents | 6b5a52635b3b |
children | 6907fc39b53f |
comparison
equal
deleted
inserted
replaced
2198:32f9f1e4a9ec | 2216:3673c7ec4ea2 |
---|---|
1 /* | 1 /* |
2 * This source code is public domain. | 2 * This source code is public domain. |
3 * | 3 * |
4 * Authors: Olivier Lapicque <olivierl@jps.net>, | 4 * Authors: Olivier Lapicque <olivierl@jps.net>, |
5 * Adam Goode <adam@evdebs.org> (Endian and char fixes for PPC) | 5 * Adam Goode <adam@evdebs.org> (endian and char fixes for PPC) |
6 * Marco Trillo <toad@arsystel.com> (Endian fixes for SaveIT, XM->IT Sample Converter) | |
7 * | |
8 */ | 6 */ |
9 | 7 |
10 #include "stdafx.h" | 8 #include "stdafx.h" |
11 #include "sndfile.h" | 9 #include "sndfile.h" |
12 #include "it_defs.h" | 10 #include "it_defs.h" |
13 | 11 |
12 /* blah, -mrsb. | |
13 this is a schism header */ | |
14 #include "midi.h" | |
15 | |
14 #ifdef MSC_VER | 16 #ifdef MSC_VER |
15 #pragma warning(disable:4244) | 17 #pragma warning(disable:4244) |
16 #endif | 18 #endif |
17 | 19 |
18 BYTE autovibit2xm[8] = | 20 BYTE autovibit2xm[8] = |
20 | 22 |
21 BYTE autovibxm2it[8] = | 23 BYTE autovibxm2it[8] = |
22 { 0, 2, 4, 1, 3, 0, 0, 0 }; | 24 { 0, 2, 4, 1, 3, 0, 0, 0 }; |
23 | 25 |
24 ////////////////////////////////////////////////////////// | 26 ////////////////////////////////////////////////////////// |
25 // Impulse Tracker IT file support | 27 // Impulse Tracker IT file support (import only) |
26 | 28 |
27 // for conversion of XM samples | |
28 extern WORD XMPeriodTable[96+8]; | |
29 extern UINT XMLinearTable[768]; | |
30 | 29 |
31 static inline UINT ConvertVolParam(UINT value) | 30 static inline UINT ConvertVolParam(UINT value) |
32 //-------------------------------------------- | 31 //-------------------------------------------- |
33 { | 32 { |
34 return (value > 9) ? 9 : value; | 33 return (value > 9) ? 9 : value; |
42 { | 41 { |
43 const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p; | 42 const ITOLDINSTRUMENT *pis = (const ITOLDINSTRUMENT *)p; |
44 memcpy(penv->name, pis->name, 26); | 43 memcpy(penv->name, pis->name, 26); |
45 memcpy(penv->filename, pis->filename, 12); | 44 memcpy(penv->filename, pis->filename, 12); |
46 penv->nFadeOut = bswapLE16(pis->fadeout) << 6; | 45 penv->nFadeOut = bswapLE16(pis->fadeout) << 6; |
47 penv->nGlobalVol = 64; | 46 penv->nGlobalVol = 128; |
48 for (UINT j=0; j<120; j++) | 47 for (UINT j=0; j<120; j++) |
49 { | 48 { |
50 UINT note = pis->keyboard[j*2]; | 49 UINT note = pis->keyboard[j*2]; |
51 UINT ins = pis->keyboard[j*2+1]; | 50 UINT ins = pis->keyboard[j*2+1]; |
52 if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins; | 51 if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins; |
54 else if (note >= 0xFE) penv->NoteMap[j] = note; | 53 else if (note >= 0xFE) penv->NoteMap[j] = note; |
55 } | 54 } |
56 if (pis->flags & 0x01) penv->dwFlags |= ENV_VOLUME; | 55 if (pis->flags & 0x01) penv->dwFlags |= ENV_VOLUME; |
57 if (pis->flags & 0x02) penv->dwFlags |= ENV_VOLLOOP; | 56 if (pis->flags & 0x02) penv->dwFlags |= ENV_VOLLOOP; |
58 if (pis->flags & 0x04) penv->dwFlags |= ENV_VOLSUSTAIN; | 57 if (pis->flags & 0x04) penv->dwFlags |= ENV_VOLSUSTAIN; |
59 penv->nVolLoopStart = pis->vls; | 58 penv->VolEnv.nLoopStart = pis->vls; |
60 penv->nVolLoopEnd = pis->vle; | 59 penv->VolEnv.nLoopEnd = pis->vle; |
61 penv->nVolSustainBegin = pis->sls; | 60 penv->VolEnv.nSustainStart = pis->sls; |
62 penv->nVolSustainEnd = pis->sle; | 61 penv->VolEnv.nSustainEnd = pis->sle; |
63 penv->nVolEnv = 25; | 62 penv->VolEnv.nNodes = 25; |
64 for (UINT ev=0; ev<25; ev++) | 63 for (UINT ev=0; ev<25; ev++) |
65 { | 64 { |
66 if ((penv->VolPoints[ev] = pis->nodes[ev*2]) == 0xFF) | 65 if ((penv->VolEnv.Ticks[ev] = pis->nodes[ev*2]) == 0xFF) |
67 { | 66 { |
68 penv->nVolEnv = ev; | 67 penv->VolEnv.nNodes = ev; |
69 break; | 68 break; |
70 } | 69 } |
71 penv->VolEnv[ev] = pis->nodes[ev*2+1]; | 70 penv->VolEnv.Values[ev] = pis->nodes[ev*2+1]; |
72 } | 71 } |
73 penv->nNNA = pis->nna; | 72 penv->nNNA = pis->nna; |
74 penv->nDCT = pis->dnc; | 73 penv->nDCT = pis->dnc; |
75 penv->nPan = 0x80; | 74 penv->nPan = 0x80; |
76 } else | 75 } else |
80 memcpy(penv->filename, pis->filename, 12); | 79 memcpy(penv->filename, pis->filename, 12); |
81 penv->nMidiProgram = pis->mpr; | 80 penv->nMidiProgram = pis->mpr; |
82 penv->nMidiChannel = pis->mch; | 81 penv->nMidiChannel = pis->mch; |
83 penv->wMidiBank = bswapLE16(pis->mbank); | 82 penv->wMidiBank = bswapLE16(pis->mbank); |
84 penv->nFadeOut = bswapLE16(pis->fadeout) << 5; | 83 penv->nFadeOut = bswapLE16(pis->fadeout) << 5; |
85 penv->nGlobalVol = pis->gbv >> 1; | 84 penv->nGlobalVol = pis->gbv; |
86 if (penv->nGlobalVol > 64) penv->nGlobalVol = 64; | 85 if (penv->nGlobalVol > 128) penv->nGlobalVol = 128; |
87 for (UINT j=0; j<120; j++) | 86 for (UINT j=0; j<120; j++) |
88 { | 87 { |
89 UINT note = pis->keyboard[j*2]; | 88 UINT note = pis->keyboard[j*2]; |
90 UINT ins = pis->keyboard[j*2+1]; | 89 UINT ins = pis->keyboard[j*2+1]; |
91 if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins; | 90 if (ins < MAX_SAMPLES) penv->Keyboard[j] = ins; |
95 // Volume Envelope | 94 // Volume Envelope |
96 if (pis->volenv.flags & 1) penv->dwFlags |= ENV_VOLUME; | 95 if (pis->volenv.flags & 1) penv->dwFlags |= ENV_VOLUME; |
97 if (pis->volenv.flags & 2) penv->dwFlags |= ENV_VOLLOOP; | 96 if (pis->volenv.flags & 2) penv->dwFlags |= ENV_VOLLOOP; |
98 if (pis->volenv.flags & 4) penv->dwFlags |= ENV_VOLSUSTAIN; | 97 if (pis->volenv.flags & 4) penv->dwFlags |= ENV_VOLSUSTAIN; |
99 if (pis->volenv.flags & 8) penv->dwFlags |= ENV_VOLCARRY; | 98 if (pis->volenv.flags & 8) penv->dwFlags |= ENV_VOLCARRY; |
100 penv->nVolEnv = pis->volenv.num; | 99 penv->VolEnv.nNodes = pis->volenv.num; |
101 if (penv->nVolEnv > 25) penv->nVolEnv = 25; | 100 if (penv->VolEnv.nNodes > 25) penv->VolEnv.nNodes = 25; |
102 | 101 |
103 penv->nVolLoopStart = pis->volenv.lpb; | 102 penv->VolEnv.nLoopStart = pis->volenv.lpb; |
104 penv->nVolLoopEnd = pis->volenv.lpe; | 103 penv->VolEnv.nLoopEnd = pis->volenv.lpe; |
105 penv->nVolSustainBegin = pis->volenv.slb; | 104 penv->VolEnv.nSustainStart = pis->volenv.slb; |
106 penv->nVolSustainEnd = pis->volenv.sle; | 105 penv->VolEnv.nSustainEnd = pis->volenv.sle; |
107 // Panning Envelope | 106 // Panning Envelope |
108 if (pis->panenv.flags & 1) penv->dwFlags |= ENV_PANNING; | 107 if (pis->panenv.flags & 1) penv->dwFlags |= ENV_PANNING; |
109 if (pis->panenv.flags & 2) penv->dwFlags |= ENV_PANLOOP; | 108 if (pis->panenv.flags & 2) penv->dwFlags |= ENV_PANLOOP; |
110 if (pis->panenv.flags & 4) penv->dwFlags |= ENV_PANSUSTAIN; | 109 if (pis->panenv.flags & 4) penv->dwFlags |= ENV_PANSUSTAIN; |
111 if (pis->panenv.flags & 8) penv->dwFlags |= ENV_PANCARRY; | 110 if (pis->panenv.flags & 8) penv->dwFlags |= ENV_PANCARRY; |
112 penv->nPanEnv = pis->panenv.num; | 111 penv->PanEnv.nNodes = pis->panenv.num; |
113 if (penv->nPanEnv > 25) penv->nPanEnv = 25; | 112 if (penv->PanEnv.nNodes > 25) penv->PanEnv.nNodes = 25; |
114 penv->nPanLoopStart = pis->panenv.lpb; | 113 penv->PanEnv.nLoopStart = pis->panenv.lpb; |
115 penv->nPanLoopEnd = pis->panenv.lpe; | 114 penv->PanEnv.nLoopEnd = pis->panenv.lpe; |
116 penv->nPanSustainBegin = pis->panenv.slb; | 115 penv->PanEnv.nSustainStart = pis->panenv.slb; |
117 penv->nPanSustainEnd = pis->panenv.sle; | 116 penv->PanEnv.nSustainEnd = pis->panenv.sle; |
118 // Pitch Envelope | 117 // Pitch Envelope |
119 if (pis->pitchenv.flags & 1) penv->dwFlags |= ENV_PITCH; | 118 if (pis->pitchenv.flags & 1) penv->dwFlags |= ENV_PITCH; |
120 if (pis->pitchenv.flags & 2) penv->dwFlags |= ENV_PITCHLOOP; | 119 if (pis->pitchenv.flags & 2) penv->dwFlags |= ENV_PITCHLOOP; |
121 if (pis->pitchenv.flags & 4) penv->dwFlags |= ENV_PITCHSUSTAIN; | 120 if (pis->pitchenv.flags & 4) penv->dwFlags |= ENV_PITCHSUSTAIN; |
122 if (pis->pitchenv.flags & 8) penv->dwFlags |= ENV_PITCHCARRY; | 121 if (pis->pitchenv.flags & 8) penv->dwFlags |= ENV_PITCHCARRY; |
123 if (pis->pitchenv.flags & 0x80) penv->dwFlags |= ENV_FILTER; | 122 if (pis->pitchenv.flags & 0x80) penv->dwFlags |= ENV_FILTER; |
124 penv->nPitchEnv = pis->pitchenv.num; | 123 penv->PitchEnv.nNodes = pis->pitchenv.num; |
125 if (penv->nPitchEnv > 25) penv->nPitchEnv = 25; | 124 if (penv->PitchEnv.nNodes > 25) penv->PitchEnv.nNodes = 25; |
126 penv->nPitchLoopStart = pis->pitchenv.lpb; | 125 penv->PitchEnv.nLoopStart = pis->pitchenv.lpb; |
127 penv->nPitchLoopEnd = pis->pitchenv.lpe; | 126 penv->PitchEnv.nLoopEnd = pis->pitchenv.lpe; |
128 penv->nPitchSustainBegin = pis->pitchenv.slb; | 127 penv->PitchEnv.nSustainStart = pis->pitchenv.slb; |
129 penv->nPitchSustainEnd = pis->pitchenv.sle; | 128 penv->PitchEnv.nSustainEnd = pis->pitchenv.sle; |
130 // Envelopes Data | 129 // Envelopes Data |
131 for (UINT ev=0; ev<25; ev++) | 130 for (UINT ev=0; ev<25; ev++) |
132 { | 131 { |
133 penv->VolEnv[ev] = pis->volenv.data[ev*3]; | 132 penv->VolEnv.Values[ev] = pis->volenv.data[ev*3]; |
134 penv->VolPoints[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]); | 133 penv->VolEnv.Ticks[ev] = (pis->volenv.data[ev*3+2] << 8) | (pis->volenv.data[ev*3+1]); |
135 penv->PanEnv[ev] = pis->panenv.data[ev*3] + 32; | 134 penv->PanEnv.Values[ev] = pis->panenv.data[ev*3] + 32; |
136 penv->PanPoints[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]); | 135 penv->PanEnv.Ticks[ev] = (pis->panenv.data[ev*3+2] << 8) | (pis->panenv.data[ev*3+1]); |
137 penv->PitchEnv[ev] = pis->pitchenv.data[ev*3] + 32; | 136 penv->PitchEnv.Values[ev] = pis->pitchenv.data[ev*3] + 32; |
138 penv->PitchPoints[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]); | 137 penv->PitchEnv.Ticks[ev] = (pis->pitchenv.data[ev*3+2] << 8) | (pis->pitchenv.data[ev*3+1]); |
139 } | 138 } |
140 penv->nNNA = pis->nna; | 139 penv->nNNA = pis->nna % 4; |
141 penv->nDCT = pis->dct; | 140 penv->nDCT = pis->dct % 4; |
142 penv->nDNA = pis->dca; | 141 penv->nDNA = pis->dca % 3; |
143 penv->nPPS = pis->pps; | 142 penv->nPPS = pis->pps; |
144 penv->nPPC = pis->ppc; | 143 penv->nPPC = pis->ppc; |
145 penv->nIFC = pis->ifc; | 144 penv->nIFC = pis->ifc; |
146 penv->nIFR = pis->ifr; | 145 penv->nIFR = pis->ifr; |
147 penv->nVolSwing = pis->rv; | 146 penv->nVolSwing = pis->rv; |
148 penv->nPanSwing = pis->rp; | 147 penv->nPanSwing = pis->rp; |
149 penv->nPan = (pis->dfp & 0x7F) << 2; | 148 penv->nPan = (pis->dfp & 0x7F) << 2; |
150 if (penv->nPan > 256) penv->nPan = 128; | 149 if (penv->nPan > 256) penv->nPan = 128; |
151 if (pis->dfp < 0x80) penv->dwFlags |= ENV_SETPANNING; | 150 if (pis->dfp < 0x80) penv->dwFlags |= ENV_SETPANNING; |
152 } | 151 } |
153 if ((penv->nVolLoopStart >= 25) || (penv->nVolLoopEnd >= 25)) penv->dwFlags &= ~ENV_VOLLOOP; | 152 if ((penv->VolEnv.nLoopStart >= 25) || (penv->VolEnv.nLoopEnd >= 25)) penv->dwFlags &= ~ENV_VOLLOOP; |
154 if ((penv->nVolSustainBegin >= 25) || (penv->nVolSustainEnd >= 25)) penv->dwFlags &= ~ENV_VOLSUSTAIN; | 153 if ((penv->VolEnv.nSustainStart >= 25) || (penv->VolEnv.nSustainEnd >= 25)) penv->dwFlags &= ~ENV_VOLSUSTAIN; |
155 return TRUE; | 154 return TRUE; |
156 } | 155 } |
157 | 156 |
158 | 157 |
159 BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength) | 158 BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength) |
165 DWORD smppos[MAX_SAMPLES]; | 164 DWORD smppos[MAX_SAMPLES]; |
166 DWORD patpos[MAX_PATTERNS]; | 165 DWORD patpos[MAX_PATTERNS]; |
167 BYTE chnmask[64], channels_used[64]; | 166 BYTE chnmask[64], channels_used[64]; |
168 MODCOMMAND lastvalue[64]; | 167 MODCOMMAND lastvalue[64]; |
169 | 168 |
169 if ((!lpStream) || (dwMemLength < 0xc2)) return FALSE; | |
170 | |
170 pifh.id = bswapLE32(pifh.id); | 171 pifh.id = bswapLE32(pifh.id); |
171 pifh.reserved1 = bswapLE16(pifh.reserved1); | 172 if (pifh.id == 0x49504D49) { |
173 if (dwMemLength < 554) return FALSE; | |
174 | |
175 WORD tv; | |
176 INSTRUMENTHEADER *zenv = new INSTRUMENTHEADER; | |
177 if (!zenv) return FALSE; | |
178 memset(zenv, 0, sizeof(INSTRUMENTHEADER)); | |
179 memcpy(&tv, lpStream+0x1C, 2); /* trkvers */ | |
180 if (!ITInstrToMPT(lpStream, zenv, tv)) { | |
181 delete zenv; | |
182 return FALSE; | |
183 } | |
184 | |
185 /* okay, we need samples now */ | |
186 unsigned int q = 554; | |
187 BYTE expect_samples = lpStream[0x1E]; | |
188 | |
189 m_nType = MOD_TYPE_IT; | |
190 m_nInstruments = 1; | |
191 m_nSamples = expect_samples; | |
192 m_dwSongFlags = SONG_INSTRUMENTMODE | SONG_LINEARSLIDES /* eh? */; | |
193 | |
194 memcpy(m_szNames[0], lpStream + 0x20, 26); | |
195 m_szNames[0][26] = 0; | |
196 | |
197 if (q+(80*expect_samples) >= dwMemLength) { | |
198 delete zenv; | |
199 return FALSE; | |
200 } | |
201 | |
202 for (UINT nsmp = 0; nsmp < expect_samples; nsmp++) { | |
203 | |
204 ITSAMPLESTRUCT pis = *(ITSAMPLESTRUCT *)(lpStream+q); | |
205 q += 80; /* length of ITS header */ | |
206 | |
207 pis.id = bswapLE32(pis.id); | |
208 pis.length = bswapLE32(pis.length); | |
209 pis.loopbegin = bswapLE32(pis.loopbegin); | |
210 pis.loopend = bswapLE32(pis.loopend); | |
211 pis.C5Speed = bswapLE32(pis.C5Speed); | |
212 pis.susloopbegin = bswapLE32(pis.susloopbegin); | |
213 pis.susloopend = bswapLE32(pis.susloopend); | |
214 pis.samplepointer = bswapLE32(pis.samplepointer); | |
215 | |
216 if (pis.id == 0x53504D49) | |
217 { | |
218 MODINSTRUMENT *pins = &Ins[nsmp+1]; | |
219 memcpy(pins->name, pis.filename, 12); | |
220 pins->uFlags = 0; | |
221 pins->nLength = 0; | |
222 pins->nLoopStart = pis.loopbegin; | |
223 pins->nLoopEnd = pis.loopend; | |
224 pins->nSustainStart = pis.susloopbegin; | |
225 pins->nSustainEnd = pis.susloopend; | |
226 pins->nC4Speed = pis.C5Speed; | |
227 if (!pins->nC4Speed) pins->nC4Speed = 8363; | |
228 //if (pis.C5Speed < 256) pins->nC4Speed = 256; | |
229 pins->nVolume = pis.vol << 2; | |
230 if (pins->nVolume > 256) pins->nVolume = 256; | |
231 pins->nGlobalVol = pis.gvl; | |
232 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64; | |
233 if (pis.flags & 0x10) pins->uFlags |= CHN_LOOP; | |
234 if (pis.flags & 0x20) pins->uFlags |= CHN_SUSTAINLOOP; | |
235 if (pis.flags & 0x40) pins->uFlags |= CHN_PINGPONGLOOP; | |
236 if (pis.flags & 0x80) pins->uFlags |= CHN_PINGPONGSUSTAIN; | |
237 pins->nPan = (pis.dfp & 0x7F) << 2; | |
238 if (pins->nPan > 256) pins->nPan = 256; | |
239 if (pis.dfp & 0x80) pins->uFlags |= CHN_PANNING; | |
240 pins->nVibType = autovibit2xm[pis.vit & 7]; | |
241 pins->nVibRate = pis.vis; | |
242 pins->nVibDepth = pis.vid & 0x7F; | |
243 pins->nVibSweep = pis.vir; | |
244 if ((pis.samplepointer) && (pis.samplepointer < dwMemLength) && (pis.length)) | |
245 { | |
246 pins->nLength = pis.length; | |
247 if (pins->nLength > MAX_SAMPLE_LENGTH) pins->nLength = MAX_SAMPLE_LENGTH; | |
248 UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U; | |
249 if (pis.flags & 2) | |
250 { | |
251 flags += 5; | |
252 if (pis.flags & 4) flags |= RSF_STEREO; | |
253 pins->uFlags |= CHN_16BIT; | |
254 // IT 2.14 16-bit packed sample ? | |
255 if (pis.flags & 8) flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT21516 : RS_IT21416; | |
256 } else | |
257 { | |
258 if (pis.flags & 4) flags |= RSF_STEREO; | |
259 if (pis.cvt == 0xFF) flags = RS_ADPCM4; else | |
260 // IT 2.14 8-bit packed sample ? | |
261 if (pis.flags & 8) flags = ((pifh.cmwt >= 0x215) && (pis.cvt & 4)) ? RS_IT2158 : RS_IT2148; | |
262 } | |
263 ReadSample(&Ins[nsmp+1], flags, (LPSTR)(lpStream+pis.samplepointer), dwMemLength - pis.samplepointer); | |
264 } | |
265 } | |
266 memcpy(m_szNames[nsmp+1], pis.name, 26); | |
267 | |
268 } | |
269 | |
270 Headers[1] = zenv; | |
271 return TRUE; | |
272 } | |
273 | |
274 | |
172 pifh.ordnum = bswapLE16(pifh.ordnum); | 275 pifh.ordnum = bswapLE16(pifh.ordnum); |
173 pifh.insnum = bswapLE16(pifh.insnum); | 276 pifh.insnum = bswapLE16(pifh.insnum); |
174 pifh.smpnum = bswapLE16(pifh.smpnum); | 277 pifh.smpnum = bswapLE16(pifh.smpnum); |
175 pifh.patnum = bswapLE16(pifh.patnum); | 278 pifh.patnum = bswapLE16(pifh.patnum); |
176 pifh.cwtv = bswapLE16(pifh.cwtv); | 279 pifh.cwtv = bswapLE16(pifh.cwtv); |
179 pifh.special = bswapLE16(pifh.special); | 282 pifh.special = bswapLE16(pifh.special); |
180 pifh.msglength = bswapLE16(pifh.msglength); | 283 pifh.msglength = bswapLE16(pifh.msglength); |
181 pifh.msgoffset = bswapLE32(pifh.msgoffset); | 284 pifh.msgoffset = bswapLE32(pifh.msgoffset); |
182 pifh.reserved2 = bswapLE32(pifh.reserved2); | 285 pifh.reserved2 = bswapLE32(pifh.reserved2); |
183 | 286 |
184 if ((!lpStream) || (dwMemLength < 0x100)) return FALSE; | 287 |
288 | |
185 if ((pifh.id != 0x4D504D49) || (pifh.insnum >= MAX_INSTRUMENTS) | 289 if ((pifh.id != 0x4D504D49) || (pifh.insnum >= MAX_INSTRUMENTS) |
186 || (!pifh.smpnum) || (pifh.smpnum >= MAX_INSTRUMENTS) || (!pifh.ordnum)) return FALSE; | 290 || (pifh.smpnum >= MAX_INSTRUMENTS)) return FALSE; |
187 if (dwMemPos + pifh.ordnum + pifh.insnum*4 | 291 if (dwMemPos + pifh.ordnum + pifh.insnum*4 |
188 + pifh.smpnum*4 + pifh.patnum*4 > dwMemLength) return FALSE; | 292 + pifh.smpnum*4 + pifh.patnum*4 > dwMemLength) return FALSE; |
189 m_nType = MOD_TYPE_IT; | 293 m_nType = MOD_TYPE_IT; |
294 if (!(pifh.flags & 0x01)) m_dwSongFlags |= SONG_NOSTEREO; | |
295 if (pifh.flags & 0x04) m_dwSongFlags |= SONG_INSTRUMENTMODE; | |
190 if (pifh.flags & 0x08) m_dwSongFlags |= SONG_LINEARSLIDES; | 296 if (pifh.flags & 0x08) m_dwSongFlags |= SONG_LINEARSLIDES; |
191 if (pifh.flags & 0x10) m_dwSongFlags |= SONG_ITOLDEFFECTS; | 297 if (pifh.flags & 0x10) m_dwSongFlags |= SONG_ITOLDEFFECTS; |
192 if (pifh.flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATMODE; | 298 if (pifh.flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATMODE; |
299 if (pifh.flags & 0x40) { | |
300 midi_flags |= MIDI_PITCH_BEND; | |
301 midi_pitch_depth = pifh.pwd; | |
302 } | |
193 if (pifh.flags & 0x80) m_dwSongFlags |= SONG_EMBEDMIDICFG; | 303 if (pifh.flags & 0x80) m_dwSongFlags |= SONG_EMBEDMIDICFG; |
194 if (pifh.flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE; | 304 if (pifh.flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE; |
195 memcpy(m_szNames[0], pifh.songname, 26); | 305 memcpy(m_szNames[0], pifh.songname, 26); |
196 m_szNames[0][26] = 0; | 306 m_szNames[0][26] = 0; |
307 if (pifh.cwtv >= 0x0213) { | |
308 m_rowHighlightMinor = pifh.hilight_minor; | |
309 m_rowHighlightMajor = pifh.hilight_major; | |
310 } else { | |
311 m_rowHighlightMinor = 4; | |
312 m_rowHighlightMajor = 16; | |
313 } | |
197 // Global Volume | 314 // Global Volume |
198 if (pifh.globalvol) | 315 m_nDefaultGlobalVolume = pifh.globalvol << 1; |
199 { | 316 if (m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256; |
200 m_nDefaultGlobalVolume = pifh.globalvol << 1; | |
201 if (!m_nDefaultGlobalVolume) m_nDefaultGlobalVolume = 256; | |
202 if (m_nDefaultGlobalVolume > 256) m_nDefaultGlobalVolume = 256; | |
203 } | |
204 if (pifh.speed) m_nDefaultSpeed = pifh.speed; | 317 if (pifh.speed) m_nDefaultSpeed = pifh.speed; |
205 if (pifh.tempo) m_nDefaultTempo = pifh.tempo; | 318 if (pifh.tempo) m_nDefaultTempo = pifh.tempo; |
206 m_nSongPreAmp = pifh.mv & 0x7F; | 319 m_nSongPreAmp = pifh.mv; |
320 if (m_nSongPreAmp > 128) | |
321 m_nSongPreAmp = 128; | |
322 m_nStereoSeparation = pifh.sep; | |
207 // Reading Channels Pan Positions | 323 // Reading Channels Pan Positions |
208 for (int ipan=0; ipan<64; ipan++) if (pifh.chnpan[ipan] != 0xFF) | 324 for (int ipan=0; ipan<64; ipan++) if (pifh.chnpan[ipan] != 0xFF) |
209 { | 325 { |
210 ChnSettings[ipan].nVolume = pifh.chnvol[ipan]; | 326 ChnSettings[ipan].nVolume = pifh.chnvol[ipan]; |
211 ChnSettings[ipan].nPan = 128; | 327 ChnSettings[ipan].nPan = 128; |
227 } | 343 } |
228 // Reading orders | 344 // Reading orders |
229 UINT nordsize = pifh.ordnum; | 345 UINT nordsize = pifh.ordnum; |
230 if (nordsize > MAX_ORDERS) nordsize = MAX_ORDERS; | 346 if (nordsize > MAX_ORDERS) nordsize = MAX_ORDERS; |
231 memcpy(Order, lpStream+dwMemPos, nordsize); | 347 memcpy(Order, lpStream+dwMemPos, nordsize); |
348 | |
232 dwMemPos += pifh.ordnum; | 349 dwMemPos += pifh.ordnum; |
233 // Reading Instrument Offsets | 350 // Reading Instrument Offsets |
234 memset(inspos, 0, sizeof(inspos)); | 351 memset(inspos, 0, sizeof(inspos)); |
235 UINT inspossize = pifh.insnum; | 352 UINT inspossize = pifh.insnum; |
236 if (inspossize > MAX_INSTRUMENTS) inspossize = MAX_INSTRUMENTS; | 353 if (inspossize > MAX_INSTRUMENTS) inspossize = MAX_INSTRUMENTS; |
261 for (UINT j=0; j < (patpossize>>2); j++) | 378 for (UINT j=0; j < (patpossize>>2); j++) |
262 { | 379 { |
263 patpos[j] = bswapLE32(patpos[j]); | 380 patpos[j] = bswapLE32(patpos[j]); |
264 } | 381 } |
265 dwMemPos += pifh.patnum * 4; | 382 dwMemPos += pifh.patnum * 4; |
383 | |
384 for (UINT i = 0; i < pifh.ordnum; i++) { | |
385 if (Order[i] >= pifh.patnum && Order[i] < MAX_PATTERNS) { | |
386 pifh.patnum = Order[i]; | |
387 for (UINT j = patpossize; j < (unsigned)(pifh.patnum>>2); j++) | |
388 patpos[j] = 0; | |
389 patpossize = pifh.patnum; | |
390 } | |
391 } | |
392 | |
393 | |
266 // Reading IT Extra Info | 394 // Reading IT Extra Info |
267 if (dwMemPos + 2 < dwMemLength) | 395 if (dwMemPos + 2 < dwMemLength) |
268 { | 396 { |
269 UINT nflt = bswapLE16(*((WORD *)(lpStream + dwMemPos))); | 397 UINT nflt = bswapLE16(*((WORD *)(lpStream + dwMemPos))); |
270 dwMemPos += 2; | 398 dwMemPos += 2; |
275 { | 403 { |
276 if (dwMemPos + sizeof(MODMIDICFG) < dwMemLength) | 404 if (dwMemPos + sizeof(MODMIDICFG) < dwMemLength) |
277 { | 405 { |
278 memcpy(&m_MidiCfg, lpStream+dwMemPos, sizeof(MODMIDICFG)); | 406 memcpy(&m_MidiCfg, lpStream+dwMemPos, sizeof(MODMIDICFG)); |
279 dwMemPos += sizeof(MODMIDICFG); | 407 dwMemPos += sizeof(MODMIDICFG); |
280 } | 408 } else { |
281 } | 409 ResetMidiCfg(); |
410 } | |
411 } else { | |
412 ResetMidiCfg(); | |
413 } | |
414 #if 0 | |
282 // Read pattern names: "PNAM" | 415 // Read pattern names: "PNAM" |
283 if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50)) | 416 if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50)) |
284 { | 417 { |
285 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4))); | 418 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4))); |
286 dwMemPos += 8; | 419 dwMemPos += 8; |
293 memcpy(m_lpszPatternNames, lpStream+dwMemPos, len); | 426 memcpy(m_lpszPatternNames, lpStream+dwMemPos, len); |
294 } | 427 } |
295 dwMemPos += len; | 428 dwMemPos += len; |
296 } | 429 } |
297 } | 430 } |
431 #endif | |
298 // 4-channels minimum | 432 // 4-channels minimum |
299 m_nChannels = 4; | 433 m_nChannels = 4; |
434 #if 0 | |
300 // Read channel names: "CNAM" | 435 // Read channel names: "CNAM" |
301 if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43)) | 436 if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43)) |
302 { | 437 { |
303 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4))); | 438 UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4))); |
304 dwMemPos += 8; | 439 dwMemPos += 8; |
317 // Read mix plugins information | 452 // Read mix plugins information |
318 if (dwMemPos + 8 < dwMemLength) | 453 if (dwMemPos + 8 < dwMemLength) |
319 { | 454 { |
320 dwMemPos += LoadMixPlugins(lpStream+dwMemPos, dwMemLength-dwMemPos); | 455 dwMemPos += LoadMixPlugins(lpStream+dwMemPos, dwMemLength-dwMemPos); |
321 } | 456 } |
457 #endif | |
322 // Checking for unused channels | 458 // Checking for unused channels |
323 UINT npatterns = pifh.patnum; | 459 UINT npatterns = pifh.patnum; |
324 if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS; | 460 if (npatterns > MAX_PATTERNS) npatterns = MAX_PATTERNS; |
325 for (UINT patchk=0; patchk<npatterns; patchk++) | 461 for (UINT patchk=0; patchk<npatterns; patchk++) |
326 { | 462 { |
364 if (chnmask[ch] & 8) i += 2; | 500 if (chnmask[ch] & 8) i += 2; |
365 if (i >= len) break; | 501 if (i >= len) break; |
366 } | 502 } |
367 } | 503 } |
368 // Reading Instruments | 504 // Reading Instruments |
369 m_nInstruments = 0; | 505 m_nInstruments = pifh.insnum; |
370 if (pifh.flags & 0x04) m_nInstruments = pifh.insnum; | |
371 if (m_nInstruments >= MAX_INSTRUMENTS) m_nInstruments = MAX_INSTRUMENTS-1; | 506 if (m_nInstruments >= MAX_INSTRUMENTS) m_nInstruments = MAX_INSTRUMENTS-1; |
372 for (UINT nins=0; nins<m_nInstruments; nins++) | 507 for (UINT nins=0; nins<m_nInstruments; nins++) |
373 { | 508 { |
374 if ((inspos[nins] > 0) && (inspos[nins] < dwMemLength - sizeof(ITOLDINSTRUMENT))) | 509 if ((inspos[nins] > 0) && (inspos[nins] < dwMemLength - sizeof(ITOLDINSTRUMENT))) |
375 { | 510 { |
405 pins->nLoopEnd = pis.loopend; | 540 pins->nLoopEnd = pis.loopend; |
406 pins->nSustainStart = pis.susloopbegin; | 541 pins->nSustainStart = pis.susloopbegin; |
407 pins->nSustainEnd = pis.susloopend; | 542 pins->nSustainEnd = pis.susloopend; |
408 pins->nC4Speed = pis.C5Speed; | 543 pins->nC4Speed = pis.C5Speed; |
409 if (!pins->nC4Speed) pins->nC4Speed = 8363; | 544 if (!pins->nC4Speed) pins->nC4Speed = 8363; |
410 if (pis.C5Speed < 256) pins->nC4Speed = 256; | 545 //if (pis.C5Speed < 256) pins->nC4Speed = 256; |
411 pins->nVolume = pis.vol << 2; | 546 pins->nVolume = pis.vol << 2; |
412 if (pins->nVolume > 256) pins->nVolume = 256; | 547 if (pins->nVolume > 256) pins->nVolume = 256; |
413 pins->nGlobalVol = pis.gvl; | 548 pins->nGlobalVol = pis.gvl; |
414 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64; | 549 if (pins->nGlobalVol > 64) pins->nGlobalVol = 64; |
415 if (pis.flags & 0x10) pins->uFlags |= CHN_LOOP; | 550 if (pis.flags & 0x10) pins->uFlags |= CHN_LOOP; |
420 if (pins->nPan > 256) pins->nPan = 256; | 555 if (pins->nPan > 256) pins->nPan = 256; |
421 if (pis.dfp & 0x80) pins->uFlags |= CHN_PANNING; | 556 if (pis.dfp & 0x80) pins->uFlags |= CHN_PANNING; |
422 pins->nVibType = autovibit2xm[pis.vit & 7]; | 557 pins->nVibType = autovibit2xm[pis.vit & 7]; |
423 pins->nVibRate = pis.vis; | 558 pins->nVibRate = pis.vis; |
424 pins->nVibDepth = pis.vid & 0x7F; | 559 pins->nVibDepth = pis.vid & 0x7F; |
425 pins->nVibSweep = (pis.vir + 3) / 4; | 560 pins->nVibSweep = pis.vir; |
426 if ((pis.samplepointer) && (pis.samplepointer < dwMemLength) && (pis.length)) | 561 if ((pis.samplepointer) && (pis.samplepointer < dwMemLength) && (pis.length)) |
427 { | 562 { |
428 pins->nLength = pis.length; | 563 pins->nLength = pis.length; |
429 if (pins->nLength > MAX_SAMPLE_LENGTH) pins->nLength = MAX_SAMPLE_LENGTH; | 564 if (pins->nLength > MAX_SAMPLE_LENGTH) pins->nLength = MAX_SAMPLE_LENGTH; |
430 UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U; | 565 UINT flags = (pis.cvt & 1) ? RS_PCM8S : RS_PCM8U; |
451 for (UINT npat=0; npat<npatterns; npat++) | 586 for (UINT npat=0; npat<npatterns; npat++) |
452 { | 587 { |
453 if ((!patpos[npat]) || ((DWORD)patpos[npat] + 4 >= dwMemLength)) | 588 if ((!patpos[npat]) || ((DWORD)patpos[npat] + 4 >= dwMemLength)) |
454 { | 589 { |
455 PatternSize[npat] = 64; | 590 PatternSize[npat] = 64; |
591 PatternAllocSize[npat] = 64; | |
456 Patterns[npat] = AllocatePattern(64, m_nChannels); | 592 Patterns[npat] = AllocatePattern(64, m_nChannels); |
457 continue; | 593 continue; |
458 } | 594 } |
459 | 595 |
460 UINT len = bswapLE16(*((WORD *)(lpStream+patpos[npat]))); | 596 UINT len = bswapLE16(*((WORD *)(lpStream+patpos[npat]))); |
461 UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[npat]+2))); | 597 UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[npat]+2))); |
462 if ((rows < 4) || (rows > 256)) continue; | 598 if ((rows < 4) || (rows > 256)) continue; |
463 if (patpos[npat]+8+len > dwMemLength) continue; | 599 if (patpos[npat]+8+len > dwMemLength) continue; |
464 PatternSize[npat] = rows; | 600 PatternSize[npat] = rows; |
601 PatternAllocSize[npat] = rows; | |
465 if ((Patterns[npat] = AllocatePattern(rows, m_nChannels)) == NULL) continue; | 602 if ((Patterns[npat] = AllocatePattern(rows, m_nChannels)) == NULL) continue; |
466 memset(lastvalue, 0, sizeof(lastvalue)); | 603 memset(lastvalue, 0, sizeof(lastvalue)); |
467 memset(chnmask, 0, sizeof(chnmask)); | 604 memset(chnmask, 0, sizeof(chnmask)); |
468 MODCOMMAND *m = Patterns[npat]; | 605 MODCOMMAND *m = Patterns[npat]; |
469 UINT i = 0; | 606 UINT i = 0; |
549 // 115-124: Pitch Slide Down | 686 // 115-124: Pitch Slide Down |
550 if (vol < 125) { m[ch].volcmd = VOLCMD_PORTAUP; m[ch].vol = vol - 115; } else | 687 if (vol < 125) { m[ch].volcmd = VOLCMD_PORTAUP; m[ch].vol = vol - 115; } else |
551 // 193-202: Portamento To | 688 // 193-202: Portamento To |
552 if ((vol >= 193) && (vol <= 202)) { m[ch].volcmd = VOLCMD_TONEPORTAMENTO; m[ch].vol = vol - 193; } else | 689 if ((vol >= 193) && (vol <= 202)) { m[ch].volcmd = VOLCMD_TONEPORTAMENTO; m[ch].vol = vol - 193; } else |
553 // 203-212: Vibrato | 690 // 203-212: Vibrato |
554 if ((vol >= 203) && (vol <= 212)) { m[ch].volcmd = VOLCMD_VIBRATOSPEED; m[ch].vol = vol - 203; } | 691 if ((vol >= 203) && (vol <= 212)) { m[ch].volcmd = VOLCMD_VIBRATO; m[ch].vol = vol - 203; } |
555 lastvalue[ch].volcmd = m[ch].volcmd; | 692 lastvalue[ch].volcmd = m[ch].volcmd; |
556 lastvalue[ch].vol = m[ch].vol; | 693 lastvalue[ch].vol = m[ch].vol; |
557 } | 694 } |
558 } | 695 } |
559 // Reading command/param | 696 // Reading command/param |
590 } | 727 } |
591 | 728 |
592 | 729 |
593 #ifndef MODPLUG_NO_FILESAVE | 730 #ifndef MODPLUG_NO_FILESAVE |
594 //#define SAVEITTIMESTAMP | 731 //#define SAVEITTIMESTAMP |
732 | |
733 #ifdef MSC_VER | |
595 #pragma warning(disable:4100) | 734 #pragma warning(disable:4100) |
596 | 735 #endif |
736 | |
737 #if 0 | |
597 BOOL CSoundFile::SaveIT(LPCSTR lpszFileName, UINT nPacking) | 738 BOOL CSoundFile::SaveIT(LPCSTR lpszFileName, UINT nPacking) |
598 //--------------------------------------------------------- | 739 //--------------------------------------------------------- |
599 { | 740 { |
600 DWORD dwPatNamLen, dwChnNamLen; | 741 DWORD dwPatNamLen, dwChnNamLen; |
601 ITFILEHEADER header, writeheader; | 742 ITFILEHEADER header; |
602 ITINSTRUMENT iti, writeiti; | 743 ITINSTRUMENT iti; |
603 ITSAMPLESTRUCT itss; | 744 ITSAMPLESTRUCT itss; |
604 BYTE smpcount[MAX_SAMPLES]; | 745 BYTE smpcount[MAX_SAMPLES]; |
605 DWORD inspos[MAX_INSTRUMENTS]; | 746 DWORD inspos[MAX_INSTRUMENTS]; |
606 DWORD patpos[MAX_PATTERNS]; | 747 DWORD patpos[MAX_PATTERNS]; |
607 DWORD smppos[MAX_SAMPLES]; | 748 DWORD smppos[MAX_SAMPLES]; |
619 memset(smppos, 0, sizeof(smppos)); | 760 memset(smppos, 0, sizeof(smppos)); |
620 // Writing Header | 761 // Writing Header |
621 memset(&header, 0, sizeof(header)); | 762 memset(&header, 0, sizeof(header)); |
622 dwPatNamLen = 0; | 763 dwPatNamLen = 0; |
623 dwChnNamLen = 0; | 764 dwChnNamLen = 0; |
624 header.id = 0x4D504D49; // IMPM | 765 header.id = 0x4D504D49; |
625 lstrcpyn((char *)header.songname, m_szNames[0], 27); | 766 lstrcpyn(header.songname, m_szNames[0], 27); |
626 header.reserved1 = 0x1004; | 767 header.hilight_minor = m_rowHighlightMinor; |
768 header.hilight_major = m_rowHighlightMajor; | |
627 header.ordnum = 0; | 769 header.ordnum = 0; |
628 while ((header.ordnum < MAX_ORDERS) && (Order[header.ordnum] < 0xFF)) header.ordnum++; | 770 while ((header.ordnum < MAX_ORDERS) && (Order[header.ordnum] < 0xFF)) header.ordnum++; |
629 if (header.ordnum < MAX_ORDERS) Order[header.ordnum++] = 0xFF; | 771 if (header.ordnum < MAX_ORDERS) Order[header.ordnum++] = 0xFF; |
630 header.insnum = m_nInstruments; | 772 header.insnum = m_nInstruments; |
631 header.smpnum = m_nSamples; | 773 header.smpnum = m_nSamples; |
633 while ((header.patnum > 0) && (!Patterns[header.patnum-1])) header.patnum--; | 775 while ((header.patnum > 0) && (!Patterns[header.patnum-1])) header.patnum--; |
634 header.cwtv = 0x217; | 776 header.cwtv = 0x217; |
635 header.cmwt = 0x200; | 777 header.cmwt = 0x200; |
636 header.flags = 0x0001; | 778 header.flags = 0x0001; |
637 header.special = 0x0006; | 779 header.special = 0x0006; |
638 if (m_nInstruments) header.flags |= 0x04; | 780 if (m_dwSongFlags & SONG_INSTRUMENTMODE) header.flags |= 0x04; |
639 if (m_dwSongFlags & SONG_LINEARSLIDES) header.flags |= 0x08; | 781 if (m_dwSongFlags & SONG_LINEARSLIDES) header.flags |= 0x08; |
640 if (m_dwSongFlags & SONG_ITOLDEFFECTS) header.flags |= 0x10; | 782 if (m_dwSongFlags & SONG_ITOLDEFFECTS) header.flags |= 0x10; |
641 if (m_dwSongFlags & SONG_ITCOMPATMODE) header.flags |= 0x20; | 783 if (m_dwSongFlags & SONG_ITCOMPATMODE) header.flags |= 0x20; |
642 if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000; | 784 if (m_dwSongFlags & SONG_EXFILTERRANGE) header.flags |= 0x1000; |
643 header.globalvol = m_nDefaultGlobalVolume >> 1; | 785 header.globalvol = m_nDefaultGlobalVolume >> 1; |
644 header.mv = m_nSongPreAmp; | 786 header.mv = m_nSongPreAmp; |
645 // clip song pre-amp values (between 0x20 and 0x7f) | |
646 if (header.mv < 0x20) header.mv = 0x20; | |
647 if (header.mv > 0x7F) header.mv = 0x7F; | |
648 header.speed = m_nDefaultSpeed; | 787 header.speed = m_nDefaultSpeed; |
649 header.tempo = m_nDefaultTempo; | 788 header.tempo = m_nDefaultTempo; |
650 header.sep = m_nStereoSeparation; | 789 header.sep = m_nStereoSeparation; |
651 dwHdrPos = sizeof(header) + header.ordnum; | 790 dwHdrPos = sizeof(header) + header.ordnum; |
652 // Channel Pan and Volume | 791 // Channel Pan and Volume |
689 header.special |= 1; | 828 header.special |= 1; |
690 header.msglength = strlen(m_lpszSongComments)+1; | 829 header.msglength = strlen(m_lpszSongComments)+1; |
691 header.msgoffset = dwHdrPos + dwExtra + header.insnum*4 + header.patnum*4 + header.smpnum*4; | 830 header.msgoffset = dwHdrPos + dwExtra + header.insnum*4 + header.patnum*4 + header.smpnum*4; |
692 } | 831 } |
693 // Write file header | 832 // Write file header |
694 memcpy(writeheader, header, sizeof(header)); | 833 fwrite(&header, 1, sizeof(header), f); |
695 | |
696 // Byteswap header information | |
697 writeheader.id = bswapLE32(writeheader.id); | |
698 writeheader.reserved1 = bswapLE16(writeheader.reserved1); | |
699 writeheader.ordnum = bswapLE16(writeheader.ordnum); | |
700 writeheader.insnum = bswapLE16(writeheader.insnum); | |
701 writeheader.smpnum = bswapLE16(writeheader.smpnum); | |
702 writeheader.patnum = bswapLE16(writeheader.patnum); | |
703 writeheader.cwtv = bswapLE16(writeheader.cwtv); | |
704 writeheader.cmwt = bswapLE16(writeheader.cmwt); | |
705 writeheader.flags = bswapLE16(writeheader.flags); | |
706 writeheader.special = bswapLE16(writeheader.special); | |
707 writeheader.msglength = bswapLE16(writeheader.msglength); | |
708 writeheader.msgoffset = bswapLE32(writeheader.msgoffset); | |
709 writeheader.reserved2 = bswapLE32(writeheader.reserved2); | |
710 | |
711 fwrite(&writeheader, 1, sizeof(writeheader), f); | |
712 | |
713 fwrite(Order, 1, header.ordnum, f); | 834 fwrite(Order, 1, header.ordnum, f); |
714 if (header.insnum) fwrite(inspos, 4, header.insnum, f); | 835 if (header.insnum) fwrite(inspos, 4, header.insnum, f); |
715 if (header.smpnum) fwrite(smppos, 4, header.smpnum, f); | 836 if (header.smpnum) fwrite(smppos, 4, header.smpnum, f); |
716 if (header.patnum) fwrite(patpos, 4, header.patnum, f); | 837 if (header.patnum) fwrite(patpos, 4, header.patnum, f); |
717 // Writing editor history information | 838 // Writing editor history information |
738 fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f); | 859 fwrite(&m_MidiCfg, 1, sizeof(MODMIDICFG), f); |
739 } | 860 } |
740 // Writing pattern names | 861 // Writing pattern names |
741 if (dwPatNamLen) | 862 if (dwPatNamLen) |
742 { | 863 { |
743 DWORD d = bswapLE32(0x4d414e50); | 864 DWORD d = 0x4d414e50; |
744 UINT len= bswapLE32(dwPatNamLen); | |
745 fwrite(&d, 1, 4, f); | 865 fwrite(&d, 1, 4, f); |
746 write(&len, 1, 4, f); | 866 fwrite(&dwPatNamLen, 1, 4, f); |
747 fwrite(m_lpszPatternNames, 1, dwPatNamLen, f); | 867 fwrite(m_lpszPatternNames, 1, dwPatNamLen, f); |
748 } | 868 } |
749 // Writing channel Names | 869 // Writing channel Names |
750 if (dwChnNamLen) | 870 if (dwChnNamLen) |
751 { | 871 { |
752 DWORD d = bswapLE32(0x4d414e43); | 872 DWORD d = 0x4d414e43; |
753 UINT len= bswapLE32(dwChnNamLen); | |
754 fwrite(&d, 1, 4, f); | 873 fwrite(&d, 1, 4, f); |
755 fwrite(&len, 1, 4, f); | 874 fwrite(&dwChnNamLen, 1, 4, f); |
756 UINT nChnNames = dwChnNamLen / MAX_CHANNELNAME; | 875 UINT nChnNames = dwChnNamLen / MAX_CHANNELNAME; |
757 for (UINT inam=0; inam<nChnNames; inam++) | 876 for (UINT inam=0; inam<nChnNames; inam++) |
758 { | 877 { |
759 fwrite(ChnSettings[inam].szName, 1, MAX_CHANNELNAME, f); | 878 fwrite(ChnSettings[inam].szName, 1, MAX_CHANNELNAME, f); |
760 } | 879 } |
787 iti.dct = penv->nDCT; | 906 iti.dct = penv->nDCT; |
788 iti.dca = penv->nDNA; | 907 iti.dca = penv->nDNA; |
789 iti.fadeout = penv->nFadeOut >> 5; | 908 iti.fadeout = penv->nFadeOut >> 5; |
790 iti.pps = penv->nPPS; | 909 iti.pps = penv->nPPS; |
791 iti.ppc = penv->nPPC; | 910 iti.ppc = penv->nPPC; |
792 iti.gbv = (BYTE)(penv->nGlobalVol << 1); | 911 iti.gbv = (BYTE)penv->nGlobalVol; |
793 iti.dfp = (BYTE)penv->nPan >> 2; | 912 iti.dfp = (BYTE)penv->nPan >> 2; |
794 if (!(penv->dwFlags & ENV_SETPANNING)) iti.dfp |= 0x80; | 913 if (!(penv->dwFlags & ENV_SETPANNING)) iti.dfp |= 0x80; |
795 iti.rv = penv->nVolSwing; | 914 iti.rv = penv->nVolSwing; |
796 iti.rp = penv->nPanSwing; | 915 iti.rp = penv->nPanSwing; |
797 iti.ifc = penv->nIFC; | 916 iti.ifc = penv->nIFC; |
811 // Writing Volume envelope | 930 // Writing Volume envelope |
812 if (penv->dwFlags & ENV_VOLUME) iti.volenv.flags |= 0x01; | 931 if (penv->dwFlags & ENV_VOLUME) iti.volenv.flags |= 0x01; |
813 if (penv->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02; | 932 if (penv->dwFlags & ENV_VOLLOOP) iti.volenv.flags |= 0x02; |
814 if (penv->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04; | 933 if (penv->dwFlags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04; |
815 if (penv->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08; | 934 if (penv->dwFlags & ENV_VOLCARRY) iti.volenv.flags |= 0x08; |
816 iti.volenv.num = (BYTE)penv->nVolEnv; | 935 iti.volenv.num = (BYTE)penv->VolEnv.nNodes; |
817 iti.volenv.lpb = (BYTE)penv->nVolLoopStart; | 936 iti.volenv.lpb = (BYTE)penv->VolEnv.nLoopStart; |
818 iti.volenv.lpe = (BYTE)penv->nVolLoopEnd; | 937 iti.volenv.lpe = (BYTE)penv->VolEnv.nLoopEnd; |
819 iti.volenv.slb = penv->nVolSustainBegin; | 938 iti.volenv.slb = penv->VolEnv.nSustainStart; |
820 iti.volenv.sle = penv->nVolSustainEnd; | 939 iti.volenv.sle = penv->VolEnv.nSustainEnd; |
821 // Writing Panning envelope | 940 // Writing Panning envelope |
822 if (penv->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01; | 941 if (penv->dwFlags & ENV_PANNING) iti.panenv.flags |= 0x01; |
823 if (penv->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02; | 942 if (penv->dwFlags & ENV_PANLOOP) iti.panenv.flags |= 0x02; |
824 if (penv->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04; | 943 if (penv->dwFlags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04; |
825 if (penv->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08; | 944 if (penv->dwFlags & ENV_PANCARRY) iti.panenv.flags |= 0x08; |
826 iti.panenv.num = (BYTE)penv->nPanEnv; | 945 iti.panenv.num = (BYTE)penv->PanEnv.nNodes; |
827 iti.panenv.lpb = (BYTE)penv->nPanLoopStart; | 946 iti.panenv.lpb = (BYTE)penv->PanEnv.nLoopStart; |
828 iti.panenv.lpe = (BYTE)penv->nPanLoopEnd; | 947 iti.panenv.lpe = (BYTE)penv->PanEnv.nLoopEnd; |
829 iti.panenv.slb = penv->nPanSustainBegin; | 948 iti.panenv.slb = penv->PanEnv.nSustainStart; |
830 iti.panenv.sle = penv->nPanSustainEnd; | 949 iti.panenv.sle = penv->PanEnv.nSustainEnd; |
831 // Writing Pitch Envelope | 950 // Writing Pitch Envelope |
832 if (penv->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01; | 951 if (penv->dwFlags & ENV_PITCH) iti.pitchenv.flags |= 0x01; |
833 if (penv->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02; | 952 if (penv->dwFlags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02; |
834 if (penv->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04; | 953 if (penv->dwFlags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04; |
835 if (penv->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08; | 954 if (penv->dwFlags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08; |
836 if (penv->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80; | 955 if (penv->dwFlags & ENV_FILTER) iti.pitchenv.flags |= 0x80; |
837 iti.pitchenv.num = (BYTE)penv->nPitchEnv; | 956 iti.pitchenv.num = (BYTE)penv->PitchEnv.nNodes; |
838 iti.pitchenv.lpb = (BYTE)penv->nPitchLoopStart; | 957 iti.pitchenv.lpb = (BYTE)penv->PitchEnv.nLoopStart; |
839 iti.pitchenv.lpe = (BYTE)penv->nPitchLoopEnd; | 958 iti.pitchenv.lpe = (BYTE)penv->PitchEnv.nLoopEnd; |
840 iti.pitchenv.slb = (BYTE)penv->nPitchSustainBegin; | 959 iti.pitchenv.slb = (BYTE)penv->PitchEnv.nSustainStart; |
841 iti.pitchenv.sle = (BYTE)penv->nPitchSustainEnd; | 960 iti.pitchenv.sle = (BYTE)penv->PitchEnv.nSustainEnd; |
842 // Writing Envelopes data | 961 // Writing Envelopes data |
843 for (UINT ev=0; ev<25; ev++) | 962 for (UINT ev=0; ev<25; ev++) |
844 { | 963 { |
845 iti.volenv.data[ev*3] = penv->VolEnv[ev]; | 964 iti.volenv.data[ev*3] = penv->VolEnv.Values[ev]; |
846 iti.volenv.data[ev*3+1] = penv->VolPoints[ev] & 0xFF; | 965 iti.volenv.data[ev*3+1] = penv->VolEnv.Ticks[ev] & 0xFF; |
847 iti.volenv.data[ev*3+2] = penv->VolPoints[ev] >> 8; | 966 iti.volenv.data[ev*3+2] = penv->VolEnv.Ticks[ev] >> 8; |
848 iti.panenv.data[ev*3] = penv->PanEnv[ev] - 32; | 967 iti.panenv.data[ev*3] = penv->PanEnv.Values[ev] - 32; |
849 iti.panenv.data[ev*3+1] = penv->PanPoints[ev] & 0xFF; | 968 iti.panenv.data[ev*3+1] = penv->PanEnv.Ticks[ev] & 0xFF; |
850 iti.panenv.data[ev*3+2] = penv->PanPoints[ev] >> 8; | 969 iti.panenv.data[ev*3+2] = penv->PanEnv.Ticks[ev] >> 8; |
851 iti.pitchenv.data[ev*3] = penv->PitchEnv[ev] - 32; | 970 iti.pitchenv.data[ev*3] = penv->PitchEnv.Values[ev] - 32; |
852 iti.pitchenv.data[ev*3+1] = penv->PitchPoints[ev] & 0xFF; | 971 iti.pitchenv.data[ev*3+1] = penv->PitchEnv.Ticks[ev] & 0xFF; |
853 iti.pitchenv.data[ev*3+2] = penv->PitchPoints[ev] >> 8; | 972 iti.pitchenv.data[ev*3+2] = penv->PitchEnv.Ticks[ev] >> 8; |
854 } | 973 } |
855 } else | 974 } else |
856 // Save Empty Instrument | 975 // Save Empty Instrument |
857 { | 976 { |
858 for (UINT i=0; i<120; i++) iti.keyboard[i*2] = i; | 977 for (UINT i=0; i<120; i++) iti.keyboard[i*2] = i; |
863 } | 982 } |
864 if (!iti.nos) iti.trkvers = 0; | 983 if (!iti.nos) iti.trkvers = 0; |
865 // Writing instrument | 984 // Writing instrument |
866 inspos[nins-1] = dwPos; | 985 inspos[nins-1] = dwPos; |
867 dwPos += sizeof(ITINSTRUMENT); | 986 dwPos += sizeof(ITINSTRUMENT); |
868 | 987 fwrite(&iti, 1, sizeof(ITINSTRUMENT), f); |
869 memcpy(&writeiti, &iti, sizeof(ITINSTRUMENT)); | |
870 | |
871 writeiti.fadeout = bswapLE16(writeiti.fadeout); | |
872 writeiti.id = bswapLE32(writeiti.id); | |
873 writeiti.trkvers = bswapLE16(writeiti.trkvers); | |
874 writeiti.mbank = bswapLE16(writeiti.mbank); | |
875 | |
876 fwrite(&writeiti, 1, sizeof(ITINSTRUMENT), f); | |
877 } | 988 } |
878 // Writing sample headers | 989 // Writing sample headers |
879 memset(&itss, 0, sizeof(itss)); | 990 memset(&itss, 0, sizeof(itss)); |
880 for (UINT hsmp=0; hsmp<header.smpnum; hsmp++) | 991 for (UINT hsmp=0; hsmp<header.smpnum; hsmp++) |
881 { | 992 { |
889 DWORD dwPatPos = dwPos; | 1000 DWORD dwPatPos = dwPos; |
890 UINT len; | 1001 UINT len; |
891 if (!Patterns[npat]) continue; | 1002 if (!Patterns[npat]) continue; |
892 patpos[npat] = dwPos; | 1003 patpos[npat] = dwPos; |
893 patinfo[0] = 0; | 1004 patinfo[0] = 0; |
894 patinfo[1] = bswapLE16(PatternSize[npat]); | 1005 patinfo[1] = PatternSize[npat]; |
895 patinfo[2] = 0; | 1006 patinfo[2] = 0; |
896 patinfo[3] = 0; | 1007 patinfo[3] = 0; |
897 // Check for empty pattern | 1008 // Check for empty pattern |
898 if (PatternSize[npat] == 64) | 1009 if (PatternSize[npat] == 64) |
899 { | 1010 { |
900 MODCOMMAND *pzc = Patterns[npat]; | 1011 MODCOMMAND *pzc = Patterns[npat]; |
901 UINT nz = PatternSize[npat] * m_nChannels; | 1012 UINT nz = PatternSize[npat] * m_nChannels; |
902 for (UINT iz=0; iz<nz; iz++) | 1013 UINT iz; |
1014 for (iz=0; iz<nz; iz++) | |
903 { | 1015 { |
904 if ((pzc[iz].note) || (pzc[iz].instr) | 1016 if ((pzc[iz].note) || (pzc[iz].instr) |
905 || (pzc[iz].volcmd) || (pzc[iz].command)) break; | 1017 || (pzc[iz].volcmd) || (pzc[iz].command)) break; |
906 } | 1018 } |
907 if (iz == nz) | 1019 if (iz == nz) |
924 UINT command = m->command; | 1036 UINT command = m->command; |
925 UINT param = m->param; | 1037 UINT param = m->param; |
926 UINT vol = 0xFF; | 1038 UINT vol = 0xFF; |
927 UINT note = m->note; | 1039 UINT note = m->note; |
928 if (note) b |= 1; | 1040 if (note) b |= 1; |
929 if ((note) && (note < 0x80)) note--; // 0xfe->0x80 --Toad | 1041 if ((note) && (note < 0x80)) note--; |
930 if (m->instr) b |= 2; | 1042 if (m->instr) b |= 2; |
931 if (m->volcmd) | 1043 if (m->volcmd) |
932 { | 1044 { |
933 UINT volcmd = m->volcmd; | 1045 UINT volcmd = m->volcmd; |
934 switch(volcmd) | 1046 switch(volcmd) |
937 case VOLCMD_PANNING: vol = m->vol + 128; if (vol > 192) vol = 192; break; | 1049 case VOLCMD_PANNING: vol = m->vol + 128; if (vol > 192) vol = 192; break; |
938 case VOLCMD_VOLSLIDEUP: vol = 85 + ConvertVolParam(m->vol); break; | 1050 case VOLCMD_VOLSLIDEUP: vol = 85 + ConvertVolParam(m->vol); break; |
939 case VOLCMD_VOLSLIDEDOWN: vol = 95 + ConvertVolParam(m->vol); break; | 1051 case VOLCMD_VOLSLIDEDOWN: vol = 95 + ConvertVolParam(m->vol); break; |
940 case VOLCMD_FINEVOLUP: vol = 65 + ConvertVolParam(m->vol); break; | 1052 case VOLCMD_FINEVOLUP: vol = 65 + ConvertVolParam(m->vol); break; |
941 case VOLCMD_FINEVOLDOWN: vol = 75 + ConvertVolParam(m->vol); break; | 1053 case VOLCMD_FINEVOLDOWN: vol = 75 + ConvertVolParam(m->vol); break; |
942 case VOLCMD_VIBRATOSPEED: vol = 203 + ConvertVolParam(m->vol); break; | 1054 case VOLCMD_VIBRATOSPEED: vol = 203; break; |
943 case VOLCMD_VIBRATO: vol = 203; break; | 1055 case VOLCMD_VIBRATO: vol = 203 + ConvertVolParam(m->vol); break; |
944 case VOLCMD_TONEPORTAMENTO: vol = 193 + ConvertVolParam(m->vol); break; | 1056 case VOLCMD_TONEPORTAMENTO: vol = 193 + ConvertVolParam(m->vol); break; |
945 case VOLCMD_PORTADOWN: vol = 105 + ConvertVolParam(m->vol); break; | 1057 case VOLCMD_PORTADOWN: vol = 105 + ConvertVolParam(m->vol); break; |
946 case VOLCMD_PORTAUP: vol = 115 + ConvertVolParam(m->vol); break; | 1058 case VOLCMD_PORTAUP: vol = 115 + ConvertVolParam(m->vol); break; |
947 default: vol = 0xFF; | 1059 default: vol = 0xFF; |
948 } | 1060 } |
1032 dwPos += len; | 1144 dwPos += len; |
1033 patinfo[0] += len; | 1145 patinfo[0] += len; |
1034 fwrite(buf, 1, len, f); | 1146 fwrite(buf, 1, len, f); |
1035 } | 1147 } |
1036 fseek(f, dwPatPos, SEEK_SET); | 1148 fseek(f, dwPatPos, SEEK_SET); |
1037 patinfo[0] = bswapLE16(patinfo[0]); // byteswap -- Toad | |
1038 fwrite(patinfo, 8, 1, f); | 1149 fwrite(patinfo, 8, 1, f); |
1039 fseek(f, dwPos, SEEK_SET); | 1150 fseek(f, dwPos, SEEK_SET); |
1040 } | 1151 } |
1041 // Writing Sample Data | 1152 // Writing Sample Data |
1042 for (UINT nsmp=1; nsmp<=header.smpnum; nsmp++) | 1153 for (UINT nsmp=1; nsmp<=header.smpnum; nsmp++) |
1045 memset(&itss, 0, sizeof(itss)); | 1156 memset(&itss, 0, sizeof(itss)); |
1046 memcpy(itss.filename, psmp->name, 12); | 1157 memcpy(itss.filename, psmp->name, 12); |
1047 memcpy(itss.name, m_szNames[nsmp], 26); | 1158 memcpy(itss.name, m_szNames[nsmp], 26); |
1048 itss.id = 0x53504D49; | 1159 itss.id = 0x53504D49; |
1049 itss.gvl = (BYTE)psmp->nGlobalVol; | 1160 itss.gvl = (BYTE)psmp->nGlobalVol; |
1050 if (m_nInstruments) | 1161 if (m_dwSongFlags & SONG_INSTRUMENTMODE) |
1051 { | 1162 { |
1052 for (UINT iu=1; iu<=m_nInstruments; iu++) if (Headers[iu]) | 1163 for (UINT iu=1; iu<=m_nInstruments; iu++) if (Headers[iu]) |
1053 { | 1164 { |
1054 INSTRUMENTHEADER *penv = Headers[iu]; | 1165 INSTRUMENTHEADER *penv = Headers[iu]; |
1055 for (UINT ju=0; ju<128; ju++) if (penv->Keyboard[ju] == nsmp) | 1166 for (UINT ju=0; ju<128; ju++) if (penv->Keyboard[ju] == nsmp) |
1065 if (psmp->uFlags & CHN_LOOP) itss.flags |= 0x10; | 1176 if (psmp->uFlags & CHN_LOOP) itss.flags |= 0x10; |
1066 if (psmp->uFlags & CHN_SUSTAINLOOP) itss.flags |= 0x20; | 1177 if (psmp->uFlags & CHN_SUSTAINLOOP) itss.flags |= 0x20; |
1067 if (psmp->uFlags & CHN_PINGPONGLOOP) itss.flags |= 0x40; | 1178 if (psmp->uFlags & CHN_PINGPONGLOOP) itss.flags |= 0x40; |
1068 if (psmp->uFlags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80; | 1179 if (psmp->uFlags & CHN_PINGPONGSUSTAIN) itss.flags |= 0x80; |
1069 itss.C5Speed = psmp->nC4Speed; | 1180 itss.C5Speed = psmp->nC4Speed; |
1070 if (!itss.C5Speed) // if no C5Speed assume it is XM Sample | 1181 if (!itss.C5Speed) itss.C5Speed = 8363; |
1071 { | |
1072 UINT period; | |
1073 | |
1074 /** | |
1075 * C5 note => number 61, but in XM samples: | |
1076 * RealNote = Note + RelativeTone | |
1077 */ | |
1078 period = GetPeriodFromNote(61+psmp->RelativeTone, psmp->nFineTune, 0); | |
1079 | |
1080 if (period) | |
1081 itss.C5Speed = GetFreqFromPeriod(period, 0, 0); | |
1082 /** | |
1083 * If it didn`t work, it may not be a XM file; | |
1084 * so put the default C5Speed, 8363Hz. | |
1085 */ | |
1086 if (!itss.C5Speed) itss.C5Speed = 8363; | |
1087 } | |
1088 | |
1089 itss.length = psmp->nLength; | 1182 itss.length = psmp->nLength; |
1090 itss.loopbegin = psmp->nLoopStart; | 1183 itss.loopbegin = psmp->nLoopStart; |
1091 itss.loopend = psmp->nLoopEnd; | 1184 itss.loopend = psmp->nLoopEnd; |
1092 itss.susloopbegin = psmp->nSustainStart; | 1185 itss.susloopbegin = psmp->nSustainStart; |
1093 itss.susloopend = psmp->nSustainEnd; | 1186 itss.susloopend = psmp->nSustainEnd; |
1094 itss.vol = psmp->nVolume >> 2; | 1187 itss.vol = psmp->nVolume >> 2; |
1095 itss.dfp = psmp->nPan >> 2; | 1188 itss.dfp = psmp->nPan >> 2; |
1096 itss.vit = autovibxm2it[psmp->nVibType & 7]; | 1189 itss.vit = autovibxm2it[psmp->nVibType & 7]; |
1097 itss.vis = psmp->nVibRate; | 1190 itss.vis = psmp->nVibRate; |
1098 itss.vid = psmp->nVibDepth; | 1191 itss.vid = psmp->nVibDepth; |
1099 itss.vir = (psmp->nVibSweep < 64) ? psmp->nVibSweep * 4 : 255; | 1192 itss.vir = psmp->nVibSweep; |
1100 if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; | 1193 if (psmp->uFlags & CHN_PANNING) itss.dfp |= 0x80; |
1101 if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01; | 1194 if ((psmp->pSample) && (psmp->nLength)) itss.cvt = 0x01; |
1102 UINT flags = RS_PCM8S; | 1195 UINT flags = RS_PCM8S; |
1103 #ifndef NO_PACKING | 1196 #ifndef NO_PACKING |
1104 if (nPacking) | 1197 if (nPacking) |
1105 { | 1198 { |
1106 if ((!(psmp->uFlags & (CHN_16BIT|CHN_STEREO))) | 1199 if ((!(psmp->uFlags & (CHN_16BIT|CHN_STEREO))) |
1107 && (CanPackSample((char *)psmp->pSample, psmp->nLength, nPacking))) | 1200 && (CanPackSample(psmp->pSample, psmp->nLength, nPacking))) |
1108 { | 1201 { |
1109 flags = RS_ADPCM4; | 1202 flags = RS_ADPCM4; |
1110 itss.cvt = 0xFF; | 1203 itss.cvt = 0xFF; |
1111 } | 1204 } |
1112 } else | 1205 } else |
1123 flags = (psmp->uFlags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S; | 1216 flags = (psmp->uFlags & CHN_STEREO) ? RS_STPCM16S : RS_PCM16S; |
1124 } | 1217 } |
1125 } | 1218 } |
1126 itss.samplepointer = dwPos; | 1219 itss.samplepointer = dwPos; |
1127 fseek(f, smppos[nsmp-1], SEEK_SET); | 1220 fseek(f, smppos[nsmp-1], SEEK_SET); |
1128 | |
1129 itss.id = bswapLE32(itss.id); | |
1130 itss.length = bswapLE32(itss.length); | |
1131 itss.loopbegin = bswapLE32(itss.loopbegin); | |
1132 itss.loopend = bswapLE32(itss.loopend); | |
1133 itss.C5Speed = bswapLE32(itss.C5Speed); | |
1134 itss.susloopbegin = bswapLE32(itss.susloopbegin); | |
1135 itss.susloopend = bswapLE32(itss.susloopend); | |
1136 itss.samplepointer = bswapLE32(itss.samplepointer); | |
1137 | |
1138 fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f); | 1221 fwrite(&itss, 1, sizeof(ITSAMPLESTRUCT), f); |
1139 fseek(f, dwPos, SEEK_SET); | 1222 fseek(f, dwPos, SEEK_SET); |
1140 if ((psmp->pSample) && (psmp->nLength)) | 1223 if ((psmp->pSample) && (psmp->nLength)) |
1141 { | 1224 { |
1142 dwPos += WriteSample(f, psmp, flags); | 1225 dwPos += WriteSample(f, psmp, flags); |
1143 } | 1226 } |
1144 } | 1227 } |
1145 // Updating offsets | 1228 // Updating offsets |
1146 fseek(f, dwHdrPos, SEEK_SET); | 1229 fseek(f, dwHdrPos, SEEK_SET); |
1147 | |
1148 /* <Toad> Now we can byteswap them ;-) */ | |
1149 UINT WW; | |
1150 UINT WX; | |
1151 WX = (UINT)header.insnum; | |
1152 WX <<= 2; | |
1153 for (WW=0; WW < (WX>>2); WW++) | |
1154 inspos[WW] = bswapLE32(inspos[WW]); | |
1155 | |
1156 WX = (UINT)header.smpnum; | |
1157 WX <<= 2; | |
1158 for (WW=0; WW < (WX>>2); WW++) | |
1159 smppos[WW] = bswapLE32(smppos[WW]); | |
1160 | |
1161 WX=(UINT)header.patnum; | |
1162 WX <<= 2; | |
1163 for (WW=0; WW < (WX>>2); WW++) | |
1164 patpos[WW] = bswapLE32(patpos[WW]); | |
1165 | |
1166 if (header.insnum) fwrite(inspos, 4, header.insnum, f); | 1230 if (header.insnum) fwrite(inspos, 4, header.insnum, f); |
1167 if (header.smpnum) fwrite(smppos, 4, header.smpnum, f); | 1231 if (header.smpnum) fwrite(smppos, 4, header.smpnum, f); |
1168 if (header.patnum) fwrite(patpos, 4, header.patnum, f); | 1232 if (header.patnum) fwrite(patpos, 4, header.patnum, f); |
1169 fclose(f); | 1233 fclose(f); |
1170 return TRUE; | 1234 return TRUE; |
1171 } | 1235 } |
1172 | 1236 #endif |
1173 //#pragma warning(default:4100) | 1237 |
1238 #ifdef MSC_VER | |
1239 #pragma warning(default:4100) | |
1240 #endif | |
1241 | |
1174 #endif // MODPLUG_NO_FILESAVE | 1242 #endif // MODPLUG_NO_FILESAVE |
1175 | 1243 |
1176 ////////////////////////////////////////////////////////////////////////////// | 1244 ////////////////////////////////////////////////////////////////////////////// |
1177 // IT 2.14 compression | 1245 // IT 2.14 compression |
1178 | 1246 |
1372 UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate) | 1440 UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate) |
1373 //---------------------------------------------------- | 1441 //---------------------------------------------------- |
1374 { | 1442 { |
1375 DWORD chinfo[64]; | 1443 DWORD chinfo[64]; |
1376 CHAR s[32]; | 1444 CHAR s[32]; |
1377 DWORD nPluginSize, writeSwapDWORD; | 1445 DWORD nPluginSize; |
1378 SNDMIXPLUGININFO writePluginInfo; | |
1379 UINT nTotalSize = 0; | 1446 UINT nTotalSize = 0; |
1380 UINT nChInfo = 0; | 1447 UINT nChInfo = 0; |
1381 | 1448 |
1382 for (UINT i=0; i<MAX_MIXPLUGINS; i++) | 1449 for (UINT i=0; i<MAX_MIXPLUGINS; i++) |
1383 { | 1450 { |
1398 s[0] = 'F'; | 1465 s[0] = 'F'; |
1399 s[1] = 'X'; | 1466 s[1] = 'X'; |
1400 s[2] = '0' + (i/10); | 1467 s[2] = '0' + (i/10); |
1401 s[3] = '0' + (i%10); | 1468 s[3] = '0' + (i%10); |
1402 fwrite(s, 1, 4, f); | 1469 fwrite(s, 1, 4, f); |
1403 writeSwapDWORD = bswapLE32(nPluginSize); | 1470 fwrite(&nPluginSize, 1, 4, f); |
1404 fwrite(&writeSwapDWORD, 1, 4, f); | 1471 fwrite(&p->Info, 1, sizeof(SNDMIXPLUGININFO), f); |
1405 | 1472 fwrite(&m_MixPlugins[i].nPluginDataSize, 1, 4, f); |
1406 // Copy Information To Be Written for ByteSwapping | |
1407 memcpy(&writePluginInfo, &p->Info, sizeof(SNDMIXPLUGININFO)); | |
1408 writePluginInfo.dwPluginId1 = bswapLE32(p->Info.dwPluginId1); | |
1409 writePluginInfo.dwPluginId2 = bswapLE32(p->Info.dwPluginId2); | |
1410 writePluginInfo.dwInputRouting = bswapLE32(p->Info.dwInputRouting); | |
1411 writePluginInfo.dwOutputRouting = bswapLE32(p->Info.dwOutputRouting); | |
1412 for (UINT j=0; j<4; j++) | |
1413 { | |
1414 writePluginInfo.dwReserved[j] = bswapLE32(p->Info.dwReserved[j]); | |
1415 } | |
1416 | |
1417 fwrite(&writePluginInfo, 1, sizeof(SNDMIXPLUGININFO), f); | |
1418 writeSwapDWORD = bswapLE32(m_MixPlugins[i].nPluginDataSize); | |
1419 fwrite(&writeSwapDWORD, 1, 4, f); | |
1420 if (m_MixPlugins[i].pPluginData) | 1473 if (m_MixPlugins[i].pPluginData) |
1421 { | 1474 { |
1422 fwrite(m_MixPlugins[i].pPluginData, 1, m_MixPlugins[i].nPluginDataSize, f); | 1475 fwrite(m_MixPlugins[i].pPluginData, 1, m_MixPlugins[i].nPluginDataSize, f); |
1423 } | 1476 } |
1424 } | 1477 } |
1430 if (j < 64) | 1483 if (j < 64) |
1431 { | 1484 { |
1432 if ((chinfo[j] = ChnSettings[j].nMixPlugin) != 0) | 1485 if ((chinfo[j] = ChnSettings[j].nMixPlugin) != 0) |
1433 { | 1486 { |
1434 nChInfo = j+1; | 1487 nChInfo = j+1; |
1435 chinfo[j] = bswapLE32(chinfo[j]); // inplace BS | |
1436 } | 1488 } |
1437 } | 1489 } |
1438 } | 1490 } |
1439 if (nChInfo) | 1491 if (nChInfo) |
1440 { | 1492 { |
1441 if (f) | 1493 if (f) |
1442 { | 1494 { |
1443 nPluginSize = bswapLE32(0x58464843); | 1495 nPluginSize = 0x58464843; |
1444 fwrite(&nPluginSize, 1, 4, f); | 1496 fwrite(&nPluginSize, 1, 4, f); |
1445 nPluginSize = nChInfo*4; | 1497 nPluginSize = nChInfo*4; |
1446 writeSwapDWORD = bswapLE32(nPluginSize); | 1498 fwrite(&nPluginSize, 1, 4, f); |
1447 fwrite(&writeSwapDWORD, 1, 4, f); | |
1448 fwrite(chinfo, 1, nPluginSize, f); | 1499 fwrite(chinfo, 1, nPluginSize, f); |
1449 } | 1500 } |
1450 nTotalSize += nChInfo*4 + 8; | 1501 nTotalSize += nChInfo*4 + 8; |
1451 } | 1502 } |
1452 return nTotalSize; | 1503 return nTotalSize; |