Development: Formats/IT

From OpenMPT Wiki
Jump to: navigation, search

General information concerning the IT file format. Any variable names in this document refer to the original variable names from ITTECH.TXT. Variable names and hexadecimal numbers (in little-endian formats) are indicated by a monospace font.

Note: Impulse tracker is now open source! You can grab the source code at Bitbucket.

Tracker IDs[edit]

The IT header contains a field, Cwt/v, which is used to identify the application that was used to create the file. The following custom tracker IDs (read as little-endian hexadecimal numbers) are known to be found in the Cwt/v field:

  • 0xyy - Impulse Tracker x.yy - Many other trackers, like ModPlug Tracker, disguise as various versions of Impulse Tracker, so this is not a reliable way to tell if a file was really made with Impulse Tracker. See below for detecting such trackers.
  • 1xyy - Schism Tracker x.yy (up to Schism Tracker v0.50, later versions encode a timestamp in the version number - see Schism Tracker’s version.c)
  • 4xyy - pyIT x.yy
  • 5xyy - OpenMPT x.yy
  • 6xyy - BeRoTracker x.yy
  • 7xyz - ITMCK x.y.z (N.B. the user can override the value of the Cwt/v header by the -w command-line switch or the #TRACKER-VERSION command in the input file)
  • 8xyy - Tralala x.yy; prealpha versions, built from svn, before the first release identify as version 0.00 (i.e. Cwt/v=8000)
  • Cxyy - ChickDune ChipTune Tracker x.yy (currently non-public alpha version)
  • DAEB - spc2it (after commit d3d1b524032f668be8ee20d25339e1c635fb9bcf)

Are you a tracker developer and you tracker can save IT files? Please add your Tracker ID to this list!

Once we run out of tracker IDs, a more sophisticated approach will have to be found. For example, the ID 0FFF could be reserved, and a pointer to extended tracker information could be placed in the reserved header field.

Detecting other trackers[edit]

Some trackers disguise as Impulse Tracker 2, but there are ways to uncover this diguise:

BeRoTracker[edit]

Earlier versions of BeRoTracker, which did not use the tracker ID described above, can be identified by the four byte MODU magic which can be found after the Edit History / MIDI Macro block.

ChibiTracker[edit]

Cwt/v and Cmwt are both 0214, reserved reads CHBI.

Further interesting criteria: Sample data is stored directly after header. All sample and instrument filenames read -DEPRECATED- (obviously this should not be used as a detection criterion, as files re-saved with other trackers will still use these filenames). ChibiTracker also uses a line feed character (0A or \n) instead of a carriage return (0D or \r) in the song message.

ModPlug Tracker[edit]

  • ModPlug Tracker 1.00a5: Cwt/v is 0214, Cmwt is 0200, reserved is 0. Instruments are 560 bytes apart.
  • ModPlug Tracker 1.00b3.3 - 1.07: Cwt/v is 0214, Cmwt is 0202, reserved is 0. Instruments are 557 bytes apart.
  • Newer versions of ModPlug Tracker, OpenMPT 1.17 in compatible mode: Cwt/v is 0217, Cmwt is 0200, reserved is 0. If there are any instruments in the file, the instrument TrkVers field is 0211 for ModPlug Tracker and 0220 for OpenMPT. ModPlug Tracker writes FF for unused channels in the panning map, OpenMPT never does this.

OpenMPT[edit]

OpenMPT 1.17 wrote the value 0888 in both the Cwt/v and Cmwt fields.

Later versions of OpenMPT use the tracker ID provided above. In that case, the reserved field reads OMPT if the file was saved in normal mode, and is 0 if it was saved in compatible mode.

OpenSPC conversions[edit]

OpenSPC is a tool to convert SNES music from the SPC format to the IT format. If all the following conditions are true, you can be fairly sure that a module was written with OpenSPC:

  • Cwt/v is 0214.
  • Cmwt is 0200.
  • Flags is 09 (Linear Slides, Stereo Playback).
  • Special is 0.
  • Both pattern highlight values are 00.
  • No instruments are used.
  • PatNum + 1 == OrdNum.
  • Global volume is 128 decimal.
  • Master volume is 100 decimal.
  • Initial Speed is 1.
  • Pan Separation is 128 (decimal).
  • Pitch wheel depth is 0.
  • There is no song message, i.e. message length and offset are 0.
  • reserved is 0.

Earlier versions of spc2it (before commit d3d1b524032f668be8ee20d25339e1c635fb9bcf) will be mis-identified as OpenSPC, as the tool closely follows the way its predecessor writes out IT files.

UNMO3[edit]

UNMO3 is a tool to convert an MO3-compressed module file back into its original format.

In IT files created with UNMO3, Cwt/v is 0214, Cmwt is 0214, reserved is 0. The Special bit 2 (embed row highlights) is never set.

Note: UNMO3 older than version 2.4.0.1 does not set the edit history flag, but writes two edit history length bytes (zeroes) in the file anyway. Keep this in mind, as MIDI Macros will not load properly if you don’t. A fairly reliable (but not perfect) way to detect such malformed IT files would be to try to read the edit history length if all of the above conditions are fulfilled and the edit history flag is not set. For these old versions of UNMO3, you should read two zero bytes. If that is the case, it means that the first MIDI macro would be empty. This cannot happen in our case because UNMO3 writes out default values for the nine global macros, and the first default value is “FF” (MIDI Start), so it is clear that the two zero bytes belong to the (empty) edit history.

Later version of UNMO3 set the correct header flag for the edit history and write the two zero length bytes.

Special Header Flags[edit]

The following "Special" flags are not documented:

  • Bit 1 (02): If set, edit history information (see below) is present.
  • Bit 2 (04): If set, the row highlights (at offset 1E - 1F) should be read. If not set, they should be ignored.

Edit History[edit]

It is little known that the latest versions of Impulse Tracker keep track of when an IT file is opened and how long it is left open. The edit history can be found directly after the IT header and before the possibly present MIDI macro configuration.

A 16-Bit integer num tells how many edit history blocks are present. Every block is 8 bytes long, so the 16-bit integer is followed by 8 * num bytes of edit history information.

Each history block consists of a 16-Bit FAT date, a 16-Bit FAT time and a 32-Bit DOS timer, which contains the time how long the file was open in the editor, in 1/18.2th seconds. Information on how to decode the FAT date and time stamps can be found on the MSDN.

Note: Many programs don’t write an edit history, but they set the edit history flag in the header and write the two zero bytes for the history length. Many of them also ignore the edit history flag when loading files and always read the two num num bytes (ignoring the special flag), so if you want to write out an IT file that does not have an edit history and do not mind about the two extra bytes, the safest (most compatible) way is to set the edit history flag and write two zero bytes for num.

Also note that none of this is really relevant if you are sure that you never write out the MIDI macro configuration or ModPlug extensions, since these are the only two things that could normally follow the edit history. So if you have no MIDI macros and no ModPlug extensions, it is always safe to not set the special flag and not write the two extra bytes.

Proposed way to store compressed stereo samples[edit]

Since Impulse Tracker itself does not support stereo samples, a common way of how to decode compressed stereo samples had to be found - After all, it is possible to just treat them as one continuous stream (not stopping the encoding / decoding process after the end of the left channel), or to treat them as two separate, consecutive streams. GreaseMonkey has decided to follow XMPlay's way of decoding compressed stereo samples by treating them as two streams of the same length, so OpenMPT follows this example. If you intend to add IT sample compression support in your application, you should do the same to ensure compatibility across as many applications as possible.

OpenMPT Hacks[edit]

For a list of all the file format hacks that ModPlug Tracker / OpenMPT added to the IT format over the years, see the OpenMPT Format Extensions article.