Snd_defs.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. /*
  2. * Snd_Defs.h
  3. * ----------
  4. * Purpose: Basic definitions of data types, enums, etc. for the playback engine core.
  5. * Notes : (currently none)
  6. * Authors: Olivier Lapicque
  7. * OpenMPT Devs
  8. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  9. */
  10. #pragma once
  11. #include "openmpt/all/BuildSettings.hpp"
  12. #include "openmpt/base/FlagSet.hpp"
  13. OPENMPT_NAMESPACE_BEGIN
  14. using ROWINDEX = uint32;
  15. inline constexpr ROWINDEX ROWINDEX_INVALID = uint32_max;
  16. using CHANNELINDEX = uint16;
  17. inline constexpr CHANNELINDEX CHANNELINDEX_INVALID = uint16_max;
  18. using ORDERINDEX = uint16;
  19. inline constexpr ORDERINDEX ORDERINDEX_INVALID = uint16_max;
  20. inline constexpr ORDERINDEX ORDERINDEX_MAX = uint16_max - 1;
  21. using PATTERNINDEX = uint16;
  22. inline constexpr PATTERNINDEX PATTERNINDEX_INVALID = uint16_max;
  23. using PLUGINDEX = uint8;
  24. inline constexpr PLUGINDEX PLUGINDEX_INVALID = uint8_max;
  25. using SAMPLEINDEX = uint16;
  26. inline constexpr SAMPLEINDEX SAMPLEINDEX_INVALID = uint16_max;
  27. using INSTRUMENTINDEX = uint16;
  28. inline constexpr INSTRUMENTINDEX INSTRUMENTINDEX_INVALID = uint16_max;
  29. using SEQUENCEINDEX = uint8;
  30. inline constexpr SEQUENCEINDEX SEQUENCEINDEX_INVALID = uint8_max;
  31. using SmpLength = uint32;
  32. inline constexpr SmpLength MAX_SAMPLE_LENGTH = 0x10000000; // Sample length in frames. Sample size in bytes can be more than this (= 256 MB).
  33. inline constexpr ROWINDEX MAX_PATTERN_ROWS = 1024;
  34. inline constexpr ROWINDEX MAX_ROWS_PER_BEAT = 65536;
  35. inline constexpr ORDERINDEX MAX_ORDERS = ORDERINDEX_MAX + 1;
  36. inline constexpr PATTERNINDEX MAX_PATTERNS = 4000;
  37. inline constexpr SAMPLEINDEX MAX_SAMPLES = 4000;
  38. inline constexpr INSTRUMENTINDEX MAX_INSTRUMENTS = 256;
  39. inline constexpr PLUGINDEX MAX_MIXPLUGINS = 250;
  40. inline constexpr SEQUENCEINDEX MAX_SEQUENCES = 50;
  41. inline constexpr CHANNELINDEX MAX_BASECHANNELS = 127; // Maximum pattern channels.
  42. inline constexpr CHANNELINDEX MAX_CHANNELS = 256; // Maximum number of mixing channels.
  43. enum { FREQ_FRACBITS = 4 }; // Number of fractional bits in return value of CSoundFile::GetFreqFromPeriod()
  44. // String lengths (including trailing null char)
  45. enum
  46. {
  47. MAX_SAMPLENAME = 32,
  48. MAX_SAMPLEFILENAME = 22,
  49. MAX_INSTRUMENTNAME = 32,
  50. MAX_INSTRUMENTFILENAME = 32,
  51. MAX_PATTERNNAME = 32,
  52. MAX_CHANNELNAME = 20,
  53. };
  54. enum MODTYPE
  55. {
  56. MOD_TYPE_NONE = 0x00,
  57. MOD_TYPE_MOD = 0x01,
  58. MOD_TYPE_S3M = 0x02,
  59. MOD_TYPE_XM = 0x04,
  60. MOD_TYPE_MED = 0x08,
  61. MOD_TYPE_MTM = 0x10,
  62. MOD_TYPE_IT = 0x20,
  63. MOD_TYPE_669 = 0x40,
  64. MOD_TYPE_ULT = 0x80,
  65. MOD_TYPE_STM = 0x100,
  66. MOD_TYPE_FAR = 0x200,
  67. MOD_TYPE_DTM = 0x400,
  68. MOD_TYPE_AMF = 0x800,
  69. MOD_TYPE_AMS = 0x1000,
  70. MOD_TYPE_DSM = 0x2000,
  71. MOD_TYPE_MDL = 0x4000,
  72. MOD_TYPE_OKT = 0x8000,
  73. MOD_TYPE_MID = 0x10000,
  74. MOD_TYPE_DMF = 0x20000,
  75. MOD_TYPE_PTM = 0x40000,
  76. MOD_TYPE_DBM = 0x80000,
  77. MOD_TYPE_MT2 = 0x100000,
  78. MOD_TYPE_AMF0 = 0x200000,
  79. MOD_TYPE_PSM = 0x400000,
  80. MOD_TYPE_J2B = 0x800000,
  81. MOD_TYPE_MPT = 0x1000000,
  82. MOD_TYPE_IMF = 0x2000000,
  83. MOD_TYPE_DIGI = 0x4000000,
  84. MOD_TYPE_STP = 0x8000000,
  85. MOD_TYPE_PLM = 0x10000000,
  86. MOD_TYPE_SFX = 0x20000000,
  87. };
  88. DECLARE_FLAGSET(MODTYPE)
  89. enum MODCONTAINERTYPE
  90. {
  91. MOD_CONTAINERTYPE_NONE = 0x0,
  92. MOD_CONTAINERTYPE_UMX = 0x3,
  93. MOD_CONTAINERTYPE_XPK = 0x4,
  94. MOD_CONTAINERTYPE_PP20 = 0x5,
  95. MOD_CONTAINERTYPE_MMCMP= 0x6,
  96. MOD_CONTAINERTYPE_WAV = 0x7, // WAV as module
  97. MOD_CONTAINERTYPE_UAX = 0x8, // Unreal sample set as module
  98. };
  99. // Module channel / sample flags
  100. enum ChannelFlags
  101. {
  102. // Sample Flags
  103. CHN_16BIT = 0x01, // 16-bit sample
  104. CHN_LOOP = 0x02, // Looped sample
  105. CHN_PINGPONGLOOP = 0x04, // Bidi-looped sample
  106. CHN_SUSTAINLOOP = 0x08, // Sample with sustain loop
  107. CHN_PINGPONGSUSTAIN = 0x10, // Sample with bidi sustain loop
  108. CHN_PANNING = 0x20, // Sample with forced panning
  109. CHN_STEREO = 0x40, // Stereo sample
  110. CHN_REVERSE = 0x80, // Start sample playback from sample / loop end (Velvet Studio feature)
  111. CHN_SURROUND = 0x100, // Use surround channel
  112. CHN_ADLIB = 0x200, // Adlib / OPL instrument is active on this channel
  113. // Channel Flags
  114. CHN_PINGPONGFLAG = 0x80, // When flag is on, sample is processed backwards - this is intentionally the same flag as CHN_REVERSE.
  115. CHN_MUTE = 0x400, // Muted channel
  116. CHN_KEYOFF = 0x800, // Exit sustain
  117. CHN_NOTEFADE = 0x1000, // Fade note (instrument mode)
  118. CHN_WRAPPED_LOOP = 0x2000, // Loop just wrapped around to loop start (required for correct interpolation around loop points)
  119. CHN_AMIGAFILTER = 0x4000, // Apply Amiga low-pass filter
  120. CHN_FILTER = 0x8000, // Apply resonant filter on sample
  121. CHN_VOLUMERAMP = 0x10000, // Apply volume ramping
  122. CHN_VIBRATO = 0x20000, // Apply vibrato
  123. CHN_TREMOLO = 0x40000, // Apply tremolo
  124. CHN_PORTAMENTO = 0x80000, // Apply portamento
  125. CHN_GLISSANDO = 0x100000, // Glissando (force portamento to semitones) mode
  126. CHN_FASTVOLRAMP = 0x200000, // Force usage of global ramping settings instead of ramping over the complete render buffer length
  127. CHN_EXTRALOUD = 0x400000, // Force sample to play at 0dB
  128. CHN_REVERB = 0x800000, // Apply reverb on this channel
  129. CHN_NOREVERB = 0x1000000, // Disable reverb on this channel
  130. CHN_SOLO = 0x2000000, // Solo channel
  131. CHN_NOFX = 0x4000000, // Dry channel (no plugins)
  132. CHN_SYNCMUTE = 0x8000000, // Keep sample sync on mute
  133. // Sample flags (only present in ModSample::uFlags, may overlap with CHN_CHANNELFLAGS)
  134. SMP_MODIFIED = 0x2000, // Sample data has been edited in the tracker
  135. SMP_KEEPONDISK = 0x4000, // Sample is not saved to file, data is restored from original sample file
  136. SMP_NODEFAULTVOLUME = 0x8000, // Ignore default volume setting
  137. };
  138. DECLARE_FLAGSET(ChannelFlags)
  139. #define CHN_SAMPLEFLAGS (CHN_16BIT | CHN_LOOP | CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN | CHN_PANNING | CHN_STEREO | CHN_PINGPONGFLAG | CHN_REVERSE | CHN_SURROUND | CHN_ADLIB)
  140. #define CHN_CHANNELFLAGS (~CHN_SAMPLEFLAGS | CHN_SURROUND)
  141. // Sample flags fit into the first 16 bits, and with the current memory layout, storing them as a 16-bit integer packs struct ModSample nicely.
  142. using SampleFlags = FlagSet<ChannelFlags, uint16>;
  143. // Instrument envelope-specific flags
  144. enum EnvelopeFlags : uint8
  145. {
  146. ENV_ENABLED = 0x01, // env is enabled
  147. ENV_LOOP = 0x02, // env loop
  148. ENV_SUSTAIN = 0x04, // env sustain
  149. ENV_CARRY = 0x08, // env carry
  150. ENV_FILTER = 0x10, // filter env enabled (this has to be combined with ENV_ENABLED in the pitch envelope's flags)
  151. };
  152. DECLARE_FLAGSET(EnvelopeFlags)
  153. // Envelope value boundaries
  154. #define ENVELOPE_MIN 0 // Vertical min value of a point
  155. #define ENVELOPE_MID 32 // Vertical middle line
  156. #define ENVELOPE_MAX 64 // Vertical max value of a point
  157. #define MAX_ENVPOINTS 240 // Maximum length of each instrument envelope
  158. // Instrument-specific flags
  159. enum InstrumentFlags : uint8
  160. {
  161. INS_SETPANNING = 0x01, // Panning enabled
  162. INS_MUTE = 0x02, // Instrument is muted
  163. };
  164. DECLARE_FLAGSET(InstrumentFlags)
  165. // envelope types in instrument editor
  166. enum EnvelopeType : uint8
  167. {
  168. ENV_VOLUME = 0,
  169. ENV_PANNING,
  170. ENV_PITCH,
  171. ENV_MAXTYPES
  172. };
  173. // Filter Modes
  174. enum class FilterMode : uint8
  175. {
  176. Unchanged = 0xFF,
  177. LowPass = 0,
  178. HighPass = 1,
  179. };
  180. // NNA types (New Note Action)
  181. enum class NewNoteAction : uint8
  182. {
  183. NoteCut = 0,
  184. Continue = 1,
  185. NoteOff = 2,
  186. NoteFade = 3,
  187. };
  188. // DCT types (Duplicate Check Types)
  189. enum class DuplicateCheckType : uint8
  190. {
  191. None = 0,
  192. Note = 1,
  193. Sample = 2,
  194. Instrument = 3,
  195. Plugin = 4,
  196. };
  197. // DNA types (Duplicate Note Action)
  198. enum class DuplicateNoteAction : uint8
  199. {
  200. NoteCut = 0,
  201. NoteOff = 1,
  202. NoteFade = 2,
  203. };
  204. // Module flags - contains both song configuration and playback state... Use SONG_FILE_FLAGS and SONG_PLAY_FLAGS distinguish between the two.
  205. enum SongFlags
  206. {
  207. SONG_FASTVOLSLIDES = 0x02, // Old Scream Tracker 3.0 volume slides
  208. SONG_ITOLDEFFECTS = 0x04, // Old Impulse Tracker effect implementations
  209. SONG_ITCOMPATGXX = 0x08, // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects)
  210. SONG_LINEARSLIDES = 0x10, // Linear slides vs. Amiga slides
  211. SONG_PATTERNLOOP = 0x20, // Loop current pattern (pattern editor)
  212. SONG_STEP = 0x40, // Song is in "step" mode (pattern editor)
  213. SONG_PAUSED = 0x80, // Song is paused (no tick processing, just rendering audio)
  214. SONG_FADINGSONG = 0x0100, // Song is fading out
  215. SONG_ENDREACHED = 0x0200, // Song is finished
  216. SONG_FIRSTTICK = 0x1000, // Is set when the current tick is the first tick of the row
  217. SONG_MPTFILTERMODE = 0x2000, // Local filter mode (reset filter on each note)
  218. SONG_SURROUNDPAN = 0x4000, // Pan in the rear channels
  219. SONG_EXFILTERRANGE = 0x8000, // Cutoff Filter has double frequency range (up to ~10Khz)
  220. SONG_AMIGALIMITS = 0x1'0000, // Enforce amiga frequency limits
  221. SONG_S3MOLDVIBRATO = 0x2'0000, // ScreamTracker 2 vibrato in S3M files
  222. SONG_BREAKTOROW = 0x8'0000, // Break to row command encountered (internal flag, do not touch)
  223. SONG_POSJUMP = 0x10'0000, // Position jump encountered (internal flag, do not touch)
  224. SONG_PT_MODE = 0x20'0000, // ProTracker 1/2 playback mode
  225. SONG_PLAYALLSONGS = 0x40'0000, // Play all subsongs consecutively (libopenmpt)
  226. SONG_ISAMIGA = 0x80'0000, // Is an Amiga module and thus qualifies to be played using the Paula BLEP resampler
  227. SONG_IMPORTED = 0x100'0000, // Song type does not represent actual module format / was imported from a different format (OpenMPT)
  228. };
  229. DECLARE_FLAGSET(SongFlags)
  230. #define SONG_FILE_FLAGS (SONG_FASTVOLSLIDES|SONG_ITOLDEFFECTS|SONG_ITCOMPATGXX|SONG_LINEARSLIDES|SONG_EXFILTERRANGE|SONG_AMIGALIMITS|SONG_S3MOLDVIBRATO|SONG_PT_MODE|SONG_ISAMIGA|SONG_IMPORTED)
  231. #define SONG_PLAY_FLAGS (~SONG_FILE_FLAGS)
  232. // Global Options (Renderer)
  233. #ifndef NO_AGC
  234. #define SNDDSP_AGC 0x40 // Automatic gain control
  235. #endif // ~NO_AGC
  236. #ifndef NO_DSP
  237. #define SNDDSP_MEGABASS 0x02 // Bass expansion
  238. #define SNDDSP_SURROUND 0x08 // Surround mix
  239. #define SNDDSP_BITCRUSH 0x01
  240. #endif // NO_DSP
  241. #ifndef NO_REVERB
  242. #define SNDDSP_REVERB 0x20 // Apply reverb
  243. #endif // NO_REVERB
  244. #ifndef NO_EQ
  245. #define SNDDSP_EQ 0x80 // Apply EQ
  246. #endif // NO_EQ
  247. #define SNDMIX_SOFTPANNING 0x10 // Soft panning mode (this is forced with mixmode RC3 and later)
  248. // Misc Flags (can safely be turned on or off)
  249. #define SNDMIX_MAXDEFAULTPAN 0x80000 // Currently unused (should be used by Amiga MOD loaders)
  250. #define SNDMIX_MUTECHNMODE 0x100000 // Notes are not played on muted channels
  251. #define MAX_GLOBAL_VOLUME 256u
  252. // Resampling modes
  253. enum ResamplingMode : uint8
  254. {
  255. // ATTENTION: Do not change ANY of these values, as they get written out to files in per instrument interpolation settings
  256. // and old files have these exact values in them which should not change meaning.
  257. SRCMODE_NEAREST = 0, // 1 tap, no AA
  258. SRCMODE_LINEAR = 1, // 2 tap, no AA
  259. SRCMODE_CUBIC = 2, // 4 tap, no AA
  260. SRCMODE_SINC8 = 4, // 8 tap, no AA (yes, index 4) (XMMS-ModPlug)
  261. SRCMODE_SINC8LP = 3, // 8 tap, with AA (yes, index 3) (Polyphase)
  262. SRCMODE_DEFAULT = 5, // Only used for instrument settings, not used inside the mixer
  263. SRCMODE_AMIGA = 0xFF, // Not explicitely user-selectable
  264. };
  265. namespace Resampling
  266. {
  267. enum class AmigaFilter
  268. {
  269. Off = 0,
  270. A500 = 1,
  271. A1200 = 2,
  272. Unfiltered = 3,
  273. };
  274. inline std::array<ResamplingMode, 5> AllModes() noexcept { return { { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_CUBIC, SRCMODE_SINC8, SRCMODE_SINC8LP } }; }
  275. inline std::array<ResamplingMode, 6> AllModesWithDefault() noexcept { return { { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_CUBIC, SRCMODE_SINC8, SRCMODE_SINC8LP, SRCMODE_DEFAULT } }; }
  276. constexpr ResamplingMode Default() noexcept { return SRCMODE_SINC8LP; }
  277. constexpr bool IsKnownMode(int mode) noexcept { return (mode >= 0) && (mode < SRCMODE_DEFAULT); }
  278. constexpr ResamplingMode ToKnownMode(int mode) noexcept
  279. {
  280. return Resampling::IsKnownMode(mode) ? static_cast<ResamplingMode>(mode)
  281. : (mode == SRCMODE_AMIGA) ? SRCMODE_LINEAR
  282. : Resampling::Default();
  283. }
  284. constexpr int Length(ResamplingMode mode) noexcept
  285. {
  286. return mode == SRCMODE_NEAREST ? 1
  287. : mode == SRCMODE_LINEAR ? 2
  288. : mode == SRCMODE_CUBIC ? 4
  289. : mode == SRCMODE_SINC8 ? 8
  290. : mode == SRCMODE_SINC8LP ? 8
  291. : 0;
  292. }
  293. constexpr bool HasAA(ResamplingMode mode) noexcept { return (mode == SRCMODE_SINC8LP); }
  294. constexpr ResamplingMode AddAA(ResamplingMode mode) noexcept { return (mode == SRCMODE_SINC8) ? SRCMODE_SINC8LP : mode; }
  295. constexpr ResamplingMode RemoveAA(ResamplingMode mode) noexcept { return (mode == SRCMODE_SINC8LP) ? SRCMODE_SINC8 : mode; }
  296. }
  297. // Release node defines
  298. #define ENV_RELEASE_NODE_UNSET 0xFF
  299. #define NOT_YET_RELEASED (-1)
  300. static_assert(ENV_RELEASE_NODE_UNSET > MAX_ENVPOINTS);
  301. enum PluginPriority
  302. {
  303. ChannelOnly,
  304. InstrumentOnly,
  305. PrioritiseInstrument,
  306. PrioritiseChannel,
  307. };
  308. enum PluginMutePriority
  309. {
  310. EvenIfMuted,
  311. RespectMutes,
  312. };
  313. // Plugin velocity handling options
  314. enum PlugVelocityHandling : uint8
  315. {
  316. PLUGIN_VELOCITYHANDLING_CHANNEL = 0,
  317. PLUGIN_VELOCITYHANDLING_VOLUME
  318. };
  319. // Plugin volumecommand handling options
  320. enum PlugVolumeHandling : uint8
  321. {
  322. PLUGIN_VOLUMEHANDLING_MIDI = 0,
  323. PLUGIN_VOLUMEHANDLING_DRYWET,
  324. PLUGIN_VOLUMEHANDLING_IGNORE,
  325. PLUGIN_VOLUMEHANDLING_CUSTOM,
  326. PLUGIN_VOLUMEHANDLING_MAX,
  327. };
  328. enum MidiChannel : uint8
  329. {
  330. MidiNoChannel = 0,
  331. MidiFirstChannel = 1,
  332. MidiLastChannel = 16,
  333. MidiMappedChannel = 17,
  334. };
  335. // Vibrato Types
  336. enum VibratoType : uint8
  337. {
  338. VIB_SINE = 0,
  339. VIB_SQUARE,
  340. VIB_RAMP_UP,
  341. VIB_RAMP_DOWN,
  342. VIB_RANDOM
  343. };
  344. // Tracker-specific playback behaviour
  345. // Note: The index of every flag has to be fixed, so do not remove flags. Always add new flags at the end!
  346. enum PlayBehaviour
  347. {
  348. MSF_COMPATIBLE_PLAY, // No-op - only used during loading (Old general compatibility flag for IT/MPT/XM)
  349. kMPTOldSwingBehaviour, // MPT 1.16 swing behaviour (IT/MPT, deprecated)
  350. kMIDICCBugEmulation, // Emulate broken volume MIDI CC behaviour (IT/MPT/XM, deprecated)
  351. kOldMIDIPitchBends, // Old VST MIDI pitch bend behaviour (IT/MPT/XM, deprecated)
  352. kFT2VolumeRamping, // Smooth volume ramping like in FT2 (XM)
  353. kMODVBlankTiming, // F21 and above set speed instead of tempo
  354. kSlidesAtSpeed1, // Execute normal slides at speed 1 as if they were fine slides
  355. kPeriodsAreHertz, // Compute note frequency in Hertz rather than periods
  356. kTempoClamp, // Clamp tempo to 32-255 range.
  357. kPerChannelGlobalVolSlide, // Global volume slide memory is per-channel
  358. kPanOverride, // Panning commands override surround and random pan variation
  359. kITInstrWithoutNote, // Avoid instrument handling if there is no note
  360. kITVolColFinePortamento, // Volume column portamento never does fine portamento
  361. kITArpeggio, // IT arpeggio algorithm
  362. kITOutOfRangeDelay, // Out-of-range delay command behaviour in IT
  363. kITPortaMemoryShare, // Gxx shares memory with Exx and Fxx
  364. kITPatternLoopTargetReset, // After finishing a pattern loop, set the pattern loop target to the next row
  365. kITFT2PatternLoop, // Nested pattern loop behaviour
  366. kITPingPongNoReset, // Don't reset ping pong direction with instrument numbers
  367. kITEnvelopeReset, // IT envelope reset behaviour
  368. kITClearOldNoteAfterCut, // Forget the previous note after cutting it
  369. kITVibratoTremoloPanbrello, // More IT-like Hxx / hx, Rxx, Yxx and autovibrato handling, including more precise LUTs
  370. kITTremor, // Ixx behaves like in IT
  371. kITRetrigger, // Qxx behaves like in IT
  372. kITMultiSampleBehaviour, // Properly update C-5 frequency when changing in multisampled instrument
  373. kITPortaTargetReached, // Clear portamento target after it has been reached
  374. kITPatternLoopBreak, // Don't reset loop count on pattern break.
  375. kITOffset, // IT-style Oxx edge case handling
  376. kITSwingBehaviour, // IT's swing behaviour
  377. kITNNAReset, // NNA is reset on every note change, not every instrument change
  378. kITSCxStopsSample, // SCx really stops the sample and does not just mute it
  379. kITEnvelopePositionHandling, // IT-style envelope position advance + enable/disable behaviour
  380. kITPortamentoInstrument, // No sample changes during portamento with Compatible Gxx enabled, instrument envelope reset with portamento
  381. kITPingPongMode, // Don't repeat last sample point in ping pong loop, like IT's software mixer
  382. kITRealNoteMapping, // Use triggered note rather than translated note for PPS and other effects
  383. kITHighOffsetNoRetrig, // SAx should not apply an offset effect to a note next to it
  384. kITFilterBehaviour, // User IT's filter coefficients (unless extended filter range is used)
  385. kITNoSurroundPan, // Panning and surround are mutually exclusive
  386. kITShortSampleRetrig, // Don't retrigger already stopped channels
  387. kITPortaNoNote, // Don't apply any portamento if no previous note is playing
  388. kITFT2DontResetNoteOffOnPorta, // Only reset note-off status on portamento in IT Compatible Gxx mode
  389. kITVolColMemory, // IT volume column effects share their memory with the effect column
  390. kITPortamentoSwapResetsPos, // Portamento with sample swap plays the new sample from the beginning
  391. kITEmptyNoteMapSlot, // IT ignores instrument note map entries with no note completely
  392. kITFirstTickHandling, // IT-style first tick handling
  393. kITSampleAndHoldPanbrello, // IT-style sample&hold panbrello waveform
  394. kITClearPortaTarget, // New notes reset portamento target in IT
  395. kITPanbrelloHold, // Don't reset panbrello effect until next note or panning effect
  396. kITPanningReset, // Sample and instrument panning is only applied on note change, not instrument change
  397. kITPatternLoopWithJumpsOld, // Bxx on the same row as SBx terminates the loop in IT (old implementation of kITPatternLoopWithJumps)
  398. kITInstrWithNoteOff, // Instrument number with note-off recalls default volume
  399. kFT2Arpeggio, // FT2 arpeggio algorithm
  400. kFT2Retrigger, // Rxx behaves like in FT2
  401. kFT2VolColVibrato, // Vibrato depth in volume column does not actually execute the vibrato effect
  402. kFT2PortaNoNote, // Don't play portamento-ed note if no previous note is playing
  403. kFT2KeyOff, // FT2-style Kxx handling
  404. kFT2PanSlide, // Volume-column pan slides should be handled like fine slides
  405. kFT2ST3OffsetOutOfRange, // Offset past sample end stops the note
  406. kFT2RestrictXCommand, // Don't allow MPT extensions to Xxx command in XM
  407. kFT2RetrigWithNoteDelay, // Retrigger envelopes if there is a note delay with no note
  408. kFT2SetPanEnvPos, // Lxx only sets the pan env position if the volume envelope's sustain flag is set
  409. kFT2PortaIgnoreInstr, // Portamento plus instrument number applies the volume settings of the new sample, but not the new sample itself.
  410. kFT2VolColMemory, // No volume column memory in FT2
  411. kFT2LoopE60Restart, // Next pattern starts on the same row as the last E60 command
  412. kFT2ProcessSilentChannels, // Keep processing silent channels for later 3xx pickup
  413. kFT2ReloadSampleSettings, // Reload sample settings even if a note-off is placed next to an instrument number
  414. kFT2PortaDelay, // Portamento with note delay next to it is ignored in FT2
  415. kFT2Transpose, // Out-of-range transposed notes in FT2
  416. kFT2PatternLoopWithJumps, // Bxx or Dxx on the same row as E6x terminates the loop in FT2
  417. kFT2PortaTargetNoReset, // Portamento target is not reset with new notes in FT2
  418. kFT2EnvelopeEscape, // FT2 sustain point at end of envelope
  419. kFT2Tremor, // Txx behaves like in FT2
  420. kFT2OutOfRangeDelay, // Out-of-range delay command behaviour in FT2
  421. kFT2Periods, // Use FT2's broken period handling
  422. kFT2PanWithDelayedNoteOff, // Pan command with delayed note-off
  423. kFT2VolColDelay, // FT2-style volume column handling if there is a note delay
  424. kFT2FinetunePrecision, // Only take the upper 4 bits of sample finetune.
  425. kST3NoMutedChannels, // Don't process any effects on muted S3M channels
  426. kST3EffectMemory, // Most effects share the same memory in ST3
  427. kST3PortaSampleChange, // Portamento plus instrument number applies the volume settings of the new sample, but not the new sample itself (GUS behaviour).
  428. kST3VibratoMemory, // Do not remember vibrato type in effect memory
  429. kST3LimitPeriod, // Cut note instead of limiting final period (ModPlug Tracker style)
  430. KST3PortaAfterArpeggio, // Portamento after arpeggio continues at the note where the arpeggio left off
  431. kMODOneShotLoops, // Allow ProTracker-like oneshot loops
  432. kMODIgnorePanning, // Do not process any panning commands
  433. kMODSampleSwap, // On-the-fly sample swapping
  434. kFT2NoteOffFlags, // Set and reset the correct fade/key-off flags with note-off and instrument number after note-off
  435. kITMultiSampleInstrumentNumber, // After portamento to different sample within multi-sampled instrument, lone instrument numbers in patterns always recall the new sample's default settings
  436. kRowDelayWithNoteDelay, // Retrigger note delays on every reptition of a row
  437. kFT2MODTremoloRampWaveform, // FT2-/ProTracker-compatible tremolo ramp down / triangle waveform
  438. kFT2PortaUpDownMemory, // Portamento up and down have separate memory
  439. kMODOutOfRangeNoteDelay, // ProTracker behaviour for out-of-range note delays
  440. kMODTempoOnSecondTick, // ProTracker sets tempo after the first tick
  441. kFT2PanSustainRelease, // If the sustain point of a panning envelope is reached before key-off, FT2 does not escape it anymore
  442. kLegacyReleaseNode, // Legacy release node volume processing
  443. kOPLBeatingOscillators, // Emulate beating FM oscillators from CDFM / Composer 670
  444. kST3OffsetWithoutInstrument, // Note without instrument uses same offset as previous note
  445. kReleaseNodePastSustainBug, // OpenMPT 1.23.01.02 / r4009 broke release nodes past the sustain point, fixed in OpenMPT 1.28
  446. kFT2NoteDelayWithoutInstr, // Sometime between OpenMPT 1.18.03.00 and 1.19.01.00, delayed instrument-less notes in XM started recalling the default sample volume and panning
  447. kOPLFlexibleNoteOff, // Full control after note-off over OPL voices, ^^^ sends note cut instead of just note-off
  448. kITInstrWithNoteOffOldEffects, // Instrument number with note-off recalls default volume - special cases with Old Effects enabled
  449. kMIDIVolumeOnNoteOffBug, // Update MIDI channel volume on note-off (legacy bug emulation)
  450. kITDoNotOverrideChannelPan, // Sample / instrument pan does not override channel pan for following samples / instruments that are not panned
  451. kITPatternLoopWithJumps, // Bxx right of SBx terminates the loop in IT
  452. kITDCTBehaviour, // DCT="Sample" requires sample instrument, DCT="Note" checks old pattern note against new pattern note (previously was checking old pattern note against new translated note)
  453. kOPLwithNNA, // NNA note-off / fade are applied to OPL channels
  454. kST3RetrigAfterNoteCut, // Qxy does not retrigger note after it has been cut with ^^^ or SCx
  455. kST3SampleSwap, // On-the-fly sample swapping (SoundBlaster behaviour)
  456. kOPLRealRetrig, // Retrigger effect (Qxy) restarts OPL notes
  457. kOPLNoResetAtEnvelopeEnd, // Do not reset OPL channel status at end of envelope (OpenMPT 1.28 inconsistency with samples)
  458. kOPLNoteStopWith0Hz, // Set note frequency to 0 Hz to "stop" OPL notes
  459. kOPLNoteOffOnNoteChange, // Send note-off events for old note on every note change
  460. kFT2PortaResetDirection, // Reset portamento direction when reaching portamento target from below
  461. kApplyUpperPeriodLimit, // Enforce m_nMaxPeriod
  462. kApplyOffsetWithoutNote, // Offset commands even work when there's no note next to them (e.g. DMF, MDL, PLM formats)
  463. kITPitchPanSeparation, // Pitch/Pan Separation can be overridden by panning commands (this also fixes a bug where any "special" notes affect PPS)
  464. kImprecisePingPongLoops, // Use old (less precise) ping-pong overshoot calculation
  465. // Add new play behaviours here.
  466. kMaxPlayBehaviours,
  467. };
  468. // Tempo swing determines how much every row in modern tempo mode contributes to a beat.
  469. class TempoSwing : public std::vector<uint32>
  470. {
  471. public:
  472. static constexpr uint32 Unity = 1u << 24;
  473. // Normalize the tempo swing coefficients so that they add up to exactly the specified tempo again
  474. void Normalize();
  475. void resize(size_type newSize, value_type val = Unity) { std::vector<uint32>::resize(newSize, val); Normalize(); }
  476. static void Serialize(std::ostream &oStrm, const TempoSwing &swing);
  477. static void Deserialize(std::istream &iStrm, TempoSwing &swing, const size_t);
  478. };
  479. // Sample position and sample position increment value
  480. struct SamplePosition
  481. {
  482. using value_t = int64;
  483. using unsigned_value_t = uint64;
  484. protected:
  485. value_t v = 0;
  486. public:
  487. static constexpr uint32 fractMax = 0xFFFFFFFFu;
  488. MPT_CONSTEXPRINLINE SamplePosition() { }
  489. MPT_CONSTEXPRINLINE explicit SamplePosition(value_t pos) : v(pos) { }
  490. MPT_CONSTEXPRINLINE SamplePosition(int32 intPart, uint32 fractPart) : v((static_cast<value_t>(intPart) * (1ll << 32)) | fractPart) { }
  491. static SamplePosition Ratio(uint32 dividend, uint32 divisor) { return SamplePosition((static_cast<int64>(dividend) << 32) / divisor); }
  492. static SamplePosition FromDouble(double pos) { return SamplePosition(static_cast<value_t>(pos * 4294967296.0)); }
  493. double ToDouble() const { return v / 4294967296.0; }
  494. // Set integer and fractional part
  495. MPT_CONSTEXPRINLINE SamplePosition &Set(int32 intPart, uint32 fractPart = 0) { v = (static_cast<int64>(intPart) << 32) | fractPart; return *this; }
  496. // Set integer part, keep fractional part
  497. MPT_CONSTEXPRINLINE SamplePosition &SetInt(int32 intPart) { v = (static_cast<value_t>(intPart) << 32) | GetFract(); return *this; }
  498. // Get integer part (as sample length / position)
  499. MPT_CONSTEXPRINLINE SmpLength GetUInt() const { return static_cast<SmpLength>(static_cast<unsigned_value_t>(v) >> 32); }
  500. // Get integer part
  501. MPT_CONSTEXPRINLINE int32 GetInt() const { return static_cast<int32>(static_cast<unsigned_value_t>(v) >> 32); }
  502. // Get fractional part
  503. MPT_CONSTEXPRINLINE uint32 GetFract() const { return static_cast<uint32>(v); }
  504. // Get the inverted fractional part
  505. MPT_CONSTEXPRINLINE SamplePosition GetInvertedFract() const { return SamplePosition(0x100000000ll - GetFract()); }
  506. // Get the raw fixed-point value
  507. MPT_CONSTEXPRINLINE int64 GetRaw() const { return v; }
  508. // Negate the current value
  509. MPT_CONSTEXPRINLINE SamplePosition &Negate() { v = -v; return *this; }
  510. // Multiply and divide by given integer scalars
  511. MPT_CONSTEXPRINLINE SamplePosition &MulDiv(uint32 mul, uint32 div) { v = (v * mul) / div; return *this; }
  512. // Removes the integer part, only keeping fractions
  513. MPT_CONSTEXPRINLINE SamplePosition &RemoveInt() { v &= fractMax; return *this; }
  514. // Check if value is 1.0
  515. MPT_CONSTEXPRINLINE bool IsUnity() const { return v == 0x100000000ll; }
  516. // Check if value is 0
  517. MPT_CONSTEXPRINLINE bool IsZero() const { return v == 0; }
  518. // Check if value is > 0
  519. MPT_CONSTEXPRINLINE bool IsPositive() const { return v > 0; }
  520. // Check if value is < 0
  521. MPT_CONSTEXPRINLINE bool IsNegative() const { return v < 0; }
  522. // Addition / subtraction of another fixed-point number
  523. SamplePosition operator+ (const SamplePosition &other) const { return SamplePosition(v + other.v); }
  524. SamplePosition operator- (const SamplePosition &other) const { return SamplePosition(v - other.v); }
  525. void operator+= (const SamplePosition &other) { v += other.v; }
  526. void operator-= (const SamplePosition &other) { v -= other.v; }
  527. // Multiplication with integer scalar
  528. template<typename T>
  529. SamplePosition operator* (T other) const { return SamplePosition(static_cast<value_t>(v * other)); }
  530. template<typename T>
  531. void operator*= (T other) { v = static_cast<value_t>(v *other); }
  532. // Division by other fractional point number; returns scalar
  533. value_t operator/ (SamplePosition other) const { return v / other.v; }
  534. // Division by scalar; returns fractional point number
  535. SamplePosition operator/ (int div) const { return SamplePosition(v / div); }
  536. MPT_CONSTEXPRINLINE bool operator==(const SamplePosition &other) const { return v == other.v; }
  537. MPT_CONSTEXPRINLINE bool operator!=(const SamplePosition &other) const { return v != other.v; }
  538. MPT_CONSTEXPRINLINE bool operator<=(const SamplePosition &other) const { return v <= other.v; }
  539. MPT_CONSTEXPRINLINE bool operator>=(const SamplePosition &other) const { return v >= other.v; }
  540. MPT_CONSTEXPRINLINE bool operator<(const SamplePosition &other) const { return v < other.v; }
  541. MPT_CONSTEXPRINLINE bool operator>(const SamplePosition &other) const { return v > other.v; }
  542. };
  543. // Aaaand another fixed-point type, e.g. used for fractional tempos
  544. // Note that this doesn't use classical bit shifting for the fixed point part.
  545. // This is mostly for the clarity of stored values and to be able to represent any value .0000 to .9999 properly.
  546. // For easier debugging, use the Debugger Visualizers available in build/vs/debug/
  547. // to easily display the stored values.
  548. template<size_t FFact, typename T>
  549. struct FPInt
  550. {
  551. protected:
  552. T v;
  553. MPT_CONSTEXPRINLINE FPInt(T rawValue) : v(rawValue) { }
  554. public:
  555. enum : size_t { fractFact = FFact };
  556. using store_t = T;
  557. MPT_CONSTEXPRINLINE FPInt() : v(0) { }
  558. MPT_CONSTEXPRINLINE FPInt(T intPart, T fractPart) : v((intPart * fractFact) + (fractPart % fractFact)) { }
  559. explicit MPT_CONSTEXPRINLINE FPInt(float f) : v(mpt::saturate_round<T>(f * float(fractFact))) { }
  560. explicit MPT_CONSTEXPRINLINE FPInt(double f) : v(mpt::saturate_round<T>(f * double(fractFact))) { }
  561. // Set integer and fractional part
  562. MPT_CONSTEXPRINLINE FPInt<fractFact, T> &Set(T intPart, T fractPart = 0) { v = (intPart * fractFact) + (fractPart % fractFact); return *this; }
  563. // Set raw internal representation directly
  564. MPT_CONSTEXPRINLINE FPInt<fractFact, T> &SetRaw(T value) { v = value; return *this; }
  565. // Retrieve the integer part of the stored value
  566. MPT_CONSTEXPRINLINE T GetInt() const { return v / fractFact; }
  567. // Retrieve the fractional part of the stored value
  568. MPT_CONSTEXPRINLINE T GetFract() const { return v % fractFact; }
  569. // Retrieve the raw internal representation of the stored value
  570. MPT_CONSTEXPRINLINE T GetRaw() const { return v; }
  571. // Formats the stored value as a floating-point value
  572. MPT_CONSTEXPRINLINE double ToDouble() const { return v / double(fractFact); }
  573. MPT_CONSTEXPRINLINE friend FPInt<fractFact, T> operator+ (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return FPInt<fractFact, T>(a.v + b.v); }
  574. MPT_CONSTEXPRINLINE friend FPInt<fractFact, T> operator- (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return FPInt<fractFact, T>(a.v - b.v); }
  575. MPT_CONSTEXPRINLINE FPInt<fractFact, T> operator+= (const FPInt<fractFact, T> &other) noexcept { v += other.v; return *this; }
  576. MPT_CONSTEXPRINLINE FPInt<fractFact, T> operator-= (const FPInt<fractFact, T> &other) noexcept { v -= other.v; return *this; }
  577. MPT_CONSTEXPRINLINE friend bool operator== (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v == b.v; }
  578. MPT_CONSTEXPRINLINE friend bool operator!= (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v != b.v; }
  579. MPT_CONSTEXPRINLINE friend bool operator<= (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v <= b.v; }
  580. MPT_CONSTEXPRINLINE friend bool operator>= (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v >= b.v; }
  581. MPT_CONSTEXPRINLINE friend bool operator< (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v < b.v; }
  582. MPT_CONSTEXPRINLINE friend bool operator> (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v > b.v; }
  583. };
  584. using TEMPO = FPInt<10000, uint32>;
  585. using OPLPatch = std::array<uint8, 12>;
  586. OPENMPT_NAMESPACE_END