diff options
Diffstat (limited to 'apps/codecs/dumb/src/it/itread.c')
-rw-r--r-- | apps/codecs/dumb/src/it/itread.c | 1181 |
1 files changed, 1181 insertions, 0 deletions
diff --git a/apps/codecs/dumb/src/it/itread.c b/apps/codecs/dumb/src/it/itread.c new file mode 100644 index 0000000000..7384b30a92 --- /dev/null +++ b/apps/codecs/dumb/src/it/itread.c | |||
@@ -0,0 +1,1181 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * itread.c - Code to read an Impulse Tracker / / \ \ | ||
12 | * module from an open file. | < / \_ | ||
13 | * | \/ /\ / | ||
14 | * Based on the loader from an IT player by Bob. \_ / > / | ||
15 | * Adapted for DUMB by entheh. | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | #include <stdlib.h> | ||
21 | #include <string.h>//might not be necessary later; required for memset | ||
22 | |||
23 | #include "dumb.h" | ||
24 | #include "internal/it.h" | ||
25 | |||
26 | |||
27 | |||
28 | #define INVESTIGATE_OLD_INSTRUMENTS | ||
29 | |||
30 | |||
31 | |||
32 | static int it_seek(DUMBFILE *f, long offset) | ||
33 | { | ||
34 | long pos = dumbfile_pos(f); | ||
35 | |||
36 | if (pos > offset) | ||
37 | return -1; | ||
38 | |||
39 | if (pos < offset) | ||
40 | if (dumbfile_skip(f, offset - pos)) | ||
41 | return -1; | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | |||
47 | |||
48 | typedef unsigned char byte; | ||
49 | typedef unsigned short word; | ||
50 | typedef unsigned long dword; | ||
51 | |||
52 | |||
53 | |||
54 | static unsigned char *sourcebuf = NULL; | ||
55 | static unsigned char *sourcepos = NULL; | ||
56 | static unsigned char *sourceend; | ||
57 | static int rembits = 0; | ||
58 | |||
59 | |||
60 | |||
61 | static int readblock(DUMBFILE *f) | ||
62 | { | ||
63 | long size; | ||
64 | int c; | ||
65 | |||
66 | size = dumbfile_igetw(f); | ||
67 | if (size < 0) | ||
68 | return size; | ||
69 | |||
70 | sourcebuf = malloc(size); | ||
71 | if (!sourcebuf) | ||
72 | return -1; | ||
73 | |||
74 | c = dumbfile_getnc((char *)sourcebuf, size, f); | ||
75 | if (c < size) { | ||
76 | free(sourcebuf); | ||
77 | sourcebuf = NULL; | ||
78 | return -1; | ||
79 | } | ||
80 | |||
81 | sourcepos = sourcebuf; | ||
82 | sourceend = sourcebuf + size; | ||
83 | rembits = 8; | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | |||
88 | |||
89 | static void freeblock(void) | ||
90 | { | ||
91 | free(sourcebuf); | ||
92 | sourcebuf = NULL; | ||
93 | } | ||
94 | |||
95 | |||
96 | |||
97 | static int readbits(int bitwidth) | ||
98 | { | ||
99 | int val = 0; | ||
100 | int b = 0; | ||
101 | |||
102 | if (sourcepos >= sourceend) return val; | ||
103 | |||
104 | while (bitwidth > rembits) { | ||
105 | val |= *sourcepos++ << b; | ||
106 | if (sourcepos >= sourceend) return val; | ||
107 | b += rembits; | ||
108 | bitwidth -= rembits; | ||
109 | rembits = 8; | ||
110 | } | ||
111 | |||
112 | val |= (*sourcepos & ((1 << bitwidth) - 1)) << b; | ||
113 | *sourcepos >>= bitwidth; | ||
114 | rembits -= bitwidth; | ||
115 | |||
116 | return val; | ||
117 | } | ||
118 | |||
119 | |||
120 | |||
121 | /** WARNING - do we even need to pass `right`? */ | ||
122 | /** WARNING - why bother memsetting at all? The whole array is written... */ | ||
123 | // if we do memset, dumb_silence() would be neater... | ||
124 | static int decompress8(DUMBFILE *f, sample_t *left, sample_t *right, int len, int cmwt) | ||
125 | { | ||
126 | int blocklen, blockpos; | ||
127 | byte bitwidth; | ||
128 | word val; | ||
129 | char d1, d2; | ||
130 | |||
131 | memset(left, 0, len * sizeof(*left)); | ||
132 | if (right) { | ||
133 | memset(right, 0, len * sizeof(*right)); | ||
134 | len <<= 1; | ||
135 | } | ||
136 | |||
137 | while (len > 0) { | ||
138 | //Read a block of compressed data: | ||
139 | if (readblock(f)) | ||
140 | return -1; | ||
141 | //Set up a few variables | ||
142 | blocklen = (len < 0x8000) ? len : 0x8000; //Max block length is 0x8000 bytes | ||
143 | blockpos = 0; | ||
144 | bitwidth = 9; | ||
145 | d1 = d2 = 0; | ||
146 | //Start the decompression: | ||
147 | while (blockpos < blocklen) { | ||
148 | //Read a value: | ||
149 | val = (word)readbits(bitwidth); | ||
150 | //Check for bit width change: | ||
151 | |||
152 | if (bitwidth < 7) { //Method 1: | ||
153 | if (val == (1 << (bitwidth - 1))) { | ||
154 | val = (word)readbits(3) + 1; | ||
155 | bitwidth = (val < bitwidth) ? val : val + 1; | ||
156 | continue; | ||
157 | } | ||
158 | } | ||
159 | else if (bitwidth < 9) { //Method 2 | ||
160 | byte border = (0xFF >> (9 - bitwidth)) - 4; | ||
161 | |||
162 | if (val > border && val <= (border + 8)) { | ||
163 | val -= border; | ||
164 | bitwidth = (val < bitwidth) ? val : val + 1; | ||
165 | continue; | ||
166 | } | ||
167 | } | ||
168 | else if (bitwidth == 9) { //Method 3 | ||
169 | if (val & 0x100) { | ||
170 | bitwidth = (val + 1) & 0xFF; | ||
171 | continue; | ||
172 | } | ||
173 | } | ||
174 | else { //Illegal width, abort ? | ||
175 | freeblock(); | ||
176 | return -1; | ||
177 | } | ||
178 | |||
179 | //Expand the value to signed byte: | ||
180 | { | ||
181 | char v; //The sample value: | ||
182 | if (bitwidth < 8) { | ||
183 | byte shift = 8 - bitwidth; | ||
184 | v = (val << shift); | ||
185 | v >>= shift; | ||
186 | } | ||
187 | else | ||
188 | v = (char)val; | ||
189 | |||
190 | //And integrate the sample value | ||
191 | //(It always has to end with integration doesn't it ? ;-) | ||
192 | d1 += v; | ||
193 | d2 += d1; | ||
194 | } | ||
195 | |||
196 | //Store ! | ||
197 | /* Version 2.15 was an unofficial version with hacked compression | ||
198 | * code. Yay, better compression :D | ||
199 | */ | ||
200 | if (right && (len & 1)) | ||
201 | *right++ = (int)(signed char)(cmwt == 0x215 ? d2 : d1) << 16; | ||
202 | else | ||
203 | *left++ = (int)(signed char)(cmwt == 0x215 ? d2 : d1) << 16; | ||
204 | len--; | ||
205 | blockpos++; | ||
206 | } | ||
207 | freeblock(); | ||
208 | } | ||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | |||
213 | |||
214 | static int decompress16(DUMBFILE *f, sample_t *left, sample_t *right, int len, int cmwt) | ||
215 | { | ||
216 | int blocklen, blockpos; | ||
217 | byte bitwidth; | ||
218 | long val; | ||
219 | short d1, d2; | ||
220 | |||
221 | memset(left, 0, len * sizeof(*left)); | ||
222 | if (right) { | ||
223 | memset(right, 0, len * sizeof(*right)); | ||
224 | len <<= 1; | ||
225 | } | ||
226 | |||
227 | while (len > 0) { | ||
228 | //Read a block of compressed data: | ||
229 | if (readblock(f)) | ||
230 | return -1; | ||
231 | //Set up a few variables | ||
232 | blocklen = (len < 0x4000) ? len : 0x4000; // Max block length is 0x4000 bytes | ||
233 | blockpos = 0; | ||
234 | bitwidth = 17; | ||
235 | d1 = d2 = 0; | ||
236 | //Start the decompression: | ||
237 | while (blockpos < blocklen) { | ||
238 | val = readbits(bitwidth); | ||
239 | //Check for bit width change: | ||
240 | |||
241 | if (bitwidth < 7) { //Method 1: | ||
242 | if (val == (1 << (bitwidth - 1))) { | ||
243 | val = readbits(4) + 1; | ||
244 | bitwidth = (val < bitwidth) ? val : val + 1; | ||
245 | continue; | ||
246 | } | ||
247 | } | ||
248 | else if (bitwidth < 17) { //Method 2 | ||
249 | word border = (0xFFFF >> (17 - bitwidth)) - 8; | ||
250 | |||
251 | if (val > border && val <= (border + 16)) { | ||
252 | val -= border; | ||
253 | bitwidth = val < bitwidth ? val : val + 1; | ||
254 | continue; | ||
255 | } | ||
256 | } | ||
257 | else if (bitwidth == 17) { //Method 3 | ||
258 | if (val & 0x10000) { | ||
259 | bitwidth = (val + 1) & 0xFF; | ||
260 | continue; | ||
261 | } | ||
262 | } | ||
263 | else { //Illegal width, abort ? | ||
264 | freeblock(); | ||
265 | return -1; | ||
266 | } | ||
267 | |||
268 | //Expand the value to signed byte: | ||
269 | { | ||
270 | short v; //The sample value: | ||
271 | if (bitwidth < 16) { | ||
272 | byte shift = 16 - bitwidth; | ||
273 | v = (short)(val << shift); | ||
274 | v >>= shift; | ||
275 | } | ||
276 | else | ||
277 | v = (short)val; | ||
278 | |||
279 | //And integrate the sample value | ||
280 | //(It always has to end with integration doesn't it ? ;-) | ||
281 | d1 += v; | ||
282 | d2 += d1; | ||
283 | } | ||
284 | |||
285 | //Store ! | ||
286 | /* Version 2.15 was an unofficial version with hacked compression | ||
287 | * code. Yay, better compression :D | ||
288 | */ | ||
289 | if (right && (len & 1)) | ||
290 | *right++ = (int)(signed short)(cmwt == 0x215 ? d2 : d1) << 8; | ||
291 | else | ||
292 | *left++ = (int)(signed short)(cmwt == 0x215 ? d2 : d1) << 8; | ||
293 | len--; | ||
294 | blockpos++; | ||
295 | } | ||
296 | freeblock(); | ||
297 | } | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | |||
302 | |||
303 | static int it_read_envelope(IT_ENVELOPE *envelope, DUMBFILE *f) | ||
304 | { | ||
305 | int n; | ||
306 | |||
307 | envelope->flags = dumbfile_getc(f); | ||
308 | envelope->n_nodes = dumbfile_getc(f); | ||
309 | envelope->loop_start = dumbfile_getc(f); | ||
310 | envelope->loop_end = dumbfile_getc(f); | ||
311 | envelope->sus_loop_start = dumbfile_getc(f); | ||
312 | envelope->sus_loop_end = dumbfile_getc(f); | ||
313 | for (n = 0; n < envelope->n_nodes; n++) { | ||
314 | envelope->node_y[n] = dumbfile_getc(f); | ||
315 | envelope->node_t[n] = dumbfile_igetw(f); | ||
316 | } | ||
317 | dumbfile_skip(f, 75 - envelope->n_nodes * 3 + 1); | ||
318 | |||
319 | return dumbfile_error(f); | ||
320 | } | ||
321 | |||
322 | |||
323 | |||
324 | static int it_read_old_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f) | ||
325 | { | ||
326 | int n; | ||
327 | |||
328 | if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE) | ||
329 | return -1; | ||
330 | |||
331 | /* Skip DOS Filename. */ | ||
332 | dumbfile_skip(f, 13); | ||
333 | |||
334 | instrument->volume_envelope.flags = dumbfile_getc(f); | ||
335 | instrument->volume_envelope.loop_start = dumbfile_getc(f); | ||
336 | instrument->volume_envelope.loop_end = dumbfile_getc(f); | ||
337 | instrument->volume_envelope.sus_loop_start = dumbfile_getc(f); | ||
338 | instrument->volume_envelope.sus_loop_end = dumbfile_getc(f); | ||
339 | |||
340 | /* Skip two unused bytes. */ | ||
341 | dumbfile_skip(f, 2); | ||
342 | |||
343 | /* In the old instrument format, fadeout ranges from 0 to 64, and is | ||
344 | * subtracted at intervals from a value starting at 512. In the new | ||
345 | * format, all these values are doubled. Therefore we double when loading | ||
346 | * from the old instrument format - that way we don't have to think about | ||
347 | * it later. | ||
348 | */ | ||
349 | instrument->fadeout = dumbfile_igetw(f) << 1; | ||
350 | instrument->new_note_action = dumbfile_getc(f); | ||
351 | instrument->dup_check_type = dumbfile_getc(f); | ||
352 | instrument->dup_check_action = DCA_NOTE_CUT; // This might be wrong! | ||
353 | /** WARNING - what is the duplicate check action for old-style instruments? */ | ||
354 | |||
355 | /* Skip Tracker Version and Number of Samples. These are only used in | ||
356 | * separate instrument files. Also skip unused bytes and Instrument Name. | ||
357 | */ | ||
358 | dumbfile_skip(f, 36); | ||
359 | |||
360 | instrument->pp_separation = 0; | ||
361 | instrument->pp_centre = 60; | ||
362 | instrument->global_volume = 128; | ||
363 | /** WARNING - should global_volume be 64 or something? */ | ||
364 | instrument->default_pan = 32; | ||
365 | /** WARNING - should default_pan be 128, meaning don`t use? */ | ||
366 | instrument->random_volume = 0; | ||
367 | instrument->random_pan = 0; | ||
368 | |||
369 | for (n = 0; n < 120; n++) { | ||
370 | instrument->map_note[n] = dumbfile_getc(f); | ||
371 | instrument->map_sample[n] = dumbfile_getc(f); | ||
372 | } | ||
373 | |||
374 | /* Skip "Volume envelope (200 bytes)". */ | ||
375 | // - need to know better what this is for though. | ||
376 | dumbfile_skip(f, 200); | ||
377 | |||
378 | #if defined(INVESTIGATE_OLD_INSTRUMENTS) && 0 | ||
379 | fprintf(stderr, "Inst %02d Env:", n); | ||
380 | #endif | ||
381 | |||
382 | for (n = 0; n < 25; n++) | ||
383 | { | ||
384 | instrument->volume_envelope.node_t[n] = dumbfile_getc(f); | ||
385 | instrument->volume_envelope.node_y[n] = dumbfile_getc(f); | ||
386 | |||
387 | #if defined(INVESTIGATE_OLD_INSTRUMENTS) && 0 | ||
388 | fprintf(stderr, " %d,%d", | ||
389 | instrument->volume_envelope.node_t[n], | ||
390 | instrument->volume_envelope.node_y[n]); | ||
391 | #endif | ||
392 | |||
393 | // This loop is unfinished, as we can probably escape from it before | ||
394 | // the end if we want to. Hence the otherwise useless dumbfile_skip() | ||
395 | // call below. | ||
396 | } | ||
397 | dumbfile_skip(f, 50 - (n << 1)); | ||
398 | instrument->volume_envelope.n_nodes = n; | ||
399 | |||
400 | #if defined(INVESTIGATE_OLD_INSTRUMENTS) && 0 | ||
401 | fprintf(stderr, "\n"); | ||
402 | #endif | ||
403 | |||
404 | if (dumbfile_error(f)) | ||
405 | return -1; | ||
406 | |||
407 | instrument->filter_cutoff = 127; | ||
408 | instrument->filter_resonance = 0; | ||
409 | |||
410 | instrument->pan_envelope.flags = 0; | ||
411 | instrument->pitch_envelope.flags = 0; | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | |||
417 | |||
418 | static int it_read_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f) | ||
419 | { | ||
420 | int n; | ||
421 | |||
422 | if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE) | ||
423 | return -1; | ||
424 | |||
425 | /* Skip DOS Filename. */ | ||
426 | dumbfile_skip(f, 13); | ||
427 | |||
428 | instrument->new_note_action = dumbfile_getc(f); | ||
429 | instrument->dup_check_type = dumbfile_getc(f); | ||
430 | instrument->dup_check_action = dumbfile_getc(f); | ||
431 | instrument->fadeout = dumbfile_igetw(f); | ||
432 | instrument->pp_separation = dumbfile_getc(f); | ||
433 | instrument->pp_centre = dumbfile_getc(f); | ||
434 | instrument->global_volume = dumbfile_getc(f); | ||
435 | instrument->default_pan = dumbfile_getc(f); | ||
436 | instrument->random_volume = dumbfile_getc(f); | ||
437 | instrument->random_pan = dumbfile_getc(f); | ||
438 | |||
439 | /* Skip Tracker Version and Number of Samples. These are only used in | ||
440 | * separate instrument files. Also skip unused byte and Instrument Name. | ||
441 | */ | ||
442 | dumbfile_skip(f, 30); | ||
443 | |||
444 | instrument->filter_cutoff = dumbfile_getc(f); | ||
445 | instrument->filter_resonance = dumbfile_getc(f); | ||
446 | |||
447 | /* Skip MIDI Channel, Program and Bank. */ | ||
448 | dumbfile_skip(f, 4); | ||
449 | |||
450 | for (n = 0; n < 120; n++) { | ||
451 | instrument->map_note[n] = dumbfile_getc(f); | ||
452 | instrument->map_sample[n] = dumbfile_getc(f); | ||
453 | } | ||
454 | |||
455 | if (dumbfile_error(f)) | ||
456 | return -1; | ||
457 | |||
458 | if (it_read_envelope(&instrument->volume_envelope, f)) return -1; | ||
459 | if (it_read_envelope(&instrument->pan_envelope, f)) return -1; | ||
460 | if (it_read_envelope(&instrument->pitch_envelope, f)) return -1; | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | |||
466 | |||
467 | static int it_read_sample_header(IT_SAMPLE *sample, unsigned char *convert, long *offset, DUMBFILE *f) | ||
468 | { | ||
469 | if (dumbfile_mgetl(f) != IT_SAMPLE_SIGNATURE) | ||
470 | return -1; | ||
471 | |||
472 | /* Skip DOS Filename. */ | ||
473 | dumbfile_skip(f, 13); | ||
474 | |||
475 | sample->global_volume = dumbfile_getc(f); | ||
476 | sample->flags = dumbfile_getc(f); | ||
477 | sample->default_volume = dumbfile_getc(f); | ||
478 | |||
479 | /* Skip Sample Name. */ | ||
480 | dumbfile_skip(f, 26); | ||
481 | |||
482 | *convert = dumbfile_getc(f); | ||
483 | sample->default_pan = dumbfile_getc(f); | ||
484 | sample->length = dumbfile_igetl(f); | ||
485 | sample->loop_start = dumbfile_igetl(f); | ||
486 | sample->loop_end = dumbfile_igetl(f); | ||
487 | sample->C5_speed = dumbfile_igetl(f); | ||
488 | sample->sus_loop_start = dumbfile_igetl(f); | ||
489 | sample->sus_loop_end = dumbfile_igetl(f); | ||
490 | |||
491 | #ifdef STEREO_SAMPLES_COUNT_AS_TWO | ||
492 | if (sample->flags & IT_SAMPLE_STEREO) { | ||
493 | sample->length >>= 1; | ||
494 | sample->loop_start >>= 1; | ||
495 | sample->loop_end >>= 1; | ||
496 | sample->C5_speed >>= 1; | ||
497 | sample->sus_loop_start >>= 1; | ||
498 | sample->sus_loop_end >>= 1; | ||
499 | } | ||
500 | #endif | ||
501 | |||
502 | if (sample->flags & IT_SAMPLE_EXISTS) { | ||
503 | if (sample->length <= 0) | ||
504 | sample->flags &= ~IT_SAMPLE_EXISTS; | ||
505 | else { | ||
506 | if ((unsigned int)sample->loop_end > (unsigned int)sample->length) | ||
507 | sample->flags &= ~IT_SAMPLE_LOOP; | ||
508 | else if ((unsigned int)sample->loop_start >= (unsigned int)sample->loop_end) | ||
509 | sample->flags &= ~IT_SAMPLE_LOOP; | ||
510 | |||
511 | if ((unsigned int)sample->sus_loop_end > (unsigned int)sample->length) | ||
512 | sample->flags &= ~IT_SAMPLE_SUS_LOOP; | ||
513 | else if ((unsigned int)sample->sus_loop_start >= (unsigned int)sample->sus_loop_end) | ||
514 | sample->flags &= ~IT_SAMPLE_SUS_LOOP; | ||
515 | |||
516 | /* We may be able to truncate the sample to save memory. */ | ||
517 | if (sample->flags & IT_SAMPLE_LOOP) { | ||
518 | if ((sample->flags & IT_SAMPLE_SUS_LOOP) && sample->sus_loop_end >= sample->loop_end) | ||
519 | sample->length = sample->sus_loop_end; | ||
520 | else | ||
521 | sample->length = sample->loop_end; | ||
522 | } | ||
523 | } | ||
524 | } | ||
525 | |||
526 | *offset = dumbfile_igetl(f); | ||
527 | |||
528 | sample->vibrato_speed = dumbfile_getc(f); | ||
529 | sample->vibrato_depth = dumbfile_getc(f); | ||
530 | sample->vibrato_rate = dumbfile_getc(f); | ||
531 | sample->vibrato_waveform = dumbfile_getc(f); | ||
532 | |||
533 | return dumbfile_error(f); | ||
534 | } | ||
535 | |||
536 | |||
537 | |||
538 | static long it_read_sample_data(int cmwt, IT_SAMPLE *sample, unsigned char convert, DUMBFILE *f) | ||
539 | { | ||
540 | long n; | ||
541 | |||
542 | sample->left = malloc(sample->length * sizeof(*sample->left)); | ||
543 | if (!sample->left) | ||
544 | return -1; | ||
545 | |||
546 | if (sample->flags & IT_SAMPLE_STEREO) { | ||
547 | sample->right = malloc(sample->length * sizeof(*sample->right)); | ||
548 | if (!sample->right) | ||
549 | return -1; | ||
550 | } | ||
551 | |||
552 | if (sample->flags & 8) { | ||
553 | /* If the sample is packed, then we must unpack it. */ | ||
554 | |||
555 | /** WARNING - unresolved business here... test with ModPlug? */ | ||
556 | |||
557 | if (sample->flags & IT_SAMPLE_STEREO) | ||
558 | exit(37); | ||
559 | |||
560 | /* | ||
561 | //#ifndef STEREO_SAMPLES_COUNT_AS_TWO | ||
562 | ASSERT(!(sample->flags & IT_SAMPLE_STEREO)); | ||
563 | //#endif | ||
564 | */ | ||
565 | if (sample->flags & IT_SAMPLE_16BIT) | ||
566 | decompress16(f, sample->left, sample->right, sample->length, cmwt); | ||
567 | else | ||
568 | decompress8(f, sample->left, sample->right, sample->length, cmwt); | ||
569 | } else if (sample->flags & IT_SAMPLE_STEREO) { | ||
570 | if (sample->flags & IT_SAMPLE_16BIT) { | ||
571 | if (convert & 2) { | ||
572 | for (n = 0; n < sample->length; n++) { | ||
573 | sample->left[n] = (int)(signed short)dumbfile_mgetw(f) << 8; | ||
574 | sample->right[n] = (int)(signed short)dumbfile_mgetw(f) << 8; | ||
575 | } | ||
576 | } else { | ||
577 | for (n = 0; n < sample->length; n++) { | ||
578 | sample->left[n] = (int)(signed short)dumbfile_igetw(f) << 8; | ||
579 | sample->right[n] = (int)(signed short)dumbfile_igetw(f) << 8; | ||
580 | } | ||
581 | } | ||
582 | } else { | ||
583 | for (n = 0; n < sample->length; n++) { | ||
584 | sample->left[n] = (int)(signed char)dumbfile_getc(f) << 16; | ||
585 | sample->right[n] = (int)(signed char)dumbfile_getc(f) << 16; | ||
586 | } | ||
587 | } | ||
588 | } else if (sample->flags & IT_SAMPLE_16BIT) { | ||
589 | if (convert & 2) | ||
590 | for (n = 0; n < sample->length; n++) | ||
591 | sample->left[n] = (int)(signed short)dumbfile_mgetw(f) << 8; | ||
592 | else | ||
593 | for (n = 0; n < sample->length; n++) | ||
594 | sample->left[n] = (int)(signed short)dumbfile_igetw(f) << 8; | ||
595 | } else | ||
596 | for (n = 0; n < sample->length; n++) | ||
597 | sample->left[n] = (int)(signed char)dumbfile_getc(f) << 16; | ||
598 | |||
599 | if (dumbfile_error(f)) | ||
600 | return -1; | ||
601 | |||
602 | if (!(convert & 1)) { | ||
603 | /* Convert to signed. */ | ||
604 | for (n = 0; n < sample->length; n++) | ||
605 | sample->left[n] ^= 0xFF800000; | ||
606 | |||
607 | if (sample->right) | ||
608 | for (n = 0; n < sample->length; n++) | ||
609 | sample->right[n] ^= 0xFF800000; | ||
610 | } | ||
611 | |||
612 | /* NOT SUPPORTED: | ||
613 | * | ||
614 | * convert & 4 - Samples stored as delta values | ||
615 | * convert & 16 - Samples stored as TX-Wave 12-bit values | ||
616 | * convert & 32 - Left/Right/All Stereo prompt | ||
617 | */ | ||
618 | |||
619 | return 0; | ||
620 | } | ||
621 | |||
622 | |||
623 | |||
624 | #define DETECT_DUPLICATE_CHANNELS | ||
625 | #ifdef DETECT_DUPLICATE_CHANNELS | ||
626 | #include <stdio.h> | ||
627 | #endif | ||
628 | static int it_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer) | ||
629 | { | ||
630 | unsigned char cmask[DUMB_IT_N_CHANNELS]; | ||
631 | unsigned char cnote[DUMB_IT_N_CHANNELS]; | ||
632 | unsigned char cinstrument[DUMB_IT_N_CHANNELS]; | ||
633 | unsigned char cvolpan[DUMB_IT_N_CHANNELS]; | ||
634 | unsigned char ceffect[DUMB_IT_N_CHANNELS]; | ||
635 | unsigned char ceffectvalue[DUMB_IT_N_CHANNELS]; | ||
636 | #ifdef DETECT_DUPLICATE_CHANNELS | ||
637 | IT_ENTRY *dupentry[DUMB_IT_N_CHANNELS]; | ||
638 | #endif | ||
639 | |||
640 | int n_entries = 0; | ||
641 | int buflen; | ||
642 | int bufpos = 0; | ||
643 | |||
644 | IT_ENTRY *entry; | ||
645 | |||
646 | unsigned char channel; | ||
647 | unsigned char mask; | ||
648 | |||
649 | memset(cmask, 0, sizeof(cmask)); | ||
650 | memset(cnote, 0, sizeof(cnote)); | ||
651 | memset(cinstrument, 0, sizeof(cinstrument)); | ||
652 | memset(cvolpan, 0, sizeof(cvolpan)); | ||
653 | memset(ceffect, 0, sizeof(ceffect)); | ||
654 | memset(ceffectvalue, 0, sizeof(ceffectvalue)); | ||
655 | #ifdef DETECT_DUPLICATE_CHANNELS | ||
656 | { | ||
657 | int i; | ||
658 | for (i = 0; i < DUMB_IT_N_CHANNELS; i++) dupentry[i] = NULL; | ||
659 | } | ||
660 | #endif | ||
661 | |||
662 | buflen = dumbfile_igetw(f); | ||
663 | pattern->n_rows = dumbfile_igetw(f); | ||
664 | |||
665 | /* Skip four unused bytes. */ | ||
666 | dumbfile_skip(f, 4); | ||
667 | |||
668 | if (dumbfile_error(f)) | ||
669 | return -1; | ||
670 | |||
671 | /* Read in the pattern data. */ | ||
672 | dumbfile_getnc(buffer, buflen, f); | ||
673 | |||
674 | if (dumbfile_error(f)) | ||
675 | return -1; | ||
676 | |||
677 | /* Scan the pattern data, and work out how many entries we need room for. */ | ||
678 | while (bufpos < buflen) { | ||
679 | unsigned char b = buffer[bufpos++]; | ||
680 | |||
681 | if (b == 0) { | ||
682 | /* End of row */ | ||
683 | n_entries++; | ||
684 | continue; | ||
685 | } | ||
686 | |||
687 | channel = (b - 1) & 63; | ||
688 | |||
689 | if (b & 128) | ||
690 | cmask[channel] = mask = buffer[bufpos++]; | ||
691 | else | ||
692 | mask = cmask[channel]; | ||
693 | |||
694 | { | ||
695 | static const unsigned char used[16] = {0, 1, 1, 2, 1, 2, 2, 3, 2, 3, 3, 4, 3, 4, 4, 5}; | ||
696 | n_entries += (mask != 0); | ||
697 | bufpos += used[mask & 15]; | ||
698 | } | ||
699 | } | ||
700 | |||
701 | pattern->n_entries = n_entries; | ||
702 | |||
703 | pattern->entry = malloc(n_entries * sizeof(*pattern->entry)); | ||
704 | |||
705 | if (!pattern->entry) | ||
706 | return -1; | ||
707 | |||
708 | bufpos = 0; | ||
709 | memset(cmask, 0, sizeof(cmask)); | ||
710 | |||
711 | entry = pattern->entry; | ||
712 | |||
713 | while (bufpos < buflen) { | ||
714 | unsigned char b = buffer[bufpos++]; | ||
715 | |||
716 | if (b == 0) { | ||
717 | /* End of row */ | ||
718 | IT_SET_END_ROW(entry); | ||
719 | entry++; | ||
720 | #ifdef DETECT_DUPLICATE_CHANNELS | ||
721 | { | ||
722 | int i; | ||
723 | for (i = 0; i < DUMB_IT_N_CHANNELS; i++) dupentry[i] = NULL; | ||
724 | } | ||
725 | #endif | ||
726 | continue; | ||
727 | } | ||
728 | |||
729 | channel = (b - 1) & 63; | ||
730 | |||
731 | if (b & 128) | ||
732 | cmask[channel] = mask = buffer[bufpos++]; | ||
733 | else | ||
734 | mask = cmask[channel]; | ||
735 | |||
736 | if (mask) { | ||
737 | entry->mask = (mask & 15) | (mask >> 4); | ||
738 | entry->channel = channel; | ||
739 | |||
740 | if (mask & IT_ENTRY_NOTE) | ||
741 | cnote[channel] = entry->note = buffer[bufpos++]; | ||
742 | else if (mask & (IT_ENTRY_NOTE << 4)) | ||
743 | entry->note = cnote[channel]; | ||
744 | |||
745 | if (mask & IT_ENTRY_INSTRUMENT) | ||
746 | cinstrument[channel] = entry->instrument = buffer[bufpos++]; | ||
747 | else if (mask & (IT_ENTRY_INSTRUMENT << 4)) | ||
748 | entry->instrument = cinstrument[channel]; | ||
749 | |||
750 | if (mask & IT_ENTRY_VOLPAN) | ||
751 | cvolpan[channel] = entry->volpan = buffer[bufpos++]; | ||
752 | else if (mask & (IT_ENTRY_VOLPAN << 4)) | ||
753 | entry->volpan = cvolpan[channel]; | ||
754 | |||
755 | if (mask & IT_ENTRY_EFFECT) { | ||
756 | ceffect[channel] = entry->effect = buffer[bufpos++]; | ||
757 | ceffectvalue[channel] = entry->effectvalue = buffer[bufpos++]; | ||
758 | } else { | ||
759 | entry->effect = ceffect[channel]; | ||
760 | entry->effectvalue = ceffectvalue[channel]; | ||
761 | } | ||
762 | |||
763 | #if defined( DETECT_DUPLICATE_CHANNELS) && 0 | ||
764 | if (dupentry[channel]) { | ||
765 | FILE *f = fopen("dupentry.txt", "a"); | ||
766 | if (!f) abort(); | ||
767 | fprintf(f, "Two events on channel %d:", channel); | ||
768 | fprintf(f, " Event #1:"); | ||
769 | if (dupentry[channel]->mask & IT_ENTRY_NOTE ) fprintf(f, " %03d", dupentry[channel]->note ); else fprintf(f, " ..."); | ||
770 | if (dupentry[channel]->mask & IT_ENTRY_INSTRUMENT) fprintf(f, " %03d", dupentry[channel]->instrument); else fprintf(f, " ..."); | ||
771 | if (dupentry[channel]->mask & IT_ENTRY_VOLPAN ) fprintf(f, " %03d", dupentry[channel]->volpan ); else fprintf(f, " ..."); | ||
772 | if (dupentry[channel]->mask & IT_ENTRY_EFFECT) fprintf(f, " %c%02X\n", 'A' - 1 + dupentry[channel]->effect, dupentry[channel]->effectvalue); else fprintf(f, " ...\n"); | ||
773 | fprintf(f, " Event #2:"); | ||
774 | if (entry->mask & IT_ENTRY_NOTE ) fprintf(f, " %03d", entry->note ); else fprintf(f, " ..."); | ||
775 | if (entry->mask & IT_ENTRY_INSTRUMENT) fprintf(f, " %03d", entry->instrument); else fprintf(f, " ..."); | ||
776 | if (entry->mask & IT_ENTRY_VOLPAN ) fprintf(f, " %03d", entry->volpan ); else fprintf(f, " ..."); | ||
777 | if (entry->mask & IT_ENTRY_EFFECT) fprintf(f, " %c%02X\n", 'A' - 1 + entry->effect, entry->effectvalue); else fprintf(f, " ...\n"); | ||
778 | fclose(f); | ||
779 | } | ||
780 | dupentry[channel] = entry; | ||
781 | #endif | ||
782 | |||
783 | entry++; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | ASSERT(entry == pattern->entry + n_entries); | ||
788 | |||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | |||
793 | |||
794 | /* Currently we assume the sample data are stored after the sample headers in | ||
795 | * module files. This assumption may be unjustified; let me know if you have | ||
796 | * trouble. | ||
797 | */ | ||
798 | |||
799 | #define IT_COMPONENT_INSTRUMENT 1 | ||
800 | #define IT_COMPONENT_PATTERN 2 | ||
801 | #define IT_COMPONENT_SAMPLE 3 | ||
802 | |||
803 | typedef struct IT_COMPONENT | ||
804 | { | ||
805 | unsigned char type; | ||
806 | unsigned char n; | ||
807 | long offset; | ||
808 | short sampfirst; /* component[sampfirst] = first sample data after this */ | ||
809 | short sampnext; /* sampnext is used to create linked lists of sample data */ | ||
810 | } | ||
811 | IT_COMPONENT; | ||
812 | |||
813 | |||
814 | |||
815 | static int it_component_compare(const void *e1, const void *e2) | ||
816 | { | ||
817 | return ((const IT_COMPONENT *)e1)->offset - | ||
818 | ((const IT_COMPONENT *)e2)->offset; | ||
819 | } | ||
820 | |||
821 | |||
822 | |||
823 | static sigdata_t *it_load_sigdata(DUMBFILE *f) | ||
824 | { | ||
825 | DUMB_IT_SIGDATA *sigdata; | ||
826 | |||
827 | int cwt, cmwt; | ||
828 | int special; | ||
829 | |||
830 | IT_COMPONENT *component; | ||
831 | int n_components = 0; | ||
832 | |||
833 | unsigned char sample_convert[256]; | ||
834 | |||
835 | int n; | ||
836 | |||
837 | unsigned char *buffer; | ||
838 | |||
839 | if (dumbfile_mgetl(f) != IT_SIGNATURE) | ||
840 | return NULL; | ||
841 | |||
842 | sigdata = malloc(sizeof(*sigdata)); | ||
843 | |||
844 | if (!sigdata) | ||
845 | return NULL; | ||
846 | |||
847 | sigdata->order = NULL; | ||
848 | sigdata->instrument = NULL; | ||
849 | sigdata->sample = NULL; | ||
850 | sigdata->pattern = NULL; | ||
851 | sigdata->midi = NULL; | ||
852 | sigdata->checkpoint = NULL; | ||
853 | |||
854 | /* Skip song name and pattern row highlight info. */ | ||
855 | dumbfile_skip(f, 28); | ||
856 | |||
857 | sigdata->n_orders = dumbfile_igetw(f); | ||
858 | sigdata->n_instruments = dumbfile_igetw(f); | ||
859 | sigdata->n_samples = dumbfile_igetw(f); | ||
860 | sigdata->n_patterns = dumbfile_igetw(f); | ||
861 | |||
862 | cwt = dumbfile_igetw(f); | ||
863 | cmwt = dumbfile_igetw(f); | ||
864 | |||
865 | sigdata->flags = dumbfile_igetw(f); | ||
866 | special = dumbfile_igetw(f); | ||
867 | |||
868 | sigdata->global_volume = dumbfile_getc(f); | ||
869 | sigdata->mixing_volume = dumbfile_getc(f); | ||
870 | sigdata->speed = dumbfile_getc(f); | ||
871 | if (sigdata->speed == 0) sigdata->speed = 6; // Should we? What about tempo? | ||
872 | sigdata->tempo = dumbfile_getc(f); | ||
873 | sigdata->pan_separation = dumbfile_getc(f); /** WARNING: use this */ | ||
874 | |||
875 | /* Skip Pitch Wheel Depth, Message Length, Message Offset and Reserved. */ | ||
876 | dumbfile_skip(f, 11); | ||
877 | |||
878 | dumbfile_getnc(sigdata->channel_pan, DUMB_IT_N_CHANNELS, f); | ||
879 | dumbfile_getnc(sigdata->channel_volume, DUMB_IT_N_CHANNELS, f); | ||
880 | |||
881 | if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_instruments > 256 || sigdata->n_samples > 256 || sigdata->n_patterns > 256) { | ||
882 | _dumb_it_unload_sigdata(sigdata); | ||
883 | return NULL; | ||
884 | } | ||
885 | |||
886 | sigdata->order = malloc(sigdata->n_orders); | ||
887 | if (!sigdata->order) { | ||
888 | _dumb_it_unload_sigdata(sigdata); | ||
889 | return NULL; | ||
890 | } | ||
891 | |||
892 | if (sigdata->n_instruments) { | ||
893 | sigdata->instrument = malloc(sigdata->n_instruments * sizeof(*sigdata->instrument)); | ||
894 | if (!sigdata->instrument) { | ||
895 | _dumb_it_unload_sigdata(sigdata); | ||
896 | return NULL; | ||
897 | } | ||
898 | } | ||
899 | |||
900 | if (sigdata->n_samples) { | ||
901 | sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample)); | ||
902 | if (!sigdata->sample) { | ||
903 | _dumb_it_unload_sigdata(sigdata); | ||
904 | return NULL; | ||
905 | } | ||
906 | for (n = 0; n < sigdata->n_samples; n++) | ||
907 | sigdata->sample[n].right = sigdata->sample[n].left = NULL; | ||
908 | } | ||
909 | |||
910 | if (sigdata->n_patterns) { | ||
911 | sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern)); | ||
912 | if (!sigdata->pattern) { | ||
913 | _dumb_it_unload_sigdata(sigdata); | ||
914 | return NULL; | ||
915 | } | ||
916 | for (n = 0; n < sigdata->n_patterns; n++) | ||
917 | sigdata->pattern[n].entry = NULL; | ||
918 | } | ||
919 | |||
920 | dumbfile_getnc(sigdata->order, sigdata->n_orders, f); | ||
921 | sigdata->restart_position = 0; | ||
922 | |||
923 | component = malloc(768 * sizeof(*component)); | ||
924 | if (!component) { | ||
925 | _dumb_it_unload_sigdata(sigdata); | ||
926 | return NULL; | ||
927 | } | ||
928 | |||
929 | for (n = 0; n < sigdata->n_instruments; n++) { | ||
930 | component[n_components].type = IT_COMPONENT_INSTRUMENT; | ||
931 | component[n_components].n = n; | ||
932 | component[n_components].offset = dumbfile_igetl(f); | ||
933 | component[n_components].sampfirst = -1; | ||
934 | n_components++; | ||
935 | } | ||
936 | |||
937 | for (n = 0; n < sigdata->n_samples; n++) { | ||
938 | component[n_components].type = IT_COMPONENT_SAMPLE; | ||
939 | component[n_components].n = n; | ||
940 | component[n_components].offset = dumbfile_igetl(f); | ||
941 | component[n_components].sampfirst = -1; | ||
942 | n_components++; | ||
943 | } | ||
944 | |||
945 | for (n = 0; n < sigdata->n_patterns; n++) { | ||
946 | long offset = dumbfile_igetl(f); | ||
947 | if (offset) { | ||
948 | component[n_components].type = IT_COMPONENT_PATTERN; | ||
949 | component[n_components].n = n; | ||
950 | component[n_components].offset = offset; | ||
951 | component[n_components].sampfirst = -1; | ||
952 | n_components++; | ||
953 | } else { | ||
954 | /* Empty 64-row pattern */ | ||
955 | sigdata->pattern[n].n_rows = 64; | ||
956 | sigdata->pattern[n].n_entries = 0; | ||
957 | } | ||
958 | } | ||
959 | |||
960 | if (dumbfile_error(f)) { | ||
961 | free(component); | ||
962 | _dumb_it_unload_sigdata(sigdata); | ||
963 | return NULL; | ||
964 | } | ||
965 | |||
966 | if (!(sigdata->flags & 128) != !(special & 8)) { | ||
967 | #if 0 | ||
968 | fprintf(stderr, "Flags Bit 7 (\"Request embedded MIDI configuration\"): %s\n", sigdata->flags & 128 ? "=SET=" : "clear"); | ||
969 | fprintf(stderr, "Special Bit 3 (\"MIDI configuration embedded\") : %s\n", special & 8 ? "=SET=" : "clear"); | ||
970 | fprintf(stderr, "entheh would like to investigate this IT file.\n"); | ||
971 | fprintf(stderr, "Please contact him! entheh@users.sf.net\n"); | ||
972 | #endif | ||
973 | } | ||
974 | |||
975 | if (special & 8) { | ||
976 | /* MIDI configuration is embedded. */ | ||
977 | unsigned char mididata[32]; | ||
978 | int i; | ||
979 | sigdata->midi = malloc(sizeof(*sigdata->midi)); | ||
980 | if (!sigdata->midi) { | ||
981 | free(component); | ||
982 | _dumb_it_unload_sigdata(sigdata); | ||
983 | return NULL; | ||
984 | // Should we be happy with this outcome in some situations? | ||
985 | } | ||
986 | // What are we skipping? | ||
987 | i = dumbfile_igetw(f); | ||
988 | if (dumbfile_error(f) || dumbfile_skip(f, 8*i)) { | ||
989 | free(component); | ||
990 | _dumb_it_unload_sigdata(sigdata); | ||
991 | return NULL; | ||
992 | } | ||
993 | /* Read embedded MIDI configuration */ | ||
994 | // What are the first 9 commands for? | ||
995 | if (dumbfile_skip(f, 32*9)) { | ||
996 | free(component); | ||
997 | _dumb_it_unload_sigdata(sigdata); | ||
998 | return NULL; | ||
999 | } | ||
1000 | for (i = 0; i < 16; i++) { | ||
1001 | unsigned char len = 0; | ||
1002 | int j, leftdigit = -1; | ||
1003 | if (dumbfile_getnc(mididata, 32, f) < 32) { | ||
1004 | free(component); | ||
1005 | _dumb_it_unload_sigdata(sigdata); | ||
1006 | return NULL; | ||
1007 | } | ||
1008 | sigdata->midi->SFmacroz[i] = 0; | ||
1009 | for (j = 0; j < 32; j++) { | ||
1010 | if (leftdigit >= 0) { | ||
1011 | if (mididata[j] == 0) { | ||
1012 | sigdata->midi->SFmacro[i][len++] = leftdigit; | ||
1013 | break; | ||
1014 | } else if (mididata[j] == ' ') | ||
1015 | sigdata->midi->SFmacro[i][len++] = leftdigit; | ||
1016 | else if (mididata[j] >= '0' && mididata[j] <= '9') | ||
1017 | sigdata->midi->SFmacro[i][len++] = (leftdigit << 4) | (mididata[j] - '0'); | ||
1018 | else if (mididata[j] >= 'A' && mididata[j] <= 'F') | ||
1019 | sigdata->midi->SFmacro[i][len++] = (leftdigit << 4) | (mididata[j] - 'A' + 0xA); | ||
1020 | leftdigit = -1; | ||
1021 | } else if (mididata[j] == 0) | ||
1022 | break; | ||
1023 | else if (mididata[j] == 'z') | ||
1024 | sigdata->midi->SFmacroz[i] |= 1 << len++; | ||
1025 | else if (mididata[j] >= '0' && mididata[j] <= '9') | ||
1026 | leftdigit = mididata[j] - '0'; | ||
1027 | else if (mididata[j] >= 'A' && mididata[j] <= 'F') | ||
1028 | leftdigit = mididata[j] - 'A' + 0xA; | ||
1029 | } | ||
1030 | sigdata->midi->SFmacrolen[i] = len; | ||
1031 | } | ||
1032 | for (i = 0; i < 128; i++) { | ||
1033 | unsigned char len = 0; | ||
1034 | int j, leftdigit = -1; | ||
1035 | dumbfile_getnc(mididata, 32, f); | ||
1036 | for (j = 0; j < 32; j++) { | ||
1037 | if (leftdigit >= 0) { | ||
1038 | if (mididata[j] == 0) { | ||
1039 | sigdata->midi->Zmacro[i][len++] = leftdigit; | ||
1040 | break; | ||
1041 | } else if (mididata[j] == ' ') | ||
1042 | sigdata->midi->Zmacro[i][len++] = leftdigit; | ||
1043 | else if (mididata[j] >= '0' && mididata[j] <= '9') | ||
1044 | sigdata->midi->Zmacro[i][len++] = (leftdigit << 4) | (mididata[j] - '0'); | ||
1045 | else if (mididata[j] >= 'A' && mididata[j] <= 'F') | ||
1046 | sigdata->midi->Zmacro[i][len++] = (leftdigit << 4) | (mididata[j] - 'A' + 0xA); | ||
1047 | leftdigit = -1; | ||
1048 | } else if (mididata[j] == 0) | ||
1049 | break; | ||
1050 | else if (mididata[j] >= '0' && mididata[j] <= '9') | ||
1051 | leftdigit = mididata[j] - '0'; | ||
1052 | else if (mididata[j] >= 'A' && mididata[j] <= 'F') | ||
1053 | leftdigit = mididata[j] - 'A' + 0xA; | ||
1054 | } | ||
1055 | sigdata->midi->Zmacrolen[i] = len; | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | sigdata->flags &= IT_REAL_FLAGS; | ||
1060 | |||
1061 | qsort(component, n_components, sizeof(IT_COMPONENT), &it_component_compare); | ||
1062 | |||
1063 | buffer = malloc(65536); | ||
1064 | if (!buffer) { | ||
1065 | free(component); | ||
1066 | _dumb_it_unload_sigdata(sigdata); | ||
1067 | return NULL; | ||
1068 | } | ||
1069 | |||
1070 | for (n = 0; n < n_components; n++) { | ||
1071 | long offset; | ||
1072 | int m; | ||
1073 | |||
1074 | if (it_seek(f, component[n].offset)) { | ||
1075 | free(buffer); | ||
1076 | free(component); | ||
1077 | _dumb_it_unload_sigdata(sigdata); | ||
1078 | return NULL; | ||
1079 | } | ||
1080 | |||
1081 | switch (component[n].type) { | ||
1082 | |||
1083 | case IT_COMPONENT_INSTRUMENT: | ||
1084 | if (cmwt < 0x200) | ||
1085 | m = it_read_old_instrument(&sigdata->instrument[component[n].n], f); | ||
1086 | else | ||
1087 | m = it_read_instrument(&sigdata->instrument[component[n].n], f); | ||
1088 | |||
1089 | if (m) { | ||
1090 | free(buffer); | ||
1091 | free(component); | ||
1092 | _dumb_it_unload_sigdata(sigdata); | ||
1093 | return NULL; | ||
1094 | } | ||
1095 | break; | ||
1096 | |||
1097 | case IT_COMPONENT_PATTERN: | ||
1098 | if (it_read_pattern(&sigdata->pattern[component[n].n], f, buffer)) { | ||
1099 | free(buffer); | ||
1100 | free(component); | ||
1101 | _dumb_it_unload_sigdata(sigdata); | ||
1102 | return NULL; | ||
1103 | } | ||
1104 | break; | ||
1105 | |||
1106 | case IT_COMPONENT_SAMPLE: | ||
1107 | if (it_read_sample_header(&sigdata->sample[component[n].n], &sample_convert[component[n].n], &offset, f)) { | ||
1108 | free(buffer); | ||
1109 | free(component); | ||
1110 | _dumb_it_unload_sigdata(sigdata); | ||
1111 | return NULL; | ||
1112 | } | ||
1113 | |||
1114 | if (sigdata->sample[component[n].n].flags & IT_SAMPLE_EXISTS) { | ||
1115 | short *sample; | ||
1116 | |||
1117 | for (m = n + 1; m < n_components; m++) | ||
1118 | if (component[m].offset > offset) | ||
1119 | break; | ||
1120 | m--; | ||
1121 | |||
1122 | sample = &component[m].sampfirst; | ||
1123 | |||
1124 | while (*sample >= 0 && component[*sample].offset <= offset) | ||
1125 | sample = &component[*sample].sampnext; | ||
1126 | |||
1127 | component[n].sampnext = *sample; | ||
1128 | *sample = n; | ||
1129 | |||
1130 | component[n].offset = offset; | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1134 | m = component[n].sampfirst; | ||
1135 | |||
1136 | while (m >= 0) { | ||
1137 | if (it_seek(f, component[m].offset)) { | ||
1138 | free(buffer); | ||
1139 | free(component); | ||
1140 | _dumb_it_unload_sigdata(sigdata); | ||
1141 | return NULL; | ||
1142 | } | ||
1143 | |||
1144 | if (it_read_sample_data(cmwt, &sigdata->sample[component[m].n], sample_convert[component[m].n], f)) { | ||
1145 | free(buffer); | ||
1146 | free(component); | ||
1147 | _dumb_it_unload_sigdata(sigdata); | ||
1148 | return NULL; | ||
1149 | } | ||
1150 | |||
1151 | m = component[m].sampnext; | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | free(buffer); | ||
1156 | free(component); | ||
1157 | |||
1158 | _dumb_it_fix_invalid_orders(sigdata); | ||
1159 | |||
1160 | return sigdata; | ||
1161 | } | ||
1162 | |||
1163 | |||
1164 | |||
1165 | DUH *dumb_read_it(DUMBFILE *f) | ||
1166 | { | ||
1167 | sigdata_t *sigdata; | ||
1168 | long length; | ||
1169 | |||
1170 | DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it; | ||
1171 | |||
1172 | sigdata = it_load_sigdata(f); | ||
1173 | |||
1174 | if (!sigdata) | ||
1175 | return NULL; | ||
1176 | |||
1177 | length = _dumb_it_build_checkpoints(sigdata); | ||
1178 | |||
1179 | return make_duh(length, 1, &descptr, &sigdata); | ||
1180 | } | ||
1181 | |||