1
0

ITTools.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*
  2. * ITTools.h
  3. * ---------
  4. * Purpose: Definition of IT file structures and helper functions
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #pragma once
  10. #include "openmpt/all/BuildSettings.hpp"
  11. #include "../soundlib/ModInstrument.h"
  12. #include "../soundlib/ModSample.h"
  13. #include "../soundlib/SampleIO.h"
  14. OPENMPT_NAMESPACE_BEGIN
  15. struct ITFileHeader
  16. {
  17. // Header Flags
  18. enum ITHeaderFlags
  19. {
  20. useStereoPlayback = 0x01,
  21. vol0Optimisations = 0x02,
  22. instrumentMode = 0x04,
  23. linearSlides = 0x08,
  24. itOldEffects = 0x10,
  25. itCompatGxx = 0x20,
  26. useMIDIPitchController = 0x40,
  27. reqEmbeddedMIDIConfig = 0x80,
  28. extendedFilterRange = 0x1000,
  29. };
  30. // Special Flags
  31. enum ITHeaderSpecialFlags
  32. {
  33. embedSongMessage = 0x01,
  34. embedEditHistory = 0x02,
  35. embedPatternHighlights = 0x04,
  36. embedMIDIConfiguration = 0x08,
  37. };
  38. char id[4]; // Magic Bytes (IMPM)
  39. char songname[26]; // Song Name, null-terminated (but may also contain nulls)
  40. uint8le highlight_minor; // Rows per Beat highlight
  41. uint8le highlight_major; // Rows per Measure highlight
  42. uint16le ordnum; // Number of Orders
  43. uint16le insnum; // Number of Instruments
  44. uint16le smpnum; // Number of Samples
  45. uint16le patnum; // Number of Patterns
  46. uint16le cwtv; // "Made With" Tracker
  47. uint16le cmwt; // "Compatible With" Tracker
  48. uint16le flags; // Header Flags
  49. uint16le special; // Special Flags, for embedding extra information
  50. uint8le globalvol; // Global Volume (0...128)
  51. uint8le mv; // Master Volume (0...128), referred to as Sample Volume in OpenMPT
  52. uint8le speed; // Initial Speed (1...255)
  53. uint8le tempo; // Initial Tempo (31...255)
  54. uint8le sep; // Pan Separation (0...128)
  55. uint8le pwd; // Pitch Wheel Depth
  56. uint16le msglength; // Length of Song Message
  57. uint32le msgoffset; // Offset of Song Message in File (IT crops message after first null)
  58. uint32le reserved; // Some IT versions save an edit timer here. ChibiTracker writes "CHBI" here. OpenMPT and Schism Tracker save extended version information here.
  59. uint8le chnpan[64]; // Initial Channel Panning
  60. uint8le chnvol[64]; // Initial Channel Volume
  61. };
  62. MPT_BINARY_STRUCT(ITFileHeader, 192)
  63. struct ITEnvelope
  64. {
  65. // Envelope Flags
  66. enum ITEnvelopeFlags
  67. {
  68. envEnabled = 0x01,
  69. envLoop = 0x02,
  70. envSustain = 0x04,
  71. envCarry = 0x08,
  72. envFilter = 0x80,
  73. };
  74. struct Node
  75. {
  76. int8le value;
  77. uint16le tick;
  78. };
  79. uint8 flags; // Envelope Flags
  80. uint8 num; // Number of Envelope Nodes
  81. uint8 lpb; // Loop Start
  82. uint8 lpe; // Loop End
  83. uint8 slb; // Sustain Start
  84. uint8 sle; // Sustain End
  85. Node data[25]; // Envelope Node Positions / Values
  86. uint8 reserved; // Reserved
  87. // Convert OpenMPT's internal envelope format to an IT/MPTM envelope.
  88. void ConvertToIT(const InstrumentEnvelope &mptEnv, uint8 envOffset, uint8 envDefault);
  89. // Convert IT/MPTM envelope data into OpenMPT's internal envelope format - To be used by ITInstrToMPT()
  90. void ConvertToMPT(InstrumentEnvelope &mptEnv, uint8 envOffset, uint8 maxNodes) const;
  91. };
  92. MPT_BINARY_STRUCT(ITEnvelope::Node, 3)
  93. MPT_BINARY_STRUCT(ITEnvelope, 82)
  94. // Old Impulse Instrument Format (cmwt < 0x200)
  95. struct ITOldInstrument
  96. {
  97. enum ITOldInstrFlags
  98. {
  99. envEnabled = 0x01,
  100. envLoop = 0x02,
  101. envSustain = 0x04,
  102. };
  103. char id[4]; // Magic Bytes (IMPI)
  104. char filename[13]; // DOS Filename, null-terminated
  105. uint8le flags; // Volume Envelope Flags
  106. uint8le vls; // Envelope Loop Start
  107. uint8le vle; // Envelope Loop End
  108. uint8le sls; // Envelope Sustain Start
  109. uint8le sle; // Envelope Sustain End
  110. char reserved1[2]; // Reserved
  111. uint16le fadeout; // Instrument Fadeout (0...128)
  112. uint8le nna; // New Note Action
  113. uint8le dnc; // Duplicate Note Check Type
  114. uint16le trkvers; // Tracker ID
  115. uint8le nos; // Number of embedded samples
  116. char reserved2; // Reserved
  117. char name[26]; // Instrument Name, null-terminated (but may also contain nulls)
  118. char reserved3[6]; // Even more reserved bytes
  119. uint8le keyboard[240]; // Sample / Transpose map
  120. uint8le volenv[200]; // This appears to be a pre-computed (interpolated) version of the volume envelope data found below.
  121. uint8le nodes[25 * 2]; // Volume Envelope Node Positions / Values
  122. // Convert an ITOldInstrument to OpenMPT's internal instrument representation.
  123. void ConvertToMPT(ModInstrument &mptIns) const;
  124. };
  125. MPT_BINARY_STRUCT(ITOldInstrument, 554)
  126. // Impulse Instrument Format
  127. struct ITInstrument
  128. {
  129. enum ITInstrumentFlags
  130. {
  131. ignorePanning = 0x80,
  132. enableCutoff = 0x80,
  133. enableResonance = 0x80,
  134. };
  135. char id[4]; // Magic Bytes (IMPI)
  136. char filename[13]; // DOS Filename, null-terminated
  137. uint8le nna; // New Note Action
  138. uint8le dct; // Duplicate Note Check Type
  139. uint8le dca; // Duplicate Note Check Action
  140. uint16le fadeout; // Instrument Fadeout (0...256, although values up to 1024 would be sensible. Up to IT2.07, the limit was 0...128)
  141. int8le pps; // Pitch/Pan Separatation
  142. uint8le ppc; // Pitch/Pan Centre
  143. uint8le gbv; // Global Volume
  144. uint8le dfp; // Panning
  145. uint8le rv; // Vol Swing
  146. uint8le rp; // Pan Swing
  147. uint16le trkvers; // Tracker ID
  148. uint8le nos; // Number of embedded samples
  149. char reserved1; // Reserved
  150. char name[26]; // Instrument Name, null-terminated (but may also contain nulls)
  151. uint8le ifc; // Filter Cutoff
  152. uint8le ifr; // Filter Resonance
  153. uint8le mch; // MIDI Channel
  154. uint8le mpr; // MIDI Program
  155. uint8le mbank[2]; // MIDI Bank
  156. uint8le keyboard[240]; // Sample / Transpose map
  157. ITEnvelope volenv; // Volume Envelope
  158. ITEnvelope panenv; // Pan Envelope
  159. ITEnvelope pitchenv; // Pitch / Filter Envelope
  160. 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.
  161. // Convert OpenMPT's internal instrument representation to an ITInstrument. Returns amount of bytes that need to be written.
  162. uint32 ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile);
  163. // Convert an ITInstrument to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read.
  164. uint32 ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const;
  165. };
  166. MPT_BINARY_STRUCT(ITInstrument, 554)
  167. // MPT IT Instrument Extension
  168. struct ITInstrumentEx
  169. {
  170. ITInstrument iti; // Normal IT Instrument
  171. uint8 keyboardhi[120]; // High Byte of Sample map
  172. // Convert OpenMPT's internal instrument representation to an ITInstrumentEx. Returns amount of bytes that need to be written.
  173. uint32 ConvertToIT(const ModInstrument &mptIns, bool compatExport, const CSoundFile &sndFile);
  174. // Convert an ITInstrumentEx to OpenMPT's internal instrument representation. Returns size of the instrument data that has been read.
  175. uint32 ConvertToMPT(ModInstrument &mptIns, MODTYPE fromType) const;
  176. };
  177. MPT_BINARY_STRUCT(ITInstrumentEx, sizeof(ITInstrument) + 120)
  178. // IT Sample Format
  179. struct ITSample
  180. {
  181. // Magic Bytes
  182. enum Magic
  183. {
  184. magic = 0x53504D49, // "IMPS" IT Sample Header Magic Bytes
  185. };
  186. enum ITSampleFlags
  187. {
  188. sampleDataPresent = 0x01,
  189. sample16Bit = 0x02,
  190. sampleStereo = 0x04,
  191. sampleCompressed = 0x08,
  192. sampleLoop = 0x10,
  193. sampleSustain = 0x20,
  194. sampleBidiLoop = 0x40,
  195. sampleBidiSustain = 0x80,
  196. enablePanning = 0x80,
  197. cvtSignedSample = 0x01,
  198. cvtOPLInstrument = 0x40, // FM instrument in MPTM
  199. cvtExternalSample = 0x80, // Keep MPTM sample on disk
  200. cvtADPCMSample = 0xFF, // MODPlugin :(
  201. // ITTECH.TXT says these convert flags are "safe to ignore". IT doesn't ignore them, though, so why should we? :)
  202. cvtBigEndian = 0x02,
  203. cvtDelta = 0x04,
  204. cvtPTM8to16 = 0x08,
  205. };
  206. char id[4]; // Magic Bytes (IMPS)
  207. char filename[13]; // DOS Filename, null-terminated
  208. uint8le gvl; // Global Volume
  209. uint8le flags; // Sample Flags
  210. uint8le vol; // Default Volume
  211. char name[26]; // Sample Name, null-terminated (but may also contain nulls)
  212. uint8le cvt; // Sample Import Format
  213. uint8le dfp; // Sample Panning
  214. uint32le length; // Sample Length (in samples)
  215. uint32le loopbegin; // Sample Loop Begin (in samples)
  216. uint32le loopend; // Sample Loop End (in samples)
  217. uint32le C5Speed; // C-5 frequency
  218. uint32le susloopbegin; // Sample Sustain Begin (in samples)
  219. uint32le susloopend; // Sample Sustain End (in samples)
  220. uint32le samplepointer; // Pointer to sample data
  221. uint8le vis; // Auto-Vibrato Rate (called Sweep in IT)
  222. uint8le vid; // Auto-Vibrato Depth
  223. uint8le vir; // Auto-Vibrato Sweep (called Rate in IT)
  224. uint8le vit; // Auto-Vibrato Type
  225. // Convert OpenMPT's internal sample representation to an ITSample.
  226. void ConvertToIT(const ModSample &mptSmp, MODTYPE fromType, bool compress, bool compressIT215, bool allowExternal);
  227. // Convert an ITSample to OpenMPT's internal sample representation.
  228. uint32 ConvertToMPT(ModSample &mptSmp) const;
  229. // Retrieve the internal sample format flags for this instrument.
  230. SampleIO GetSampleFormat(uint16 cwtv = 0x214) const;
  231. };
  232. MPT_BINARY_STRUCT(ITSample, 80)
  233. struct FileHistory;
  234. // IT Header extension: Save history
  235. struct ITHistoryStruct
  236. {
  237. 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
  238. uint16le fattime; // DOS / FAT time when the file was opened / created in the editor.
  239. uint32le runtime; // The time how long the file was open in the editor, in 1/18.2th seconds. (= ticks of the DOS timer)
  240. // Convert an ITHistoryStruct to OpenMPT's internal edit history representation
  241. void ConvertToMPT(FileHistory &mptHistory) const;
  242. // Convert OpenMPT's internal edit history representation to an ITHistoryStruct
  243. void ConvertToIT(const FileHistory &mptHistory);
  244. };
  245. MPT_BINARY_STRUCT(ITHistoryStruct, 8)
  246. enum IT_ReaderBitMasks
  247. {
  248. // pattern row parsing, the channel data is read to obtain
  249. // number of channels active in the pattern. These bit masks are
  250. // to blank out sections of the byte of data being read.
  251. IT_bitmask_patternChanField_c = 0x7f,
  252. IT_bitmask_patternChanMask_c = 0x3f,
  253. IT_bitmask_patternChanEnabled_c = 0x80,
  254. IT_bitmask_patternChanUsed_c = 0x0f
  255. };
  256. // Calculate Schism Tracker version field for IT / S3M header based on specified release date
  257. // Date calculation derived from https://alcor.concordia.ca/~gpkatch/gdate-algorithm.html
  258. template<int32 y, int32 m, int32 d>
  259. struct SchismVersionFromDate
  260. {
  261. private:
  262. static constexpr int32 mm = (m + 9) % 12;
  263. static constexpr int32 yy = y - mm / 10;
  264. public:
  265. static constexpr int32 date = yy * 365 + yy / 4 - yy / 100 + yy / 400 + (mm * 306 + 5) / 10 + (d - 1);
  266. };
  267. inline constexpr int32 SchismTrackerEpoch = SchismVersionFromDate<2009, 10, 31>::date;
  268. uint32 DecodeITEditTimer(uint16 cwtv, uint32 editTime);
  269. OPENMPT_NAMESPACE_END