aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/soundlib/ITTools.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/ITTools.h')
-rw-r--r--Src/external_dependencies/openmpt-trunk/soundlib/ITTools.h323
1 files changed, 323 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/ITTools.h b/Src/external_dependencies/openmpt-trunk/soundlib/ITTools.h
new file mode 100644
index 00000000..4176df70
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/soundlib/ITTools.h
@@ -0,0 +1,323 @@
+/*
+ * 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