123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693 |
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include "openmpt/base/FlagSet.hpp"
- OPENMPT_NAMESPACE_BEGIN
- using ROWINDEX = uint32;
- inline constexpr ROWINDEX ROWINDEX_INVALID = uint32_max;
- using CHANNELINDEX = uint16;
- inline constexpr CHANNELINDEX CHANNELINDEX_INVALID = uint16_max;
- using ORDERINDEX = uint16;
- inline constexpr ORDERINDEX ORDERINDEX_INVALID = uint16_max;
- inline constexpr ORDERINDEX ORDERINDEX_MAX = uint16_max - 1;
- using PATTERNINDEX = uint16;
- inline constexpr PATTERNINDEX PATTERNINDEX_INVALID = uint16_max;
- using PLUGINDEX = uint8;
- inline constexpr PLUGINDEX PLUGINDEX_INVALID = uint8_max;
- using SAMPLEINDEX = uint16;
- inline constexpr SAMPLEINDEX SAMPLEINDEX_INVALID = uint16_max;
- using INSTRUMENTINDEX = uint16;
- inline constexpr INSTRUMENTINDEX INSTRUMENTINDEX_INVALID = uint16_max;
- using SEQUENCEINDEX = uint8;
- inline constexpr SEQUENCEINDEX SEQUENCEINDEX_INVALID = uint8_max;
- using SmpLength = uint32;
- inline constexpr SmpLength MAX_SAMPLE_LENGTH = 0x10000000;
- inline constexpr ROWINDEX MAX_PATTERN_ROWS = 1024;
- inline constexpr ROWINDEX MAX_ROWS_PER_BEAT = 65536;
- inline constexpr ORDERINDEX MAX_ORDERS = ORDERINDEX_MAX + 1;
- inline constexpr PATTERNINDEX MAX_PATTERNS = 4000;
- inline constexpr SAMPLEINDEX MAX_SAMPLES = 4000;
- inline constexpr INSTRUMENTINDEX MAX_INSTRUMENTS = 256;
- inline constexpr PLUGINDEX MAX_MIXPLUGINS = 250;
- inline constexpr SEQUENCEINDEX MAX_SEQUENCES = 50;
- inline constexpr CHANNELINDEX MAX_BASECHANNELS = 127;
- inline constexpr CHANNELINDEX MAX_CHANNELS = 256;
- enum { FREQ_FRACBITS = 4 };
- enum
- {
- MAX_SAMPLENAME = 32,
- MAX_SAMPLEFILENAME = 22,
- MAX_INSTRUMENTNAME = 32,
- MAX_INSTRUMENTFILENAME = 32,
- MAX_PATTERNNAME = 32,
- MAX_CHANNELNAME = 20,
- };
- enum MODTYPE
- {
- MOD_TYPE_NONE = 0x00,
- MOD_TYPE_MOD = 0x01,
- MOD_TYPE_S3M = 0x02,
- MOD_TYPE_XM = 0x04,
- MOD_TYPE_MED = 0x08,
- MOD_TYPE_MTM = 0x10,
- MOD_TYPE_IT = 0x20,
- MOD_TYPE_669 = 0x40,
- MOD_TYPE_ULT = 0x80,
- MOD_TYPE_STM = 0x100,
- MOD_TYPE_FAR = 0x200,
- MOD_TYPE_DTM = 0x400,
- MOD_TYPE_AMF = 0x800,
- MOD_TYPE_AMS = 0x1000,
- MOD_TYPE_DSM = 0x2000,
- MOD_TYPE_MDL = 0x4000,
- MOD_TYPE_OKT = 0x8000,
- MOD_TYPE_MID = 0x10000,
- MOD_TYPE_DMF = 0x20000,
- MOD_TYPE_PTM = 0x40000,
- MOD_TYPE_DBM = 0x80000,
- MOD_TYPE_MT2 = 0x100000,
- MOD_TYPE_AMF0 = 0x200000,
- MOD_TYPE_PSM = 0x400000,
- MOD_TYPE_J2B = 0x800000,
- MOD_TYPE_MPT = 0x1000000,
- MOD_TYPE_IMF = 0x2000000,
- MOD_TYPE_DIGI = 0x4000000,
- MOD_TYPE_STP = 0x8000000,
- MOD_TYPE_PLM = 0x10000000,
- MOD_TYPE_SFX = 0x20000000,
- };
- DECLARE_FLAGSET(MODTYPE)
- enum MODCONTAINERTYPE
- {
- MOD_CONTAINERTYPE_NONE = 0x0,
- MOD_CONTAINERTYPE_UMX = 0x3,
- MOD_CONTAINERTYPE_XPK = 0x4,
- MOD_CONTAINERTYPE_PP20 = 0x5,
- MOD_CONTAINERTYPE_MMCMP= 0x6,
- MOD_CONTAINERTYPE_WAV = 0x7,
- MOD_CONTAINERTYPE_UAX = 0x8,
- };
- enum ChannelFlags
- {
-
- CHN_16BIT = 0x01,
- CHN_LOOP = 0x02,
- CHN_PINGPONGLOOP = 0x04,
- CHN_SUSTAINLOOP = 0x08,
- CHN_PINGPONGSUSTAIN = 0x10,
- CHN_PANNING = 0x20,
- CHN_STEREO = 0x40,
- CHN_REVERSE = 0x80,
- CHN_SURROUND = 0x100,
- CHN_ADLIB = 0x200,
-
- CHN_PINGPONGFLAG = 0x80,
- CHN_MUTE = 0x400,
- CHN_KEYOFF = 0x800,
- CHN_NOTEFADE = 0x1000,
- CHN_WRAPPED_LOOP = 0x2000,
- CHN_AMIGAFILTER = 0x4000,
- CHN_FILTER = 0x8000,
- CHN_VOLUMERAMP = 0x10000,
- CHN_VIBRATO = 0x20000,
- CHN_TREMOLO = 0x40000,
- CHN_PORTAMENTO = 0x80000,
- CHN_GLISSANDO = 0x100000,
- CHN_FASTVOLRAMP = 0x200000,
- CHN_EXTRALOUD = 0x400000,
- CHN_REVERB = 0x800000,
- CHN_NOREVERB = 0x1000000,
- CHN_SOLO = 0x2000000,
- CHN_NOFX = 0x4000000,
- CHN_SYNCMUTE = 0x8000000,
-
- SMP_MODIFIED = 0x2000,
- SMP_KEEPONDISK = 0x4000,
- SMP_NODEFAULTVOLUME = 0x8000,
- };
- DECLARE_FLAGSET(ChannelFlags)
- #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)
- #define CHN_CHANNELFLAGS (~CHN_SAMPLEFLAGS | CHN_SURROUND)
- using SampleFlags = FlagSet<ChannelFlags, uint16>;
- enum EnvelopeFlags : uint8
- {
- ENV_ENABLED = 0x01,
- ENV_LOOP = 0x02,
- ENV_SUSTAIN = 0x04,
- ENV_CARRY = 0x08,
- ENV_FILTER = 0x10,
- };
- DECLARE_FLAGSET(EnvelopeFlags)
- #define ENVELOPE_MIN 0
- #define ENVELOPE_MID 32
- #define ENVELOPE_MAX 64
- #define MAX_ENVPOINTS 240
- enum InstrumentFlags : uint8
- {
- INS_SETPANNING = 0x01,
- INS_MUTE = 0x02,
- };
- DECLARE_FLAGSET(InstrumentFlags)
- enum EnvelopeType : uint8
- {
- ENV_VOLUME = 0,
- ENV_PANNING,
- ENV_PITCH,
- ENV_MAXTYPES
- };
- enum class FilterMode : uint8
- {
- Unchanged = 0xFF,
- LowPass = 0,
- HighPass = 1,
- };
- enum class NewNoteAction : uint8
- {
- NoteCut = 0,
- Continue = 1,
- NoteOff = 2,
- NoteFade = 3,
- };
- enum class DuplicateCheckType : uint8
- {
- None = 0,
- Note = 1,
- Sample = 2,
- Instrument = 3,
- Plugin = 4,
- };
- enum class DuplicateNoteAction : uint8
- {
- NoteCut = 0,
- NoteOff = 1,
- NoteFade = 2,
- };
- enum SongFlags
- {
- SONG_FASTVOLSLIDES = 0x02,
- SONG_ITOLDEFFECTS = 0x04,
- SONG_ITCOMPATGXX = 0x08,
- SONG_LINEARSLIDES = 0x10,
- SONG_PATTERNLOOP = 0x20,
- SONG_STEP = 0x40,
- SONG_PAUSED = 0x80,
- SONG_FADINGSONG = 0x0100,
- SONG_ENDREACHED = 0x0200,
- SONG_FIRSTTICK = 0x1000,
- SONG_MPTFILTERMODE = 0x2000,
- SONG_SURROUNDPAN = 0x4000,
- SONG_EXFILTERRANGE = 0x8000,
- SONG_AMIGALIMITS = 0x1'0000,
- SONG_S3MOLDVIBRATO = 0x2'0000,
- SONG_BREAKTOROW = 0x8'0000,
- SONG_POSJUMP = 0x10'0000,
- SONG_PT_MODE = 0x20'0000,
- SONG_PLAYALLSONGS = 0x40'0000,
- SONG_ISAMIGA = 0x80'0000,
- SONG_IMPORTED = 0x100'0000,
- };
- DECLARE_FLAGSET(SongFlags)
- #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)
- #define SONG_PLAY_FLAGS (~SONG_FILE_FLAGS)
- #ifndef NO_AGC
- #define SNDDSP_AGC 0x40
- #endif
- #ifndef NO_DSP
- #define SNDDSP_MEGABASS 0x02
- #define SNDDSP_SURROUND 0x08
- #define SNDDSP_BITCRUSH 0x01
- #endif
- #ifndef NO_REVERB
- #define SNDDSP_REVERB 0x20
- #endif
- #ifndef NO_EQ
- #define SNDDSP_EQ 0x80
- #endif
- #define SNDMIX_SOFTPANNING 0x10
- #define SNDMIX_MAXDEFAULTPAN 0x80000
- #define SNDMIX_MUTECHNMODE 0x100000
- #define MAX_GLOBAL_VOLUME 256u
- enum ResamplingMode : uint8
- {
-
-
- SRCMODE_NEAREST = 0,
- SRCMODE_LINEAR = 1,
- SRCMODE_CUBIC = 2,
- SRCMODE_SINC8 = 4,
- SRCMODE_SINC8LP = 3,
- SRCMODE_DEFAULT = 5,
- SRCMODE_AMIGA = 0xFF,
- };
- namespace Resampling
- {
- enum class AmigaFilter
- {
- Off = 0,
- A500 = 1,
- A1200 = 2,
- Unfiltered = 3,
- };
- inline std::array<ResamplingMode, 5> AllModes() noexcept { return { { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_CUBIC, SRCMODE_SINC8, SRCMODE_SINC8LP } }; }
- inline std::array<ResamplingMode, 6> AllModesWithDefault() noexcept { return { { SRCMODE_NEAREST, SRCMODE_LINEAR, SRCMODE_CUBIC, SRCMODE_SINC8, SRCMODE_SINC8LP, SRCMODE_DEFAULT } }; }
- constexpr ResamplingMode Default() noexcept { return SRCMODE_SINC8LP; }
- constexpr bool IsKnownMode(int mode) noexcept { return (mode >= 0) && (mode < SRCMODE_DEFAULT); }
- constexpr ResamplingMode ToKnownMode(int mode) noexcept
- {
- return Resampling::IsKnownMode(mode) ? static_cast<ResamplingMode>(mode)
- : (mode == SRCMODE_AMIGA) ? SRCMODE_LINEAR
- : Resampling::Default();
- }
- constexpr int Length(ResamplingMode mode) noexcept
- {
- return mode == SRCMODE_NEAREST ? 1
- : mode == SRCMODE_LINEAR ? 2
- : mode == SRCMODE_CUBIC ? 4
- : mode == SRCMODE_SINC8 ? 8
- : mode == SRCMODE_SINC8LP ? 8
- : 0;
- }
- constexpr bool HasAA(ResamplingMode mode) noexcept { return (mode == SRCMODE_SINC8LP); }
- constexpr ResamplingMode AddAA(ResamplingMode mode) noexcept { return (mode == SRCMODE_SINC8) ? SRCMODE_SINC8LP : mode; }
- constexpr ResamplingMode RemoveAA(ResamplingMode mode) noexcept { return (mode == SRCMODE_SINC8LP) ? SRCMODE_SINC8 : mode; }
- }
- #define ENV_RELEASE_NODE_UNSET 0xFF
- #define NOT_YET_RELEASED (-1)
- static_assert(ENV_RELEASE_NODE_UNSET > MAX_ENVPOINTS);
- enum PluginPriority
- {
- ChannelOnly,
- InstrumentOnly,
- PrioritiseInstrument,
- PrioritiseChannel,
- };
- enum PluginMutePriority
- {
- EvenIfMuted,
- RespectMutes,
- };
- enum PlugVelocityHandling : uint8
- {
- PLUGIN_VELOCITYHANDLING_CHANNEL = 0,
- PLUGIN_VELOCITYHANDLING_VOLUME
- };
- enum PlugVolumeHandling : uint8
- {
- PLUGIN_VOLUMEHANDLING_MIDI = 0,
- PLUGIN_VOLUMEHANDLING_DRYWET,
- PLUGIN_VOLUMEHANDLING_IGNORE,
- PLUGIN_VOLUMEHANDLING_CUSTOM,
- PLUGIN_VOLUMEHANDLING_MAX,
- };
- enum MidiChannel : uint8
- {
- MidiNoChannel = 0,
- MidiFirstChannel = 1,
- MidiLastChannel = 16,
- MidiMappedChannel = 17,
- };
- enum VibratoType : uint8
- {
- VIB_SINE = 0,
- VIB_SQUARE,
- VIB_RAMP_UP,
- VIB_RAMP_DOWN,
- VIB_RANDOM
- };
- enum PlayBehaviour
- {
- MSF_COMPATIBLE_PLAY,
- kMPTOldSwingBehaviour,
- kMIDICCBugEmulation,
- kOldMIDIPitchBends,
- kFT2VolumeRamping,
- kMODVBlankTiming,
- kSlidesAtSpeed1,
- kPeriodsAreHertz,
- kTempoClamp,
- kPerChannelGlobalVolSlide,
- kPanOverride,
- kITInstrWithoutNote,
- kITVolColFinePortamento,
- kITArpeggio,
- kITOutOfRangeDelay,
- kITPortaMemoryShare,
- kITPatternLoopTargetReset,
- kITFT2PatternLoop,
- kITPingPongNoReset,
- kITEnvelopeReset,
- kITClearOldNoteAfterCut,
- kITVibratoTremoloPanbrello,
- kITTremor,
- kITRetrigger,
- kITMultiSampleBehaviour,
- kITPortaTargetReached,
- kITPatternLoopBreak,
- kITOffset,
- kITSwingBehaviour,
- kITNNAReset,
- kITSCxStopsSample,
- kITEnvelopePositionHandling,
- kITPortamentoInstrument,
- kITPingPongMode,
- kITRealNoteMapping,
- kITHighOffsetNoRetrig,
- kITFilterBehaviour,
- kITNoSurroundPan,
- kITShortSampleRetrig,
- kITPortaNoNote,
- kITFT2DontResetNoteOffOnPorta,
- kITVolColMemory,
- kITPortamentoSwapResetsPos,
- kITEmptyNoteMapSlot,
- kITFirstTickHandling,
- kITSampleAndHoldPanbrello,
- kITClearPortaTarget,
- kITPanbrelloHold,
- kITPanningReset,
- kITPatternLoopWithJumpsOld,
- kITInstrWithNoteOff,
- kFT2Arpeggio,
- kFT2Retrigger,
- kFT2VolColVibrato,
- kFT2PortaNoNote,
- kFT2KeyOff,
- kFT2PanSlide,
- kFT2ST3OffsetOutOfRange,
- kFT2RestrictXCommand,
- kFT2RetrigWithNoteDelay,
- kFT2SetPanEnvPos,
- kFT2PortaIgnoreInstr,
- kFT2VolColMemory,
- kFT2LoopE60Restart,
- kFT2ProcessSilentChannels,
- kFT2ReloadSampleSettings,
- kFT2PortaDelay,
- kFT2Transpose,
- kFT2PatternLoopWithJumps,
- kFT2PortaTargetNoReset,
- kFT2EnvelopeEscape,
- kFT2Tremor,
- kFT2OutOfRangeDelay,
- kFT2Periods,
- kFT2PanWithDelayedNoteOff,
- kFT2VolColDelay,
- kFT2FinetunePrecision,
- kST3NoMutedChannels,
- kST3EffectMemory,
- kST3PortaSampleChange,
- kST3VibratoMemory,
- kST3LimitPeriod,
- KST3PortaAfterArpeggio,
- kMODOneShotLoops,
- kMODIgnorePanning,
- kMODSampleSwap,
- kFT2NoteOffFlags,
- kITMultiSampleInstrumentNumber,
- kRowDelayWithNoteDelay,
- kFT2MODTremoloRampWaveform,
- kFT2PortaUpDownMemory,
- kMODOutOfRangeNoteDelay,
- kMODTempoOnSecondTick,
- kFT2PanSustainRelease,
- kLegacyReleaseNode,
- kOPLBeatingOscillators,
- kST3OffsetWithoutInstrument,
- kReleaseNodePastSustainBug,
- kFT2NoteDelayWithoutInstr,
- kOPLFlexibleNoteOff,
- kITInstrWithNoteOffOldEffects,
- kMIDIVolumeOnNoteOffBug,
- kITDoNotOverrideChannelPan,
- kITPatternLoopWithJumps,
- kITDCTBehaviour,
- kOPLwithNNA,
- kST3RetrigAfterNoteCut,
- kST3SampleSwap,
- kOPLRealRetrig,
- kOPLNoResetAtEnvelopeEnd,
- kOPLNoteStopWith0Hz,
- kOPLNoteOffOnNoteChange,
- kFT2PortaResetDirection,
- kApplyUpperPeriodLimit,
- kApplyOffsetWithoutNote,
- kITPitchPanSeparation,
- kImprecisePingPongLoops,
-
- kMaxPlayBehaviours,
- };
- class TempoSwing : public std::vector<uint32>
- {
- public:
- static constexpr uint32 Unity = 1u << 24;
-
- void Normalize();
- void resize(size_type newSize, value_type val = Unity) { std::vector<uint32>::resize(newSize, val); Normalize(); }
- static void Serialize(std::ostream &oStrm, const TempoSwing &swing);
- static void Deserialize(std::istream &iStrm, TempoSwing &swing, const size_t);
- };
- struct SamplePosition
- {
- using value_t = int64;
- using unsigned_value_t = uint64;
- protected:
- value_t v = 0;
- public:
- static constexpr uint32 fractMax = 0xFFFFFFFFu;
- MPT_CONSTEXPRINLINE SamplePosition() { }
- MPT_CONSTEXPRINLINE explicit SamplePosition(value_t pos) : v(pos) { }
- MPT_CONSTEXPRINLINE SamplePosition(int32 intPart, uint32 fractPart) : v((static_cast<value_t>(intPart) * (1ll << 32)) | fractPart) { }
- static SamplePosition Ratio(uint32 dividend, uint32 divisor) { return SamplePosition((static_cast<int64>(dividend) << 32) / divisor); }
- static SamplePosition FromDouble(double pos) { return SamplePosition(static_cast<value_t>(pos * 4294967296.0)); }
- double ToDouble() const { return v / 4294967296.0; }
-
- MPT_CONSTEXPRINLINE SamplePosition &Set(int32 intPart, uint32 fractPart = 0) { v = (static_cast<int64>(intPart) << 32) | fractPart; return *this; }
-
- MPT_CONSTEXPRINLINE SamplePosition &SetInt(int32 intPart) { v = (static_cast<value_t>(intPart) << 32) | GetFract(); return *this; }
-
- MPT_CONSTEXPRINLINE SmpLength GetUInt() const { return static_cast<SmpLength>(static_cast<unsigned_value_t>(v) >> 32); }
-
- MPT_CONSTEXPRINLINE int32 GetInt() const { return static_cast<int32>(static_cast<unsigned_value_t>(v) >> 32); }
-
- MPT_CONSTEXPRINLINE uint32 GetFract() const { return static_cast<uint32>(v); }
-
- MPT_CONSTEXPRINLINE SamplePosition GetInvertedFract() const { return SamplePosition(0x100000000ll - GetFract()); }
-
- MPT_CONSTEXPRINLINE int64 GetRaw() const { return v; }
-
- MPT_CONSTEXPRINLINE SamplePosition &Negate() { v = -v; return *this; }
-
- MPT_CONSTEXPRINLINE SamplePosition &MulDiv(uint32 mul, uint32 div) { v = (v * mul) / div; return *this; }
-
- MPT_CONSTEXPRINLINE SamplePosition &RemoveInt() { v &= fractMax; return *this; }
-
- MPT_CONSTEXPRINLINE bool IsUnity() const { return v == 0x100000000ll; }
-
- MPT_CONSTEXPRINLINE bool IsZero() const { return v == 0; }
-
- MPT_CONSTEXPRINLINE bool IsPositive() const { return v > 0; }
-
- MPT_CONSTEXPRINLINE bool IsNegative() const { return v < 0; }
-
- SamplePosition operator+ (const SamplePosition &other) const { return SamplePosition(v + other.v); }
- SamplePosition operator- (const SamplePosition &other) const { return SamplePosition(v - other.v); }
- void operator+= (const SamplePosition &other) { v += other.v; }
- void operator-= (const SamplePosition &other) { v -= other.v; }
-
- template<typename T>
- SamplePosition operator* (T other) const { return SamplePosition(static_cast<value_t>(v * other)); }
- template<typename T>
- void operator*= (T other) { v = static_cast<value_t>(v *other); }
-
- value_t operator/ (SamplePosition other) const { return v / other.v; }
-
- SamplePosition operator/ (int div) const { return SamplePosition(v / div); }
- MPT_CONSTEXPRINLINE bool operator==(const SamplePosition &other) const { return v == other.v; }
- MPT_CONSTEXPRINLINE bool operator!=(const SamplePosition &other) const { return v != other.v; }
- MPT_CONSTEXPRINLINE bool operator<=(const SamplePosition &other) const { return v <= other.v; }
- MPT_CONSTEXPRINLINE bool operator>=(const SamplePosition &other) const { return v >= other.v; }
- MPT_CONSTEXPRINLINE bool operator<(const SamplePosition &other) const { return v < other.v; }
- MPT_CONSTEXPRINLINE bool operator>(const SamplePosition &other) const { return v > other.v; }
- };
- template<size_t FFact, typename T>
- struct FPInt
- {
- protected:
- T v;
- MPT_CONSTEXPRINLINE FPInt(T rawValue) : v(rawValue) { }
- public:
- enum : size_t { fractFact = FFact };
- using store_t = T;
- MPT_CONSTEXPRINLINE FPInt() : v(0) { }
- MPT_CONSTEXPRINLINE FPInt(T intPart, T fractPart) : v((intPart * fractFact) + (fractPart % fractFact)) { }
- explicit MPT_CONSTEXPRINLINE FPInt(float f) : v(mpt::saturate_round<T>(f * float(fractFact))) { }
- explicit MPT_CONSTEXPRINLINE FPInt(double f) : v(mpt::saturate_round<T>(f * double(fractFact))) { }
-
- MPT_CONSTEXPRINLINE FPInt<fractFact, T> &Set(T intPart, T fractPart = 0) { v = (intPart * fractFact) + (fractPart % fractFact); return *this; }
-
- MPT_CONSTEXPRINLINE FPInt<fractFact, T> &SetRaw(T value) { v = value; return *this; }
-
- MPT_CONSTEXPRINLINE T GetInt() const { return v / fractFact; }
-
- MPT_CONSTEXPRINLINE T GetFract() const { return v % fractFact; }
-
- MPT_CONSTEXPRINLINE T GetRaw() const { return v; }
-
- MPT_CONSTEXPRINLINE double ToDouble() const { return v / double(fractFact); }
- 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); }
- 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); }
- MPT_CONSTEXPRINLINE FPInt<fractFact, T> operator+= (const FPInt<fractFact, T> &other) noexcept { v += other.v; return *this; }
- MPT_CONSTEXPRINLINE FPInt<fractFact, T> operator-= (const FPInt<fractFact, T> &other) noexcept { v -= other.v; return *this; }
- MPT_CONSTEXPRINLINE friend bool operator== (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v == b.v; }
- MPT_CONSTEXPRINLINE friend bool operator!= (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v != b.v; }
- MPT_CONSTEXPRINLINE friend bool operator<= (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v <= b.v; }
- MPT_CONSTEXPRINLINE friend bool operator>= (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v >= b.v; }
- MPT_CONSTEXPRINLINE friend bool operator< (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v < b.v; }
- MPT_CONSTEXPRINLINE friend bool operator> (const FPInt<fractFact, T> &a, const FPInt<fractFact, T> &b) noexcept { return a.v > b.v; }
- };
- using TEMPO = FPInt<10000, uint32>;
- using OPLPatch = std::array<uint8, 12>;
- OPENMPT_NAMESPACE_END
|