void Mod::File::read(bool) { if(!isOpen()) return; seek(1080); ByteVector modId = readBlock(4); READ_ASSERT(modId.size() == 4); int channels = 4; unsigned int instruments = 31; if(modId == "M.K." || modId == "M!K!" || modId == "M&K!" || modId == "N.T.") { d->tag.setTrackerName("ProTracker"); channels = 4; } else if(modId.startsWith("FLT") || modId.startsWith("TDZ")) { d->tag.setTrackerName("StarTrekker"); char digit = modId[3]; READ_ASSERT(digit >= '0' && digit <= '9'); channels = digit - '0'; } else if(modId.endsWith("CHN")) { d->tag.setTrackerName("StarTrekker"); char digit = modId[0]; READ_ASSERT(digit >= '0' && digit <= '9'); channels = digit - '0'; } else if(modId == "CD81" || modId == "OKTA") { d->tag.setTrackerName("Atari Oktalyzer"); channels = 8; } else if(modId.endsWith("CH") || modId.endsWith("CN")) { d->tag.setTrackerName("TakeTracker"); char digit = modId[0]; READ_ASSERT(digit >= '0' && digit <= '9'); channels = (digit - '0') * 10; digit = modId[1]; READ_ASSERT(digit >= '0' && digit <= '9'); channels += digit - '0'; } else { // Not sure if this is correct. I'd need a file // created with NoiseTracker to check this. d->tag.setTrackerName("NoiseTracker"); // probably channels = 4; instruments = 15; } d->properties.setChannels(channels); d->properties.setInstrumentCount(instruments); seek(0); READ_STRING(d->tag.setTitle, 20); StringList comment; for(unsigned int i = 0; i < instruments; ++ i) { READ_STRING_AS(instrumentName, 22); // value in words, * 2 (<< 1) for bytes: READ_U16B_AS(sampleLength); READ_BYTE_AS(fineTuneByte); int fineTune = fineTuneByte & 0xF; // > 7 means negative value if(fineTune > 7) fineTune -= 16; READ_BYTE_AS(volume); if(volume > 64) volume = 64; // volume in decibels: 20 * log10(volume / 64) // value in words, * 2 (<< 1) for bytes: READ_U16B_AS(repeatStart); // value in words, * 2 (<< 1) for bytes: READ_U16B_AS(repatLength); comment.append(instrumentName); } READ_BYTE(d->properties.setLengthInPatterns); d->tag.setComment(comment.toString("\n")); }