You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
(1) |
Apr
(1) |
May
|
Jun
(1) |
Jul
|
Aug
(10) |
Sep
|
Oct
|
Nov
|
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(1) |
Feb
(2) |
Mar
(3) |
Apr
(2) |
May
(10) |
Jun
(2) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(3) |
Dec
|
2008 |
Jan
(6) |
Feb
(4) |
Mar
(5) |
Apr
(2) |
May
(1) |
Jun
(1) |
Jul
(4) |
Aug
(6) |
Sep
(2) |
Oct
(9) |
Nov
(1) |
Dec
(4) |
2009 |
Jan
(9) |
Feb
(2) |
Mar
(2) |
Apr
(2) |
May
(6) |
Jun
(18) |
Jul
(33) |
Aug
(39) |
Sep
(33) |
Oct
(24) |
Nov
(23) |
Dec
(22) |
2010 |
Jan
(29) |
Feb
(32) |
Mar
(51) |
Apr
(17) |
May
(31) |
Jun
(21) |
Jul
(32) |
Aug
(28) |
Sep
(35) |
Oct
(27) |
Nov
(11) |
Dec
(13) |
2011 |
Jan
(14) |
Feb
(13) |
Mar
(27) |
Apr
(27) |
May
(28) |
Jun
(20) |
Jul
(43) |
Aug
(52) |
Sep
(66) |
Oct
(61) |
Nov
(11) |
Dec
(8) |
2012 |
Jan
(20) |
Feb
(30) |
Mar
(38) |
Apr
(21) |
May
(33) |
Jun
(21) |
Jul
(25) |
Aug
(9) |
Sep
(24) |
Oct
(42) |
Nov
(27) |
Dec
(41) |
2013 |
Jan
(20) |
Feb
(35) |
Mar
(156) |
Apr
(298) |
May
(258) |
Jun
(201) |
Jul
(105) |
Aug
(60) |
Sep
(193) |
Oct
(245) |
Nov
(280) |
Dec
(194) |
2014 |
Jan
(63) |
Feb
(202) |
Mar
(200) |
Apr
(23) |
May
(53) |
Jun
(105) |
Jul
(18) |
Aug
(26) |
Sep
(110) |
Oct
(187) |
Nov
(97) |
Dec
(74) |
2015 |
Jan
(45) |
Feb
(55) |
Mar
(116) |
Apr
(116) |
May
(193) |
Jun
(164) |
Jul
(50) |
Aug
(111) |
Sep
(98) |
Oct
(71) |
Nov
(103) |
Dec
(63) |
2016 |
Jan
(33) |
Feb
(101) |
Mar
(182) |
Apr
(139) |
May
(140) |
Jun
(103) |
Jul
(165) |
Aug
(286) |
Sep
(208) |
Oct
(127) |
Nov
(97) |
Dec
(54) |
2017 |
Jan
(64) |
Feb
(335) |
Mar
(202) |
Apr
(212) |
May
(139) |
Jun
(127) |
Jul
(294) |
Aug
(154) |
Sep
(170) |
Oct
(152) |
Nov
(156) |
Dec
(62) |
2018 |
Jan
(168) |
Feb
(237) |
Mar
(196) |
Apr
(174) |
May
(174) |
Jun
(161) |
Jul
(127) |
Aug
(88) |
Sep
(149) |
Oct
(66) |
Nov
(52) |
Dec
(135) |
2019 |
Jan
(146) |
Feb
(126) |
Mar
(104) |
Apr
(58) |
May
(60) |
Jun
(28) |
Jul
(197) |
Aug
(129) |
Sep
(141) |
Oct
(148) |
Nov
(63) |
Dec
(100) |
2020 |
Jan
(74) |
Feb
(37) |
Mar
(59) |
Apr
(154) |
May
(194) |
Jun
(133) |
Jul
(313) |
Aug
(197) |
Sep
(49) |
Oct
(162) |
Nov
(143) |
Dec
(57) |
2021 |
Jan
(120) |
Feb
(107) |
Mar
(314) |
Apr
(157) |
May
(524) |
Jun
(169) |
Jul
(72) |
Aug
(133) |
Sep
(135) |
Oct
(146) |
Nov
(198) |
Dec
(325) |
2022 |
Jan
(409) |
Feb
(249) |
Mar
(138) |
Apr
(95) |
May
(102) |
Jun
(221) |
Jul
(66) |
Aug
(120) |
Sep
(192) |
Oct
(131) |
Nov
(53) |
Dec
(171) |
2023 |
Jan
(357) |
Feb
(82) |
Mar
(168) |
Apr
(218) |
May
(196) |
Jun
(86) |
Jul
(115) |
Aug
(49) |
Sep
(190) |
Oct
(102) |
Nov
(45) |
Dec
(76) |
2024 |
Jan
(86) |
Feb
(50) |
Mar
(324) |
Apr
(209) |
May
(197) |
Jun
(232) |
Jul
(194) |
Aug
(247) |
Sep
(219) |
Oct
(266) |
Nov
(328) |
Dec
(304) |
2025 |
Jan
(191) |
Feb
(115) |
Mar
(137) |
Apr
(32) |
May
(126) |
Jun
(403) |
Jul
(126) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <sv...@op...> - 2024-12-19 18:11:27
|
Author: sagamusix Date: Thu Dec 19 19:11:15 2024 New Revision: 22577 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22577 Log: [Ref] Remove CSoundFile::GetDefaultTuning. Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/ModInstrument.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/test/test.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp ============================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp Thu Dec 19 19:03:17 2024 (r22576) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp Thu Dec 19 19:11:15 2024 (r22577) @@ -2965,7 +2965,7 @@ Reporting::Notification(MPT_CFORMAT("Tuning {} was not found. Setting to default tuning.")(mpt::ToCString(m_sndFile.Instruments[m_nInstrument]->pTuning->GetName()))); CriticalSection cs; - pIns->SetTuning(m_sndFile.GetDefaultTuning()); + pIns->SetTuning(nullptr); m_modDoc.SetModified(); } Modified: trunk/OpenMPT/soundlib/Load_it.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp Thu Dec 19 19:03:17 2024 (r22576) +++ trunk/OpenMPT/soundlib/Load_it.cpp Thu Dec 19 19:11:15 2024 (r22577) @@ -262,13 +262,13 @@ #endif // MODPLUG_TRACKER } - csf.Instruments[i]->pTuning = csf.GetDefaultTuning(); + csf.Instruments[i]->pTuning = nullptr; } else { //This 'else' happens probably only in case of corrupted file. if(csf.Instruments[i]) - csf.Instruments[i]->pTuning = csf.GetDefaultTuning(); + csf.Instruments[i]->pTuning = nullptr; } } Modified: trunk/OpenMPT/soundlib/ModInstrument.cpp ============================================================================== --- trunk/OpenMPT/soundlib/ModInstrument.cpp Thu Dec 19 19:03:17 2024 (r22576) +++ trunk/OpenMPT/soundlib/ModInstrument.cpp Thu Dec 19 19:11:15 2024 (r22577) @@ -159,8 +159,6 @@ pitchToTempoLock.Set(0); - pTuning = CSoundFile::GetDefaultTuning(); - AssignSample(sample); ResetNoteMap(); } Modified: trunk/OpenMPT/soundlib/Sndfile.h ============================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h Thu Dec 19 19:03:17 2024 (r22576) +++ trunk/OpenMPT/soundlib/Sndfile.h Thu Dec 19 19:11:15 2024 (r22577) @@ -409,7 +409,6 @@ //Tuning--> public: static std::unique_ptr<CTuning> CreateTuning12TET(const mpt::ustring &name); - static CTuning *GetDefaultTuning() {return nullptr;} CTuningCollection& GetTuneSpecificTunings() {return *m_pTuningsTuneSpecific;} mpt::ustring GetNoteName(const ModCommand::NOTE note, const INSTRUMENTINDEX inst, const NoteName *noteNames = nullptr) const; Modified: trunk/OpenMPT/test/test.cpp ============================================================================== --- trunk/OpenMPT/test/test.cpp Thu Dec 19 19:03:17 2024 (r22576) +++ trunk/OpenMPT/test/test.cpp Thu Dec 19 19:11:15 2024 (r22577) @@ -2823,7 +2823,7 @@ VERIFY_EQUAL_NONCONT(pIns->wMidiBank, 2); VERIFY_EQUAL_NONCONT(pIns->midiPWD, 8); - VERIFY_EQUAL_NONCONT(pIns->pTuning, sndFile.GetDefaultTuning()); + VERIFY_EQUAL_NONCONT(pIns->pTuning, nullptr); VERIFY_EQUAL_NONCONT(pIns->pitchToTempoLock, TEMPO(0, 0)); @@ -3144,7 +3144,7 @@ VERIFY_EQUAL_NONCONT(pIns->wMidiBank, 2); VERIFY_EQUAL_NONCONT(pIns->midiPWD, -1); - VERIFY_EQUAL_NONCONT(pIns->pTuning, sndFile.GetDefaultTuning()); + VERIFY_EQUAL_NONCONT(pIns->pTuning, nullptr); VERIFY_EQUAL_NONCONT(pIns->pitchToTempoLock, TEMPO(130, 2000)); |
From: <sv...@op...> - 2024-12-19 18:03:31
|
Author: sagamusix Date: Thu Dec 19 19:03:17 2024 New Revision: 22576 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22576 Log: [Fix] Instrument Extensions: Condition when to always write pitch wheel depth was inverted. Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp ============================================================================== --- trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Thu Dec 19 10:18:34 2024 (r22575) +++ trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Thu Dec 19 19:03:17 2024 (r22576) @@ -301,7 +301,7 @@ WriteProperty(f, MagicBE("FO.."), instruments, PropertyWriterInt<&ModInstrument::nFadeOut>{[](const ModInstrument &ins) { return (ins.nFadeOut % 32u) || ins.nFadeOut > 8192; }}); // XM instrument headers already have support for this // Note: For ITI we always want to write this property, hence the allInstruments check - int32 prevPWD = allInstruments ? int32_max : int32_min; + int32 prevPWD = allInstruments ? int32_min : int32_max; WriteProperty(f, MagicBE("MPWD"), instruments, PropertyWriterInt<&ModInstrument::midiPWD, std::function<bool(const ModInstrument &)>>{[&prevPWD](const ModInstrument& ins) { if((prevPWD != int32_min && ins.midiPWD != prevPWD) || (ins.midiPWD < 0)) |
From: <sv...@op...> - 2024-12-19 09:18:41
|
Author: manx Date: Thu Dec 19 10:18:34 2024 New Revision: 22575 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22575 Log: [Fix] Do not use rvalue reference for sink parameter with default argument. Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp ============================================================================== --- trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Thu Dec 19 10:13:39 2024 (r22574) +++ trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Thu Dec 19 10:18:34 2024 (r22575) @@ -148,7 +148,7 @@ PropertyNeededFunc IsPropertyNeeded; static constexpr auto Size = PropertySizeFunc; - PropertyWriterBase(PropertyNeededFunc &&propertyNeededFunc = IsPropertyNonDefault<Member>) + PropertyWriterBase(PropertyNeededFunc propertyNeededFunc = IsPropertyNonDefault<Member>) : IsPropertyNeeded{std::move(propertyNeededFunc)} { } }; |
From: <sv...@op...> - 2024-12-19 09:13:51
|
Author: manx Date: Thu Dec 19 10:13:39 2024 New Revision: 22574 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22574 Log: [Fix] Remove superfluous semicolon. Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp ============================================================================== --- trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Thu Dec 19 10:11:38 2024 (r22573) +++ trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Thu Dec 19 10:13:39 2024 (r22574) @@ -182,7 +182,7 @@ struct PropertyWriterEnvelopeBase { - PropertyWriterEnvelopeBase(uint32 nodes, EnvelopeType type) : nodes{nodes}, type{type} {}; + PropertyWriterEnvelopeBase(uint32 nodes, EnvelopeType type) : nodes{nodes}, type{type} {} static bool IsPropertyNeeded(const ModInstrument&) noexcept { return true; |
From: <sv...@op...> - 2024-12-19 09:11:51
|
Author: manx Date: Thu Dec 19 10:11:38 2024 New Revision: 22573 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22573 Log: [Fix] Compile fix. Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp ============================================================================== --- trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Wed Dec 18 23:57:29 2024 (r22572) +++ trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Thu Dec 19 10:11:38 2024 (r22573) @@ -183,7 +183,7 @@ struct PropertyWriterEnvelopeBase { PropertyWriterEnvelopeBase(uint32 nodes, EnvelopeType type) : nodes{nodes}, type{type} {}; - static constexpr bool IsPropertyNeeded(const ModInstrument&) noexcept + static bool IsPropertyNeeded(const ModInstrument&) noexcept { return true; } @@ -242,7 +242,7 @@ struct PropertyWriterPitchTempoLock { - static constexpr bool IsPropertyNeeded(const ModInstrument &ins) noexcept { return ModInstrument{}.pitchToTempoLock != ins.pitchToTempoLock; } + static bool IsPropertyNeeded(const ModInstrument &ins) noexcept { return ModInstrument{}.pitchToTempoLock != ins.pitchToTempoLock; } static constexpr uint16 Size() noexcept { return sizeof(uint16le); } PropertyWriterPitchTempoLock(bool intPart) : m_intPart{intPart} {} void Write(std::ostream &file, const ModInstrument &ins) |
From: <sv...@op...> - 2024-12-18 22:57:41
|
Author: sagamusix Date: Wed Dec 18 23:57:29 2024 New Revision: 22572 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22572 Log: [Ref] Avoid clang warnings. Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp ============================================================================== --- trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Wed Dec 18 23:42:09 2024 (r22571) +++ trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Wed Dec 18 23:57:29 2024 (r22572) @@ -136,13 +136,8 @@ #ifndef MODPLUG_NO_FILESAVE -namespace -{ - const ModInstrument DEFAULT_INSTRUMENT; -} - template <auto Member> -constexpr bool IsPropertyNonDefault(const ModInstrument &ins) { return DEFAULT_INSTRUMENT.*Member != ins.*Member; } +constexpr bool IsPropertyNonDefault(const ModInstrument &ins) { return ModInstrument{}.*Member != ins.*Member; } template <auto Member> constexpr uint16 PropertySize() noexcept { return sizeof(ModInstrument{}.*Member); } @@ -179,7 +174,7 @@ struct PropertyWriterReleaseNode { - bool IsPropertyNeeded(const ModInstrument &ins) const noexcept { return DEFAULT_INSTRUMENT.GetEnvelope(type).nReleaseNode != ins.GetEnvelope(type).nReleaseNode; } + bool IsPropertyNeeded(const ModInstrument &ins) const noexcept { return ModInstrument{}.GetEnvelope(type).nReleaseNode != ins.GetEnvelope(type).nReleaseNode; } static constexpr uint16 Size() noexcept { return sizeof(InstrumentEnvelope{}.nReleaseNode); } void Write(std::ostream &file, const ModInstrument &ins) const { mpt::IO::WriteIntLE(file, ins.GetEnvelope(type).nReleaseNode); } const EnvelopeType type; @@ -187,19 +182,25 @@ struct PropertyWriterEnvelopeBase { - static constexpr bool IsPropertyNeeded(const ModInstrument &) noexcept { return true; } + PropertyWriterEnvelopeBase(uint32 nodes, EnvelopeType type) : nodes{nodes}, type{type} {}; + static constexpr bool IsPropertyNeeded(const ModInstrument&) noexcept + { + return true; + } const uint32 nodes; const EnvelopeType type; }; struct PropertyWriterEnvelopeSize : PropertyWriterEnvelopeBase { + using PropertyWriterEnvelopeBase::PropertyWriterEnvelopeBase; static constexpr uint16 Size() noexcept { return sizeof(uint32le); } void Write(std::ostream &file, const ModInstrument &ins) const { mpt::IO::WriteIntLE<uint32>(file, ins.GetEnvelope(type).size()); } }; struct PropertyWriterEnvelopeTicks : PropertyWriterEnvelopeBase { + using PropertyWriterEnvelopeBase::PropertyWriterEnvelopeBase; uint16 Size() const noexcept { return static_cast<uint16>(sizeof(uint16le) * nodes); } void Write(std::ostream &file, const ModInstrument &ins) const { @@ -220,6 +221,7 @@ struct PropertyWriterEnvelopeValues : PropertyWriterEnvelopeBase { + using PropertyWriterEnvelopeBase::PropertyWriterEnvelopeBase; uint16 Size() const noexcept { return static_cast<uint16>(sizeof(uint8) * nodes); } void Write(std::ostream &file, const ModInstrument &ins) const { @@ -240,7 +242,7 @@ struct PropertyWriterPitchTempoLock { - static constexpr bool IsPropertyNeeded(const ModInstrument &ins) noexcept { return DEFAULT_INSTRUMENT.pitchToTempoLock != ins.pitchToTempoLock; } + static constexpr bool IsPropertyNeeded(const ModInstrument &ins) noexcept { return ModInstrument{}.pitchToTempoLock != ins.pitchToTempoLock; } static constexpr uint16 Size() noexcept { return sizeof(uint16le); } PropertyWriterPitchTempoLock(bool intPart) : m_intPart{intPart} {} void Write(std::ostream &file, const ModInstrument &ins) @@ -267,9 +269,10 @@ return; mpt::IO::WriteIntLE<uint32>(f, code); mpt::IO::WriteIntLE<uint16>(f, property.Size()); + ModInstrument defaultInstr{}; for(const ModInstrument *ins : instruments) { - property.Write(f, ins ? *ins : DEFAULT_INSTRUMENT); + property.Write(f, ins ? *ins : defaultInstr); } } |
From: <sv...@op...> - 2024-12-18 22:42:18
|
Author: sagamusix Date: Wed Dec 18 23:42:09 2024 New Revision: 22571 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22571 Log: [Ref] Unify instrument extension writing code for module and instrument formats, and remove the old macro-based cruft. [Imp] Like in in IT/XM, unneeded instrument properties are no longer written to ITI/XI files as well. Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/SampleFormats.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp ============================================================================== --- trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Wed Dec 18 23:03:55 2024 (r22570) +++ trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Wed Dec 18 23:42:09 2024 (r22571) @@ -4,7 +4,7 @@ * Purpose: Instrument properties I/O * Notes : Welcome to the absolutely horrible abominations that are the "extended instrument properties" * which are some of the earliest additions OpenMPT did to the IT / XM format. They are ugly, - * and the way they work even differs between IT/XM and ITI/XI/ITP. + * and the way they work even differs between IT/XM/ITI/XI and ITI/XI/ITP. * Yes, the world would be a better place without this stuff. * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. @@ -18,6 +18,8 @@ #include "mpt/io/base.hpp" #include "mpt/io/io.hpp" #include "mpt/io/io_stdstream.hpp" + +#include <functional> #endif OPENMPT_NAMESPACE_BEGIN @@ -30,10 +32,9 @@ * to update: ------------ -- both following functions need to be updated when adding a new member in ModInstrument : - -void WriteInstrumentHeaderStructOrField(ModInstrument * input, std::ostream &file, uint32 onlyThisCode, int16 fixedsize); -void ReadInstrumentHeaderField(ModInstrument &ins, uint32 fcode, FileReader &file); +- both following functions need to be updated when adding a new member in ModInstrument: + - SaveExtendedInstrumentProperties + - ReadInstrumentHeaderField - see below for body declaration. @@ -57,7 +58,7 @@ - use only characters used in full member name, ordered as they appear in it - match character attribute (small, capital) -Example with "PanEnv.nLoopEnd" , "PitchEnv.nLoopEnd" & "VolEnv.Values[MAX_ENVPOINTS]" members : +Example with "PanEnv.nLoopEnd" , "PitchEnv.nLoopEnd" & "VolEnv.Values[MAX_ENVPOINTS]" members: - use 'PLE.' for PanEnv.nLoopEnd - use 'PiLE' for PitchEnv.nLoopEnd - use 'VE[.' for VolEnv.Values[MAX_ENVPOINTS] @@ -66,65 +67,64 @@ * In use CODE tag dictionary (alphabetical order): -------------------------------------------------- -AERN PanEnv.nReleaseNode -AFLG PanEnv.dwFlags -CS.. nCutSwing -DCT. nDCT -dF.. dwFlags -DNA. nDNA -FM.. filterMode -fn[. filename[12] -FO.. nFadeOut -GV.. nGlobalVol -IFC. nIFC -IFR. nIFR -K[.. Keyboard[128] -MB.. wMidiBank -MC.. nMidiChannel -MDK. nMidiDrumKey -MiP. nMixPlug -MP.. nMidiProgram -MPWD MIDI Pitch Wheel Depth -n[.. name[32] -NM[. NoteMap[128] -NNA. nNNA -P... nPan -PE.. PanEnv.nNodes -PE[. PanEnv.Values[MAX_ENVPOINTS] -PERN PitchEnv.nReleaseNode -PFLG PitchEnv.dwFlag -PiE. PitchEnv.nNodes -PiE[ PitchEnv.Values[MAX_ENVPOINTS] -PiLE PitchEnv.nLoopEnd -PiLS PitchEnv.nLoopStart -PiP[ PitchEnv.Ticks[MAX_ENVPOINTS] -PiSB PitchEnv.nSustainStart -PiSE PitchEnv.nSustainEnd -PLE. PanEnv.nLoopEnd -PLS. PanEnv.nLoopStart -PP[. PanEnv.Ticks[MAX_ENVPOINTS] -PPC. nPPC -PPS. nPPS -PS.. nPanSwing -PSB. PanEnv.nSustainStart -PSE. PanEnv.nSustainEnd -PTTF pitchToTempoLock (fractional part) -PTTL pitchToTempoLock -PVEH pluginVelocityHandling -PVOH pluginVolumeHandling -R... Resampling -RS.. nResSwing -VE.. VolEnv.nNodes -VE[. VolEnv.Values[MAX_ENVPOINTS] -VERN VolEnv.nReleaseNode -VFLG VolEnv.dwFlags -VLE. VolEnv.nLoopEnd -VLS. VolEnv.nLoopStart -VP[. VolEnv.Ticks[MAX_ENVPOINTS] -VR.. nVolRampUp -VS.. nVolSwing -VSB. VolEnv.nSustainStart -VSE. VolEnv.nSustainEnd +AERN RW PanEnv.nReleaseNode +AFLG R PanEnv.dwFlags +CS.. RW nCutSwing +DCT. R nDCT +dF.. R dwFlags +DNA. R nDNA +FM.. RW filterMode +fn[. R filename[12] +FO.. RW nFadeOut +GV.. R nGlobalVol +IFC. R nIFC +IFR. R nIFR +K[.. Keyboard[128] +MB.. RW wMidiBank +MC.. RW nMidiChannel +MiP. RW nMixPlug +MP.. RW nMidiProgram +MPWD RW MIDI Pitch Wheel Depth +n[.. R name[32] +NM[. R NoteMap[128] +NNA. R nNNA +P... RW nPan +PE.. RW PanEnv.nNodes +PE[. RW PanEnv.Values[MAX_ENVPOINTS] +PERN RW PitchEnv.nReleaseNode +PFLG R PitchEnv.dwFlags +PiE. RW PitchEnv.nNodes +PiE[ RW PitchEnv.Values[MAX_ENVPOINTS] +PiLE R PitchEnv.nLoopEnd +PiLS R PitchEnv.nLoopStart +PiP[ RW PitchEnv.Ticks[MAX_ENVPOINTS] +PiSB R PitchEnv.nSustainStart +PiSE R PitchEnv.nSustainEnd +PLE. R PanEnv.nLoopEnd +PLS. R PanEnv.nLoopStart +PP[. RW PanEnv.Ticks[MAX_ENVPOINTS] +PPC. R nPPC +PPS. R nPPS +PS.. R nPanSwing +PSB. R PanEnv.nSustainStart +PSE. R PanEnv.nSustainEnd +PTTF RW pitchToTempoLock (fractional part) +PTTL RW pitchToTempoLock (integer part) +PVEH RW pluginVelocityHandling +PVOH RW pluginVolumeHandling +R... RW Resampling +RS.. RW nResSwing +VE.. RW VolEnv.nNodes +VE[. RW VolEnv.Values[MAX_ENVPOINTS] +VERN RW VolEnv.nReleaseNode +VFLG R VolEnv.dwFlags +VLE. R VolEnv.nLoopEnd +VLS. R VolEnv.nLoopStart +VP[. RW VolEnv.Ticks[MAX_ENVPOINTS] +VR.. RW nVolRampUp +VS.. R nVolSwing +VSB. R VolEnv.nSustainStart +VSE. R VolEnv.nSustainEnd Note that many of these extensions were only relevant for ITP files, and thus there is no code for writing them, only reading. Some of them used to be written but were never read ("K[.." sample map - it was only relevant for ITP files, but even there @@ -136,292 +136,224 @@ #ifndef MODPLUG_NO_FILESAVE -template<typename T, bool is_signed> struct IsNegativeFunctor { bool operator()(T val) const { return val < 0; } }; -template<typename T> struct IsNegativeFunctor<T, true> { bool operator()(T val) const { return val < 0; } }; -template<typename T> struct IsNegativeFunctor<T, false> { bool operator()(T /*val*/) const { return false; } }; - -template<typename T> -bool IsNegative(const T &val) +namespace { - return IsNegativeFunctor<T, std::numeric_limits<T>::is_signed>()(val); + const ModInstrument DEFAULT_INSTRUMENT; } -// ------------------------------------------------------------------------------------------ -// Convenient macro to help WRITE_HEADER declaration for single type members ONLY (non-array) -// ------------------------------------------------------------------------------------------ -#define WRITE_MPTHEADER_sized_member(name,type,code) \ - static_assert(sizeof(input->name) == sizeof(type), "Instrument property does match specified type!");\ - fcode = code;\ - fsize = sizeof( type );\ - if(writeAll) \ - { \ - mpt::IO::WriteIntLE<uint32>(file, fcode); \ - mpt::IO::WriteIntLE<uint16>(file, fsize); \ - } else if(onlyThisCode == fcode)\ - { \ - MPT_ASSERT(fixedsize == fsize); \ - } \ - if(onlyThisCode == fcode || onlyThisCode == Util::MaxValueOfType(onlyThisCode)) \ - { \ - type tmp = (type)(input-> name ); \ - mpt::IO::WriteIntLE(file, tmp); \ - } \ -/**/ - -// ----------------------------------------------------------------------------------------------------- -// Convenient macro to help WRITE_HEADER declaration for single type members which are written truncated -// ----------------------------------------------------------------------------------------------------- -#define WRITE_MPTHEADER_trunc_member(name,type,code) \ - static_assert(sizeof(input->name) > sizeof(type), "Instrument property would not be truncated, use WRITE_MPTHEADER_sized_member instead!");\ - fcode = code;\ - fsize = sizeof( type );\ - if(writeAll) \ - { \ - mpt::IO::WriteIntLE<uint32>(file, fcode); \ - mpt::IO::WriteIntLE<uint16>(file, fsize); \ - type tmp = (type)(input-> name ); \ - mpt::IO::WriteIntLE(file, tmp); \ - } else if(onlyThisCode == fcode)\ - { \ - /* hackish workaround to resolve mismatched size values: */ \ - /* nResampling was a long time declared as uint32 but these macro tables used uint16 and UINT. */ \ - /* This worked fine on little-endian, on big-endian not so much. Thus support writing size-mismatched fields. */ \ - MPT_ASSERT(fixedsize >= fsize); \ - type tmp = (type)(input-> name ); \ - mpt::IO::WriteIntLE(file, tmp); \ - if(fixedsize > fsize) \ - { \ - for(int16 i = 0; i < fixedsize - fsize; ++i) \ - { \ - uint8 fillbyte = !IsNegative(tmp) ? 0 : 0xff; /* sign extend */ \ - mpt::IO::WriteIntLE(file, fillbyte); \ - } \ - } \ - } \ -/**/ - -// ------------------------------------------------------------------------ -// Convenient macro to help WRITE_HEADER declaration for envelope members ONLY -// ------------------------------------------------------------------------ -#define WRITE_MPTHEADER_envelope_member(envType,envField,type,code) \ - {\ - const InstrumentEnvelope &env = input->GetEnvelope(envType); \ - static_assert(sizeof(type) == sizeof(env[0]. envField)); \ - fcode = code;\ - fsize = mpt::saturate_cast<int16>(sizeof( type ) * env.size());\ - MPT_ASSERT(size_t(fsize) == sizeof( type ) * env.size()); \ - \ - if(writeAll) \ - { \ - mpt::IO::WriteIntLE<uint32>(file, fcode); \ - mpt::IO::WriteIntLE<uint16>(file, fsize); \ - } else if(onlyThisCode == fcode)\ - { \ - fsize = fixedsize; /* just trust the size we got passed */ \ - } \ - if(onlyThisCode == fcode || onlyThisCode == Util::MaxValueOfType(onlyThisCode)) \ - { \ - uint32 maxNodes = std::min(static_cast<uint32>(fsize/sizeof(type)), static_cast<uint32>(env.size())); \ - for(uint32 i = 0; i < maxNodes; ++i) \ - { \ - type tmp; \ - tmp = env[i]. envField ; \ - mpt::IO::WriteIntLE(file, tmp); \ - } \ - /* Not every instrument's envelope will be the same length. fill up with zeros. */ \ - for(uint32 i = maxNodes; i < fsize/sizeof(type); ++i) \ - { \ - type tmp = 0; \ - mpt::IO::WriteIntLE(file, tmp); \ - } \ - } \ - }\ -/**/ - - -// Write (in 'file') 'input' ModInstrument with 'code' & 'size' extra field infos for each member -void WriteInstrumentHeaderStructOrField(ModInstrument * input, std::ostream &file, uint32 onlyThisCode, uint16 fixedsize) -{ - uint32 fcode; - uint16 fsize; - // If true, all extension are written to the file; otherwise only the specified extension is written. - // writeAll is true iff we are saving an instrument (or, hypothetically, the legacy ITP format) - const bool writeAll = onlyThisCode == Util::MaxValueOfType(onlyThisCode); +template <auto Member> +constexpr bool IsPropertyNonDefault(const ModInstrument &ins) { return DEFAULT_INSTRUMENT.*Member != ins.*Member; } + +template <auto Member> +constexpr uint16 PropertySize() noexcept { return sizeof(ModInstrument{}.*Member); } - if(!writeAll) +template <auto Member, typename PropertyNeededFunc, auto PropertySizeFunc> +struct PropertyWriterBase +{ + PropertyNeededFunc IsPropertyNeeded; + static constexpr auto Size = PropertySizeFunc; + + PropertyWriterBase(PropertyNeededFunc &&propertyNeededFunc = IsPropertyNonDefault<Member>) + : IsPropertyNeeded{std::move(propertyNeededFunc)} + { } +}; + +template <auto Member, typename PropertyNeededFunc = decltype(&IsPropertyNonDefault<Member>), auto PropertySizeFunc = PropertySize<Member>> +struct PropertyWriterInt : PropertyWriterBase<Member, PropertyNeededFunc, PropertySizeFunc> +{ + using PropertyWriterBase<Member, PropertyNeededFunc, PropertySizeFunc>::PropertyWriterBase; + static void Write(std::ostream &file, const ModInstrument &ins) { mpt::IO::WriteIntLE(file, ins.*Member); } +}; + +template <auto Member, typename PropertyNeededFunc = decltype(&IsPropertyNonDefault<Member>), auto PropertySizeFunc = PropertySize<Member>> +struct PropertyWriterEnum : PropertyWriterBase<Member, PropertyNeededFunc, PropertySizeFunc> +{ + using PropertyWriterBase<Member, PropertyNeededFunc, PropertySizeFunc>::PropertyWriterBase; + static void Write(std::ostream &file, const ModInstrument &ins) { - MPT_ASSERT(fixedsize > 0); + const auto value = ins.*Member; + static_assert(std::is_enum_v<decltype(value)>); + mpt::IO::WriteIntLE(file, mpt::to_underlying(value)); } +}; - // clang-format off - WRITE_MPTHEADER_sized_member( nFadeOut , uint32 , MagicBE("FO..") ) - WRITE_MPTHEADER_sized_member( nPan , uint32 , MagicBE("P...") ) - WRITE_MPTHEADER_sized_member( VolEnv.size() , uint32 , MagicBE("VE..") ) - WRITE_MPTHEADER_sized_member( PanEnv.size() , uint32 , MagicBE("PE..") ) - WRITE_MPTHEADER_sized_member( PitchEnv.size() , uint32 , MagicBE("PiE.") ) - WRITE_MPTHEADER_sized_member( wMidiBank , uint16 , MagicBE("MB..") ) - WRITE_MPTHEADER_sized_member( nMidiProgram , uint8 , MagicBE("MP..") ) - WRITE_MPTHEADER_sized_member( nMidiChannel , uint8 , MagicBE("MC..") ) - WRITE_MPTHEADER_envelope_member( ENV_VOLUME , tick , uint16 , MagicBE("VP[.") ) - WRITE_MPTHEADER_envelope_member( ENV_PANNING , tick , uint16 , MagicBE("PP[.") ) - WRITE_MPTHEADER_envelope_member( ENV_PITCH , tick , uint16 , MagicBE("PiP[") ) - WRITE_MPTHEADER_envelope_member( ENV_VOLUME , value , uint8 , MagicBE("VE[.") ) - WRITE_MPTHEADER_envelope_member( ENV_PANNING , value , uint8 , MagicBE("PE[.") ) - WRITE_MPTHEADER_envelope_member( ENV_PITCH , value , uint8 , MagicBE("PiE[") ) - WRITE_MPTHEADER_sized_member( nMixPlug , uint8 , MagicBE("MiP.") ) - WRITE_MPTHEADER_sized_member( nVolRampUp , uint16 , MagicBE("VR..") ) - WRITE_MPTHEADER_sized_member( resampling , uint8 , MagicBE("R...") ) - WRITE_MPTHEADER_sized_member( nCutSwing , uint8 , MagicBE("CS..") ) - WRITE_MPTHEADER_sized_member( nResSwing , uint8 , MagicBE("RS..") ) - WRITE_MPTHEADER_sized_member( filterMode , uint8 , MagicBE("FM..") ) - WRITE_MPTHEADER_sized_member( pluginVelocityHandling , uint8 , MagicBE("PVEH") ) - WRITE_MPTHEADER_sized_member( pluginVolumeHandling , uint8 , MagicBE("PVOH") ) - WRITE_MPTHEADER_trunc_member( pitchToTempoLock.GetInt() , uint16 , MagicBE("PTTL") ) - WRITE_MPTHEADER_trunc_member( pitchToTempoLock.GetFract() , uint16 , MagicLE("PTTF") ) - WRITE_MPTHEADER_sized_member( PitchEnv.nReleaseNode , uint8 , MagicBE("PERN") ) - WRITE_MPTHEADER_sized_member( PanEnv.nReleaseNode , uint8 , MagicBE("AERN") ) - WRITE_MPTHEADER_sized_member( VolEnv.nReleaseNode , uint8 , MagicBE("VERN") ) - WRITE_MPTHEADER_sized_member( midiPWD , int8 , MagicBE("MPWD") ) - // clang-format on +struct PropertyWriterReleaseNode +{ + bool IsPropertyNeeded(const ModInstrument &ins) const noexcept { return DEFAULT_INSTRUMENT.GetEnvelope(type).nReleaseNode != ins.GetEnvelope(type).nReleaseNode; } + static constexpr uint16 Size() noexcept { return sizeof(InstrumentEnvelope{}.nReleaseNode); } + void Write(std::ostream &file, const ModInstrument &ins) const { mpt::IO::WriteIntLE(file, ins.GetEnvelope(type).nReleaseNode); } + const EnvelopeType type; +}; -} +struct PropertyWriterEnvelopeBase +{ + static constexpr bool IsPropertyNeeded(const ModInstrument &) noexcept { return true; } + const uint32 nodes; + const EnvelopeType type; +}; +struct PropertyWriterEnvelopeSize : PropertyWriterEnvelopeBase +{ + static constexpr uint16 Size() noexcept { return sizeof(uint32le); } + void Write(std::ostream &file, const ModInstrument &ins) const { mpt::IO::WriteIntLE<uint32>(file, ins.GetEnvelope(type).size()); } +}; -template<typename TIns, typename PropType> -static bool IsPropertyNeeded(const TIns &Instruments, PropType ModInstrument::*Prop) +struct PropertyWriterEnvelopeTicks : PropertyWriterEnvelopeBase { - const ModInstrument defaultIns; - for(const auto ins : Instruments) + uint16 Size() const noexcept { return static_cast<uint16>(sizeof(uint16le) * nodes); } + void Write(std::ostream &file, const ModInstrument &ins) const { - if(ins != nullptr && defaultIns.*Prop != ins->*Prop) - return true; + const auto &env = ins.GetEnvelope(type); + const uint32 maxNodes = std::min(nodes, static_cast<uint32>(env.size())); + for(uint32 i = 0; i < maxNodes; ++i) + { + mpt::IO::WriteIntLE(file, static_cast<uint16>(env[i].tick)); + } + // Not every instrument's envelope will be the same length. fill up with zeros. + uint16le padding{}; + for(uint32 i = maxNodes; i < nodes; ++i) + { + mpt::IO::Write(file, padding); + } } - return false; -} +}; +struct PropertyWriterEnvelopeValues : PropertyWriterEnvelopeBase +{ + uint16 Size() const noexcept { return static_cast<uint16>(sizeof(uint8) * nodes); } + void Write(std::ostream &file, const ModInstrument &ins) const + { + const auto &env = ins.GetEnvelope(type); + const uint32 maxNodes = std::min(nodes, static_cast<uint32>(env.size())); + for(uint32 i = 0; i < maxNodes; ++i) + { + mpt::IO::WriteIntLE(file, static_cast<uint8>(env[i].value)); + } + // Not every instrument's envelope will be the same length. fill up with zeros. + uint16le padding{}; + for(uint32 i = maxNodes; i < nodes; ++i) + { + mpt::IO::Write(file, padding); + } + } +}; -template<typename PropType> -static void WritePropertyIfNeeded(const CSoundFile &sndFile, PropType ModInstrument::*Prop, uint32 code, uint16 size, std::ostream &f, INSTRUMENTINDEX numInstruments) +struct PropertyWriterPitchTempoLock { - if(IsPropertyNeeded(sndFile.Instruments, Prop)) + static constexpr bool IsPropertyNeeded(const ModInstrument &ins) noexcept { return DEFAULT_INSTRUMENT.pitchToTempoLock != ins.pitchToTempoLock; } + static constexpr uint16 Size() noexcept { return sizeof(uint16le); } + PropertyWriterPitchTempoLock(bool intPart) : m_intPart{intPart} {} + void Write(std::ostream &file, const ModInstrument &ins) { - sndFile.WriteInstrumentPropertyForAllInstruments(code, size, f, numInstruments); + mpt::IO::WriteIntLE(file, static_cast<uint16>(m_intPart ? ins.pitchToTempoLock.GetInt() : ins.pitchToTempoLock.GetFract())); } -} + const bool m_intPart; +}; -// Used only when saving IT, XM and MPTM. -// ITI, ITP saves using Ericus' macros etc... -// The reason is that ITs and XMs save [code][size][ins1.Value][ins2.Value]... -// whereas ITP saves [code][size][ins1.Value][code][size][ins2.Value]... -// too late to turn back.... -void CSoundFile::SaveExtendedInstrumentProperties(INSTRUMENTINDEX numInstruments, std::ostream &f) const +template <typename PropertyWriter> +static void WriteProperty(std::ostream &f, uint32 code, mpt::span<const ModInstrument *const> instruments, PropertyWriter property) { - uint32 code = MagicBE("MPTX"); // write extension header code + bool writeProperty = false; + for(const ModInstrument *ins : instruments) + { + if(ins != nullptr && property.IsPropertyNeeded(*ins)) + { + writeProperty = true; + break; + } + } + if(!writeProperty) + return; mpt::IO::WriteIntLE<uint32>(f, code); + mpt::IO::WriteIntLE<uint16>(f, property.Size()); + for(const ModInstrument *ins : instruments) + { + property.Write(f, ins ? *ins : DEFAULT_INSTRUMENT); + } +} - if (numInstruments == 0) - return; - WritePropertyIfNeeded(*this, &ModInstrument::nVolRampUp, MagicBE("VR.."), sizeof(ModInstrument::nVolRampUp), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::nMixPlug, MagicBE("MiP."), sizeof(ModInstrument::nMixPlug), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::nMidiChannel, MagicBE("MC.."), sizeof(ModInstrument::nMidiChannel), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::nMidiProgram, MagicBE("MP.."), sizeof(ModInstrument::nMidiProgram), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::wMidiBank, MagicBE("MB.."), sizeof(ModInstrument::wMidiBank), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::resampling, MagicBE("R..."), sizeof(ModInstrument::resampling), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::pluginVelocityHandling, MagicBE("PVEH"), sizeof(ModInstrument::pluginVelocityHandling), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::pluginVolumeHandling, MagicBE("PVOH"), sizeof(ModInstrument::pluginVolumeHandling), f, numInstruments); +void CSoundFile::SaveExtendedInstrumentProperties(INSTRUMENTINDEX instr, MODTYPE forceType, std::ostream &f) const +{ + const bool allInstruments = (instr < 1 || instr > GetNumInstruments()); + const auto instruments = mpt::as_span(Instruments).subspan(allInstruments ? 1 : instr, allInstruments ? GetNumInstruments() : 1); + SaveExtendedInstrumentProperties(instruments, forceType, f, allInstruments); +} + +void CSoundFile::SaveExtendedInstrumentProperties(mpt::span<const ModInstrument * const> instruments, MODTYPE forceType, std::ostream &f, bool allInstruments) +{ + uint32 code = MagicBE("MPTX"); // write extension header code + mpt::IO::WriteIntLE<uint32>(f, code); - if(!(GetType() & MOD_TYPE_XM)) + WriteProperty(f, MagicBE("VR.."), instruments, PropertyWriterInt<&ModInstrument::nVolRampUp>{}); + WriteProperty(f, MagicBE("MiP."), instruments, PropertyWriterInt<&ModInstrument::nMixPlug>{}); + WriteProperty(f, MagicBE("R..."), instruments, PropertyWriterEnum<&ModInstrument::resampling>{}); + WriteProperty(f, MagicBE("PVEH"), instruments, PropertyWriterEnum<&ModInstrument::pluginVelocityHandling>{}); + WriteProperty(f, MagicBE("PVOH"), instruments, PropertyWriterEnum<&ModInstrument::pluginVolumeHandling>{}); + + if(!(forceType & MOD_TYPE_XM)) { // XM instrument headers already stores full-precision fade-out - bool writeFadeOut = false, writePan = false, writePWD = false; - int32 prevPWD = int32_min; - for(const auto ins : Instruments) - { - if(ins == nullptr) - continue; - if((ins->nFadeOut % 32u) || ins->nFadeOut > 8192) - writeFadeOut = true; - if(ins->dwFlags[INS_SETPANNING] && (ins->nPan % 4u)) - writePan = true; - if((prevPWD != int32_min && ins->midiPWD != prevPWD) || (ins->midiPWD < 0)) - writePWD = true; - prevPWD = ins->midiPWD; - } - if(writeFadeOut) - WriteInstrumentPropertyForAllInstruments(MagicBE("FO.."), sizeof(ModInstrument::nFadeOut), f, numInstruments); + WriteProperty(f, MagicBE("FO.."), instruments, PropertyWriterInt<&ModInstrument::nFadeOut>{[](const ModInstrument &ins) { return (ins.nFadeOut % 32u) || ins.nFadeOut > 8192; }}); // XM instrument headers already have support for this - if(writePWD) - WriteInstrumentPropertyForAllInstruments(MagicBE("MPWD"), sizeof(ModInstrument::midiPWD), f, numInstruments); + // Note: For ITI we always want to write this property, hence the allInstruments check + int32 prevPWD = allInstruments ? int32_max : int32_min; + WriteProperty(f, MagicBE("MPWD"), instruments, PropertyWriterInt<&ModInstrument::midiPWD, std::function<bool(const ModInstrument &)>>{[&prevPWD](const ModInstrument& ins) + { + if((prevPWD != int32_min && ins.midiPWD != prevPWD) || (ins.midiPWD < 0)) + return true; + prevPWD = ins.midiPWD; + return false; + }}); // We never supported these as hacks in XM (luckily!) - if(writePan) - WriteInstrumentPropertyForAllInstruments(MagicBE("P..."), sizeof(ModInstrument::nPan), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::nCutSwing, MagicBE("CS.."), sizeof(ModInstrument::nCutSwing), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::nResSwing, MagicBE("RS.."), sizeof(ModInstrument::nResSwing), f, numInstruments); - WritePropertyIfNeeded(*this, &ModInstrument::filterMode, MagicBE("FM.."), sizeof(ModInstrument::filterMode), f, numInstruments); - if(IsPropertyNeeded(Instruments, &ModInstrument::pitchToTempoLock)) - { - WriteInstrumentPropertyForAllInstruments(MagicBE("PTTL"), sizeof(uint16), f, numInstruments); - WriteInstrumentPropertyForAllInstruments(MagicLE("PTTF"), sizeof(uint16), f, numInstruments); - } + WriteProperty(f, MagicBE("P..."), instruments, PropertyWriterInt<&ModInstrument::nPan>{[](const ModInstrument &ins) { return ins.dwFlags[INS_SETPANNING] && (ins.nPan % 4u); }}); + WriteProperty(f, MagicBE("CS.."), instruments, PropertyWriterInt<&ModInstrument::nCutSwing>{}); + WriteProperty(f, MagicBE("RS.."), instruments, PropertyWriterInt<&ModInstrument::nResSwing>{}); + WriteProperty(f, MagicBE("FM.."), instruments, PropertyWriterEnum<&ModInstrument::filterMode>{}); + WriteProperty(f, MagicBE("PTTL"), instruments, PropertyWriterPitchTempoLock{true}); + WriteProperty(f, MagicLE("PTTF"), instruments, PropertyWriterPitchTempoLock{false}); + } else + { + WriteProperty(f, MagicBE("MC.."), instruments, PropertyWriterInt<&ModInstrument::nMidiChannel>{[](const ModInstrument &ins) { return ins.nMidiChannel == MidiMappedChannel; }}); + // Can be saved in XM, but it's not possible to NOT save a MIDI program if a MIDI channel is set + WriteProperty(f, MagicBE("MP.."), instruments, PropertyWriterInt<&ModInstrument::nMidiProgram>{[](const ModInstrument &ins) { return ins.HasValidMIDIChannel() == (ins.nMidiProgram == 0); }}); + WriteProperty(f, MagicBE("MB.."), instruments, PropertyWriterInt<&ModInstrument::wMidiBank>{}); } - if(GetType() & MOD_TYPE_MPT) + if(forceType & MOD_TYPE_MPT) { uint32 maxNodes[3] = { 0, 0, 0 }; - bool hasReleaseNode[3] = { false, false, false }; - for(INSTRUMENTINDEX i = 1; i <= numInstruments; i++) if(Instruments[i] != nullptr) + for(const ModInstrument *ins : instruments) { - maxNodes[0] = std::max(maxNodes[0], Instruments[i]->VolEnv.size()); - maxNodes[1] = std::max(maxNodes[1], Instruments[i]->PanEnv.size()); - maxNodes[2] = std::max(maxNodes[2], Instruments[i]->PitchEnv.size()); - hasReleaseNode[0] |= (Instruments[i]->VolEnv.nReleaseNode != ENV_RELEASE_NODE_UNSET); - hasReleaseNode[1] |= (Instruments[i]->PanEnv.nReleaseNode != ENV_RELEASE_NODE_UNSET); - hasReleaseNode[2] |= (Instruments[i]->PitchEnv.nReleaseNode != ENV_RELEASE_NODE_UNSET); + if(ins == nullptr) + continue; + maxNodes[0] = std::max(maxNodes[0], ins->VolEnv.size()); + maxNodes[1] = std::max(maxNodes[1], ins->PanEnv.size()); + maxNodes[2] = std::max(maxNodes[2], ins->PitchEnv.size()); } // write full envelope information for MPTM files (more env points) if(maxNodes[0] > 25) { - WriteInstrumentPropertyForAllInstruments(MagicBE("VE.."), sizeof(ModInstrument::VolEnv.size()), f, numInstruments); - WriteInstrumentPropertyForAllInstruments(MagicBE("VP[."), static_cast<uint16>(maxNodes[0] * sizeof(EnvelopeNode::tick)), f, numInstruments); - WriteInstrumentPropertyForAllInstruments(MagicBE("VE[."), static_cast<uint16>(maxNodes[0] * sizeof(EnvelopeNode::value)), f, numInstruments); + WriteProperty(f, MagicBE("VE.."), instruments, PropertyWriterEnvelopeSize{maxNodes[0], ENV_VOLUME}); + WriteProperty(f, MagicBE("VP[."), instruments, PropertyWriterEnvelopeTicks{maxNodes[0], ENV_VOLUME}); + WriteProperty(f, MagicBE("VE[."), instruments, PropertyWriterEnvelopeValues{maxNodes[0], ENV_VOLUME}); } if(maxNodes[1] > 25) { - WriteInstrumentPropertyForAllInstruments(MagicBE("PE.."), sizeof(ModInstrument::PanEnv.size()), f, numInstruments); - WriteInstrumentPropertyForAllInstruments(MagicBE("PP[."), static_cast<uint16>(maxNodes[1] * sizeof(EnvelopeNode::tick)), f, numInstruments); - WriteInstrumentPropertyForAllInstruments(MagicBE("PE[."), static_cast<uint16>(maxNodes[1] * sizeof(EnvelopeNode::value)), f, numInstruments); + WriteProperty(f, MagicBE("PE.."), instruments, PropertyWriterEnvelopeSize{maxNodes[1], ENV_PANNING}); + WriteProperty(f, MagicBE("PP[."), instruments, PropertyWriterEnvelopeTicks{maxNodes[1], ENV_PANNING}); + WriteProperty(f, MagicBE("PE[."), instruments, PropertyWriterEnvelopeValues{maxNodes[1], ENV_PANNING}); } if(maxNodes[2] > 25) { - WriteInstrumentPropertyForAllInstruments(MagicBE("PiE."), sizeof(ModInstrument::PitchEnv.size()), f, numInstruments); - WriteInstrumentPropertyForAllInstruments(MagicBE("PiP["), static_cast<uint16>(maxNodes[2] * sizeof(EnvelopeNode::tick)), f, numInstruments); - WriteInstrumentPropertyForAllInstruments(MagicBE("PiE["), static_cast<uint16>(maxNodes[2] * sizeof(EnvelopeNode::value)), f, numInstruments); - } - if(hasReleaseNode[0]) - WriteInstrumentPropertyForAllInstruments(MagicBE("VERN"), sizeof(ModInstrument::VolEnv.nReleaseNode), f, numInstruments); - if(hasReleaseNode[1]) - WriteInstrumentPropertyForAllInstruments(MagicBE("AERN"), sizeof(ModInstrument::PanEnv.nReleaseNode), f, numInstruments); - if(hasReleaseNode[2]) - WriteInstrumentPropertyForAllInstruments(MagicBE("PERN"), sizeof(ModInstrument::PitchEnv.nReleaseNode), f, numInstruments); - } -} - -void CSoundFile::WriteInstrumentPropertyForAllInstruments(uint32 code, uint16 size, std::ostream &f, INSTRUMENTINDEX nInstruments) const -{ - mpt::IO::WriteIntLE<uint32>(f, code); //write code - mpt::IO::WriteIntLE<uint16>(f, size); //write size - for(INSTRUMENTINDEX i = 1; i <= nInstruments; i++) //for all instruments... - { - if (Instruments[i]) - { - WriteInstrumentHeaderStructOrField(Instruments[i], f, code, size); - } else - { - ModInstrument emptyInstrument; - WriteInstrumentHeaderStructOrField(&emptyInstrument, f, code, size); - } + WriteProperty(f, MagicBE("PiE."), instruments, PropertyWriterEnvelopeSize{maxNodes[2], ENV_PITCH}); + WriteProperty(f, MagicBE("PiP["), instruments, PropertyWriterEnvelopeTicks{maxNodes[2], ENV_PITCH}); + WriteProperty(f, MagicBE("PiE["), instruments, PropertyWriterEnvelopeValues{maxNodes[2], ENV_PITCH}); + } + WriteProperty(f, MagicBE("VERN"), instruments, PropertyWriterReleaseNode{ENV_VOLUME}); + WriteProperty(f, MagicBE("AERN"), instruments, PropertyWriterReleaseNode{ENV_PANNING}); + WriteProperty(f, MagicBE("PERN"), instruments, PropertyWriterReleaseNode{ENV_PITCH}); } } @@ -605,7 +537,7 @@ // For ITP and internal usage -void ReadExtendedInstrumentProperty(mpt::span<ModInstrument *> instruments, const uint32 code, FileReader &file) +void CSoundFile::ReadExtendedInstrumentProperty(mpt::span<ModInstrument *> instruments, const uint32 code, FileReader &file) { uint16 size = file.ReadUint16LE(); for(ModInstrument *ins : instruments) Modified: trunk/OpenMPT/soundlib/Load_it.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp Wed Dec 18 23:03:55 2024 (r22570) +++ trunk/OpenMPT/soundlib/Load_it.cpp Wed Dec 18 23:42:09 2024 (r22571) @@ -2030,7 +2030,7 @@ { if(GetNumInstruments()) { - SaveExtendedInstrumentProperties(itHeader.insnum, f); + SaveExtendedInstrumentProperties(0, GetType(), f); } SaveExtendedSongProperties(f); } Modified: trunk/OpenMPT/soundlib/Load_xm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp Wed Dec 18 23:03:55 2024 (r22570) +++ trunk/OpenMPT/soundlib/Load_xm.cpp Wed Dec 18 23:42:09 2024 (r22571) @@ -1527,7 +1527,7 @@ SaveMixPlugins(&f); if(GetNumInstruments()) { - SaveExtendedInstrumentProperties(writeInstruments, f); + SaveExtendedInstrumentProperties(0, MOD_TYPE_XM, f); } SaveExtendedSongProperties(f); } Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp ============================================================================== --- trunk/OpenMPT/soundlib/SampleFormats.cpp Wed Dec 18 23:03:55 2024 (r22570) +++ trunk/OpenMPT/soundlib/SampleFormats.cpp Wed Dec 18 23:42:09 2024 (r22571) @@ -1402,9 +1402,7 @@ } } - // Write 'MPTX' extension tag - mpt::IO::WriteText(f, "XTPM"); - WriteInstrumentHeaderStructOrField(pIns, f); // Write full extended header. + SaveExtendedInstrumentProperties(nInstr, MOD_TYPE_XM, f); return true; } @@ -2490,9 +2488,7 @@ } mpt::IO::SeekEnd(f); - // Write 'MPTX' extension tag - mpt::IO::WriteRaw(f, "XTPM", 4); - WriteInstrumentHeaderStructOrField(pIns, f); // Write full extended header. + SaveExtendedInstrumentProperties(nInstr, MOD_TYPE_MPT, f); return true; } Modified: trunk/OpenMPT/soundlib/Sndfile.h ============================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h Wed Dec 18 23:03:55 2024 (r22570) +++ trunk/OpenMPT/soundlib/Sndfile.h Wed Dec 18 23:42:09 2024 (r22571) @@ -68,16 +68,6 @@ bool SettingCacheCompleteFileBeforeLoading(); -// ----------------------------------------------------------------------------- -// MODULAR ModInstrument FIELD ACCESS : body content in InstrumentExtensions.cpp -// ----------------------------------------------------------------------------- -#ifndef MODPLUG_NO_FILESAVE -void WriteInstrumentHeaderStructOrField(ModInstrument * input, std::ostream &file, uint32 only_this_code = -1 /* -1 for all */, uint16 fixedsize = 0); -#endif // !MODPLUG_NO_FILESAVE -// ITP: Read instrument property with 'code' from 'file' to instrument 'ins'. -void ReadExtendedInstrumentProperty(mpt::span<ModInstrument *> instruments, const uint32 code, FileReader &file); - - // Sample decompression routines in format-specific source files void AMSUnpack(mpt::const_byte_span source, mpt::byte_span dest, int8 packCharacter); uintptr_t DMFUnpack(FileReader &file, uint8 *psample, uint32 maxlen); @@ -933,10 +923,11 @@ bool SaveMod(std::ostream &f) const; bool SaveIT(std::ostream &f, const mpt::PathString &filename, bool compatibilityExport = false); uint32 SaveMixPlugins(std::ostream *file=nullptr, bool bUpdate=true); - void WriteInstrumentPropertyForAllInstruments(uint32 code, uint16 size, std::ostream &f, INSTRUMENTINDEX nInstruments) const; - void SaveExtendedInstrumentProperties(INSTRUMENTINDEX nInstruments, std::ostream &f) const; + void SaveExtendedInstrumentProperties(INSTRUMENTINDEX instr, MODTYPE forceType, std::ostream &f) const; + static void SaveExtendedInstrumentProperties(mpt::span<const ModInstrument * const> instruments, MODTYPE forceType, std::ostream &f, bool allInstruments); void SaveExtendedSongProperties(std::ostream &f) const; #endif // MODPLUG_NO_FILESAVE + static void ReadExtendedInstrumentProperty(mpt::span<ModInstrument *> instruments, const uint32 code, FileReader &file); bool LoadExtendedSongProperties(FileReader &file, bool ignoreChannelCount, bool* pInterpretMptMade = nullptr); void LoadMPTMProperties(FileReader &file, uint16 cwtv); |
From: <sv...@op...> - 2024-12-18 22:04:06
|
Author: sagamusix Date: Wed Dec 18 23:03:55 2024 New Revision: 22570 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22570 Log: [Fix] Instrument Synth: Always avoid ending up in endless loops if a synth script is longer than 65535 lines, even if it was not sanitized (e.g. global scripts). Modified: trunk/OpenMPT/soundlib/InstrumentSynth.cpp Modified: trunk/OpenMPT/soundlib/InstrumentSynth.cpp ============================================================================== --- trunk/OpenMPT/soundlib/InstrumentSynth.cpp Wed Dec 18 16:58:55 2024 (r22569) +++ trunk/OpenMPT/soundlib/InstrumentSynth.cpp Wed Dec 18 23:03:55 2024 (r22570) @@ -307,7 +307,7 @@ while(!m_ticksRemain) { m_currentRow = m_nextRow; - if(m_currentRow >= events.size()) + if(m_currentRow >= std::min(events.size(), static_cast<size_t>(STOP_ROW))) break; m_nextRow++; if(EvaluateEvent(events[m_currentRow], playState, channel, sndFile, states)) |
From: <sv...@op...> - 2024-12-18 15:59:07
|
Author: manx Date: Wed Dec 18 16:58:55 2024 New Revision: 22569 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22569 Log: [Imp] Test: Print a message after a finished libopenmpt-test run. Modified: trunk/OpenMPT/libopenmpt/libopenmpt_test/libopenmpt_test.cpp trunk/OpenMPT/test/test.cpp trunk/OpenMPT/test/test.h Modified: trunk/OpenMPT/libopenmpt/libopenmpt_test/libopenmpt_test.cpp ============================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt_test/libopenmpt_test.cpp Wed Dec 18 16:47:05 2024 (r22568) +++ trunk/OpenMPT/libopenmpt/libopenmpt_test/libopenmpt_test.cpp Wed Dec 18 16:58:55 2024 (r22569) @@ -44,6 +44,8 @@ using namespace OpenMPT; + Test::PrintHeader(); + // run test with "C" / classic() locale Test::DoTests(); @@ -65,6 +67,8 @@ // and now, run all tests once again Test::DoTests(); + Test::PrintFooter(); + } catch ( const std::exception & e ) { std::cerr << "TEST ERROR: exception: " << ( e.what() ? e.what() : "" ) << std::endl; return 255; Modified: trunk/OpenMPT/test/test.cpp ============================================================================== --- trunk/OpenMPT/test/test.cpp Wed Dec 18 16:47:05 2024 (r22568) +++ trunk/OpenMPT/test/test.cpp Wed Dec 18 16:58:55 2024 (r22569) @@ -166,6 +166,20 @@ } +void PrintHeader() +{ + #ifdef LIBOPENMPT_BUILD + std::cout << "libopenmpt test suite starting." << std::endl; + #endif +} + +void PrintFooter() +{ + #ifdef LIBOPENMPT_BUILD + std::cout << "libopenmpt test suite finished." << std::endl; + #endif +} + void DoTests() { @@ -175,7 +189,7 @@ std::clog << std::flush; std::cerr << std::flush; - std::cout << "libopenmpt test suite" << std::endl; + std::cout << "libopenmpt test run" << std::endl; std::cout << "Version: " << mpt::ToCharset(mpt::Charset::ASCII, Build::GetVersionString(Build::StringVersion | Build::StringRevision | Build::StringSourceInfo | Build::StringBuildFlags | Build::StringBuildFeatures)) << std::endl; std::cout << "Compiler: " << mpt::ToCharset(mpt::Charset::ASCII, Build::GetBuildCompilerString()) << std::endl; Modified: trunk/OpenMPT/test/test.h ============================================================================== --- trunk/OpenMPT/test/test.h Wed Dec 18 16:47:05 2024 (r22568) +++ trunk/OpenMPT/test/test.h Wed Dec 18 16:58:55 2024 (r22569) @@ -17,6 +17,10 @@ namespace Test { +void PrintHeader(); + +void PrintFooter(); + void DoTests(); } // namespace Test |
From: <sv...@op...> - 2024-12-18 15:47:18
|
Author: manx Date: Wed Dec 18 16:47:05 2024 New Revision: 22568 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22568 Log: [Ref] mpt/base/saturate_round.hpp: Add full set of _trunc, _round, _ceil, _floor variants. [Ref] mpt/base/saturate_round.hpp: Template on floating point type. Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp trunk/OpenMPT/src/mpt/base/saturate_round.hpp trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp ============================================================================== --- trunk/OpenMPT/soundlib/SampleFormats.cpp Wed Dec 18 16:45:24 2024 (r22567) +++ trunk/OpenMPT/soundlib/SampleFormats.cpp Wed Dec 18 16:47:05 2024 (r22568) @@ -1618,11 +1618,11 @@ return false; } - if(!mpt::in_range<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate))) + if(!mpt::in_range<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate.get()))) { return false; } - uint32 sampleRate = static_cast<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate)); + uint32 sampleRate = static_cast<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate.get())); if(sampleRate <= 0) { return false; Modified: trunk/OpenMPT/src/mpt/base/saturate_round.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/saturate_round.hpp Wed Dec 18 16:45:24 2024 (r22567) +++ trunk/OpenMPT/src/mpt/base/saturate_round.hpp Wed Dec 18 16:47:05 2024 (r22568) @@ -10,6 +10,9 @@ #include "mpt/base/math.hpp" #include <limits> +#include <type_traits> + +#include <cmath> @@ -18,23 +21,13 @@ -template <typename Tdst> -constexpr Tdst saturate_trunc(double src) { - if (src >= static_cast<double>(std::numeric_limits<Tdst>::max())) { - return std::numeric_limits<Tdst>::max(); - } - if (src <= static_cast<double>(std::numeric_limits<Tdst>::min())) { - return std::numeric_limits<Tdst>::min(); - } - return static_cast<Tdst>(src); -} - -template <typename Tdst> -constexpr Tdst saturate_trunc(float src) { - if (src >= static_cast<float>(std::numeric_limits<Tdst>::max())) { +template <typename Tdst, typename Tsrc> +constexpr Tdst saturate_trunc(Tsrc src) { + static_assert(std::is_floating_point<Tsrc>::value); + if (src >= static_cast<Tsrc>(std::numeric_limits<Tdst>::max())) { return std::numeric_limits<Tdst>::max(); } - if (src <= static_cast<float>(std::numeric_limits<Tdst>::min())) { + if (src <= static_cast<Tsrc>(std::numeric_limits<Tdst>::min())) { return std::numeric_limits<Tdst>::min(); } return static_cast<Tdst>(src); @@ -44,22 +37,27 @@ // Rounds given double value to nearest integer value of type T. // Out-of-range values are saturated to the specified integer type's limits. -template <typename T> -inline T saturate_round(float val) { - static_assert(std::numeric_limits<T>::is_integer); - return mpt::saturate_trunc<T>(mpt::round(val)); +template <typename Tdst, typename Tsrc> +inline Tdst saturate_round(Tsrc val) { + static_assert(std::is_floating_point<Tsrc>::value); + static_assert(std::numeric_limits<Tdst>::is_integer); + return mpt::saturate_trunc<Tdst>(mpt::round(val)); } -template <typename T> -inline T saturate_round(double val) { - static_assert(std::numeric_limits<T>::is_integer); - return mpt::saturate_trunc<T>(mpt::round(val)); + +template <typename Tdst, typename Tsrc> +inline Tdst saturate_ceil(Tsrc val) { + static_assert(std::is_floating_point<Tsrc>::value); + static_assert(std::numeric_limits<Tdst>::is_integer); + return mpt::saturate_trunc<Tdst>(std::ceil(val)); } -template <typename T> -inline T saturate_round(long double val) { - static_assert(std::numeric_limits<T>::is_integer); - return mpt::saturate_trunc<T>(mpt::round(val)); + +template <typename Tdst, typename Tsrc> +inline Tdst saturate_floor(Tsrc val) { + static_assert(std::is_floating_point<Tsrc>::value); + static_assert(std::numeric_limits<Tdst>::is_integer); + return mpt::saturate_trunc<Tdst>(std::floor(val)); } Modified: trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp Wed Dec 18 16:45:24 2024 (r22567) +++ trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp Wed Dec 18 16:47:05 2024 (r22568) @@ -44,6 +44,34 @@ MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(110.1), 110); MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-110.1), -110); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(-0.6), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(-0.5), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(-0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(0.5), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(0.6), 0); + + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-0.6), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-0.5), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(0.5), 1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(0.6), 1); + + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(-0.6), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(-0.5), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(-0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(0.4), 1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(0.5), 1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(0.6), 1); + + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(-0.6), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(-0.5), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(-0.4), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(0.5), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(0.6), 0); + // These should fail to compile //mpt::saturate_round<std::string>(1.0); //mpt::saturate_round<int64>(1.0); |
From: <sv...@op...> - 2024-12-18 15:45:31
|
Author: manx Date: Wed Dec 18 16:45:24 2024 New Revision: 22567 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22567 Log: [Ref] mpt/endian/floatingpoint.hpp: Add get() and set(), like for packed integers. Modified: trunk/OpenMPT/src/mpt/endian/floatingpoint.hpp Modified: trunk/OpenMPT/src/mpt/endian/floatingpoint.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/endian/floatingpoint.hpp Wed Dec 18 16:07:45 2024 (r22566) +++ trunk/OpenMPT/src/mpt/endian/floatingpoint.hpp Wed Dec 18 16:45:24 2024 (r22567) @@ -160,6 +160,13 @@ MPT_FORCEINLINE operator somefloat32() const { return DecodeIEEE754binary32(GetInt32()); } + MPT_FORCEINLINE self_t & set(somefloat32 f) { + SetInt32(EncodeIEEE754binary32(f)); + return *this; + } + MPT_FORCEINLINE somefloat32 get() const { + return DecodeIEEE754binary32(GetInt32()); + } MPT_FORCEINLINE self_t & SetInt32(uint32 i) { bytes[hihi] = static_cast<std::byte>(i >> 24); bytes[hilo] = static_cast<std::byte>(i >> 16); @@ -216,6 +223,13 @@ MPT_FORCEINLINE operator somefloat64() const { return DecodeIEEE754binary64(GetInt64()); } + MPT_FORCEINLINE self_t & set(somefloat64 f) { + SetInt64(EncodeIEEE754binary64(f)); + return *this; + } + MPT_FORCEINLINE somefloat64 get() const { + return DecodeIEEE754binary64(GetInt64()); + } MPT_FORCEINLINE self_t & SetInt64(uint64 i) { bytes[hihihi] = static_cast<std::byte>(i >> 56); bytes[hihilo] = static_cast<std::byte>(i >> 48); @@ -315,6 +329,13 @@ MPT_FORCEINLINE operator somefloat32() const { return value; } + MPT_FORCEINLINE IEEE754binary32Native & set(somefloat32 f) { + value = f; + return *this; + } + MPT_FORCEINLINE somefloat32 get() const { + return value; + } MPT_FORCEINLINE IEEE754binary32Native & SetInt32(uint32 i) { value = DecodeIEEE754binary32(i); return *this; @@ -365,6 +386,13 @@ MPT_FORCEINLINE operator somefloat64() const { return value; } + MPT_FORCEINLINE IEEE754binary64Native & set(somefloat64 f) { + value = f; + return *this; + } + MPT_FORCEINLINE somefloat64 get() const { + return value; + } MPT_FORCEINLINE IEEE754binary64Native & SetInt64(uint64 i) { value = DecodeIEEE754binary64(i); return *this; |
From: <sv...@op...> - 2024-12-18 15:07:58
|
Author: manx Date: Wed Dec 18 16:07:45 2024 New Revision: 22566 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22566 Log: [Ref] mpt/base/math.hpp: Add mpt::trunc. DJGPP is missing std::trunc. [Ref] mpt/base/tests/tests_base_math.hpp: Add trivial tests for mpt::trunc, std::ceil, and std::floor. Modified: trunk/OpenMPT/src/mpt/base/math.hpp trunk/OpenMPT/src/mpt/base/tests/tests_base_math.hpp Modified: trunk/OpenMPT/src/mpt/base/math.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/math.hpp Tue Dec 17 23:12:57 2024 (r22565) +++ trunk/OpenMPT/src/mpt/base/math.hpp Wed Dec 18 16:07:45 2024 (r22566) @@ -63,6 +63,28 @@ #endif // MPT_OS_DJGPP +#if MPT_OS_DJGPP + +inline long double trunc(const long double val) { + return ::truncl(val); +} + +inline double trunc(const double val) { + return ::trunc(val); +} + +inline float trunc(const float val) { + return ::truncf(val); +} + +#else // !MPT_OS_DJGPP + +// C++11 std::trunc +using std::trunc; + +#endif // MPT_OS_DJGPP + + template <typename T> inline T sanitize_nan(T val) { static_assert(std::is_floating_point<T>::value); Modified: trunk/OpenMPT/src/mpt/base/tests/tests_base_math.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/tests/tests_base_math.hpp Tue Dec 17 23:12:57 2024 (r22565) +++ trunk/OpenMPT/src/mpt/base/tests/tests_base_math.hpp Wed Dec 18 16:07:45 2024 (r22566) @@ -11,6 +11,8 @@ #include "mpt/test/test.hpp" #include "mpt/test/test_macros.hpp" +#include <cmath> + namespace mpt { @@ -31,6 +33,14 @@ #pragma clang diagnostic pop #endif { + MPT_TEST_EXPECT_EQUAL(mpt::round(1.99f), 2.0f); + MPT_TEST_EXPECT_EQUAL(mpt::round(1.5f), 2.0f); + MPT_TEST_EXPECT_EQUAL(mpt::round(1.1f), 1.0f); + MPT_TEST_EXPECT_EQUAL(mpt::round(-0.1f), 0.0f); + MPT_TEST_EXPECT_EQUAL(mpt::round(-0.5f), -1.0f); + MPT_TEST_EXPECT_EQUAL(mpt::round(-0.9f), -1.0f); + MPT_TEST_EXPECT_EQUAL(mpt::round(-1.4f), -1.0f); + MPT_TEST_EXPECT_EQUAL(mpt::round(-1.7f), -2.0f); MPT_TEST_EXPECT_EQUAL(mpt::round(1.99), 2.0); MPT_TEST_EXPECT_EQUAL(mpt::round(1.5), 2.0); MPT_TEST_EXPECT_EQUAL(mpt::round(1.1), 1.0); @@ -39,6 +49,89 @@ MPT_TEST_EXPECT_EQUAL(mpt::round(-0.9), -1.0); MPT_TEST_EXPECT_EQUAL(mpt::round(-1.4), -1.0); MPT_TEST_EXPECT_EQUAL(mpt::round(-1.7), -2.0); + MPT_TEST_EXPECT_EQUAL(mpt::round(1.99l), 2.0l); + MPT_TEST_EXPECT_EQUAL(mpt::round(1.5l), 2.0l); + MPT_TEST_EXPECT_EQUAL(mpt::round(1.1l), 1.0l); + MPT_TEST_EXPECT_EQUAL(mpt::round(-0.1l), 0.0l); + MPT_TEST_EXPECT_EQUAL(mpt::round(-0.5l), -1.0l); + MPT_TEST_EXPECT_EQUAL(mpt::round(-0.9l), -1.0l); + MPT_TEST_EXPECT_EQUAL(mpt::round(-1.4l), -1.0l); + MPT_TEST_EXPECT_EQUAL(mpt::round(-1.7l), -2.0l); + + MPT_TEST_EXPECT_EQUAL(std::ceil(1.99f), 2.0f); + MPT_TEST_EXPECT_EQUAL(std::ceil(1.5f), 2.0f); + MPT_TEST_EXPECT_EQUAL(std::ceil(1.1f), 2.0f); + MPT_TEST_EXPECT_EQUAL(std::ceil(-0.1f), 0.0f); + MPT_TEST_EXPECT_EQUAL(std::ceil(-0.5f), 0.0f); + MPT_TEST_EXPECT_EQUAL(std::ceil(-0.9f), 0.0f); + MPT_TEST_EXPECT_EQUAL(std::ceil(-1.4f), -1.0f); + MPT_TEST_EXPECT_EQUAL(std::ceil(-1.7f), -1.0f); + MPT_TEST_EXPECT_EQUAL(std::ceil(1.99), 2.0); + MPT_TEST_EXPECT_EQUAL(std::ceil(1.5), 2.0); + MPT_TEST_EXPECT_EQUAL(std::ceil(1.1), 2.0); + MPT_TEST_EXPECT_EQUAL(std::ceil(-0.1), 0.0); + MPT_TEST_EXPECT_EQUAL(std::ceil(-0.5), 0.0); + MPT_TEST_EXPECT_EQUAL(std::ceil(-0.9), 0.0); + MPT_TEST_EXPECT_EQUAL(std::ceil(-1.4), -1.0); + MPT_TEST_EXPECT_EQUAL(std::ceil(-1.7), -1.0); + MPT_TEST_EXPECT_EQUAL(std::ceil(1.99l), 2.0l); + MPT_TEST_EXPECT_EQUAL(std::ceil(1.5l), 2.0l); + MPT_TEST_EXPECT_EQUAL(std::ceil(1.1l), 2.0l); + MPT_TEST_EXPECT_EQUAL(std::ceil(-0.1l), 0.0l); + MPT_TEST_EXPECT_EQUAL(std::ceil(-0.5l), 0.0l); + MPT_TEST_EXPECT_EQUAL(std::ceil(-0.9l), 0.0l); + MPT_TEST_EXPECT_EQUAL(std::ceil(-1.4l), -1.0l); + MPT_TEST_EXPECT_EQUAL(std::ceil(-1.7l), -1.0l); + + MPT_TEST_EXPECT_EQUAL(std::floor(1.99f), 1.0f); + MPT_TEST_EXPECT_EQUAL(std::floor(1.5f), 1.0f); + MPT_TEST_EXPECT_EQUAL(std::floor(1.1f), 1.0f); + MPT_TEST_EXPECT_EQUAL(std::floor(-0.1f), -1.0f); + MPT_TEST_EXPECT_EQUAL(std::floor(-0.5f), -1.0f); + MPT_TEST_EXPECT_EQUAL(std::floor(-0.9f), -1.0f); + MPT_TEST_EXPECT_EQUAL(std::floor(-1.4f), -2.0f); + MPT_TEST_EXPECT_EQUAL(std::floor(-1.7f), -2.0f); + MPT_TEST_EXPECT_EQUAL(std::floor(1.99), 1.0); + MPT_TEST_EXPECT_EQUAL(std::floor(1.5), 1.0); + MPT_TEST_EXPECT_EQUAL(std::floor(1.1), 1.0); + MPT_TEST_EXPECT_EQUAL(std::floor(-0.1), -1.0); + MPT_TEST_EXPECT_EQUAL(std::floor(-0.5), -1.0); + MPT_TEST_EXPECT_EQUAL(std::floor(-0.9), -1.0); + MPT_TEST_EXPECT_EQUAL(std::floor(-1.4), -2.0); + MPT_TEST_EXPECT_EQUAL(std::floor(-1.7), -2.0); + MPT_TEST_EXPECT_EQUAL(std::floor(1.99l), 1.0l); + MPT_TEST_EXPECT_EQUAL(std::floor(1.5l), 1.0l); + MPT_TEST_EXPECT_EQUAL(std::floor(1.1l), 1.0l); + MPT_TEST_EXPECT_EQUAL(std::floor(-0.1l), -1.0l); + MPT_TEST_EXPECT_EQUAL(std::floor(-0.5l), -1.0l); + MPT_TEST_EXPECT_EQUAL(std::floor(-0.9l), -1.0l); + MPT_TEST_EXPECT_EQUAL(std::floor(-1.4l), -2.0l); + MPT_TEST_EXPECT_EQUAL(std::floor(-1.7l), -2.0l); + + MPT_TEST_EXPECT_EQUAL(mpt::trunc(1.99f), 1.0f); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(1.5f), 1.0f); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(1.1f), 1.0f); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-0.1f), 0.0f); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-0.5f), 0.0f); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-0.9f), 0.0f); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-1.4f), -1.0f); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-1.7f), -1.0f); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(1.99), 1.0); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(1.5), 1.0); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(1.1), 1.0); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-0.1), 0.0); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-0.5), 0.0); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-0.9), 0.0); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-1.4), -1.0); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-1.7), -1.0); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(1.99l), 1.0l); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(1.5l), 1.0l); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(1.1l), 1.0l); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-0.1l), 0.0l); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-0.5l), 0.0l); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-0.9l), 0.0l); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-1.4l), -1.0l); + MPT_TEST_EXPECT_EQUAL(mpt::trunc(-1.7l), -1.0l); } } // namespace math |
From: <sv...@op...> - 2024-12-17 22:13:10
|
Author: sagamusix Date: Tue Dec 17 23:12:57 2024 New Revision: 22565 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22565 Log: [Ref] Combine instrument extension reading for ITI/XI and IT/XM/MO3 into the same parsing logic. Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/soundlib/SampleFormats.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/soundlib/InstrumentExtensions.cpp ============================================================================== --- trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Tue Dec 17 16:43:09 2024 (r22564) +++ trunk/OpenMPT/soundlib/InstrumentExtensions.cpp Tue Dec 17 23:12:57 2024 (r22565) @@ -51,11 +51,11 @@ - have a look below in current tag dictionnary - take the initial ones of the field name -- 4 caracters code (not more, not less) -- must be filled with '.' caracters if code has less than 4 caracters -- for arrays, must include a '[' caracter following significant caracters ('.' not significant!!!) -- use only caracters used in full member name, ordered as they appear in it -- match caracter attribute (small,capital) +- 4 characters code (not more, not less) +- must be filled with '.' characters if code has less than 4 characters +- for arrays, must include a '[' character following significant characters ('.' not significant!!!) +- use only characters used in full member name, ordered as they appear in it +- match character attribute (small, capital) Example with "PanEnv.nLoopEnd" , "PitchEnv.nLoopEnd" & "VolEnv.Values[MAX_ENVPOINTS]" members : - use 'PLE.' for PanEnv.nLoopEnd @@ -66,6 +66,8 @@ * In use CODE tag dictionary (alphabetical order): -------------------------------------------------- +AERN PanEnv.nReleaseNode +AFLG PanEnv.dwFlags CS.. nCutSwing DCT. nDCT dF.. dwFlags @@ -82,12 +84,15 @@ MDK. nMidiDrumKey MiP. nMixPlug MP.. nMidiProgram +MPWD MIDI Pitch Wheel Depth n[.. name[32] -NNA. nNNA NM[. NoteMap[128] +NNA. nNNA P... nPan PE.. PanEnv.nNodes PE[. PanEnv.Values[MAX_ENVPOINTS] +PERN PitchEnv.nReleaseNode +PFLG PitchEnv.dwFlag PiE. PitchEnv.nNodes PiE[ PitchEnv.Values[MAX_ENVPOINTS] PiLE PitchEnv.nLoopEnd @@ -103,14 +108,16 @@ PS.. nPanSwing PSB. PanEnv.nSustainStart PSE. PanEnv.nSustainEnd -PTTL pitchToTempoLock PTTF pitchToTempoLock (fractional part) +PTTL pitchToTempoLock PVEH pluginVelocityHandling PVOH pluginVolumeHandling R... Resampling RS.. nResSwing VE.. VolEnv.nNodes VE[. VolEnv.Values[MAX_ENVPOINTS] +VERN VolEnv.nReleaseNode +VFLG VolEnv.dwFlags VLE. VolEnv.nLoopEnd VLS. VolEnv.nLoopStart VP[. VolEnv.Ticks[MAX_ENVPOINTS] @@ -118,13 +125,6 @@ VS.. nVolSwing VSB. VolEnv.nSustainStart VSE. VolEnv.nSustainEnd -PERN PitchEnv.nReleaseNode -AERN PanEnv.nReleaseNode -VERN VolEnv.nReleaseNode -PFLG PitchEnv.dwFlag -AFLG PanEnv.dwFlags -VFLG VolEnv.dwFlags -MPWD MIDI Pitch Wheel Depth Note that many of these extensions were only relevant for ITP files, and thus there is no code for writing them, only reading. Some of them used to be written but were never read ("K[.." sample map - it was only relevant for ITP files, but even there @@ -605,30 +605,20 @@ // For ITP and internal usage -void ReadExtendedInstrumentProperty(ModInstrument *ins, const uint32 code, FileReader &file) +void ReadExtendedInstrumentProperty(mpt::span<ModInstrument *> instruments, const uint32 code, FileReader &file) { uint16 size = file.ReadUint16LE(); - FileReader chunk = file.ReadChunk(size); - if(ins && chunk.GetLength() == size) - ReadInstrumentHeaderField(*ins, code, chunk); -} - - -// For ITI / XI -void ReadExtendedInstrumentProperties(ModInstrument &ins, FileReader &file) -{ - if(!file.ReadMagic("XTPM")) // 'MPTX' - return; - - while(file.CanRead(7)) + for(ModInstrument *ins : instruments) { - ReadExtendedInstrumentProperty(&ins, file.ReadUint32LE(), file); + FileReader chunk = file.ReadChunk(size); + if(ins && chunk.GetLength() == size) + ReadInstrumentHeaderField(*ins, code, chunk); } } -// For IT / XM / MO3 -bool CSoundFile::LoadExtendedInstrumentProperties(FileReader &file) +// For IT / XM / MO3 / ITI / XI +bool CSoundFile::LoadExtendedInstrumentProperties(mpt::span<ModInstrument *> instruments, FileReader &file) { if(!file.ReadMagic("XTPM")) // 'MPTX' return false; @@ -645,15 +635,7 @@ break; } - // Read size of this property for *one* instrument - const uint16 size = file.ReadUint16LE(); - - for(INSTRUMENTINDEX i = 1; i <= GetNumInstruments(); i++) - { - FileReader chunk = file.ReadChunk(size); - if(Instruments[i] && chunk.GetLength() == size) - ReadInstrumentHeaderField(*Instruments[i], code, chunk); - } + ReadExtendedInstrumentProperty(instruments, code, file); } return true; } Modified: trunk/OpenMPT/soundlib/Load_itp.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_itp.cpp Tue Dec 17 16:43:09 2024 (r22564) +++ trunk/OpenMPT/soundlib/Load_itp.cpp Tue Dec 17 23:12:57 2024 (r22565) @@ -387,7 +387,7 @@ ins++; } else { - ReadExtendedInstrumentProperty(Instruments[ins], code, file); + ReadExtendedInstrumentProperty(mpt::as_span(&Instruments[ins], 1), code, file); } code = file.ReadUint32LE(); Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp ============================================================================== --- trunk/OpenMPT/soundlib/SampleFormats.cpp Tue Dec 17 16:43:09 2024 (r22564) +++ trunk/OpenMPT/soundlib/SampleFormats.cpp Tue Dec 17 23:12:57 2024 (r22565) @@ -1341,7 +1341,7 @@ } // Read MPT crap - ReadExtendedInstrumentProperties(*pIns, file); + LoadExtendedInstrumentProperties(mpt::as_span(&Instruments[nInstr], 1), file); pIns->Convert(MOD_TYPE_XM, GetType()); pIns->Sanitize(GetType()); return true; @@ -2405,7 +2405,7 @@ if(file.Seek(extraOffset)) { // Read MPT crap - ReadExtendedInstrumentProperties(*pIns, file); + LoadExtendedInstrumentProperties(mpt::as_span(&Instruments[nInstr], 1), file); } pIns->Convert(MOD_TYPE_IT, GetType()); Modified: trunk/OpenMPT/soundlib/Sndfile.h ============================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h Tue Dec 17 16:43:09 2024 (r22564) +++ trunk/OpenMPT/soundlib/Sndfile.h Tue Dec 17 23:12:57 2024 (r22565) @@ -75,9 +75,7 @@ void WriteInstrumentHeaderStructOrField(ModInstrument * input, std::ostream &file, uint32 only_this_code = -1 /* -1 for all */, uint16 fixedsize = 0); #endif // !MODPLUG_NO_FILESAVE // ITP: Read instrument property with 'code' from 'file' to instrument 'ins'. -void ReadExtendedInstrumentProperty(ModInstrument *ins, const uint32 code, FileReader &file); -// ITI / XI: Read extended instrument properties from 'file' to instrument 'ins'. -void ReadExtendedInstrumentProperties(ModInstrument &ins, FileReader &file); +void ReadExtendedInstrumentProperty(mpt::span<ModInstrument *> instruments, const uint32 code, FileReader &file); // Sample decompression routines in format-specific source files @@ -945,9 +943,10 @@ static mpt::ustring GetImpulseTrackerVersion(uint16 cwtv, uint16 cmwt); static mpt::ustring GetSchismTrackerVersion(uint16 cwtv, uint32 reserved); - // Reads extended instrument properties(XM/IT/MPTM). + // Reads extended instrument properties(XM/IT/MPTM/ITI/XI). // Returns true if extended instrument properties were found. - bool LoadExtendedInstrumentProperties(FileReader &file); + bool LoadExtendedInstrumentProperties(FileReader &file) { return LoadExtendedInstrumentProperties(mpt::as_span(Instruments).subspan(1, GetNumInstruments()), file); } + static bool LoadExtendedInstrumentProperties(mpt::span<ModInstrument *> instruments, FileReader &file); void SetDefaultPlaybackBehaviour(MODTYPE type); static PlayBehaviourSet GetSupportedPlaybackBehaviour(MODTYPE type); |
From: <sv...@op...> - 2024-12-17 15:43:21
|
Author: manx Date: Tue Dec 17 16:43:09 2024 New Revision: 22564 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22564 Log: [Fix] mpt/base/utility.hpp: Compile fix for Android NDK. Modified: trunk/OpenMPT/src/mpt/base/utility.hpp Modified: trunk/OpenMPT/src/mpt/base/utility.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/utility.hpp Tue Dec 17 16:42:16 2024 (r22563) +++ trunk/OpenMPT/src/mpt/base/utility.hpp Tue Dec 17 16:43:09 2024 (r22564) @@ -9,7 +9,7 @@ #include "mpt/base/detect_libcxx.hpp" #include "mpt/base/namespace.hpp" -#if MPT_CXX_BEFORE(20) && !MPT_LIBCXX_LLVM_BEFORE(13000) +#if MPT_CXX_BEFORE(20) || MPT_LIBCXX_LLVM_BEFORE(13000) #include "mpt/base/saturate_cast.hpp" #include "mpt/base/saturate_round.hpp" #endif |
From: <sv...@op...> - 2024-12-17 15:42:29
|
Author: manx Date: Tue Dec 17 16:42:16 2024 New Revision: 22563 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22563 Log: [Fix] mpt/base/utility.hpp: Compile fix for Android NDK. Modified: trunk/OpenMPT/src/mpt/base/utility.hpp Modified: trunk/OpenMPT/src/mpt/base/utility.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/utility.hpp Tue Dec 17 10:57:26 2024 (r22562) +++ trunk/OpenMPT/src/mpt/base/utility.hpp Tue Dec 17 16:42:16 2024 (r22563) @@ -9,7 +9,7 @@ #include "mpt/base/detect_libcxx.hpp" #include "mpt/base/namespace.hpp" -#if MPT_CXX_BEFORE(20) +#if MPT_CXX_BEFORE(20) && !MPT_LIBCXX_LLVM_BEFORE(13000) #include "mpt/base/saturate_cast.hpp" #include "mpt/base/saturate_round.hpp" #endif |
From: <sv...@op...> - 2024-12-17 09:57:33
|
Author: manx Date: Tue Dec 17 10:57:26 2024 New Revision: 22562 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22562 Log: [Var] Run clang-format. Modified: trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_cast.hpp trunk/OpenMPT/src/mpt/base/utility.hpp Modified: trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_cast.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_cast.hpp Tue Dec 17 10:49:25 2024 (r22561) +++ trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_cast.hpp Tue Dec 17 10:57:26 2024 (r22562) @@ -94,7 +94,6 @@ MPT_TEST_EXPECT_EQUAL(mpt::saturate_cast<uint32>(std::numeric_limits<int64>::max() - 1), std::numeric_limits<uint32>::max()); MPT_TEST_EXPECT_EQUAL(mpt::saturate_cast<int32>(std::numeric_limits<uint64>::max() - 1), std::numeric_limits<int32>::max()); - } } // namespace saturate_cast Modified: trunk/OpenMPT/src/mpt/base/utility.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/utility.hpp Tue Dec 17 10:49:25 2024 (r22561) +++ trunk/OpenMPT/src/mpt/base/utility.hpp Tue Dec 17 10:57:26 2024 (r22562) @@ -60,7 +60,7 @@ return mpt::saturate_trunc<Tdst>(src); } -} +} // namespace detail // Returns true iff Tdst can represent the value val. // Use as if(mpt::in_range<uint8>(-1)). |
From: <sv...@op...> - 2024-12-17 09:49:38
|
Author: manx Date: Tue Dec 17 10:49:25 2024 New Revision: 22561 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22561 Log: [Ref] mpt/base/saturate_round.hpp: Rename floating point variants of saturate_cast to saturate_trunc in order to make mpt::saturate_cast as broken as C++26 std::saturate_cast. [Ref] mpt/base/saturate_cast.hpp: Use C++26 saturate_cast if available. Modified: trunk/OpenMPT/misc/mptColor.cpp trunk/OpenMPT/mptrack/CImageListEx.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/ResizableDialog.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/plugins/MidiInOut.cpp trunk/OpenMPT/soundlib/Load_symmod.cpp trunk/OpenMPT/soundlib/SampleFormatSFZ.cpp trunk/OpenMPT/src/mpt/base/saturate_cast.hpp trunk/OpenMPT/src/mpt/base/saturate_round.hpp trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_cast.hpp trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp trunk/OpenMPT/src/mpt/base/utility.hpp trunk/OpenMPT/src/openmpt/soundbase/SampleConvert.hpp trunk/OpenMPT/src/openmpt/soundbase/SampleConvertFixedPoint.hpp Modified: trunk/OpenMPT/misc/mptColor.cpp ============================================================================== --- trunk/OpenMPT/misc/mptColor.cpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/misc/mptColor.cpp Tue Dec 17 10:49:25 2024 (r22561) @@ -20,7 +20,7 @@ uint8 GetLuma(uint8 r, uint8 g, uint8 b) noexcept { - return mpt::saturate_cast<uint8>(r * 0.299f + g * 0.587f + b * 0.114f); + return mpt::saturate_trunc<uint8>(r * 0.299f + g * 0.587f + b * 0.114f); } Modified: trunk/OpenMPT/mptrack/CImageListEx.cpp ============================================================================== --- trunk/OpenMPT/mptrack/CImageListEx.cpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/mptrack/CImageListEx.cpp Tue Dec 17 10:49:25 2024 (r22561) @@ -46,9 +46,9 @@ auto hsv = mpt::Color::RGB{pixel->r / 255.0f, pixel->g / 255.0f, pixel->b / 255.0f}.ToHSV(); hsv.v = (1.0f - hsv.v) * (1.0f - hsv.s) + (hsv.v) * hsv.s; const auto rgb = hsv.ToRGB(); - pixel->r = mpt::saturate_cast<uint8>(rgb.r * 255.0f); - pixel->g = mpt::saturate_cast<uint8>(rgb.g * 255.0f); - pixel->b = mpt::saturate_cast<uint8>(rgb.b * 255.0f); + pixel->r = mpt::saturate_trunc<uint8>(rgb.r * 255.0f); + pixel->g = mpt::saturate_trunc<uint8>(rgb.g * 255.0f); + pixel->b = mpt::saturate_trunc<uint8>(rgb.b * 255.0f); } } } Modified: trunk/OpenMPT/mptrack/Mainfrm.h ============================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/mptrack/Mainfrm.h Tue Dec 17 10:49:25 2024 (r22561) @@ -283,7 +283,7 @@ void UpdateTree(CModDoc *pModDoc, UpdateHint hint, CObject *pHint = nullptr); void RefreshDlsBanks(); static CInputHandler *GetInputHandler(); - void SetElapsedTime(double t) { m_dwTimeSec = mpt::saturate_cast<samplecount_t>(t * 10.0); } + void SetElapsedTime(double t) { m_dwTimeSec = mpt::saturate_trunc<samplecount_t>(t * 10.0); } #if defined(MPT_ENABLE_UPDATE) bool ShowUpdateIndicator(const UpdateCheckResult &result, const CString &releaseVersion, const CString &infoURL, bool showHighlight); Modified: trunk/OpenMPT/mptrack/ResizableDialog.cpp ============================================================================== --- trunk/OpenMPT/mptrack/ResizableDialog.cpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/mptrack/ResizableDialog.cpp Tue Dec 17 10:49:25 2024 (r22561) @@ -119,15 +119,15 @@ CPoint move; if(item.moveSettings.IsHorizontal()) - move.x = mpt::saturate_cast<int>(ratioX * item.moveSettings.m_nXRatio); + move.x = mpt::saturate_trunc<int>(ratioX * item.moveSettings.m_nXRatio); if(item.moveSettings.IsVertical()) - move.y = mpt::saturate_cast<int>(ratioY * item.moveSettings.m_nYRatio); + move.y = mpt::saturate_trunc<int>(ratioY * item.moveSettings.m_nYRatio); CSize size; if(item.sizeSettings.IsHorizontal()) - size.cx = mpt::saturate_cast<int>(ratioX * item.sizeSettings.m_nXRatio); + size.cx = mpt::saturate_trunc<int>(ratioX * item.sizeSettings.m_nXRatio); if(item.sizeSettings.IsVertical()) - size.cy = mpt::saturate_cast<int>(ratioY * item.sizeSettings.m_nYRatio); + size.cy = mpt::saturate_trunc<int>(ratioY * item.sizeSettings.m_nYRatio); auto itemPoint = item.initialPoint + move; auto itemSize = item.initialSize + size; Modified: trunk/OpenMPT/mptrack/View_smp.cpp ============================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/mptrack/View_smp.cpp Tue Dec 17 10:49:25 2024 (r22561) @@ -296,7 +296,7 @@ m_timelineUnit = mpt::saturate_round<int>(std::log(static_cast<double>(timelineInterval)) / std::log(power)); if(m_timelineUnit < 1) m_timelineUnit = 0; - m_timelineUnit = mpt::saturate_cast<int>(std::pow(power, m_timelineUnit)); + m_timelineUnit = mpt::saturate_trunc<int>(std::pow(power, m_timelineUnit)); timelineInterval = std::max(1.0, std::round(timelineInterval / m_timelineUnit)) * m_timelineUnit; if(format == TimelineFormat::Seconds) timelineInterval *= sampleRate / 1000.0; Modified: trunk/OpenMPT/mptrack/plugins/MidiInOut.cpp ============================================================================== --- trunk/OpenMPT/mptrack/plugins/MidiInOut.cpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/mptrack/plugins/MidiInOut.cpp Tue Dec 17 10:49:25 2024 (r22561) @@ -444,7 +444,7 @@ if(m_sendTimingInfo && !m_positionChanged && m_SndFile.m_PlayState.m_ppqPosFract == 0.0) { // Send Song Position on every pattern change or start of new measure - uint16 ppq = mpt::saturate_cast<uint16>((m_SndFile.m_PlayState.m_ppqPosBeat + m_SndFile.m_PlayState.m_ppqPosFract) * 4.0); + uint16 ppq = mpt::saturate_trunc<uint16>((m_SndFile.m_PlayState.m_ppqPosBeat + m_SndFile.m_PlayState.m_ppqPosFract) * 4.0); if(ppq < 16384) { uint32 midiCode = MIDIEvents::SongPosition(ppq); @@ -574,7 +574,7 @@ if(m_sendTimingInfo && !m_SndFile.IsPaused()) { MidiSend(0xFC); // Stop - uint16 ppq = mpt::saturate_cast<uint16>((m_SndFile.m_PlayState.m_ppqPosBeat + m_SndFile.m_PlayState.m_ppqPosFract) * 4.0); + uint16 ppq = mpt::saturate_trunc<uint16>((m_SndFile.m_PlayState.m_ppqPosBeat + m_SndFile.m_PlayState.m_ppqPosFract) * 4.0); if(ppq < 16384) MidiSend(MIDIEvents::SongPosition(ppq)); MidiSend(0xFA); // Start Modified: trunk/OpenMPT/soundlib/Load_symmod.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_symmod.cpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/soundlib/Load_symmod.cpp Tue Dec 17 10:49:25 2024 (r22561) @@ -282,8 +282,8 @@ std::pair<SmpLength, SmpLength> ConvertLoop(const ModSample &mptSmp) const { const double loopScale = static_cast<double>(mptSmp.nLength) / (100 << 16); - const SmpLength start = mpt::saturate_cast<SmpLength>(loopScale * std::min(uint32(100 << 16), loopStart.get())); - const SmpLength length = mpt::saturate_cast<SmpLength>(loopScale * std::min(uint32(100 << 16), loopLen.get())); + const SmpLength start = mpt::saturate_trunc<SmpLength>(loopScale * std::min(uint32(100 << 16), loopStart.get())); + const SmpLength length = mpt::saturate_trunc<SmpLength>(loopScale * std::min(uint32(100 << 16), loopLen.get())); return {start, std::min(mptSmp.nLength - start, length)}; } }; @@ -670,8 +670,8 @@ loopLen = (loopLen << 16) + loopLenFine; const double loopScale = static_cast<double>(mptSmp.nLength) / (100 << 16); - loopStart = std::min(mptSmp.nLength, mpt::saturate_cast<SmpLength>(loopStart * loopScale)); - loopLen = std::min(mptSmp.nLength - loopStart, mpt::saturate_cast<SmpLength>(loopLen * loopScale)); + loopStart = std::min(mptSmp.nLength, mpt::saturate_trunc<SmpLength>(loopStart * loopScale)); + loopLen = std::min(mptSmp.nLength - loopStart, mpt::saturate_trunc<SmpLength>(loopLen * loopScale)); } else if(mptSmp.HasSampleData()) { // The order of operations here may seem weird as it reduces precision, but it's taken directly from the original assembly source (UpdateRecalcLoop) Modified: trunk/OpenMPT/soundlib/SampleFormatSFZ.cpp ============================================================================== --- trunk/OpenMPT/soundlib/SampleFormatSFZ.cpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/soundlib/SampleFormatSFZ.cpp Tue Dec 17 10:49:25 2024 (r22561) @@ -901,7 +901,7 @@ if(region.ampEnv.release > 0) { const double tickDuration = m_PlayState.m_nSamplesPerTick / static_cast<double>(GetSampleRate()); - pIns->nFadeOut = std::min(mpt::saturate_cast<uint32>(32768.0 * tickDuration / region.ampEnv.release), uint32(32767)); + pIns->nFadeOut = std::min(mpt::saturate_trunc<uint32>(32768.0 * tickDuration / region.ampEnv.release), uint32(32767)); if(GetType() == MOD_TYPE_IT) pIns->nFadeOut = std::min((pIns->nFadeOut + 16u) & ~31u, uint32(8192)); } Modified: trunk/OpenMPT/src/mpt/base/saturate_cast.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/saturate_cast.hpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/src/mpt/base/saturate_cast.hpp Tue Dec 17 10:49:25 2024 (r22561) @@ -5,10 +5,14 @@ +#include "mpt/base/detect.hpp" #include "mpt/base/namespace.hpp" #include <algorithm> #include <limits> +#if MPT_CXX_AT_LEAST(26) +#include <numeric> +#endif @@ -16,6 +20,12 @@ inline namespace MPT_INLINE_NS { +#if MPT_CXX_AT_LEAST(26) + +using std::saturate_cast; + +#else + // Saturate the value of src to the domain of Tdst template <typename Tdst, typename Tsrc> constexpr Tdst saturate_cast(Tsrc src) noexcept { @@ -51,27 +61,7 @@ } } -template <typename Tdst> -constexpr Tdst saturate_cast(double src) { - if (src >= static_cast<double>(std::numeric_limits<Tdst>::max())) { - return std::numeric_limits<Tdst>::max(); - } - if (src <= static_cast<double>(std::numeric_limits<Tdst>::min())) { - return std::numeric_limits<Tdst>::min(); - } - return static_cast<Tdst>(src); -} - -template <typename Tdst> -constexpr Tdst saturate_cast(float src) { - if (src >= static_cast<float>(std::numeric_limits<Tdst>::max())) { - return std::numeric_limits<Tdst>::max(); - } - if (src <= static_cast<float>(std::numeric_limits<Tdst>::min())) { - return std::numeric_limits<Tdst>::min(); - } - return static_cast<Tdst>(src); -} +#endif } // namespace MPT_INLINE_NS Modified: trunk/OpenMPT/src/mpt/base/saturate_round.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/saturate_round.hpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/src/mpt/base/saturate_round.hpp Tue Dec 17 10:49:25 2024 (r22561) @@ -8,7 +8,6 @@ #include "mpt/base/namespace.hpp" #include "mpt/base/math.hpp" -#include "mpt/base/saturate_cast.hpp" #include <limits> @@ -18,25 +17,49 @@ inline namespace MPT_INLINE_NS { + +template <typename Tdst> +constexpr Tdst saturate_trunc(double src) { + if (src >= static_cast<double>(std::numeric_limits<Tdst>::max())) { + return std::numeric_limits<Tdst>::max(); + } + if (src <= static_cast<double>(std::numeric_limits<Tdst>::min())) { + return std::numeric_limits<Tdst>::min(); + } + return static_cast<Tdst>(src); +} + +template <typename Tdst> +constexpr Tdst saturate_trunc(float src) { + if (src >= static_cast<float>(std::numeric_limits<Tdst>::max())) { + return std::numeric_limits<Tdst>::max(); + } + if (src <= static_cast<float>(std::numeric_limits<Tdst>::min())) { + return std::numeric_limits<Tdst>::min(); + } + return static_cast<Tdst>(src); +} + + // Rounds given double value to nearest integer value of type T. // Out-of-range values are saturated to the specified integer type's limits. template <typename T> inline T saturate_round(float val) { static_assert(std::numeric_limits<T>::is_integer); - return mpt::saturate_cast<T>(mpt::round(val)); + return mpt::saturate_trunc<T>(mpt::round(val)); } template <typename T> inline T saturate_round(double val) { static_assert(std::numeric_limits<T>::is_integer); - return mpt::saturate_cast<T>(mpt::round(val)); + return mpt::saturate_trunc<T>(mpt::round(val)); } template <typename T> inline T saturate_round(long double val) { static_assert(std::numeric_limits<T>::is_integer); - return mpt::saturate_cast<T>(mpt::round(val)); + return mpt::saturate_trunc<T>(mpt::round(val)); } Modified: trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_cast.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_cast.hpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_cast.hpp Tue Dec 17 10:49:25 2024 (r22561) @@ -95,7 +95,6 @@ MPT_TEST_EXPECT_EQUAL(mpt::saturate_cast<int32>(std::numeric_limits<uint64>::max() - 1), std::numeric_limits<int32>::max()); - MPT_TEST_EXPECT_EQUAL(mpt::saturate_cast<uint32>(static_cast<double>(std::numeric_limits<int64>::max())), std::numeric_limits<uint32>::max()); } } // namespace saturate_cast Modified: trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp Tue Dec 17 10:49:25 2024 (r22561) @@ -34,6 +34,8 @@ #pragma clang diagnostic pop #endif { + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<uint32>(static_cast<double>(std::numeric_limits<int64>::max())), std::numeric_limits<uint32>::max()); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int32>(std::numeric_limits<int32>::max() + 0.1), std::numeric_limits<int32>::max()); MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int32>(std::numeric_limits<int32>::max() - 0.4), std::numeric_limits<int32>::max()); MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int32>(std::numeric_limits<int32>::min() + 0.1), std::numeric_limits<int32>::min()); Modified: trunk/OpenMPT/src/mpt/base/utility.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/utility.hpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/src/mpt/base/utility.hpp Tue Dec 17 10:49:25 2024 (r22561) @@ -11,6 +11,7 @@ #if MPT_CXX_BEFORE(20) #include "mpt/base/saturate_cast.hpp" +#include "mpt/base/saturate_round.hpp" #endif #if MPT_CXX_BEFORE(23) && !MPT_COMPILER_MSVC && !MPT_COMPILER_GCC && !MPT_COMPILER_CLANG @@ -42,11 +43,30 @@ #else +namespace detail { + +template <typename Tdst, typename Tsrc> +constexpr Tdst saturate_cast(Tsrc src) noexcept { + return mpt::saturate_cast<Tdst>(src); +} + +template <typename Tdst> +constexpr Tdst saturate_cast(double src) { + return mpt::saturate_trunc<Tdst>(src); +} + +template <typename Tdst> +constexpr Tdst saturate_cast(float src) { + return mpt::saturate_trunc<Tdst>(src); +} + +} + // Returns true iff Tdst can represent the value val. // Use as if(mpt::in_range<uint8>(-1)). template <typename Tdst, typename Tsrc> constexpr bool in_range(Tsrc val) { - return (static_cast<Tsrc>(mpt::saturate_cast<Tdst>(val)) == val); + return (static_cast<Tsrc>(mpt::detail::saturate_cast<Tdst>(val)) == val); } #endif Modified: trunk/OpenMPT/src/openmpt/soundbase/SampleConvert.hpp ============================================================================== --- trunk/OpenMPT/src/openmpt/soundbase/SampleConvert.hpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/src/openmpt/soundbase/SampleConvert.hpp Tue Dec 17 10:49:25 2024 (r22561) @@ -10,6 +10,7 @@ #include "mpt/base/macros.hpp" #include "mpt/base/math.hpp" #include "mpt/base/saturate_cast.hpp" +#include "mpt/base/saturate_round.hpp" #include "openmpt/base/Int24.hpp" #include "openmpt/base/Types.hpp" #include "openmpt/soundbase/SampleConvert.hpp" @@ -566,7 +567,7 @@ { val = mpt::safe_clamp(val, -1.0f, 1.0f); val *= static_cast<float>(uint64(1) << 63); - return mpt::saturate_cast<int64>(SC::fastround(val)); + return mpt::saturate_trunc<int64>(SC::fastround(val)); } }; @@ -579,7 +580,7 @@ { val = std::clamp(val, -1.0, 1.0); val *= static_cast<double>(uint64(1) << 63); - return mpt::saturate_cast<int64>(SC::fastround(val)); + return mpt::saturate_trunc<int64>(SC::fastround(val)); } }; Modified: trunk/OpenMPT/src/openmpt/soundbase/SampleConvertFixedPoint.hpp ============================================================================== --- trunk/OpenMPT/src/openmpt/soundbase/SampleConvertFixedPoint.hpp Tue Dec 17 10:27:32 2024 (r22560) +++ trunk/OpenMPT/src/openmpt/soundbase/SampleConvertFixedPoint.hpp Tue Dec 17 10:49:25 2024 (r22561) @@ -232,7 +232,7 @@ { static_assert(fractionalBits >= 0 && fractionalBits <= sizeof(input_t) * 8 - 1); val = mpt::sanitize_nan(val); - return mpt::saturate_cast<output_t>(SC::fastround(val * factor)); + return mpt::saturate_trunc<output_t>(SC::fastround(val * factor)); } }; @@ -251,7 +251,7 @@ { static_assert(fractionalBits >= 0 && fractionalBits <= sizeof(input_t) * 8 - 1); val = mpt::sanitize_nan(val); - return mpt::saturate_cast<output_t>(SC::fastround(val * factor)); + return mpt::saturate_trunc<output_t>(SC::fastround(val * factor)); } }; |
From: <sv...@op...> - 2024-12-17 09:27:44
|
Author: manx Date: Tue Dec 17 10:27:32 2024 New Revision: 22560 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22560 Log: Merged revision(s) 22556 from trunk/OpenMPT: [Fix] mpt/base/saturate_round.hpp: Fix includes. ........ Modified: branches/OpenMPT-1.30/ (props changed) branches/OpenMPT-1.30/src/mpt/base/saturate_round.hpp Modified: branches/OpenMPT-1.30/src/mpt/base/saturate_round.hpp ============================================================================== --- branches/OpenMPT-1.30/src/mpt/base/saturate_round.hpp Tue Dec 17 10:26:59 2024 (r22559) +++ branches/OpenMPT-1.30/src/mpt/base/saturate_round.hpp Tue Dec 17 10:27:32 2024 (r22560) @@ -10,7 +10,7 @@ #include "mpt/base/math.hpp" #include "mpt/base/saturate_cast.hpp" -#include <type_traits> +#include <limits> |
From: <sv...@op...> - 2024-12-17 09:27:11
|
Author: manx Date: Tue Dec 17 10:26:59 2024 New Revision: 22559 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22559 Log: Merged revision(s) 22555 from trunk/OpenMPT: [Ref] mpt/base/arithmetic_shift.hpp: Remove unneeded include. ........ Modified: branches/OpenMPT-1.30/ (props changed) branches/OpenMPT-1.30/src/mpt/base/arithmetic_shift.hpp Modified: branches/OpenMPT-1.30/src/mpt/base/arithmetic_shift.hpp ============================================================================== --- branches/OpenMPT-1.30/src/mpt/base/arithmetic_shift.hpp Tue Dec 17 10:26:18 2024 (r22558) +++ branches/OpenMPT-1.30/src/mpt/base/arithmetic_shift.hpp Tue Dec 17 10:26:59 2024 (r22559) @@ -8,8 +8,6 @@ #include "mpt/base/detect.hpp" #include "mpt/base/namespace.hpp" -#include "mpt/base/saturate_cast.hpp" - namespace mpt { inline namespace MPT_INLINE_NS { |
From: <sv...@op...> - 2024-12-17 09:26:25
|
Author: manx Date: Tue Dec 17 10:26:18 2024 New Revision: 22558 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22558 Log: Merged revision(s) 22556 from trunk/OpenMPT: [Fix] mpt/base/saturate_round.hpp: Fix includes. ........ Modified: branches/OpenMPT-1.31/ (props changed) branches/OpenMPT-1.31/src/mpt/base/saturate_round.hpp Modified: branches/OpenMPT-1.31/src/mpt/base/saturate_round.hpp ============================================================================== --- branches/OpenMPT-1.31/src/mpt/base/saturate_round.hpp Tue Dec 17 10:25:42 2024 (r22557) +++ branches/OpenMPT-1.31/src/mpt/base/saturate_round.hpp Tue Dec 17 10:26:18 2024 (r22558) @@ -10,7 +10,7 @@ #include "mpt/base/math.hpp" #include "mpt/base/saturate_cast.hpp" -#include <type_traits> +#include <limits> |
From: <sv...@op...> - 2024-12-17 09:25:54
|
Author: manx Date: Tue Dec 17 10:25:42 2024 New Revision: 22557 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22557 Log: Merged revision(s) 22555 from trunk/OpenMPT: [Ref] mpt/base/arithmetic_shift.hpp: Remove unneeded include. ........ Modified: branches/OpenMPT-1.31/ (props changed) branches/OpenMPT-1.31/src/mpt/base/arithmetic_shift.hpp Modified: branches/OpenMPT-1.31/src/mpt/base/arithmetic_shift.hpp ============================================================================== --- branches/OpenMPT-1.31/src/mpt/base/arithmetic_shift.hpp Tue Dec 17 10:25:10 2024 (r22556) +++ branches/OpenMPT-1.31/src/mpt/base/arithmetic_shift.hpp Tue Dec 17 10:25:42 2024 (r22557) @@ -8,8 +8,6 @@ #include "mpt/base/detect.hpp" #include "mpt/base/namespace.hpp" -#include "mpt/base/saturate_cast.hpp" - namespace mpt { inline namespace MPT_INLINE_NS { |
From: <sv...@op...> - 2024-12-17 09:25:22
|
Author: manx Date: Tue Dec 17 10:25:10 2024 New Revision: 22556 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22556 Log: [Fix] mpt/base/saturate_round.hpp: Fix includes. Modified: trunk/OpenMPT/src/mpt/base/saturate_round.hpp Modified: trunk/OpenMPT/src/mpt/base/saturate_round.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/saturate_round.hpp Tue Dec 17 10:23:41 2024 (r22555) +++ trunk/OpenMPT/src/mpt/base/saturate_round.hpp Tue Dec 17 10:25:10 2024 (r22556) @@ -10,7 +10,7 @@ #include "mpt/base/math.hpp" #include "mpt/base/saturate_cast.hpp" -#include <type_traits> +#include <limits> |
From: <sv...@op...> - 2024-12-17 09:23:54
|
Author: manx Date: Tue Dec 17 10:23:41 2024 New Revision: 22555 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22555 Log: [Ref] mpt/base/arithmetic_shift.hpp: Remove unneeded include. Modified: trunk/OpenMPT/src/mpt/base/arithmetic_shift.hpp Modified: trunk/OpenMPT/src/mpt/base/arithmetic_shift.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/arithmetic_shift.hpp Mon Dec 16 21:38:45 2024 (r22554) +++ trunk/OpenMPT/src/mpt/base/arithmetic_shift.hpp Tue Dec 17 10:23:41 2024 (r22555) @@ -8,8 +8,6 @@ #include "mpt/base/detect.hpp" #include "mpt/base/namespace.hpp" -#include "mpt/base/saturate_cast.hpp" - namespace mpt { inline namespace MPT_INLINE_NS { |
From: <sv...@op...> - 2024-12-16 21:10:07
|
Author: sagamusix Revision: 22554 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1,2 +1,2 @@ -[Fix] IT: r22552 was too generic. +[Fix] IT: r22551 was too generic. Lxx still needs to initialize the portamento effect, just not take the effect parameter. [Imp] Reset portamento memory when resetting channels. \ No newline at end of file |
From: <sv...@op...> - 2024-12-16 20:38:57
|
Author: sagamusix Date: Mon Dec 16 21:38:45 2024 New Revision: 22554 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22554 Log: [Fix] IT: r22552 was too generic. [Imp] Reset portamento memory when resetting channels. Modified: trunk/OpenMPT/soundlib/ModChannel.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/soundlib/ModChannel.cpp ============================================================================== --- trunk/OpenMPT/soundlib/ModChannel.cpp Sun Dec 15 23:33:15 2024 (r22553) +++ trunk/OpenMPT/soundlib/ModChannel.cpp Mon Dec 16 21:38:45 2024 (r22554) @@ -81,6 +81,8 @@ nVibratoPos = nTremoloPos = nPanbrelloPos = 0; nOldHiOffset = 0; nLeftVU = nRightVU = 0; + nOldExtraFinePortaUpDown = nOldFinePortaUpDown = nOldPortaDown = nOldPortaUp = 0; + portamentoSlide = 0; // Custom tuning related m_ReCalculateFreqOnFirstTick = false; Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp Sun Dec 15 23:33:15 2024 (r22553) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp Mon Dec 16 21:38:45 2024 (r22554) @@ -3171,9 +3171,9 @@ // Test cases: DoubleSlide.it, DoubleSlideCompatGxx.it if(m_playBehaviour[kITDoublePortamentoSlides] && chn.isFirstTick) { - const bool effectColumnTonePorta = (cmd == CMD_TONEPORTAMENTO); + const bool effectColumnTonePorta = (cmd == CMD_TONEPORTAMENTO || cmd == CMD_TONEPORTAVOL); if(effectColumnTonePorta) - InitTonePortamento(chn, static_cast<uint16>(param)); + InitTonePortamento(chn, static_cast<uint16>(cmd == CMD_TONEPORTAVOL ? 0 : param)); if(volcmd == VOLCMD_TONEPORTAMENTO) InitTonePortamento(chn, GetVolCmdTonePorta(chn.rowCommand, nStartTick).first); |