Exemple #1
0
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"));
}