123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- /*
- * ITTools.h
- * ---------
- * Purpose: Definition of IT file structures and helper functions
- * Notes : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include "../soundlib/ModInstrument.h"
- #include "../soundlib/ModSample.h"
- #include "../soundlib/SampleIO.h"
- OPENMPT_NAMESPACE_BEGIN
- struct ITFileHeader
- {
- // Header Flags
- enum ITHeaderFlags
- {
- useStereoPlayback = 0x01,
- vol0Optimisations = 0x02,
- instrumentMode = 0x04,
- linearSlides = 0x08,
- itOldEffects = 0x10,
- itCompatGxx = 0x20,
- useMIDIPitchController = 0x40,
- reqEmbeddedMIDIConfig = 0x80,
- extendedFilterRange = 0x1000,
- };
- // Special Flags
- enum ITHeaderSpecialFlags
- {
- embedSongMessage = 0x01,
- embedEditHistory = 0x02,
- embedPatternHighlights = 0x04,
- embedMIDIConfiguration = 0x08,
- };
- char id[4]; // Magic Bytes (IMPM)
- char songname[26]; // Song Name, null-terminated (but may also contain nulls)
- uint8le highlight_minor; // Rows per Beat highlight
- uint8le highlight_major; // Rows per Measure highlight
- uint16le ordnum; // Number of Orders
- uint16le insnum; // Number of Instruments
- uint16le smpnum; // Number of Samples
- uint16le patnum; // Number of Patterns
- uint16le cwtv; // "Made With" Tracker
- uint16le cmwt; // "Compatible With" Tracker
- uint16le flags; // Header Flags
- uint16le special; // Special Flags, for embedding extra information
- uint8le globalvol; // Global Volume (0...128)
- uint8le mv; // Master Volume (0...128), referred to as Sample Volume in OpenMPT
- uint8le speed; // Initial Speed (1...255)
- uint8le tempo; // Initial Tempo (31...255)
- uint8le sep; // Pan Separation (0...128)
- uint8le pwd; // Pitch Wheel Depth
- uint16le msglength; // Length of Song Message
- uint32le msgoffset; // Offset of Song Message in File (IT crops message after first null)
- uint32le reserved; // Some IT versions save an edit timer here. ChibiTracker writes "CHBI" here. OpenMPT and Schism Tracker save extended version information here.
- uint8le chnpan[64]; // Initial Channel Panning
- uint8le chnvol[64]; // Initial Channel Volume
- };
- MPT_BINARY_STRUCT(ITFileHeader, 192)
- struct ITEnvelope
- {
- // Envelope Flags
- enum ITEnvelopeFlags
- {
- envEnabled = 0x01,
- envLoop = 0x02,
- envSustain = 0x04,
- envCarry = 0x08,
- envFilter = 0x80,
- };
- struct Node
- {
- int8le value;
- uint16le tick;
- };
- uint8 flags; // Envelope Flags
- uint8 num; // Number of Envelope Nodes
- uint8 lpb; // Loop Start
- uint8 lpe; // Loop End
- uint8 slb; // Sustain Start
- uint8 sle; // Sustain End
- Node data[25]; // Envelope Node Positions / Values
- uint8 reserved; // Reserved
- // Convert OpenMPT's internal envelope format to an IT/MPTM envelope.
- void ConvertToIT(const InstrumentEnvelope &mptEnv, uint8 envOffset, uint8 envDefault);
- // Convert IT/MPTM envelope data into OpenMPT's internal envelope format - To be used by ITInstrToMPT()
- void ConvertToMPT(InstrumentEnvelope &mptEnv, uint8 envOffset, uint8 maxNodes) const;
- };
- MPT_BINARY_STRUCT(ITEnvelope::Node, 3)
- MPT_BINARY_STRUCT(ITEnvelope, 82)
- // Old Impulse Instrument Format (cmwt < 0x200)
- struct ITOldInstrument
- {
- enum ITOldInstrFlags
- {
- envEnabled = 0x01,
- envLoop = 0x02,
- envSustain = 0x04,
- };
- char id[4]; // Magic Bytes (IMPI)
- char filename[13]; // DOS Filename, null-terminated
- uint8le flags; // Volume Envelope Flags
- uint8le vls; // Envelope Loop Start
- uint8le vle; // Envelope Loop End
- uint8le sls; // Envelope Sustain Start
- uint8le sle; // Envelope Sustain End
- char reserved1[2]; // Reserved
- uint16le fadeout; // Instrument Fadeout (0...128)
- uint8le nna; // New Note Action
- uint8le dnc; // Duplicate Note Check Type
- uint16le trkvers; // Tracker ID
- uint8le nos; // Number of embedded samples
- char reserved2; // Reserved
- char name[26]; // Instrument Name, null-terminated (but may also contain nulls)
- char reserved3[6]; // Even more reserved bytes
- uint8le keyboard[240]; // Sample / Transpose map
- uint8le volenv[200]; // This appears to be a pre-computed (interpolated) version of the volume envelope data found below.
- uint8le nodes[25 * 2]; // Volume Envelope Node Positions / Values
- // Convert an ITOldInstrument to OpenMPT's internal instrument representation.
- void ConvertToMPT(ModInstrument &mptIns) const;
- };
- MPT_BINARY_STRUCT(ITOldInstrument, 554)
- // Impulse Instrument Format
- struct ITInstrument
- {
- enum ITInstrumentFlags
- {
- ignorePanning = 0x80,
- enableCutoff = 0x80,
- enableResonance = 0x80,
- };
- char id[4]; // Magic Bytes (IMPI)
- char filename[13]; // DOS Filename, null-terminated
- uint8le nna; // New Note Action
- uint8le dct; // Duplicate Note Check Type
- uint8le dca; // Duplicate Note Check Action
- uint16le fadeout; // Instrument Fadeout (0...256, although values up to 1024 would be sensible. Up to IT2.07, the limit was 0...128)
- int8le pps; // Pitch/Pan Separatation
- uint8le ppc; // Pitch/Pan Centre
- uint8le gbv; // Global Volume
- uint8le dfp; // Panning
- uint8le rv; // Vol Swing
- uint8le rp; // Pan Swing
- uint16le trkvers; // Tracker ID
- uint8le nos; // Number of embedded samples
- char reserved1; // Reserved
- char name[26]; // Instrument Name, null-terminated (but may also contain nulls)
- uint8le ifc; // Filter Cutoff
- uint8le ifr; // Filter Resonance
- uint8le mch; // MIDI Channel
- uint8le mpr; // MIDI Program
- uint8le mbank[2]; // MIDI Bank
- uint8le keyboard[240]; // Sample / Transpose map
- ITEnvelope volenv; // Volume Envelope
- ITEnvelope panenv; // Pan Envelope
- ITEnvelope pitchenv; // Pitch / Filter Envelope
- char dummy[4]; // IT saves some additional padding bytes to match the size of the old instrument format for simplified loading. We use them for some hacks.
- // Convert OpenMPT's internal instrument representation to an ITInstrument. Returns amount of bytes that need to be written.
- uint32 ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile);
- // Convert an ITInstrument to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read.
- uint32 ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const;
- };
- MPT_BINARY_STRUCT(ITInstrument, 554)
- // MPT IT Instrument Extension
- struct ITInstrumentEx
- {
- ITInstrument iti; // Normal IT Instrument
- uint8 keyboardhi[120]; // High Byte of Sample map
-
- // Convert OpenMPT's internal instrument representation to an ITInstrumentEx. Returns amount of bytes that need to be written.
- uint32 ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile);
- // Convert an ITInstrumentEx to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read.
- uint32 ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const;
- };
- MPT_BINARY_STRUCT(ITInstrumentEx, sizeof(ITInstrument) + 120)
- // IT Sample Format
- struct ITSample
- {
- // Magic Bytes
- enum Magic
- {
- magic = 0x53504D49, // "IMPS" IT Sample Header Magic Bytes
- };
- enum ITSampleFlags
- {
- sampleDataPresent = 0x01,
- sample16Bit = 0x02,
- sampleStereo = 0x04,
- sampleCompressed = 0x08,
- sampleLoop = 0x10,
- sampleSustain = 0x20,
- sampleBidiLoop = 0x40,
- sampleBidiSustain = 0x80,
- enablePanning = 0x80,
- cvtSignedSample = 0x01,
- cvtOPLInstrument = 0x40, // FM instrument in MPTM
- cvtExternalSample = 0x80, // Keep MPTM sample on disk
- cvtADPCMSample = 0xFF, // MODPlugin :(
- // ITTECH.TXT says these convert flags are "safe to ignore". IT doesn't ignore them, though, so why should we? :)
- cvtBigEndian = 0x02,
- cvtDelta = 0x04,
- cvtPTM8to16 = 0x08,
- };
- char id[4]; // Magic Bytes (IMPS)
- char filename[13]; // DOS Filename, null-terminated
- uint8le gvl; // Global Volume
- uint8le flags; // Sample Flags
- uint8le vol; // Default Volume
- char name[26]; // Sample Name, null-terminated (but may also contain nulls)
- uint8le cvt; // Sample Import Format
- uint8le dfp; // Sample Panning
- uint32le length; // Sample Length (in samples)
- uint32le loopbegin; // Sample Loop Begin (in samples)
- uint32le loopend; // Sample Loop End (in samples)
- uint32le C5Speed; // C-5 frequency
- uint32le susloopbegin; // Sample Sustain Begin (in samples)
- uint32le susloopend; // Sample Sustain End (in samples)
- uint32le samplepointer; // Pointer to sample data
- uint8le vis; // Auto-Vibrato Rate (called Sweep in IT)
- uint8le vid; // Auto-Vibrato Depth
- uint8le vir; // Auto-Vibrato Sweep (called Rate in IT)
- uint8le vit; // Auto-Vibrato Type
- // Convert OpenMPT's internal sample representation to an ITSample.
- void ConvertToIT(const ModSample &mptSmp, MODTYPE fromType, bool compress, bool compressIT215, bool allowExternal);
- // Convert an ITSample to OpenMPT's internal sample representation.
- uint32 ConvertToMPT(ModSample &mptSmp) const;
- // Retrieve the internal sample format flags for this instrument.
- SampleIO GetSampleFormat(uint16 cwtv = 0x214) const;
- };
- MPT_BINARY_STRUCT(ITSample, 80)
- struct FileHistory;
- // IT Header extension: Save history
- struct ITHistoryStruct
- {
- uint16le fatdate; // DOS / FAT date when the file was opened / created in the editor. For details, read https://docs.microsoft.com/de-de/windows/win32/api/winbase/nf-winbase-dosdatetimetofiletime
- uint16le fattime; // DOS / FAT time when the file was opened / created in the editor.
- uint32le runtime; // The time how long the file was open in the editor, in 1/18.2th seconds. (= ticks of the DOS timer)
- // Convert an ITHistoryStruct to OpenMPT's internal edit history representation
- void ConvertToMPT(FileHistory &mptHistory) const;
- // Convert OpenMPT's internal edit history representation to an ITHistoryStruct
- void ConvertToIT(const FileHistory &mptHistory);
- };
- MPT_BINARY_STRUCT(ITHistoryStruct, 8)
- enum IT_ReaderBitMasks
- {
- // pattern row parsing, the channel data is read to obtain
- // number of channels active in the pattern. These bit masks are
- // to blank out sections of the byte of data being read.
- IT_bitmask_patternChanField_c = 0x7f,
- IT_bitmask_patternChanMask_c = 0x3f,
- IT_bitmask_patternChanEnabled_c = 0x80,
- IT_bitmask_patternChanUsed_c = 0x0f
- };
- // Calculate Schism Tracker version field for IT / S3M header based on specified release date
- // Date calculation derived from https://alcor.concordia.ca/~gpkatch/gdate-algorithm.html
- template<int32 y, int32 m, int32 d>
- struct SchismVersionFromDate
- {
- private:
- static constexpr int32 mm = (m + 9) % 12;
- static constexpr int32 yy = y - mm / 10;
- public:
- static constexpr int32 date = yy * 365 + yy / 4 - yy / 100 + yy / 400 + (mm * 306 + 5) / 10 + (d - 1);
- };
- inline constexpr int32 SchismTrackerEpoch = SchismVersionFromDate<2009, 10, 31>::date;
- uint32 DecodeITEditTimer(uint16 cwtv, uint32 editTime);
- OPENMPT_NAMESPACE_END
|