/* _______ ____ __ ___ ___ * \ _ \ \ / \ / \ \ / / ' ' ' * | | \ \ | | || | \/ | . . * | | | | | | || ||\ /| | * | | | | | | || || \/ | | ' ' ' * | | | | | | || || | | . . * | |_/ / \ \__// || | | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque * / \ * / . \ * itread.c - Code to read an Impulse Tracker / / \ \ * module from an open file. | < / \_ * | \/ /\ / * Based on the loader from an IT player by Bob. \_ / > / * Adapted for DUMB by entheh. | \ / / * | ' / * \__/ */ #include <stdlib.h>#include <string.h> //might not be necessary later; required for memset #include "dumb.h"#include "internal/it.h" #ifndef min#define min(a, b) (((a) < (b)) ? (a) : (b))#endif //#define INVESTIGATE_OLD_INSTRUMENTS typedef unsigned char byte;typedef unsigned short word;typedef unsigned long dword; typedef struct readblock_crap readblock_crap; struct readblock_crap { unsigned char *sourcebuf; unsigned char *sourcepos; unsigned char *sourceend; int rembits;}; static int readblock(DUMBFILE *f, readblock_crap *crap) { long size; int c; size = dumbfile_igetw(f); if (size < 0) return (int)size; crap->sourcebuf = malloc(size); if (!crap->sourcebuf) return -1; c = (int)dumbfile_getnc((char *)crap->sourcebuf, size, f); if (c < size) { free(crap->sourcebuf); crap->sourcebuf = NULL; return -1; } crap->sourcepos = crap->sourcebuf; crap->sourceend = crap->sourcebuf + size; crap->rembits = 8; return 0;} static void freeblock(readblock_crap *crap) { free(crap->sourcebuf); crap->sourcebuf = NULL;} static int readbits(int bitwidth, readblock_crap *crap) { int val = 0; int b = 0; if (crap->sourcepos >= crap->sourceend) return val; while (bitwidth > crap->rembits) { val |= *crap->sourcepos++ << b; if (crap->sourcepos >= crap->sourceend) return val; b += crap->rembits; bitwidth -= crap->rembits; crap->rembits = 8; } val |= (*crap->sourcepos & ((1 << bitwidth) - 1)) << b; *crap->sourcepos >>= bitwidth; crap->rembits -= bitwidth; return val;} /** WARNING - do we even need to pass `right`? *//** WARNING - why bother memsetting at all? The whole array is written... */// if we do memset, dumb_silence() would be neater...static int decompress8(DUMBFILE *f, signed char *data, int len, int it215, int stereo) { int blocklen, blockpos; byte bitwidth; word val; signed char d1, d2; readblock_crap crap; memset(&crap, 0, sizeof(crap)); for (blocklen = 0, blockpos = 0; blocklen < len; blocklen++, blockpos += 1 + stereo) data[blockpos] = 0; while (len > 0) { // Read a block of compressed data: if (readblock(f, &crap)) return -1; // Set up a few variables blocklen = (len < 0x8000) ? len : 0x8000; // Max block length is 0x8000 bytes blockpos = 0; bitwidth = 9; d1 = d2 = 0; // Start the decompression: while (blockpos < blocklen) { // Read a value: val = (word)readbits(bitwidth, &crap); // Check for bit width change: if (bitwidth < 7) { // Method 1: if (val == (1 << (bitwidth - 1))) { val = (word)readbits(3, &crap) + 1; bitwidth = (val < bitwidth) ? val : val + 1; continue; } } else if (bitwidth < 9) { // Method 2 byte border = (0xFF >> (9 - bitwidth)) - 4; if (val > border && val <= (border + 8)) { val -= border; bitwidth = (val < bitwidth) ? val : val + 1; continue; } } else if (bitwidth == 9) { // Method 3 if (val & 0x100) { bitwidth = (val + 1) & 0xFF; continue; } } else { // Illegal width, abort ? freeblock(&crap); return -1; } // Expand the value to signed byte: { signed char v; // The sample value: if (bitwidth < 8) { byte shift = 8 - bitwidth; v = (val << shift); v >>= shift; } else v = (signed char)val; // And integrate the sample value //(It always has to end with integration doesn't it ? ;-) d1 += v; d2 += d1; } // Store ! /* Version 2.15 was an unofficial version with hacked compression * code. Yay, better compression :D */ *data++ = it215 ? d2 : d1; data += stereo; len--; blockpos++; } freeblock(&crap); } return 0;} static int decompress16(DUMBFILE *f, short *data, int len, int it215, int stereo) { int blocklen, blockpos; byte bitwidth; long val; signed short d1, d2; readblock_crap crap; memset(&crap, 0, sizeof(crap)); for (blocklen = 0, blockpos = 0; blocklen < len; blocklen++, blockpos += 1 + stereo) data[blockpos] = 0; while (len > 0) { // Read a block of compressed data: if (readblock(f, &crap)) return -1; // Set up a few variables blocklen = (len < 0x4000) ? len : 0x4000; // Max block length is 0x4000 bytes blockpos = 0; bitwidth = 17; d1 = d2 = 0; // Start the decompression: while (blockpos < blocklen) { val = readbits(bitwidth, &crap); // Check for bit width change: if (bitwidth < 7) { // Method 1: if (val == (1 << (bitwidth - 1))) { val = readbits(4, &crap) + 1; bitwidth = (val < bitwidth) ? val : val + 1; continue; } } else if (bitwidth < 17) { // Method 2 word border = (0xFFFF >> (17 - bitwidth)) - 8; if (val > border && val <= (border + 16)) { val -= border; bitwidth = val < bitwidth ? val : val + 1; continue; } } else if (bitwidth == 17) { // Method 3 if (val & 0x10000) { bitwidth = (val + 1) & 0xFF; continue; } } else { // Illegal width, abort ? freeblock(&crap); return -1; } // Expand the value to signed byte: { short v; // The sample value: if (bitwidth < 16) { byte shift = 16 - bitwidth; v = (short)(val << shift); v >>= shift; } else v = (short)val; // And integrate the sample value //(It always has to end with integration doesn't it ? ;-) d1 += v; d2 += d1; } // Store ! /* Version 2.15 was an unofficial version with hacked compression * code. Yay, better compression :D */ *data++ = it215 ? d2 : d1; data += stereo; len--; blockpos++; } freeblock(&crap); } return 0;} static int it_read_envelope(IT_ENVELOPE *envelope, DUMBFILE *f) { int n; envelope->flags = dumbfile_getc(f); envelope->n_nodes = dumbfile_getc(f); if (envelope->n_nodes > 25) { TRACE("IT error: wrong number of envelope nodes (%d)\n", envelope->n_nodes); envelope->n_nodes = 0; return -1; } envelope->loop_start = dumbfile_getc(f); envelope->loop_end = dumbfile_getc(f); envelope->sus_loop_start = dumbfile_getc(f); envelope->sus_loop_end = dumbfile_getc(f); for (n = 0; n < envelope->n_nodes; n++) { envelope->node_y[n] = dumbfile_getc(f); envelope->node_t[n] = dumbfile_igetw(f); } dumbfile_skip(f, 75 - envelope->n_nodes * 3 + 1); if (envelope->n_nodes <= 0) envelope->flags &= ~IT_ENVELOPE_ON; else { if (envelope->loop_end >= envelope->n_nodes || envelope->loop_start > envelope->loop_end) envelope->flags &= ~IT_ENVELOPE_LOOP_ON; if (envelope->sus_loop_end >= envelope->n_nodes || envelope->sus_loop_start > envelope->sus_loop_end) envelope->flags &= ~IT_ENVELOPE_SUSTAIN_LOOP; } return dumbfile_error(f);} static int it_read_old_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f) { int n; /*if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE) return -1;*/ // XXX dumbfile_skip(f, 4); dumbfile_getnc((char *)instrument->filename, 13, f); instrument->filename[13] = 0; instrument->volume_envelope.flags = dumbfile_getc(f); instrument->volume_envelope.loop_start = dumbfile_getc(f); instrument->volume_envelope.loop_end = dumbfile_getc(f); instrument->volume_envelope.sus_loop_start = dumbfile_getc(f); instrument->volume_envelope.sus_loop_end = dumbfile_getc(f); /* Skip two unused bytes. */ dumbfile_skip(f, 2); /* In the old instrument format, fadeout ranges from 0 to 64, and is * subtracted at intervals from a value starting at 512. In the new * format, all these values are doubled. Therefore we double when loading * from the old instrument format - that way we don't have to think about * it later. */ instrument->fadeout = dumbfile_igetw(f) << 1; instrument->new_note_action = dumbfile_getc(f); instrument->dup_check_type = dumbfile_getc(f); instrument->dup_check_action = DCA_NOTE_CUT; // This might be wrong! /** WARNING - what is the duplicate check action for old-style instruments? */ /* Skip Tracker Version and Number of Samples. These are only used in * separate instrument files. Also skip unused byte. */ dumbfile_skip(f, 4); dumbfile_getnc((char *)instrument->name, 26, f); instrument->name[26] = 0; /* Skip unused bytes following the Instrument Name. */ dumbfile_skip(f, 6); instrument->pp_separation = 0; instrument->pp_centre = 60; instrument->global_volume = 128; /** WARNING - should global_volume be 64 or something? */ instrument->default_pan = 32; /** WARNING - should default_pan be 128, meaning don`t use? */ instrument->random_volume = 0; instrument->random_pan = 0; for (n = 0; n < 120; n++) { instrument->map_note[n] = dumbfile_getc(f); instrument->map_sample[n] = dumbfile_getc(f); } /* Skip "Volume envelope (200 bytes)". */ // - need to know better what this is for though. dumbfile_skip(f, 200); #ifdef INVESTIGATE_OLD_INSTRUMENTS fprintf(stderr, "Inst %02d Env:", n);#endif for (n = 0; n < 25; n++) { instrument->volume_envelope.node_t[n] = dumbfile_getc(f); instrument->volume_envelope.node_y[n] = dumbfile_getc(f); #ifdef INVESTIGATE_OLD_INSTRUMENTS fprintf(stderr, " %d,%d", instrument->volume_envelope.node_t[n], instrument->volume_envelope.node_y[n]);#endif // This loop is unfinished, as we can probably escape from it before // the end if we want to. Hence the otherwise useless dumbfile_skip() // call below. } dumbfile_skip(f, 50 - (n << 1)); instrument->volume_envelope.n_nodes = n; #ifdef INVESTIGATE_OLD_INSTRUMENTS fprintf(stderr, "\n");#endif if (dumbfile_error(f)) return -1; { IT_ENVELOPE *envelope = &instrument->volume_envelope; if (envelope->n_nodes <= 0) envelope->flags &= ~IT_ENVELOPE_ON; else { if (envelope->loop_end >= envelope->n_nodes || envelope->loop_start > envelope->loop_end) envelope->flags &= ~IT_ENVELOPE_LOOP_ON; if (envelope->sus_loop_end >= envelope->n_nodes || envelope->sus_loop_start > envelope->sus_loop_end) envelope->flags &= ~IT_ENVELOPE_SUSTAIN_LOOP; } } instrument->filter_cutoff = 127; instrument->filter_resonance = 0; instrument->pan_envelope.flags = 0; instrument->pitch_envelope.flags = 0; return 0;} static int it_read_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f, int maxlen) { int n; long len; /*if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE) return -1;*/ // XXX if (maxlen) len = dumbfile_pos(f); else len = 0; dumbfile_skip(f, 4); dumbfile_getnc((char *)instrument->filename, 13, f); instrument->filename[13] = 0; instrument->new_note_action = dumbfile_getc(f); instrument->dup_check_type = dumbfile_getc(f); instrument->dup_check_action = dumbfile_getc(f); instrument->fadeout = dumbfile_igetw(f); instrument->pp_separation = dumbfile_getc(f); instrument->pp_centre = dumbfile_getc(f); instrument->global_volume = dumbfile_getc(f); instrument->default_pan = dumbfile_getc(f); instrument->random_volume = dumbfile_getc(f); instrument->random_pan = dumbfile_getc(f); /* Skip Tracker Version and Number of Samples. These are only used in * separate instrument files. Also skip unused byte. */ dumbfile_skip(f, 4); dumbfile_getnc((char *)instrument->name, 26, f); instrument->name[26] = 0; instrument->filter_cutoff = dumbfile_getc(f); instrument->filter_resonance = dumbfile_getc(f); /* Skip MIDI Channel, Program and Bank. */ // dumbfile_skip(f, 4); /*instrument->output = dumbfile_getc(f); if ( instrument->output > 16 ) { instrument->output -= 128; } else { instrument->output = 0; } dumbfile_skip(f, 3);*/ dumbfile_skip(f, 4); for (n = 0; n < 120; n++) { instrument->map_note[n] = dumbfile_getc(f); instrument->map_sample[n] = dumbfile_getc(f); } if (dumbfile_error(f)) return -1; if (it_read_envelope(&instrument->volume_envelope, f)) return -1; if (it_read_envelope(&instrument->pan_envelope, f)) return -1; if (it_read_envelope(&instrument->pitch_envelope, f)) return -1; if (maxlen) { len = dumbfile_pos(f) - len; if (maxlen - len < 124) return 0; } if (dumbfile_mgetl(f) == IT_MPTX_SIGNATURE) { for (n = 0; n < 120; n++) { instrument->map_sample[n] += dumbfile_getc(f) << 8; } if (dumbfile_error(f)) return -1; } /*if ( dumbfile_mgetl(f) == IT_INSM_SIGNATURE ) { long end = dumbfile_igetl(f); end += dumbfile_pos(f); while ( dumbfile_pos(f) < end ) {Lines 1–500 of 1468. Load more
/* _______ ____ __ ___ ___ * \ _ \ \ / \ / \ \ / / ' ' ' * | | \ \ | | || | \/ | . . * | | | | | | || ||\ /| | * | | | | | | || || \/ | | ' ' ' * | | | | | | || || | | . . * | |_/ / \ \__// || | | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque * / \ * / . \ * itread.c - Code to read an Impulse Tracker / / \ \ * module from an open file. | < / \_ * | \/ /\ / * Based on the loader from an IT player by Bob. \_ / > / * Adapted for DUMB by entheh. | \ / / * | ' / * \__/ */ #include <stdlib.h> #include <string.h> //might not be necessary later; required for memset #include "dumb.h" #include "internal/it.h" #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif //#define INVESTIGATE_OLD_INSTRUMENTS typedef unsigned char byte; typedef unsigned short word; typedef unsigned long dword; typedef struct readblock_crap readblock_crap; struct readblock_crap { unsigned char *sourcebuf; unsigned char *sourcepos; unsigned char *sourceend; int rembits; }; static int readblock(DUMBFILE *f, readblock_crap *crap) { long size; int c; size = dumbfile_igetw(f); if (size < 0) return (int)size; crap->sourcebuf = malloc(size); if (!crap->sourcebuf) return -1; c = (int)dumbfile_getnc((char *)crap->sourcebuf, size, f); if (c < size) { free(crap->sourcebuf); crap->sourcebuf = NULL; return -1; } crap->sourcepos = crap->sourcebuf; crap->sourceend = crap->sourcebuf + size; crap->rembits = 8; return 0; } static void freeblock(readblock_crap *crap) { free(crap->sourcebuf); crap->sourcebuf = NULL; } static int readbits(int bitwidth, readblock_crap *crap) { int val = 0; int b = 0; if (crap->sourcepos >= crap->sourceend) return val; while (bitwidth > crap->rembits) { val |= *crap->sourcepos++ << b; if (crap->sourcepos >= crap->sourceend) return val; b += crap->rembits; bitwidth -= crap->rembits; crap->rembits = 8; } val |= (*crap->sourcepos & ((1 << bitwidth) - 1)) << b; *crap->sourcepos >>= bitwidth; crap->rembits -= bitwidth; return val; } /** WARNING - do we even need to pass `right`? */ /** WARNING - why bother memsetting at all? The whole array is written... */ // if we do memset, dumb_silence() would be neater... static int decompress8(DUMBFILE *f, signed char *data, int len, int it215, int stereo) { int blocklen, blockpos; byte bitwidth; word val; signed char d1, d2; readblock_crap crap; memset(&crap, 0, sizeof(crap)); for (blocklen = 0, blockpos = 0; blocklen < len; blocklen++, blockpos += 1 + stereo) data[blockpos] = 0; while (len > 0) { // Read a block of compressed data: if (readblock(f, &crap)) return -1; // Set up a few variables blocklen = (len < 0x8000) ? len : 0x8000; // Max block length is 0x8000 bytes blockpos = 0; bitwidth = 9; d1 = d2 = 0; // Start the decompression: while (blockpos < blocklen) { // Read a value: val = (word)readbits(bitwidth, &crap); // Check for bit width change: if (bitwidth < 7) { // Method 1: if (val == (1 << (bitwidth - 1))) { val = (word)readbits(3, &crap) + 1; bitwidth = (val < bitwidth) ? val : val + 1; continue; } } else if (bitwidth < 9) { // Method 2 byte border = (0xFF >> (9 - bitwidth)) - 4; if (val > border && val <= (border + 8)) { val -= border; bitwidth = (val < bitwidth) ? val : val + 1; continue; } } else if (bitwidth == 9) { // Method 3 if (val & 0x100) { bitwidth = (val + 1) & 0xFF; continue; } } else { // Illegal width, abort ? freeblock(&crap); return -1; } // Expand the value to signed byte: { signed char v; // The sample value: if (bitwidth < 8) { byte shift = 8 - bitwidth; v = (val << shift); v >>= shift; } else v = (signed char)val; // And integrate the sample value //(It always has to end with integration doesn't it ? ;-) d1 += v; d2 += d1; } // Store ! /* Version 2.15 was an unofficial version with hacked compression * code. Yay, better compression :D */ *data++ = it215 ? d2 : d1; data += stereo; len--; blockpos++; } freeblock(&crap); } return 0; } static int decompress16(DUMBFILE *f, short *data, int len, int it215, int stereo) { int blocklen, blockpos; byte bitwidth; long val; signed short d1, d2; readblock_crap crap; memset(&crap, 0, sizeof(crap)); for (blocklen = 0, blockpos = 0; blocklen < len; blocklen++, blockpos += 1 + stereo) data[blockpos] = 0; while (len > 0) { // Read a block of compressed data: if (readblock(f, &crap)) return -1; // Set up a few variables blocklen = (len < 0x4000) ? len : 0x4000; // Max block length is 0x4000 bytes blockpos = 0; bitwidth = 17; d1 = d2 = 0; // Start the decompression: while (blockpos < blocklen) { val = readbits(bitwidth, &crap); // Check for bit width change: if (bitwidth < 7) { // Method 1: if (val == (1 << (bitwidth - 1))) { val = readbits(4, &crap) + 1; bitwidth = (val < bitwidth) ? val : val + 1; continue; } } else if (bitwidth < 17) { // Method 2 word border = (0xFFFF >> (17 - bitwidth)) - 8; if (val > border && val <= (border + 16)) { val -= border; bitwidth = val < bitwidth ? val : val + 1; continue; } } else if (bitwidth == 17) { // Method 3 if (val & 0x10000) { bitwidth = (val + 1) & 0xFF; continue; } } else { // Illegal width, abort ? freeblock(&crap); return -1; } // Expand the value to signed byte: { short v; // The sample value: if (bitwidth < 16) { byte shift = 16 - bitwidth; v = (short)(val << shift); v >>= shift; } else v = (short)val; // And integrate the sample value //(It always has to end with integration doesn't it ? ;-) d1 += v; d2 += d1; } // Store ! /* Version 2.15 was an unofficial version with hacked compression * code. Yay, better compression :D */ *data++ = it215 ? d2 : d1; data += stereo; len--; blockpos++; } freeblock(&crap); } return 0; } static int it_read_envelope(IT_ENVELOPE *envelope, DUMBFILE *f) { int n; envelope->flags = dumbfile_getc(f); envelope->n_nodes = dumbfile_getc(f); if (envelope->n_nodes > 25) { TRACE("IT error: wrong number of envelope nodes (%d)\n", envelope->n_nodes); envelope->n_nodes = 0; return -1; } envelope->loop_start = dumbfile_getc(f); envelope->loop_end = dumbfile_getc(f); envelope->sus_loop_start = dumbfile_getc(f); envelope->sus_loop_end = dumbfile_getc(f); for (n = 0; n < envelope->n_nodes; n++) { envelope->node_y[n] = dumbfile_getc(f); envelope->node_t[n] = dumbfile_igetw(f); } dumbfile_skip(f, 75 - envelope->n_nodes * 3 + 1); if (envelope->n_nodes <= 0) envelope->flags &= ~IT_ENVELOPE_ON; else { if (envelope->loop_end >= envelope->n_nodes || envelope->loop_start > envelope->loop_end) envelope->flags &= ~IT_ENVELOPE_LOOP_ON; if (envelope->sus_loop_end >= envelope->n_nodes || envelope->sus_loop_start > envelope->sus_loop_end) envelope->flags &= ~IT_ENVELOPE_SUSTAIN_LOOP; } return dumbfile_error(f); } static int it_read_old_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f) { int n; /*if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE) return -1;*/ // XXX dumbfile_skip(f, 4); dumbfile_getnc((char *)instrument->filename, 13, f); instrument->filename[13] = 0; instrument->volume_envelope.flags = dumbfile_getc(f); instrument->volume_envelope.loop_start = dumbfile_getc(f); instrument->volume_envelope.loop_end = dumbfile_getc(f); instrument->volume_envelope.sus_loop_start = dumbfile_getc(f); instrument->volume_envelope.sus_loop_end = dumbfile_getc(f); /* Skip two unused bytes. */ dumbfile_skip(f, 2); /* In the old instrument format, fadeout ranges from 0 to 64, and is * subtracted at intervals from a value starting at 512. In the new * format, all these values are doubled. Therefore we double when loading * from the old instrument format - that way we don't have to think about * it later. */ instrument->fadeout = dumbfile_igetw(f) << 1; instrument->new_note_action = dumbfile_getc(f); instrument->dup_check_type = dumbfile_getc(f); instrument->dup_check_action = DCA_NOTE_CUT; // This might be wrong! /** WARNING - what is the duplicate check action for old-style instruments? */ /* Skip Tracker Version and Number of Samples. These are only used in * separate instrument files. Also skip unused byte. */ dumbfile_skip(f, 4); dumbfile_getnc((char *)instrument->name, 26, f); instrument->name[26] = 0; /* Skip unused bytes following the Instrument Name. */ dumbfile_skip(f, 6); instrument->pp_separation = 0; instrument->pp_centre = 60; instrument->global_volume = 128; /** WARNING - should global_volume be 64 or something? */ instrument->default_pan = 32; /** WARNING - should default_pan be 128, meaning don`t use? */ instrument->random_volume = 0; instrument->random_pan = 0; for (n = 0; n < 120; n++) { instrument->map_note[n] = dumbfile_getc(f); instrument->map_sample[n] = dumbfile_getc(f); } /* Skip "Volume envelope (200 bytes)". */ // - need to know better what this is for though. dumbfile_skip(f, 200); #ifdef INVESTIGATE_OLD_INSTRUMENTS fprintf(stderr, "Inst %02d Env:", n); #endif for (n = 0; n < 25; n++) { instrument->volume_envelope.node_t[n] = dumbfile_getc(f); instrument->volume_envelope.node_y[n] = dumbfile_getc(f); #ifdef INVESTIGATE_OLD_INSTRUMENTS fprintf(stderr, " %d,%d", instrument->volume_envelope.node_t[n], instrument->volume_envelope.node_y[n]); #endif // This loop is unfinished, as we can probably escape from it before // the end if we want to. Hence the otherwise useless dumbfile_skip() // call below. } dumbfile_skip(f, 50 - (n << 1)); instrument->volume_envelope.n_nodes = n; #ifdef INVESTIGATE_OLD_INSTRUMENTS fprintf(stderr, "\n"); #endif if (dumbfile_error(f)) return -1; { IT_ENVELOPE *envelope = &instrument->volume_envelope; if (envelope->n_nodes <= 0) envelope->flags &= ~IT_ENVELOPE_ON; else { if (envelope->loop_end >= envelope->n_nodes || envelope->loop_start > envelope->loop_end) envelope->flags &= ~IT_ENVELOPE_LOOP_ON; if (envelope->sus_loop_end >= envelope->n_nodes || envelope->sus_loop_start > envelope->sus_loop_end) envelope->flags &= ~IT_ENVELOPE_SUSTAIN_LOOP; } } instrument->filter_cutoff = 127; instrument->filter_resonance = 0; instrument->pan_envelope.flags = 0; instrument->pitch_envelope.flags = 0; return 0; } static int it_read_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f, int maxlen) { int n; long len; /*if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE) return -1;*/ // XXX if (maxlen) len = dumbfile_pos(f); else len = 0; dumbfile_skip(f, 4); dumbfile_getnc((char *)instrument->filename, 13, f); instrument->filename[13] = 0; instrument->new_note_action = dumbfile_getc(f); instrument->dup_check_type = dumbfile_getc(f); instrument->dup_check_action = dumbfile_getc(f); instrument->fadeout = dumbfile_igetw(f); instrument->pp_separation = dumbfile_getc(f); instrument->pp_centre = dumbfile_getc(f); instrument->global_volume = dumbfile_getc(f); instrument->default_pan = dumbfile_getc(f); instrument->random_volume = dumbfile_getc(f); instrument->random_pan = dumbfile_getc(f); /* Skip Tracker Version and Number of Samples. These are only used in * separate instrument files. Also skip unused byte. */ dumbfile_skip(f, 4); dumbfile_getnc((char *)instrument->name, 26, f); instrument->name[26] = 0; instrument->filter_cutoff = dumbfile_getc(f); instrument->filter_resonance = dumbfile_getc(f); /* Skip MIDI Channel, Program and Bank. */ // dumbfile_skip(f, 4); /*instrument->output = dumbfile_getc(f); if ( instrument->output > 16 ) { instrument->output -= 128; } else { instrument->output = 0; } dumbfile_skip(f, 3);*/ dumbfile_skip(f, 4); for (n = 0; n < 120; n++) { instrument->map_note[n] = dumbfile_getc(f); instrument->map_sample[n] = dumbfile_getc(f); } if (dumbfile_error(f)) return -1; if (it_read_envelope(&instrument->volume_envelope, f)) return -1; if (it_read_envelope(&instrument->pan_envelope, f)) return -1; if (it_read_envelope(&instrument->pitch_envelope, f)) return -1; if (maxlen) { len = dumbfile_pos(f) - len; if (maxlen - len < 124) return 0; } if (dumbfile_mgetl(f) == IT_MPTX_SIGNATURE) { for (n = 0; n < 120; n++) { instrument->map_sample[n] += dumbfile_getc(f) << 8; } if (dumbfile_error(f)) return -1; } /*if ( dumbfile_mgetl(f) == IT_INSM_SIGNATURE ) { long end = dumbfile_igetl(f); end += dumbfile_pos(f); while ( dumbfile_pos(f) < end ) {