1 /*
2 Copyright (c) 2009-2011 Tero Lindeman (kometbomb)
3
4 Permission is hereby granted, free of charge, to any person
5 obtaining a copy of this software and associated documentation
6 files (the "Software"), to deal in the Software without
7 restriction, including without limitation the rights to use,
8 copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the
10 Software is furnished to do so, subject to the following
11 conditions:
12
13 The above copyright notice and this permission notice shall be
14 included in all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 #include "xm.h"
27 #include "mod.h"
28 #include "edit.h"
29 #include "mused.h"
30 #include "event.h"
31 #include "SDL_endian.h"
32 #include "snd/freqs.h"
33 #include <assert.h>
34 #include <string.h>
35
36 extern Mused mused;
37
find_command_xm(Uint16 command)38 Uint16 find_command_xm(Uint16 command)
39 {
40 if ((command & 0xff00) == 0x0100 || (command & 0xff00) == 0x0200)
41 command = (command & 0xff00) | my_min(0xff, (command & 0xff)); // assuming linear xm freqs
42 else if ((command >> 8) == 'G')
43 command = MUS_FX_SET_GLOBAL_VOLUME | ((command & 0xff) * 2);
44 else if ((command >> 8) == 'H')
45 command = MUS_FX_FADE_GLOBAL_VOLUME | ((command & 0xff) * 2);
46 else command = find_command_pt(command, 0);
47
48 return command;
49 }
50
51
import_xm(FILE * f)52 int import_xm(FILE *f)
53 {
54 struct
55 {
56 char sig[17];
57 char name[20];
58 Uint8 _1a;
59 char tracker_name[20];
60 Uint16 version;
61 Uint32 header_size;
62 Uint16 song_length;
63 Uint16 restart_position;
64 Uint16 num_channels;
65 Uint16 num_patterns;
66 Uint16 num_instruments;
67 Uint16 flags;
68 Uint16 default_tempo;
69 Uint16 default_bpm;
70 Uint8 pattern_order[256];
71 } header;
72
73 fread(&header.sig[0], 1, sizeof(header.sig), f);
74 fread(&header.name[0], 1, sizeof(header.name), f);
75 fread(&header._1a, 1, sizeof(header._1a), f);
76 fread(&header.tracker_name[0], 1, sizeof(header.tracker_name), f);
77 fread(&header.version, 1, sizeof(header.version), f);
78
79 fread(&header.header_size, 1, sizeof(header.header_size), f);
80 fread(&header.song_length, 1, sizeof(header.song_length), f);
81 fread(&header.restart_position, 1, sizeof(header.restart_position), f);
82 fread(&header.num_channels, 1, sizeof(header.num_channels), f);
83 fread(&header.num_patterns, 1, sizeof(header.num_patterns), f);
84 fread(&header.num_instruments, 1, sizeof(header.num_instruments), f);
85 fread(&header.flags, 1, sizeof(header.flags), f);
86 fread(&header.default_tempo, 1, sizeof(header.default_tempo), f);
87 fread(&header.default_bpm, 1, sizeof(header.default_bpm), f);
88 fread(&header.pattern_order[0], 1, sizeof(header.pattern_order), f);
89
90 if (strncmp("Extended Module: ", header.sig, 17) != 0)
91 {
92 fatal("Not a FastTracker II module (sig: '%-17s')", header.sig);
93 return 0;
94 }
95
96 FIX_ENDIAN(header.version);
97 FIX_ENDIAN(header.header_size);
98 FIX_ENDIAN(header.song_length);
99 FIX_ENDIAN(header.restart_position);
100 FIX_ENDIAN(header.num_channels);
101 FIX_ENDIAN(header.num_instruments);
102 FIX_ENDIAN(header.num_patterns);
103 FIX_ENDIAN(header.flags);
104 FIX_ENDIAN(header.default_tempo);
105 FIX_ENDIAN(header.default_bpm);
106
107 if (header.version != 0x0104)
108 {
109 fatal("XM version 0x%x not supported", header.version);
110 return 0;
111 }
112
113 if ((int)header.num_channels * (int)header.num_patterns > NUM_PATTERNS)
114 {
115 fatal("Resulting song would have over %d patterns", NUM_PATTERNS);
116 return 0;
117 }
118
119 if ((int)header.num_channels * (int)header.song_length > NUM_SEQUENCES)
120 {
121 fatal("Resulting song would have over %d sequence patterns", NUM_SEQUENCES);
122 return 0;
123 }
124
125
126 int pattern_length[256];
127
128 for (int p = 0 ; p < header.num_patterns ; ++p)
129 {
130 struct
131 {
132 Uint32 header_length;
133 Uint8 packing_type;
134 Uint16 num_rows;
135 Uint16 data_size;
136 } pattern_hdr;
137
138 fread(&pattern_hdr.header_length, 1, sizeof(pattern_hdr.header_length), f);
139 fread(&pattern_hdr.packing_type, 1, sizeof(pattern_hdr.packing_type), f);
140 fread(&pattern_hdr.num_rows, 1, sizeof(pattern_hdr.num_rows), f);
141 fread(&pattern_hdr.data_size, 1, sizeof(pattern_hdr.data_size), f);
142
143 FIX_ENDIAN(pattern_hdr.data_size);
144 FIX_ENDIAN(pattern_hdr.num_rows);
145 FIX_ENDIAN(pattern_hdr.header_length);
146
147 pattern_length[p] = pattern_hdr.num_rows;
148
149 Uint8 data[256*32*5];
150
151 debug("num_rows = %d", pattern_hdr.num_rows);
152
153 fread(&data[0], 1, pattern_hdr.data_size, f);
154
155 for (int c = 0 ; c < header.num_channels ; ++c)
156 {
157 int pat = p * header.num_channels + c;
158 resize_pattern(&mused.song.pattern[pat], pattern_hdr.num_rows);
159 }
160
161 Uint8 *ptr = &data[0];
162
163 for (int r = 0 ; r < pattern_hdr.num_rows ; ++r)
164 {
165 for (int c = 0 ; c < header.num_channels ; ++c)
166 {
167 Uint8 note = *ptr++;
168 Uint8 instrument = 0, volume = 0, fx = 0, param = 0;
169
170 if (note & 0x80)
171 {
172 Uint8 flags = note;
173 note = 0;
174
175 if (flags & 1)
176 note = *ptr++;
177
178 if (flags & 2)
179 instrument = *ptr++;
180
181 if (flags & 4)
182 volume = *ptr++;
183
184 if (flags & 8)
185 fx = *ptr++;
186
187 if (flags & 16)
188 param = *ptr++;
189 }
190 else
191 {
192 instrument = *ptr++;
193 volume = *ptr++;
194 fx = *ptr++;
195 param = *ptr++;
196 }
197
198 int pat = p * header.num_channels + c;
199 MusStep *step = &mused.song.pattern[pat].step[r];
200 step->ctrl = 0;
201
202 if (note != 0 && note != 97)
203 step->note = note - 1;
204 else if (note == 97)
205 step->note = MUS_NOTE_RELEASE;
206 else
207 step->note = MUS_NOTE_NONE;
208
209 step->instrument = instrument != 0 ? instrument - 1 : MUS_NOTE_NO_INSTRUMENT;
210 step->volume = MUS_NOTE_NO_VOLUME;
211
212 if (volume >= 0x10 && volume <= 0x50)
213 step->volume = (volume - 0x10) * 2;
214 else if (volume >= 0x60 && volume <= 0x6f)
215 step->volume = MUS_NOTE_VOLUME_FADE_DN | (volume & 0xf);
216 else if (volume >= 0x70 && volume <= 0x7f)
217 step->volume = MUS_NOTE_VOLUME_FADE_UP | (volume & 0xf);
218 else if (volume >= 0xf0 && volume <= 0xff)
219 step->ctrl = MUS_CTRL_SLIDE|MUS_CTRL_LEGATO;
220 else if (volume >= 0xb0 && volume <= 0xbf)
221 step->ctrl = MUS_CTRL_VIB;
222
223 step->command = find_command_xm((fx << 8) | param);
224 }
225 }
226 }
227
228 int wt_e = 0;
229
230 for (int i = 0 ; i < header.num_instruments ; ++i)
231 {
232 struct {
233 Uint32 size;
234 char name[22];
235 Uint8 type;
236 Uint16 num_samples;
237 } instrument_hdr;
238
239 struct {
240 Uint32 size;
241 Uint8 sample[96];
242 Uint8 vol_env[48];
243 Uint8 pan_env[48];
244 Uint8 num_volume;
245 Uint8 num_panning;
246 Uint8 vol_sustain;
247 Uint8 vol_loop_start, vol_loop_end;
248 Uint8 pan_sustain;
249 Uint8 pan_loop_start, pan_loop_end;
250 Uint8 vol_type;
251 Uint8 pan_type;
252 Uint8 vib_type, vib_sweep, vib_depth, vib_rate;
253 Uint16 vol_fadeout;
254 Uint8 reserved[2];
255 } instrument_ext_hdr;
256
257 size_t si = ftell(f);
258 fread(&instrument_hdr.size, 1, sizeof(instrument_hdr.size), f);
259 fread(&instrument_hdr.name[0], 1, sizeof(instrument_hdr.name), f);
260 fread(&instrument_hdr.type, 1, sizeof(instrument_hdr.type), f);
261 fread(&instrument_hdr.num_samples, 1, sizeof(instrument_hdr.num_samples), f);
262
263 FIX_ENDIAN(instrument_hdr.size);
264 FIX_ENDIAN(instrument_hdr.num_samples);
265
266 if (instrument_hdr.num_samples > 0)
267 {
268 fread(&instrument_ext_hdr.size, 1, sizeof(instrument_ext_hdr.size), f);
269 fread(&instrument_ext_hdr.sample[0], 1, sizeof(instrument_ext_hdr.sample), f);
270 fread(&instrument_ext_hdr.vol_env[0], 1, sizeof(instrument_ext_hdr.vol_env), f);
271 fread(&instrument_ext_hdr.pan_env[0], 1, sizeof(instrument_ext_hdr.pan_env), f);
272 fread(&instrument_ext_hdr.num_volume, 1, sizeof(instrument_ext_hdr.num_volume), f);
273 fread(&instrument_ext_hdr.num_panning, 1, sizeof(instrument_ext_hdr.num_panning), f);
274 fread(&instrument_ext_hdr.vol_sustain, 1, sizeof(instrument_ext_hdr.vol_sustain), f);
275 fread(&instrument_ext_hdr.vol_loop_start, 1, sizeof(instrument_ext_hdr.vol_loop_start), f);
276 fread(&instrument_ext_hdr.vol_loop_end, 1, sizeof(instrument_ext_hdr.vol_loop_end), f);
277 fread(&instrument_ext_hdr.pan_sustain, 1, sizeof(instrument_ext_hdr.pan_sustain), f);
278 fread(&instrument_ext_hdr.pan_loop_start, 1, sizeof(instrument_ext_hdr.pan_loop_start), f);
279 fread(&instrument_ext_hdr.pan_loop_end, 1, sizeof(instrument_ext_hdr.pan_loop_end), f);
280 fread(&instrument_ext_hdr.vol_type, 1, sizeof(instrument_ext_hdr.vol_type), f);
281 fread(&instrument_ext_hdr.pan_type, 1, sizeof(instrument_ext_hdr.pan_type), f);
282 fread(&instrument_ext_hdr.vib_type, 1, sizeof(instrument_ext_hdr.vib_type), f);
283 fread(&instrument_ext_hdr.vib_sweep, 1, sizeof(instrument_ext_hdr.vib_sweep), f);
284 fread(&instrument_ext_hdr.vib_depth, 1, sizeof(instrument_ext_hdr.vib_depth), f);
285 fread(&instrument_ext_hdr.vib_rate, 1, sizeof(instrument_ext_hdr.vib_rate), f);
286 fread(&instrument_ext_hdr.vol_fadeout, 1, sizeof(instrument_ext_hdr.vol_fadeout), f);
287 fread(&instrument_ext_hdr.reserved[0], 1, sizeof(instrument_ext_hdr.reserved), f);
288
289 fseek(f, si + instrument_hdr.size, SEEK_SET);
290
291 FIX_ENDIAN(instrument_ext_hdr.vol_fadeout);
292
293 Uint32 first_length = 0, total_length = 0, type = 0;
294 Sint32 fine = 0, loop_begin = 0, loop_len = 0;
295
296 for (int s = 0 ; s < instrument_hdr.num_samples ; ++s)
297 {
298 struct
299 {
300 Uint32 sample_length;
301 Uint32 sample_loop_start;
302 Uint32 sample_loop_length;
303 Uint8 volume;
304 Sint8 finetune;
305 Uint8 type;
306 Uint8 panning;
307 Uint8 relative_note;
308 Uint8 reserved;
309 char name[22];
310 } sample_hdr;
311
312 fread(&sample_hdr.sample_length, 1, sizeof(sample_hdr.sample_length), f);
313 fread(&sample_hdr.sample_loop_start, 1, sizeof(sample_hdr.sample_loop_start), f);
314 fread(&sample_hdr.sample_loop_length, 1, sizeof(sample_hdr.sample_loop_length), f);
315 fread(&sample_hdr.volume, 1, sizeof(sample_hdr.volume), f);
316 fread(&sample_hdr.finetune, 1, sizeof(sample_hdr.finetune), f);
317 fread(&sample_hdr.type, 1, sizeof(sample_hdr.type), f);
318 fread(&sample_hdr.panning, 1, sizeof(sample_hdr.panning), f);
319 fread(&sample_hdr.relative_note, 1, sizeof(sample_hdr.relative_note), f);
320 fread(&sample_hdr.reserved, 1, sizeof(sample_hdr.reserved), f);
321 fread(&sample_hdr.name[0], 1, sizeof(sample_hdr.name), f);
322
323 FIX_ENDIAN(sample_hdr.sample_length);
324 FIX_ENDIAN(sample_hdr.sample_loop_start);
325 FIX_ENDIAN(sample_hdr.sample_loop_length);
326
327 total_length += sample_hdr.sample_length;
328
329 if (s > 0) continue; // read only first sample
330
331 first_length = sample_hdr.sample_length;
332 type = sample_hdr.type;
333
334 mused.song.instrument[i].volume = sample_hdr.volume * 2;
335 mused.song.instrument[i].base_note = MIDDLE_C + sample_hdr.relative_note;
336
337 fine = sample_hdr.finetune;
338
339 loop_begin = sample_hdr.sample_loop_start;
340 loop_len = sample_hdr.sample_loop_length;
341 }
342
343 if (first_length > 0)
344 {
345 Sint8 *smp = malloc(first_length);
346
347 fread(smp, 1, first_length, f);
348
349 if (type & 16)
350 {
351 debug("16-bit sample");
352
353 int x = 0;
354 for (int idx = 0 ; idx < first_length / 2 ; ++idx)
355 {
356 x += ((Uint16*)smp)[idx];
357 ((Uint16*)smp)[idx] = x;
358 }
359
360 cyd_wave_entry_init(&mused.mus.cyd->wavetable_entries[wt_e], smp, first_length / 2, CYD_WAVE_TYPE_SINT16, 1, 1, 1);
361 }
362 else
363 {
364 debug("8-bit sample");
365
366 int x = 0;
367 for (int idx = 0 ; idx < first_length ; ++idx)
368 {
369 x += smp[idx];
370 smp[idx] = x;
371 }
372
373 cyd_wave_entry_init(&mused.mus.cyd->wavetable_entries[wt_e], smp, first_length, CYD_WAVE_TYPE_SINT8, 1, 1, 1);
374 }
375
376 free(smp);
377
378 mused.mus.cyd->wavetable_entries[wt_e].loop_begin = loop_begin;
379 mused.mus.cyd->wavetable_entries[wt_e].loop_end = loop_begin + loop_len;
380
381 mused.mus.cyd->wavetable_entries[wt_e].loop_begin = my_min(mused.mus.cyd->wavetable_entries[wt_e].loop_begin, mused.mus.cyd->wavetable_entries[wt_e].samples - 1);
382 mused.mus.cyd->wavetable_entries[wt_e].loop_end = my_min(mused.mus.cyd->wavetable_entries[wt_e].loop_end, mused.mus.cyd->wavetable_entries[wt_e].samples);
383
384 mused.song.instrument[i].cydflags = CYD_CHN_ENABLE_WAVE | CYD_CHN_WAVE_OVERRIDE_ENV | CYD_CHN_ENABLE_KEY_SYNC;
385 mused.song.instrument[i].flags = MUS_INST_SET_PW | MUS_INST_SET_CUTOFF;
386 mused.song.instrument[i].vibrato_speed = instrument_ext_hdr.vib_rate;
387 mused.song.instrument[i].vibrato_depth = instrument_ext_hdr.vib_depth;
388 mused.song.instrument[i].vib_delay = instrument_ext_hdr.vib_sweep;
389
390 // from mod.c
391 mused.mus.cyd->wavetable_entries[wt_e].base_note = (MIDDLE_C << 8) - (Sint16)fine;
392 mused.mus.cyd->wavetable_entries[wt_e].sample_rate = 7093789.2/856;
393
394 switch (type & 3)
395 {
396 case 0: mused.mus.cyd->wavetable_entries[wt_e].flags &= ~CYD_WAVE_LOOP; break;
397 case 1: mused.mus.cyd->wavetable_entries[wt_e].flags |= CYD_WAVE_LOOP; break;
398 case 2: mused.mus.cyd->wavetable_entries[wt_e].flags |= CYD_WAVE_LOOP|CYD_WAVE_PINGPONG; break;
399 }
400
401 mused.song.instrument[i].wavetable_entry = wt_e++;
402
403 strncpy(mused.song.instrument[i].name, instrument_hdr.name, 22);
404 }
405
406 fseek(f, total_length - first_length, SEEK_CUR);
407 }
408 else
409 {
410 fseek(f, si + instrument_hdr.size, SEEK_SET);
411 }
412 }
413
414 int pos = 0;
415
416 for (int s = 0 ; s < header.song_length ; ++s)
417 {
418 if (s == header.restart_position)
419 mused.song.loop_point = pos;
420
421 for (int c = 0 ; c < header.num_channels ; ++c)
422 {
423 add_sequence(c, pos, header.pattern_order[s] * header.num_channels + c, 0);
424 }
425
426 pos += pattern_length[header.pattern_order[s]];
427 }
428
429 strncpy(mused.song.title, header.name, 20);
430 mused.song.song_length = pos;
431 mused.song.song_speed = mused.song.song_speed2 = header.default_tempo;
432 mused.song.song_rate = header.default_bpm * 50 / 125;
433 mused.song.num_channels = header.num_channels;
434 mused.sequenceview_steps = 64;
435 mused.song.num_patterns = header.num_patterns * header.num_channels;
436
437 return 1;
438 }
439