From 6f881fe3cf07f3d9d925b2cd08c09c36c9b742e2 Mon Sep 17 00:00:00 2001 From: Dalton Messmer Date: Sun, 21 May 2023 13:28:30 -0400 Subject: [PATCH 1/3] Start refactoring generated data --- include/core/generated_data.h | 1 + include/core/module_base.h | 5 + include/core/state.h | 293 ++++++++++++++++++++++------------ src/modules/dmf.cpp | 144 ++++++++--------- 4 files changed, 263 insertions(+), 180 deletions(-) diff --git a/include/core/generated_data.h b/include/core/generated_data.h index 9dce4be..49b04da 100644 --- a/include/core/generated_data.h +++ b/include/core/generated_data.h @@ -105,6 +105,7 @@ void ClearAllGenData(Storage* storage) } // namespace detail + template class GeneratedDataStorage : public CommonDef { diff --git a/include/core/module_base.h b/include/core/module_base.h index d77d4ab..bfbbf47 100644 --- a/include/core/module_base.h +++ b/include/core/module_base.h @@ -84,6 +84,11 @@ class ModuleBase : public EnableReflection, public std::enable_share */ [[nodiscard]] virtual auto GenerateData(size_t data_flags = 0) const -> size_t = 0; + /* + * Gets the generated data + */ + //[[nodiscard]] virtual auto GetGeneratedData() const -> std::shared_ptr = 0; + /* * Gets the Status object for the last import/export/convert */ diff --git a/include/core/state.h b/include/core/state.h index 23ee20d..2b3b4f5 100644 --- a/include/core/state.h +++ b/include/core/state.h @@ -40,8 +40,8 @@ struct StateDefinitionTag {}; struct OneShotDefinitionTag {}; // Sourced from: https://stackoverflow.com/a/53398815/8704745 -template -using tuple_cat_t = decltype(std::tuple_cat(std::declval()...)); +template +using tuple_cat_t = decltype(std::tuple_cat(std::declval()...)); template struct WrappedStateData {}; @@ -50,14 +50,14 @@ template struct WrappedStateData> { // type is either an empty tuple or a tuple with each Ts wrapped in a vector of pairs - using type = std::conditional_t, std::tuple>...>>; + using type = std::conditional_t, std::tuple>...>>; }; -template -using WrappedStateDataType = typename WrappedStateData::type; +template +using WrappedStateDataType = typename WrappedStateData::type; template -[[nodiscard]] constexpr auto abs(const T x) noexcept -> T +[[nodiscard]] inline constexpr auto abs(const T x) noexcept -> T { return x == T(0) ? T(0) : (x < T(0) ? -x : x); } @@ -124,9 +124,6 @@ template using SoundIndexStateData = typename SoundIndex::type; struct GlobalStateCommonDefinition : public detail::StateDefinitionTag { - static constexpr int kCommonCount = 3; // # of variants in StateEnumCommon (remember to update this after changing the enum) - static constexpr int kLowerBound = -kCommonCount; - // Common state data have negative indexes enum StateEnumCommon { @@ -143,13 +140,13 @@ struct GlobalStateCommonDefinition : public detail::StateDefinitionTag SpeedBStateData, SpeedAStateData >; + + static constexpr int kCommonCount = std::tuple_size_v; + static constexpr int kLowerBound = -kCommonCount; }; struct GlobalOneShotCommonDefinition : public detail::OneShotDefinitionTag { - static constexpr int kOneShotCommonCount = 3; // # of variants in OneShotEnumCommon (remember to update this after changing the enum) - static constexpr int kOneShotLowerBound = -kOneShotCommonCount; - // Common one-shot data have negative indexes enum OneShotEnumCommon { @@ -166,30 +163,28 @@ struct GlobalOneShotCommonDefinition : public detail::OneShotDefinitionTag PatBreakStateData, PosJumpStateData >; + + static constexpr int kOneShotCommonCount = std::tuple_size_v; + static constexpr int kOneShotLowerBound = -kOneShotCommonCount; }; -template struct ChannelStateCommonDefinition : public detail::StateDefinitionTag { - static constexpr int kCommonCount = 12; // # of variants in StateEnumCommon (remember to update this after changing the enum) - static constexpr int kLowerBound = -kCommonCount; - // Common state data have negative indexes enum StateEnumCommon { // Add additional variants here - kVolSlide = -12, - kPanning = -11, - kTremolo = -10, - kVibratoVolSlide = -9, - kPort2NoteVolSlide = -8, - kVibrato = -7, - kPort = -6, // should this be split into port up, port down, and port2note? - kArp = -5, - kVolume = -4, - kNotePlaying = -3, - kNoteSlot = -2, - kSoundIndex = -1 + kVolSlide = -11, + kPanning = -10, + kTremolo = -9, + kVibratoVolSlide = -8, + kPort2NoteVolSlide = -7, + kVibrato = -6, + kPort = -5, // should this be split into port up, port down, and port2note? + kArp = -4, + kVolume = -3, + kNotePlaying = -2, + kNoteSlot = -1 // StateEnum contains values >= 0 }; @@ -205,16 +200,15 @@ struct ChannelStateCommonDefinition : public detail::StateDefinitionTag ArpStateData, VolumeStateData, NotePlayingStateData, - NoteSlotStateData, - SoundIndexStateData + NoteSlotStateData >; + + static constexpr int kCommonCount = std::tuple_size_v; + static constexpr int kLowerBound = -kCommonCount; }; struct ChannelOneShotCommonDefinition : public detail::OneShotDefinitionTag { - static constexpr int kOneShotCommonCount = 3; // # of variants in OneShotEnumCommon (remember to update this after changing the enum) - static constexpr int kOneShotLowerBound = -kOneShotCommonCount; - // Common one-shot data have negative indexes enum OneShotEnumCommon { @@ -231,14 +225,44 @@ struct ChannelOneShotCommonDefinition : public detail::OneShotDefinitionTag NoteCutStateData, RetriggerStateData >; + + static constexpr int kOneShotCommonCount = std::tuple_size_v; + static constexpr int kOneShotLowerBound = -kOneShotCommonCount; }; /////////////////////////////////////////////////////////// // STATE STORAGE /////////////////////////////////////////////////////////// +template +class StateStorageCommon : public CommonDef +{ +public: + using typename CommonDef::StateDataCommon; + + // Tuple of all common data types stored by this state, wrapped. They should all be vectors of pairs. + using StateDataCommonWrapped = detail::WrappedStateDataType; + + virtual ~StateStorageCommon() = default; + + template = true> + [[nodiscard]] constexpr auto Get2() const -> const auto& + { + return std::get(common_data_); + } + + template = true> + [[nodiscard]] constexpr auto Get2() -> auto& + { + return std::get(common_data_); + } + +private: + StateDataCommonWrapped common_data_; +}; + template -class StateStorage : public CommonDef +class StateStorage : public StateStorageCommon { public: static constexpr int kUpperBound = sizeof...(Ts); // # of module-specific state data types @@ -246,34 +270,60 @@ class StateStorage : public CommonDef // The StateEnum for any module-specific types should be defined // in the GlobalState/ChannelState template specialization - using StateDataModuleSpecific = std::tuple; + using StateDataSpecialized = std::tuple; - // Single tuple of all data types stored by this state - using StateData = detail::tuple_cat_t; + // Tuple of all specialized data types stored by this state, wrapped. They should all be vectors of pairs. + using StateDataSpecializedWrapped = detail::WrappedStateDataType; - // Single tuple of all wrapped data types stored by this state. They should all be vectors of pairs. - using StateDataWrapped = detail::WrappedStateDataType; + using CombinedStateData = detail::tuple_cat_t::StateDataCommon, StateDataSpecialized>; - // Returns an immutable reference to state data at index state_data_index template [[nodiscard]] constexpr auto Get() const -> const auto& { - return std::get(data_); + if constexpr (state_data_index >= 0) { return std::get(specialized_data_); } + else { return StateStorageCommon::template Get2(); } } - // Returns a mutable reference to state data at index state_data_index template [[nodiscard]] constexpr auto Get() -> auto& { - return std::get(data_); + if constexpr (state_data_index >= 0) { return std::get(specialized_data_); } + else { return StateStorageCommon::template Get2(); } + } + +private: + StateDataSpecializedWrapped specialized_data_; +}; + +template +class OneShotStorageCommon : public CommonDef +{ +public: + using typename CommonDef::OneShotDataCommon; + + // Tuple of all common data types stored by this state, wrapped. They should all be vectors of pairs. + using OneShotDataCommonWrapped = detail::WrappedStateDataType; + + virtual ~OneShotStorageCommon() = default; + + template = true> + [[nodiscard]] constexpr auto GetOneShot2() const -> const auto& + { + return std::get(common_oneshot_data_); + } + + template = true> + [[nodiscard]] constexpr auto GetOneShot2() -> auto& + { + return std::get(common_oneshot_data_); } private: - StateDataWrapped data_; // Stores all state data + OneShotDataCommonWrapped common_oneshot_data_; }; template -class OneShotStorage : public CommonDef +class OneShotStorage : public OneShotStorageCommon { public: static constexpr int kOneShotUpperBound = sizeof...(Ts); // # of module-specific one-shot data types @@ -281,30 +331,27 @@ class OneShotStorage : public CommonDef // The OneShotEnum for any module-specific types should be defined // in the GlobalState/ChannelState template specialization - using OneShotDataModuleSpecific = std::tuple; - - // Single tuple of all data types stored by this one-shot state - using OneShotData = detail::tuple_cat_t; + using OneShotDataSpecialized = std::tuple; - // Single tuple of all wrapped data types stored by this one-shot state. They should all be vectors of pairs. - using OneShotDataWrapped = detail::WrappedStateDataType; + // Tuple of all specialized data types stored by this state, wrapped. They should all be vectors of pairs. + using OneShotDataSpecializedWrapped = detail::WrappedStateDataType; - // Returns an immutable reference to one-shot data at index oneshot_data_index template [[nodiscard]] constexpr auto GetOneShot() const -> const auto& { - return std::get(oneshot_data_); + if constexpr (oneshot_data_index >= 0) { return std::get(specialized_oneshot_data_); } + else { return OneShotStorageCommon::template GetOneShot2(); } } - // Returns a mutable reference to one-shot data at index oneshot_data_index template [[nodiscard]] constexpr auto GetOneShot() -> auto& { - return std::get(oneshot_data_); + if constexpr (oneshot_data_index >= 0) { return std::get(specialized_oneshot_data_); } + else { return OneShotStorageCommon::template GetOneShot2(); } } private: - OneShotDataWrapped oneshot_data_; // Stores all one-shot state data + OneShotDataSpecializedWrapped specialized_oneshot_data_; }; /////////////////////////////////////////////////////////// @@ -334,15 +381,45 @@ struct GlobalState : template struct ChannelState : - public StateStorage /* Module-specific types go here in any specializations */>, + public StateStorage /* Module-specific types go here in any specializations */>, public OneShotStorage { - using typename ChannelStateCommonDefinition::StateEnumCommon; - enum StateEnum {}; + using typename ChannelStateCommonDefinition::StateEnumCommon; + enum StateEnum { kSoundIndex }; using typename ChannelOneShotCommonDefinition::OneShotEnumCommon; enum OneShotEnum {}; }; +namespace detail { + enum StateType { kState, kOneShot }; + + template + inline constexpr int kStorageCommonCount = state_type == kState ? CommonStorage::kCommonCount : CommonStorage::kOneShotCommonCount; + + template + using CommonStorageDataType = std::conditional_t; + template + using SpecializedStorageDataType = std::conditional_t; + + template + using CommonStorageWrappedDataType = std::conditional_t; + template + using SpecializedStorageWrappedDataType = std::conditional_t; + + template + using GetTypeFromStorage = std::conditional_t<(data_index < 0), + std::tuple_element_t(data_index + kStorageCommonCount), CommonStorageDataType>, + std::tuple_element_t(data_index), SpecializedStorageDataType> + >; + + template + using GetWrappedTypeFromStorage = std::conditional_t<(data_index < 0), + std::tuple_element_t, CommonStorageWrappedDataType>, + std::tuple_element_t(data_index), SpecializedStorageWrappedDataType> + >; + +} // namespace detail + /////////////////////////////////////////////////////////// // STATE READER /////////////////////////////////////////////////////////// @@ -351,21 +428,21 @@ namespace detail { // Compile-time for loop helper template -void CopyStateHelper(Reader const* reader, Tuple& t, const Function& f, std::integer_sequence&&) +void CopyStateHelper(const Reader* reader, Tuple& t, const Function& f, std::integer_sequence&&) { (f(std::get(t), reader->template Get()), ...); } // Function F arguments are: (inner data tuple element reference, inner data) template -void CopyState(Reader const* reader, Tuple& t, const Function& f) +void CopyState(const Reader* reader, Tuple& t, const Function& f) { CopyStateHelper(reader, t, f, std::make_integer_sequence{}); } // Compile-time for loop helper template -void NextStateHelper(Reader const* reader, const Function& f, std::integer_sequence&&) +void NextStateHelper(const Reader* reader, const Function& f, std::integer_sequence&&) { if constexpr (oneshots) { (f(reader->template GetOneShotVec(), start + integers), ...); } else { (f(reader->template GetVec(), start + integers), ...); } @@ -373,7 +450,7 @@ void NextStateHelper(Reader const* reader, const Function& f, std::integer_seque // Function F arguments are: (wrapped state/one-shot data vector, index) template -void NextState(Reader const* reader, const Function& f) +void NextState(const Reader* reader, const Function& f) { NextStateHelper(reader, f, std::make_integer_sequence{}); } @@ -389,22 +466,21 @@ class StateReader // Bring in dependencies: using State = StateClass; - using StateData = typename State::StateData; - using StateDataWrapped = typename State::StateDataWrapped; + //using StateData = typename State::StateData; + //using StateDataWrapped = typename State::StateDataWrapped; using StateEnumCommon = typename State::StateEnumCommon; using StateEnum = typename State::StateEnum; - using OneShotData = typename State::OneShotData; - using OneShotDataWrapped = typename State::OneShotDataWrapped; + //using OneShotData = typename State::OneShotData; + //using OneShotDataWrapped = typename State::OneShotDataWrapped; using OneShotEnumCommon = typename State::OneShotEnumCommon; using OneShotEnum = typename State::OneShotEnum; // Helpers: - template using get_data_t = std::tuple_element_t; - template using get_data_wrapped_t = std::tuple_element_t; - - template using get_oneshot_data_t = std::tuple_element_t; - template using get_oneshot_data_wrapped_t = std::tuple_element_t; + template + using GetType = detail::GetTypeFromStorage; + template + using GetWrappedType = detail::GetWrappedTypeFromStorage; using Deltas = std::array; using OneShotDeltas = std::array; @@ -413,8 +489,8 @@ class StateReader StateReader(State* state) : state_{state} { Reset(); } virtual ~StateReader() = default; - void AssignState(State const* state) { state_ = state; channel_ = 0; } - void AssignState(State const* state, ChannelIndex channel) { state_ = state; channel_ = channel; } + void AssignState(const State* state) { state_ = state; channel_ = 0; } + void AssignState(const State* state, ChannelIndex channel) { state_ = state; channel_ = channel; } // Set current read position to the beginning of the Module's state data virtual void Reset() @@ -428,7 +504,7 @@ class StateReader // Get the specified state data vector (state_data_index) template - [[nodiscard]] inline constexpr auto GetVec() const -> const get_data_wrapped_t& + [[nodiscard]] inline constexpr auto GetVec() const -> const GetWrappedType& { assert(state_); return state_->template Get(); @@ -436,7 +512,7 @@ class StateReader // Get the specified one-shot data vector (oneshot_data_index) template - [[nodiscard]] inline constexpr auto GetOneShotVec() const -> const get_oneshot_data_wrapped_t& + [[nodiscard]] inline constexpr auto GetOneShotVec() const -> const GetWrappedType& { assert(state_); return state_->template GetOneShot(); @@ -444,7 +520,7 @@ class StateReader // Get the specified state data (state_data_index) at the current read position template - [[nodiscard]] inline constexpr auto Get() const -> const get_data_t& + [[nodiscard]] inline constexpr auto Get() const -> const GetType& { const int vec_index = cur_indexes_[GetIndex(state_data_index)]; const auto& vec = GetVec(); @@ -454,24 +530,24 @@ class StateReader // Get the specified state data (state_data_index) at the specified read index (vec_index) within the vector template - [[nodiscard]] inline constexpr auto Get(size_t vec_index) const -> const get_data_t& + [[nodiscard]] inline constexpr auto Get(size_t vec_index) const -> const GetType& { return GetVec().at(vec_index).second; } // Get the specified one-shot data (oneshot_data_index) at the current read position. Only valid if GetOneShotDelta() returned true. template - [[nodiscard]] inline constexpr auto GetOneShot() const -> const get_oneshot_data_t& + [[nodiscard]] inline constexpr auto GetOneShot() const -> const GetType& { const int vec_index = cur_indexes_oneshot_[GetOneShotIndex(oneshot_data_index)]; assert(vec_index > 0 && "Only call GetOneShot() if GetOneShotDelta() returned true"); - return GetOneShotVec().at(vec_index-1).second; + return GetOneShotVec().at(vec_index - 1).second; } // Gets the specified state data (state_data_index) if it is exactly at the current read position. // TODO: This makes a copy. Try using std::reference_wrapper template - [[nodiscard]] inline constexpr auto GetImpulse() const -> std::optional> + [[nodiscard]] inline constexpr auto GetImpulse() const -> std::optional> { const auto& vec = GetVec(); assert(!vec.empty() && "The initial state must be set before reading"); @@ -484,9 +560,9 @@ class StateReader } // Returns a tuple of all the state values at the current read position - [[nodiscard]] auto Copy() const -> StateData + [[nodiscard]] auto Copy() const -> typename State::CombinedStateData { - StateData return_val; + typename State::CombinedStateData return_val; detail::CopyState(this, return_val, [](auto& return_val_elem, const auto& val) constexpr { return_val_elem = val; }); return return_val; @@ -573,7 +649,7 @@ class StateReader } // Returns state data at given position, then restores position to what it was previously - [[nodiscard]] auto ReadAt(OrderRowPosition pos) -> StateData + [[nodiscard]] auto ReadAt(OrderRowPosition pos) -> typename State::CombinedStateData { const OrderRowPosition cur_pos_temp = cur_pos_; const auto deltas_temp = deltas_; @@ -595,7 +671,7 @@ class StateReader } // Returns state data at given position, then restores position to what it was previously - [[nodiscard]] inline auto ReadAt(OrderIndex order, RowIndex row) -> StateData + [[nodiscard]] inline auto ReadAt(OrderIndex order, RowIndex row) -> typename State::CombinedStateData { return ReadAt(GetOrderRowPosition(order, row)); } @@ -620,15 +696,15 @@ class StateReader // Only useful for ChannelStateReader [[nodiscard]] inline auto GetChannel() const -> ChannelIndex { return channel_; } - // Gets a desired value from StateData + // Gets a desired value from CombinedStateData template - [[nodiscard]] static constexpr auto GetValue(const StateData& data) -> get_data_t + [[nodiscard]] static constexpr auto GetValue(const typename State::CombinedStateData& data) -> GetType { return std::get(data); } template - [[nodiscard]] constexpr auto Find(std::function&)> cmp) const -> std::optional>> + [[nodiscard]] constexpr auto Find(std::function&)> cmp) const -> std::optional>> { const auto& vec = GetVec(); assert(!vec.empty() && "The initial state must be set before reading"); @@ -694,14 +770,15 @@ class StateReaderWriter : public StateReader // Bring in dependencies: using R = StateReader; using typename R::State; - using typename R::StateData; using typename R::StateEnumCommon; using typename R::StateEnum; - using typename R::OneShotData; using typename R::OneShotEnumCommon; using typename R::OneShotEnum; - template using get_data_t = typename R::template get_data_t; - template using get_oneshot_data_t = typename R::template get_oneshot_data_t; + + template + using GetType = typename R::template GetType; + template + using GetWrappedType = typename R::template GetWrappedType; StateReaderWriter() : R{} {} StateReaderWriter(State* state) : R{state} {} @@ -717,7 +794,7 @@ class StateReaderWriter : public StateReader // Set the initial state template - void SetInitial(get_data_t&& val) + void SetInitial(GetType&& val) { SetWritePos(-1); assert(state_write_); @@ -728,15 +805,15 @@ class StateReaderWriter : public StateReader // Set the initial state template - inline void SetInitial(const get_data_t& val) + inline void SetInitial(const GetType& val) { - get_data_t val_copy = val; + GetType val_copy = val; SetInitial(std::move(val_copy)); } // Set the specified state data (state_data_index) at the current write position (the end of the vector) to val template - void Set(get_data_t&& val) + void Set(GetType&& val) { assert(state_write_); auto& vec = state_write_->template Get(); @@ -768,15 +845,15 @@ class StateReaderWriter : public StateReader // Set the specified state data (state_data_index) at the current write position (the end of the vector) to val template - inline void Set(const get_data_t& val) + inline void Set(const GetType& val) { - get_data_t val_copy = val; + GetType val_copy = val; Set(std::move(val_copy)); } // Set the specified one-shot data (oneshot_data_index) at the current write position (the end of the vector) to val template - void SetOneShot(get_oneshot_data_t&& val) + void SetOneShot(GetType&& val) { assert(state_write_); auto& vec = state_write_->template GetOneShot(); @@ -813,14 +890,14 @@ class StateReaderWriter : public StateReader // Set the specified state data (oneshot_data_index) at the current write position (the end of the vector) to val template - inline void SetOneShot(const get_oneshot_data_t& val) + inline void SetOneShot(const GetType& val) { - get_oneshot_data_t val_copy = val; + GetType val_copy = val; SetOneShot(std::move(val_copy)); } // Inserts state data at current position. Use with Copy() in order to "resume" a state. - void Resume(const StateData& vals) + void Resume(const typename State::CombinedStateData& vals) { // Calls Set() for each element in vals detail::ResumeState(this, vals); @@ -828,7 +905,7 @@ class StateReaderWriter : public StateReader // Inserts data into the state at the current read position. The read/write position is invalid afterwards, so it is reset. template - auto Insert(const get_data_t& val) -> bool + auto Insert(const GetType& val) -> bool { assert(state_write_); auto& vec = state_write_->template Get(); @@ -858,7 +935,7 @@ class StateReaderWriter : public StateReader // Inserts data into the state at a given position. The read/write position is invalid afterwards, so it is reset. template - auto Insert(OrderRowPosition pos, const get_data_t& val) -> bool + auto Insert(OrderRowPosition pos, const GetType& val) -> bool { Reset(); R::SetReadPos(pos); @@ -922,8 +999,10 @@ struct StateReaderWriters } } + /* void Save() { + // TODO: Are oneshot states saved? saved_channel_states_.resize(channel_reader_writers.size()); saved_global_data_ = global_reader_writer.Copy(); for (unsigned i = 0; i < channel_reader_writers.size(); ++i) @@ -934,6 +1013,7 @@ struct StateReaderWriters void Restore() { + // TODO: Are oneshot states restored? assert(saved_channel_states_.size() == channel_reader_writers.size()); global_reader_writer.Restore(saved_global_data_); for (unsigned i = 0; i < channel_reader_writers.size(); ++i) @@ -941,10 +1021,11 @@ struct StateReaderWriters channel_reader_writers[i].Restore(saved_channel_states_[i]); } } + */ private: - typename GlobalState::StateData saved_global_data_; - std::vector::StateData> saved_channel_states_; + typename GlobalState::CombinedStateData saved_global_data_; + std::vector::CombinedStateData> saved_channel_states_; }; diff --git a/src/modules/dmf.cpp b/src/modules/dmf.cpp index 9532196..2ee35ca 100644 --- a/src/modules/dmf.cpp +++ b/src/modules/dmf.cpp @@ -1015,27 +1015,23 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t auto& global_state = state_reader_writers->global_reader_writer; auto& channel_states = state_reader_writers->channel_reader_writers; + // For convenience: + using GD = GeneratedData; + using GS = GlobalState; + using CS = ChannelState; + // Initialize other generated data - using GenDataEnumCommon = GeneratedData::GenDataEnumCommon; - auto& sound_indexes_used = gen_data.Get().emplace(); - auto& sound_index_note_extremes = gen_data.Get().emplace(); - //auto& channel_note_extremes = gen_data.Get().emplace(); - gen_data.Get() = false; - gen_data.Get() = data.GetNumOrders(); + auto& sound_indexes_used = gen_data.Get().emplace(); + auto& sound_index_note_extremes = gen_data.Get().emplace(); + //auto& channel_note_extremes = gen_data.Get().emplace(); + gen_data.Get() = false; + gen_data.Get() = data.GetNumOrders(); // Data flags size_t return_val = 0; const bool no_port2note_auto_off = data_flags & 0x1; const bool mod_compat_loops = data_flags & 0x2; - // For convenience: - using GlobalCommon = GlobalState::StateEnumCommon; - using GlobalOneShotCommon = GlobalState::OneShotEnumCommon; - //using GlobalEnum = GlobalState::StateEnum; - using ChannelCommon = ChannelState::StateEnumCommon; - using ChannelOneShotCommon = ChannelState::OneShotEnumCommon; - //using ChannelEnum = ChannelState::StateEnum; - /* * In spite of what the Deflemask manual says, portamento effects are automatically turned off if they * stay on long enough without a new note being played. I believe it's until C-2 is reached for port down @@ -1122,9 +1118,9 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t // Set initial state (global) global_state.Reset(); // Just in case - global_state.SetInitial(module_info_.tick_time1); // * timebase? - global_state.SetInitial(module_info_.tick_time2); // * timebase? - global_state.SetInitial(0); // TODO: How should tempo/speed info be stored? + global_state.SetInitial(module_info_.tick_time1); // * timebase? + global_state.SetInitial(module_info_.tick_time2); // * timebase? + global_state.SetInitial(0); // TODO: How should tempo/speed info be stored? // Set initial state (per-channel) for (unsigned i = 0; i < channel_states.size(); ++i) @@ -1132,18 +1128,18 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t auto& channel_state = channel_states[i]; channel_state.Reset(); // Just in case - channel_state.SetInitial(current_sound_index[i].second); - channel_state.SetInitial(NoteTypes::Empty{}); - channel_state.SetInitial(false); - channel_state.SetInitial(dmf::kGameBoyVolumeMax); - channel_state.SetInitial(0); - channel_state.SetInitial({PortamentoStateData::kNone, 0}); - channel_state.SetInitial(0); - channel_state.SetInitial(0); - channel_state.SetInitial(0); - channel_state.SetInitial(0); - channel_state.SetInitial(127); - channel_state.SetInitial(0); + channel_state.SetInitial(current_sound_index[i].second); + channel_state.SetInitial(NoteTypes::Empty{}); + channel_state.SetInitial(false); + channel_state.SetInitial(dmf::kGameBoyVolumeMax); + channel_state.SetInitial(0); + channel_state.SetInitial({PortamentoStateData::kNone, 0}); + channel_state.SetInitial(0); + channel_state.SetInitial(0); + channel_state.SetInitial(0); + channel_state.SetInitial(0); + channel_state.SetInitial(127); + channel_state.SetInitial(0); } // Main loop @@ -1172,9 +1168,9 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t if (!NoteIsEmpty(row_data.note)) { // Portamento to note stops when next note is reached or on Note OFF - if (channel_state.Get().type == PortamentoStateData::kToNote) + if (channel_state.Get().type == PortamentoStateData::kToNote) { - channel_state.Set(PortamentoStateData{PortamentoStateData::kNone, 0}); + channel_state.Set(PortamentoStateData{PortamentoStateData::kNone, 0}); } } @@ -1187,9 +1183,9 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t if (periods[channel] == target_periods[channel]) { // Portamento to note stops when it reaches its target period - if (channel_state.Get().type == PortamentoStateData::kToNote) + if (channel_state.Get().type == PortamentoStateData::kToNote) { - channel_state.Set(PortamentoStateData{PortamentoStateData::kNone, 0}); + channel_state.Set(PortamentoStateData{PortamentoStateData::kNone, 0}); } } } @@ -1198,9 +1194,9 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t if (periods[channel] >= lowest_period || periods[channel] <= highest_period) { // If the period is at the highest or lowest value, automatically stop any portamento effects - if (channel_state.Get().type != PortamentoStateData::kNone) + if (channel_state.Get().type != PortamentoStateData::kNone) { - channel_state.Set(PortamentoStateData{PortamentoStateData::kNone, 0}); + channel_state.Set(PortamentoStateData{PortamentoStateData::kNone, 0}); } } @@ -1219,7 +1215,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t // on the current row, if the left-most Port2Note were to be used with value > 0, that note will not play. // In addition, all subsequent notes in the channel will also be cancelled until the port2note is stopped by // a future port effect, note OFF, or it auto-off's. Port2Note auto-off is not implemented here though. - const bool port2note_note_cancellation_possible = channel_state.GetSize() == 1 && NoteHasPitch(row_data.note); + const bool port2note_note_cancellation_possible = channel_state.GetSize() == 1 && NoteHasPitch(row_data.note); bool just_cancelled_note = false; bool temp_note_cancelled = note_cancelled[channel]; @@ -1368,8 +1364,8 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t if (need_to_set_port) { // If setting a port to a value of zero, use kNone instead - if (temp_port.value != 0) { channel_state.Set(temp_port); } - else { channel_state.Set(PortamentoStateData{PortamentoStateData::kNone, 0}); } + if (temp_port.value != 0) { channel_state.Set(temp_port); } + else { channel_state.Set(PortamentoStateData{PortamentoStateData::kNone, 0}); } } } @@ -1380,16 +1376,16 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t } // Set other effects' states (WIP) - if (arp) { channel_state.Set(arp.value()); } - if (vibrato) { channel_state.Set(vibrato.value()); } - if (port2note_volslide) { channel_state.Set(port2note_volslide.value()); } - if (vibrato_volslide) { channel_state.Set(vibrato_volslide.value()); } - if (tremolo) { channel_state.Set(tremolo.value()); } - if (panning) { channel_state.Set(panning.value()); } - if (volslide) { channel_state.Set(volslide.value()); } - if (retrigger) { channel_state.SetOneShot(retrigger.value()); } - if (note_cut) { channel_state.SetOneShot(note_cut.value()); } - if (note_delay) { channel_state.SetOneShot(note_delay.value()); } + if (arp) { channel_state.Set(arp.value()); } + if (vibrato) { channel_state.Set(vibrato.value()); } + if (port2note_volslide) { channel_state.Set(port2note_volslide.value()); } + if (vibrato_volslide) { channel_state.Set(vibrato_volslide.value()); } + if (tremolo) { channel_state.Set(tremolo.value()); } + if (panning) { channel_state.Set(panning.value()); } + if (volslide) { channel_state.Set(volslide.value()); } + if (retrigger) { channel_state.SetOneShot(retrigger.value()); } + if (note_cut) { channel_state.SetOneShot(note_cut.value()); } + if (note_delay) { channel_state.SetOneShot(note_delay.value()); } if (sound_index.index() != SoundIndex::kNone) { @@ -1402,16 +1398,16 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t const NoteSlot& note_slot = row_data.note; if (NoteIsOff(note_slot)) { - channel_state.Set(note_slot); // channel_state.SetSingle(note_slot, NoteTypes::Empty{}); - channel_state.Set(false); - gen_data.Get() = true; + channel_state.Set(note_slot); // channel_state.SetSingle(note_slot, NoteTypes::Empty{}); + channel_state.Set(false); + gen_data.Get() = true; note_cancelled[channel] = false; // An OFF also "uncancels" notes cancelled by a port2note effect // NOTE: Note OFF does not affect the current note period } else if (NoteHasPitch(note_slot) && !note_cancelled[channel]) { - channel_state.Set(note_slot); - channel_state.Set(true); + channel_state.Set(note_slot); + channel_state.Set(true); const Note& note = GetNote(note_slot); // Update the period @@ -1427,7 +1423,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t // temporarily, but it will still be guaranteed to write to the end of the // underlying vector and not mess up the always-increasing position ordering. channel_state.SetWritePos(current_sound_index[channel].first); - channel_state.Set(sound_index); + channel_state.Set(sound_index); channel_state.SetWritePos(gen_data_order, gen_data_row); // Get lowest/highest notes @@ -1452,7 +1448,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t } // Update current period - periods[channel] = UpdatePeriod(periods[channel], row % 2, channel_state.Get(), target_periods[channel]); + periods[channel] = UpdatePeriod(periods[channel], row % 2, channel_state.Get(), target_periods[channel]); // CHANNEL STATE - VOLUME if (row_data.volume != kDMFNoVolume) @@ -1464,13 +1460,13 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t switch (row_data.volume) { case 0: case 1: case 2: case 3: - channel_state.Set(0); break; + channel_state.Set(0); break; case 4: case 5: case 6: case 7: - channel_state.Set(5); break; + channel_state.Set(5); break; case 8: case 9: case 10: case 11: - channel_state.Set(10); break; + channel_state.Set(10); break; case 12: case 13: case 14: case 15: - channel_state.Set(15); break; + channel_state.Set(15); break; default: assert(false && "Invalid DMF volume"); break; @@ -1478,7 +1474,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t } else if (NoteHasPitch(row_data.note)) { - channel_state.Set(static_cast(row_data.volume)); + channel_state.Set(static_cast(row_data.volume)); } } @@ -1554,14 +1550,14 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t } // Set the global state if needed - if (speed_a) { global_state.Set(speed_a.value()); } - if (speed_b) { global_state.Set(speed_b.value()); } - if (tempo) { global_state.Set(tempo.value()); } + if (speed_a) { global_state.Set(speed_a.value()); } + if (speed_b) { global_state.Set(speed_b.value()); } + if (tempo) { global_state.Set(tempo.value()); } if (pat_break) { // Always 0 b/c we're using row offsets - global_state.SetOneShot(0); + global_state.SetOneShot(0); // If PatBreak value > 0, rows in gen data will shifted by an offset so that they start on row 0. assert(order < data.GetNumOrders()); @@ -1588,7 +1584,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t // If not on the last row, use a PatBreak. PosJump is not needed. if (row + 1 != data.GetNumRows()) { - global_state.SetOneShot(0); + global_state.SetOneShot(0); } // Any further rows in this order/pattern are skipped because they unreachable. @@ -1610,7 +1606,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t GetOrderRowPosition(gen_data_order, gen_data_row), GetOrderRowPosition(order_map.at(pos_jump.value()), 0) ); // From/To - global_state.SetOneShot(order_map.at(pos_jump.value())); + global_state.SetOneShot(order_map.at(pos_jump.value())); // Any further orders or rows in this song are ignored because they unreachable. // Break out of entire nested loop. @@ -1642,7 +1638,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t // Gen data's total orders may be less than data's if any orders are skipped due to PosJump or // unreachable due to being an order after a loopback. - gen_data.Get().value() -= num_orders_skipped; + gen_data.Get().value() -= num_orders_skipped; const auto last_order_temp = data.GetNumOrders() - 1 - num_orders_skipped; const auto last_row_temp = last_row[last_order_temp] - 1; @@ -1654,7 +1650,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t // No pos jump + loopback has been added for the end of the song - need to add them here global_state.Reset(); global_state.SetWritePos(last_order_row); - global_state.SetOneShot(0); + global_state.SetOneShot(0); loopbacks_temp.emplace_back(last_order_row, 0); } @@ -1678,7 +1674,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t if (last != to) { global_state.SetWritePos(to); - global_state.SetOneShot(from); + global_state.SetOneShot(from); last = to; // Only proceed if using MOD-compatible loops @@ -1694,15 +1690,15 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t channel_state.SetWritePos(to); const auto state_before_loop = channel_state.ReadAt(from); - const bool playing_before = channel_state.GetValue(state_before_loop); + const bool playing_before = channel_state.GetValue(state_before_loop); if (playing_before) { // A note was playing just before looping back - const auto current_row = channel_state.GetImpulse(); + const auto current_row = channel_state.GetImpulse(); if (!current_row.has_value() || NoteIsEmpty(current_row.value())) { // There's an empty slot on this row - const bool playing_now = channel_state.Get(); + const bool playing_now = channel_state.Get(); if (playing_now) { // In Deflemask, a note would be playing on this row the first time through, but when looping back @@ -1714,8 +1710,8 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t else { // Can safely insert a Note OFF in this row to stop notes carrying over from the loop - channel_state.Insert(NoteTypes::Off{}); - gen_data.Get() = true; + channel_state.Insert(NoteTypes::Off{}); + gen_data.Get() = true; } } } From 73baf913d64201efdb54d940cb92b7d4507e81f2 Mon Sep 17 00:00:00 2001 From: Dalton Messmer Date: Sun, 21 May 2023 14:48:39 -0400 Subject: [PATCH 2/3] Fix build --- include/core/state.h | 28 +++++++++--------------- include/modules/debug.h | 2 +- src/modules/debug.cpp | 48 ++++++++++++++++++++++------------------- 3 files changed, 37 insertions(+), 41 deletions(-) diff --git a/include/core/state.h b/include/core/state.h index 2b3b4f5..319ed14 100644 --- a/include/core/state.h +++ b/include/core/state.h @@ -276,6 +276,7 @@ class StateStorage : public StateStorageCommon using StateDataSpecializedWrapped = detail::WrappedStateDataType; using CombinedStateData = detail::tuple_cat_t::StateDataCommon, StateDataSpecialized>; + using CombinedStateDataWrapped = detail::WrappedStateDataType; template [[nodiscard]] constexpr auto Get() const -> const auto& @@ -336,6 +337,9 @@ class OneShotStorage : public OneShotStorageCommon // Tuple of all specialized data types stored by this state, wrapped. They should all be vectors of pairs. using OneShotDataSpecializedWrapped = detail::WrappedStateDataType; + using CombinedOneShotData = detail::tuple_cat_t::OneShotDataCommon, OneShotDataSpecialized>; + using CombinedOneShotDataWrapped = detail::WrappedStateDataType; + template [[nodiscard]] constexpr auto GetOneShot() const -> const auto& { @@ -396,27 +400,15 @@ namespace detail { template inline constexpr int kStorageCommonCount = state_type == kState ? CommonStorage::kCommonCount : CommonStorage::kOneShotCommonCount; - template - using CommonStorageDataType = std::conditional_t; - template - using SpecializedStorageDataType = std::conditional_t; - - template - using CommonStorageWrappedDataType = std::conditional_t; - template - using SpecializedStorageWrappedDataType = std::conditional_t; + template + using CombinedStorageDataType = std::conditional_t; + template + using CombinedStorageWrappedDataType = std::conditional_t; template - using GetTypeFromStorage = std::conditional_t<(data_index < 0), - std::tuple_element_t(data_index + kStorageCommonCount), CommonStorageDataType>, - std::tuple_element_t(data_index), SpecializedStorageDataType> - >; - + using GetTypeFromStorage = std::tuple_element_t, CombinedStorageDataType>; template - using GetWrappedTypeFromStorage = std::conditional_t<(data_index < 0), - std::tuple_element_t, CommonStorageWrappedDataType>, - std::tuple_element_t(data_index), SpecializedStorageWrappedDataType> - >; + using GetWrappedTypeFromStorage = std::tuple_element_t, CombinedStorageWrappedDataType>; } // namespace detail diff --git a/include/modules/debug.h b/include/modules/debug.h index 5380653..f74b72f 100644 --- a/include/modules/debug.h +++ b/include/modules/debug.h @@ -16,7 +16,7 @@ namespace d2m { /////////////////////////////////////////////////////////// -// Setup template specializations used by DMF +// Setup template specializations used by Debug /////////////////////////////////////////////////////////// class Debug; diff --git a/src/modules/debug.cpp b/src/modules/debug.cpp index 1b6adf9..72a98f2 100644 --- a/src/modules/debug.cpp +++ b/src/modules/debug.cpp @@ -17,6 +17,25 @@ using namespace d2m; +namespace { + +struct SoundIndexVisitor +{ + auto operator()(const SoundIndexType& val) -> std::string + { + using SI = SoundIndex; + if (auto square = std::get_if(&val); square) + { return "SQUARE:" + std::to_string(square->id); } + else if (auto wave = std::get_if(&val); wave) + { return "WAVE:" + std::to_string(wave->id); } + else if (auto noise = std::get_if(&val); noise) + { return "NOISE:" + std::to_string(noise->id); } + else { return "UNKNOWN"; } + } +}; + +} // namespace + void Debug::ImportImpl(const std::string& filename) { // Not implemented @@ -46,43 +65,28 @@ void Debug::ConvertImpl(const ModulePtr& input) [[maybe_unused]] auto result = input->GenerateData(flags); dump_ += "GenerateData result: " + std::to_string(result) + "\n"; - static_assert(ChannelState::kCommonCount == 12); + static_assert(ChannelState::kCommonCount == 11); static_assert(ChannelState::kOneShotCommonCount == 3); - /* switch (input->GetType()) { case ModuleType::kDMF: { - using Common = ChannelState::ChannelOneShotCommonDefinition; - auto derived = input->Cast(); - auto gen_data = derived->GetGeneratedData(); - - const auto& note_delay = gen_data->Get(); - if (note_delay) - { - for (auto& [index, extremes] : note_delay.value()) - { - if (std::is_same_v::Square, decltype(index)>) - { - dump_ += ""; - } - } - } - + //using Common = ChannelState::ChannelOneShotCommonDefinition; + //auto derived = input->Cast(); + // ... break; } case ModuleType::kMOD: { - auto derived = input->Cast(); - auto gen_data = derived->GetGeneratedData(); - + //auto derived = input->Cast(); + //auto gen_data = derived->GetGeneratedData(); + // ... break; } default: break; } - */ } void Debug::ExportImpl(const std::string& filename) From 8aa52ab449fed07b1bca571a643929eeabb9a7f6 Mon Sep 17 00:00:00 2001 From: Dalton Messmer Date: Wed, 10 Jul 2024 23:06:39 -0400 Subject: [PATCH 3/3] Cleanup --- console/console.cpp | 4 +- include/core/conversion_options.h | 2 +- include/core/data.h | 100 ++++++++++----------- include/core/effects.h | 42 ++++----- include/core/factory.h | 8 +- include/core/generated_data.h | 24 ++--- include/core/module.h | 22 ++--- include/core/module_base.h | 14 +-- include/core/note.h | 20 ++--- include/core/options.h | 72 +++++++-------- include/core/state.h | 88 +++++++++--------- include/core/status.h | 12 +-- include/modules/debug.h | 8 +- include/modules/dmf.h | 142 +++++++++++++++--------------- include/modules/mod.h | 18 ++-- include/utils/hash.h | 4 +- include/utils/stream_reader.h | 30 +++---- include/utils/utils.h | 24 ++--- src/core/options.cpp | 6 +- src/modules/dmf.cpp | 59 ++++++------- src/modules/mod.cpp | 96 ++++++++++---------- 21 files changed, 393 insertions(+), 402 deletions(-) diff --git a/console/console.cpp b/console/console.cpp index 2db76f1..9485103 100644 --- a/console/console.cpp +++ b/console/console.cpp @@ -122,7 +122,7 @@ auto ParseArgs(std::vector& args, InputOutput& io) -> OperationType io.output_file = ""; io.output_type = ModuleType::kNone; - const size_t arg_count = args.size(); + const std::size_t arg_count = args.size(); if (arg_count == 1) { @@ -205,7 +205,7 @@ auto ParseArgs(std::vector& args, InputOutput& io) -> OperationType io.output_type = Utils::GetTypeFromCommandName(args[1]); if (io.output_type != ModuleType::kNone) { - const size_t dot_pos = io.input_file.rfind('.'); + const std::size_t dot_pos = io.input_file.rfind('.'); if (dot_pos == 0 || dot_pos + 1 >= io.input_file.size()) { std::cerr << "ERROR: The input file is invalid.\n"; diff --git a/include/core/conversion_options.h b/include/core/conversion_options.h index ec86f49..1c46c3b 100644 --- a/include/core/conversion_options.h +++ b/include/core/conversion_options.h @@ -49,7 +49,7 @@ class ConversionOptionsBase : public OptionCollection, public EnableReflection where T is the derived ConversionOptions class */ template, bool> = true> - [[nodiscard]] auto Cast() const -> std::shared_ptr + auto Cast() const -> std::shared_ptr { return std::static_pointer_cast(shared_from_this()); } diff --git a/include/core/data.h b/include/core/data.h index 367b443..2073e7b 100644 --- a/include/core/data.h +++ b/include/core/data.h @@ -16,10 +16,10 @@ namespace d2m { -using OrderIndex = uint16_t; -using PatternIndex = uint16_t; -using ChannelIndex = uint8_t; -using RowIndex = uint16_t; +using OrderIndex = std::uint16_t; +using PatternIndex = std::uint16_t; +using ChannelIndex = std::uint8_t; +using RowIndex = std::uint16_t; enum class DataStorageType { @@ -100,9 +100,9 @@ namespace detail { { public: virtual ~ModuleDataStorageBase() = default; - [[nodiscard]] inline auto GetNumChannels() const -> ChannelIndex { return num_channels_; } - [[nodiscard]] inline auto GetNumOrders() const -> OrderIndex { return num_orders_; } - [[nodiscard]] inline auto GetNumRows() const -> RowIndex { return num_rows_; } + auto GetNumChannels() const -> ChannelIndex { return num_channels_; } + auto GetNumOrders() const -> OrderIndex { return num_orders_; } + auto GetNumRows() const -> RowIndex { return num_rows_; } protected: virtual void CleanUpData() = 0; virtual void SetPatternMatrix(ChannelIndex channels, OrderIndex orders, RowIndex rows) = 0; @@ -134,20 +134,20 @@ namespace detail { using PatternMetadataType = PatternMetadata; using PatternMetadataStorageType = std::vector>; // [channel][pattern id] - [[nodiscard]] inline auto GetPatternId(ChannelIndex channel, OrderIndex order) const -> PatternIndex { return pattern_matrix_[channel][order]; } - inline void SetPatternId(ChannelIndex channel, OrderIndex order, PatternIndex pattern_id) { pattern_matrix_[channel][order] = pattern_id; } - [[nodiscard]] inline auto GetNumPatterns(ChannelIndex channel) const -> PatternIndex { return num_patterns_[channel]; } - inline void SetNumPatterns(ChannelIndex channel, PatternIndex num_patterns) { num_patterns_[channel] = num_patterns; } - [[nodiscard]] inline auto GetPattern(ChannelIndex channel, OrderIndex order) const -> PatternType { return patterns_[channel][GetPatternId(channel, order)]; } - inline void SetPattern(ChannelIndex channel, OrderIndex order, PatternType&& pattern) { patterns_[channel][GetPatternId(channel, order)] = std::move(pattern); } // TODO: Deep copy? - [[nodiscard]] inline auto GetPatternById(ChannelIndex channel, PatternIndex pattern_id) const -> PatternType { return patterns_[channel][pattern_id]; } - inline void SetPatternById(ChannelIndex channel, PatternIndex pattern_id, PatternType&& pattern) { patterns_[channel][pattern_id] = std::move(pattern); } // TODO: Deep copy? - [[nodiscard]] inline auto GetRow(ChannelIndex channel, OrderIndex order, RowIndex row) const -> const RowType& { return GetPattern(channel, order)[row]; } - inline void SetRow(ChannelIndex channel, OrderIndex order, RowIndex row, const RowType& row_value) { GetPattern(channel, order)[row] = row_value; } - [[nodiscard]] inline auto GetRowById(ChannelIndex channel, PatternIndex pattern_id, RowIndex row) const -> const RowType& { return GetPatternById(channel, pattern_id)[row]; } - inline void SetRowById(ChannelIndex channel, PatternIndex pattern_id, RowIndex row, const RowType& row_value) { GetPatternById(channel, pattern_id)[row] = row_value; } - [[nodiscard]] inline auto GetPatternMetadata(ChannelIndex channel, PatternIndex pattern_id) const -> const PatternMetadataType& { return pattern_metadata_[channel][pattern_id]; } - inline void SetPatternMetadata(ChannelIndex channel, PatternIndex pattern_id, const PatternMetadataType& pattern_metadata) { pattern_metadata_[channel][pattern_id] = pattern_metadata; } + auto GetPatternId(ChannelIndex channel, OrderIndex order) const -> PatternIndex { return pattern_matrix_[channel][order]; } + void SetPatternId(ChannelIndex channel, OrderIndex order, PatternIndex pattern_id) { pattern_matrix_[channel][order] = pattern_id; } + auto GetNumPatterns(ChannelIndex channel) const -> PatternIndex { return num_patterns_[channel]; } + void SetNumPatterns(ChannelIndex channel, PatternIndex num_patterns) { num_patterns_[channel] = num_patterns; } + auto GetPattern(ChannelIndex channel, OrderIndex order) const -> PatternType { return patterns_[channel][GetPatternId(channel, order)]; } + void SetPattern(ChannelIndex channel, OrderIndex order, PatternType&& pattern) { patterns_[channel][GetPatternId(channel, order)] = std::move(pattern); } // TODO: Deep copy? + auto GetPatternById(ChannelIndex channel, PatternIndex pattern_id) const -> PatternType { return patterns_[channel][pattern_id]; } + void SetPatternById(ChannelIndex channel, PatternIndex pattern_id, PatternType&& pattern) { patterns_[channel][pattern_id] = std::move(pattern); } // TODO: Deep copy? + auto GetRow(ChannelIndex channel, OrderIndex order, RowIndex row) const -> const RowType& { return GetPattern(channel, order)[row]; } + void SetRow(ChannelIndex channel, OrderIndex order, RowIndex row, const RowType& row_value) { GetPattern(channel, order)[row] = row_value; } + auto GetRowById(ChannelIndex channel, PatternIndex pattern_id, RowIndex row) const -> const RowType& { return GetPatternById(channel, pattern_id)[row]; } + void SetRowById(ChannelIndex channel, PatternIndex pattern_id, RowIndex row, const RowType& row_value) { GetPatternById(channel, pattern_id)[row] = row_value; } + auto GetPatternMetadata(ChannelIndex channel, PatternIndex pattern_id) const -> const PatternMetadataType& { return pattern_metadata_[channel][pattern_id]; } + void SetPatternMetadata(ChannelIndex channel, PatternIndex pattern_id, const PatternMetadataType& pattern_metadata) { pattern_metadata_[channel][pattern_id] = pattern_metadata; } protected: ModuleDataStorage() = default; @@ -250,20 +250,20 @@ namespace detail { using PatternMetadataType = PatternMetadata; using PatternMetadataStorageType = std::vector; // [pattern id] (No per-channel patterns) - [[nodiscard]] inline auto GetPatternId(OrderIndex order) const -> PatternIndex { return pattern_matrix_[order]; } - inline void SetPatternId(OrderIndex order, PatternIndex pattern_id) { pattern_matrix_[order] = pattern_id; } - [[nodiscard]] inline auto GetNumPatterns() const -> PatternIndex { return num_patterns_; } - inline void SetNumPatterns(PatternIndex num_patterns) { num_patterns_ = num_patterns; } - [[nodiscard]] inline auto GetPattern(OrderIndex order) const -> PatternType { return patterns_[GetPatternId(order)]; } - inline void SetPattern(OrderIndex order, PatternType&& pattern) { patterns_[GetPatternId(order)] = std::move(pattern); } // TODO: Deep copy? - [[nodiscard]] inline auto GetPatternById(PatternIndex pattern_id) const -> PatternType { return patterns_[pattern_id]; } - inline void SetPatternById(PatternIndex pattern_id, PatternType&& pattern) { patterns_[pattern_id] = std::move(pattern); } // TODO: Deep copy? - [[nodiscard]] inline auto GetRow(ChannelIndex channel, OrderIndex order, RowIndex row) const -> const RowType& { return GetPattern(order)[row][channel]; } - inline void SetRow(ChannelIndex channel, OrderIndex order, RowIndex row, const RowType& row_value) { GetPattern(order)[row][channel] = row_value; } - [[nodiscard]] inline auto GetRowById(ChannelIndex channel, PatternIndex pattern_id, RowIndex row) const -> const RowType& { return GetPatternById(pattern_id)[row][channel]; } - inline void SetRowById(ChannelIndex channel, PatternIndex pattern_id, RowIndex row, const RowType& row_value) { GetPatternById(pattern_id)[row][channel] = row_value; } - [[nodiscard]] inline auto GetPatternMetadata(PatternIndex pattern_id) const -> const PatternMetadataType& { return pattern_metadata_[pattern_id]; } - inline void SetPatternMetadata(PatternIndex pattern_id, const PatternMetadataType& pattern_metadata) { pattern_metadata_[pattern_id] = pattern_metadata; } + auto GetPatternId(OrderIndex order) const -> PatternIndex { return pattern_matrix_[order]; } + void SetPatternId(OrderIndex order, PatternIndex pattern_id) { pattern_matrix_[order] = pattern_id; } + auto GetNumPatterns() const -> PatternIndex { return num_patterns_; } + void SetNumPatterns(PatternIndex num_patterns) { num_patterns_ = num_patterns; } + auto GetPattern(OrderIndex order) const -> PatternType { return patterns_[GetPatternId(order)]; } + void SetPattern(OrderIndex order, PatternType&& pattern) { patterns_[GetPatternId(order)] = std::move(pattern); } // TODO: Deep copy? + auto GetPatternById(PatternIndex pattern_id) const -> PatternType { return patterns_[pattern_id]; } + void SetPatternById(PatternIndex pattern_id, PatternType&& pattern) { patterns_[pattern_id] = std::move(pattern); } // TODO: Deep copy? + auto GetRow(ChannelIndex channel, OrderIndex order, RowIndex row) const -> const RowType& { return GetPattern(order)[row][channel]; } + void SetRow(ChannelIndex channel, OrderIndex order, RowIndex row, const RowType& row_value) { GetPattern(order)[row][channel] = row_value; } + auto GetRowById(ChannelIndex channel, PatternIndex pattern_id, RowIndex row) const -> const RowType& { return GetPatternById(pattern_id)[row][channel]; } + void SetRowById(ChannelIndex channel, PatternIndex pattern_id, RowIndex row, const RowType& row_value) { GetPatternById(pattern_id)[row][channel] = row_value; } + auto GetPatternMetadata(PatternIndex pattern_id) const -> const PatternMetadataType& { return pattern_metadata_[pattern_id]; } + void SetPatternMetadata(PatternIndex pattern_id, const PatternMetadataType& pattern_metadata) { pattern_metadata_[pattern_id] = pattern_metadata; } protected: ModuleDataStorage() = default; @@ -381,30 +381,30 @@ class ModuleData final : public detail::ModuleDataStorage const typename Storage::PatternMatrixType& { return Storage::pattern_matrix_; } - inline auto PatternMatrixRef() -> typename Storage::PatternMatrixType& { return Storage::pattern_matrix_; } + auto PatternMatrixRef() const -> const typename Storage::PatternMatrixType& { return Storage::pattern_matrix_; } + auto PatternMatrixRef() -> typename Storage::PatternMatrixType& { return Storage::pattern_matrix_; } - inline auto NumPatternsRef() const -> const typename Storage::NumPatternsType& { return Storage::num_patterns_; } - inline auto NumPatternsRef() -> typename Storage::NumPatternsType& { return Storage::num_patterns_; } + auto NumPatternsRef() const -> const typename Storage::NumPatternsType& { return Storage::num_patterns_; } + auto NumPatternsRef() -> typename Storage::NumPatternsType& { return Storage::num_patterns_; } - inline auto PatternsRef() const -> const typename Storage::PatternStorageType& { return Storage::patterns_; } - inline auto PatternsRef() -> typename Storage::PatternStorageType& { return Storage::patterns_; } + auto PatternsRef() const -> const typename Storage::PatternStorageType& { return Storage::patterns_; } + auto PatternsRef() -> typename Storage::PatternStorageType& { return Storage::patterns_; } - inline auto PatternMetadataRef() const -> const typename Storage::PatternMetadataStorageType& { return Storage::pattern_metadata_; } - inline auto PatternMetadataRef() -> typename Storage::PatternMetadataStorageType& { return Storage::pattern_metadata_; } + auto PatternMetadataRef() const -> const typename Storage::PatternMetadataStorageType& { return Storage::pattern_metadata_; } + auto PatternMetadataRef() -> typename Storage::PatternMetadataStorageType& { return Storage::pattern_metadata_; } - inline auto ChannelMetadataRef() const -> const std::vector& { return channel_metadata_; } - inline auto ChannelMetadataRef() -> std::vector& { return channel_metadata_; } + auto ChannelMetadataRef() const -> const std::vector& { return channel_metadata_; } + auto ChannelMetadataRef() -> std::vector& { return channel_metadata_; } - inline auto GlobalData() const -> const GlobalDataType& { return global_data_; } - inline auto GlobalData() -> GlobalDataType& { return global_data_; } + auto GlobalData() const -> const GlobalDataType& { return global_data_; } + auto GlobalData() -> GlobalDataType& { return global_data_; } /////// GETTERS / SETTERS /////// - inline auto GetChannelMetadata(ChannelIndex channel) const -> const ChannelMetadataType& { return channel_metadata_[channel]; } - inline void SetChannelMetadata(ChannelIndex channel, const ChannelMetadataType& channelMetadata) { channel_metadata_[channel] = channelMetadata; } + auto GetChannelMetadata(ChannelIndex channel) const -> const ChannelMetadataType& { return channel_metadata_[channel]; } + void SetChannelMetadata(ChannelIndex channel, const ChannelMetadataType& channelMetadata) { channel_metadata_[channel] = channelMetadata; } - static inline constexpr auto GetStorageType() -> DataStorageType { return storage_type; } + static constexpr auto GetStorageType() -> DataStorageType { return storage_type; } /////// Other diff --git a/include/core/effects.h b/include/core/effects.h index 555a354..e42cc6b 100644 --- a/include/core/effects.h +++ b/include/core/effects.h @@ -11,8 +11,8 @@ namespace d2m { -using EffectCode = int8_t; -using EffectValue = int16_t; +using EffectCode = std::int8_t; +using EffectValue = std::int16_t; struct Effect { @@ -31,25 +31,25 @@ namespace Effects enum { // All common effects are less than 0 - kNoEffect =0, - kArp =-1, - kPortUp =-2, - kPortDown =-3, - kPort2Note =-4, - kVibrato =-5, - kPort2NoteVolSlide =-6, - kVibratoVolSlide =-7, - kTremolo =-8, - kPanning =-9, - kSpeedA =-10, - kVolSlide =-11, - kPosJump =-12, - kRetrigger =-13, - kPatBreak =-14, - kNoteCut =-15, - kNoteDelay =-16, - kTempo =-17, - kSpeedB =-18, + kNoEffect = 0, + kArp = -1, + kPortUp = -2, + kPortDown = -3, + kPort2Note = -4, + kVibrato = -5, + kPort2NoteVolSlide = -6, + kVibratoVolSlide = -7, + kTremolo = -8, + kPanning = -9, + kSpeedA = -10, + kVolSlide = -11, + kPosJump = -12, + kRetrigger = -13, + kPatBreak = -14, + kNoteCut = -15, + kNoteDelay = -16, + kTempo = -17, + kSpeedB = -18, }; // Modules should implement effects specific to them using positive values starting with 1. } diff --git a/include/core/factory.h b/include/core/factory.h index faa9751..345ebd6 100644 --- a/include/core/factory.h +++ b/include/core/factory.h @@ -227,8 +227,8 @@ template bool Factory::initialized_ = false; template struct EnableReflection : public detail::EnableReflectionBase { - [[nodiscard]] virtual auto GetType() const -> ModuleType = 0; - [[nodiscard]] virtual auto GetInfo() const -> const Info* = 0; + virtual auto GetType() const -> ModuleType = 0; + virtual auto GetInfo() const -> const Info* = 0; }; @@ -242,13 +242,13 @@ struct EnableReflection : public detail::EnableReflectionBase template struct ReflectionImpl : public Base { - [[nodiscard]] auto GetType() const -> ModuleType final + auto GetType() const -> ModuleType final { static const ModuleType module_type = Factory::template GetEnumFromType(); return module_type; } - [[nodiscard]] auto GetInfo() const -> const Info* final + auto GetInfo() const -> const Info* final { return Factory::GetInfo(GetType()); } diff --git a/include/core/generated_data.h b/include/core/generated_data.h index 49b04da..e0e673f 100644 --- a/include/core/generated_data.h +++ b/include/core/generated_data.h @@ -128,22 +128,22 @@ class GeneratedDataStorage : public CommonDef // Returns an immutable reference to generated data at index gen_data_index template - [[nodiscard]] constexpr auto Get() const -> const auto& + constexpr auto Get() const -> const auto& { return std::get(data_); } // Returns a mutable reference to generated data at index gen_data_index template - [[nodiscard]] constexpr auto Get() -> auto& + constexpr auto Get() -> auto& { return std::get(data_); } // For convenience: - [[nodiscard]] constexpr auto GetState() const -> const std::optional>& { return Get(); } - [[nodiscard]] constexpr auto GetState() -> std::optional>& { return Get(); } - [[nodiscard]] constexpr auto GetNumOrders() const -> const std::optional& { return Get(); } + constexpr auto GetState() const -> const std::optional>& { return Get(); } + constexpr auto GetState() -> std::optional>& { return Get(); } + constexpr auto GetNumOrders() const -> const std::optional& { return Get(); } // Destroys any generated data at index gen_data_index. Call this after any change which would make the data invalid. template @@ -166,16 +166,16 @@ class GeneratedDataStorage : public CommonDef status_ = 0; } - [[nodiscard]] auto IsValid() const -> bool { return generated_.has_value(); } - [[nodiscard]] auto GetGenerated() const -> std::optional { return generated_; } - void SetGenerated(std::optional val) { generated_ = val; } - [[nodiscard]] auto GetStatus() const -> size_t { return status_; } - void SetStatus(size_t val) { status_ = val; } + auto IsValid() const -> bool { return generated_.has_value(); } + auto GetGenerated() const -> std::optional { return generated_; } + void SetGenerated(std::optional val) { generated_ = val; } + auto GetStatus() const -> std::size_t { return status_; } + void SetStatus(std::size_t val) { status_ = val; } protected: GenDataWrapped data_; // Stores all generated data - std::optional generated_; // The value passed to GenerateDataImpl. Has a value if gen data is valid. - size_t status_; // The value returned by GenerateDataImpl. Only valid if IsValid() == true. + std::optional generated_; // The value passed to GenerateDataImpl. Has a value if gen data is valid. + std::size_t status_; // The value returned by GenerateDataImpl. Only valid if IsValid() == true. }; /////////////////////////////////////////////////////////// diff --git a/include/core/module.h b/include/core/module.h index 2577997..599d872 100644 --- a/include/core/module.h +++ b/include/core/module.h @@ -30,14 +30,14 @@ class ModuleInterface : public EnableFactory virtual ~ModuleInterface() = default; - inline auto GetData() const -> const ModuleData& { return data_; } - inline auto GetGlobalData() const -> const ModuleGlobalData& { return GetData().GlobalData(); } - inline auto GetGeneratedData() const -> std::shared_ptr> { return generated_data_; } + auto GetData() const -> const ModuleData& { return data_; } + auto GetGlobalData() const -> const ModuleGlobalData& { return GetData().GlobalData(); } + auto GetGeneratedData() const -> std::shared_ptr> { return generated_data_; } - [[nodiscard]] auto GetTitle() const -> std::string_view final { return GetGlobalData().title; } - [[nodiscard]] auto GetAuthor() const -> std::string_view final { return GetGlobalData().author; } + auto GetTitle() const -> std::string_view final { return GetGlobalData().title; } + auto GetAuthor() const -> std::string_view final { return GetGlobalData().author; } - [[nodiscard]] auto GenerateData(size_t data_flags = 0) const -> size_t final + auto GenerateData(std::size_t data_flags = 0) const -> std::size_t final { // If generated data has already been created using the same data_flags, just return that if (generated_data_->IsValid() && generated_data_->GetGenerated().value() == data_flags) @@ -47,7 +47,7 @@ class ModuleInterface : public EnableFactory // Else, need to generate data generated_data_->ClearAll(); - const size_t status = GenerateDataImpl(data_flags); + const std::size_t status = GenerateDataImpl(data_flags); generated_data_->SetGenerated(data_flags); generated_data_->SetStatus(status); return status; @@ -57,12 +57,12 @@ class ModuleInterface : public EnableFactory ModuleInterface() = default; - inline auto GetData() -> ModuleData& { return data_; } - inline auto GetGlobalData() -> ModuleGlobalData& { return GetData().GlobalData(); } - inline auto GetGeneratedDataMut() const -> std::shared_ptr> { return generated_data_; } + auto GetData() -> ModuleData& { return data_; } + auto GetGlobalData() -> ModuleGlobalData& { return GetData().GlobalData(); } + auto GetGeneratedDataMut() const -> std::shared_ptr> { return generated_data_; } // data_flags specifies what data was requested to be generated - [[nodiscard]] virtual auto GenerateDataImpl(size_t data_flags) const -> size_t = 0; + virtual auto GenerateDataImpl(std::size_t data_flags) const -> std::size_t = 0; private: diff --git a/include/core/module_base.h b/include/core/module_base.h index bfbbf47..8d91363 100644 --- a/include/core/module_base.h +++ b/include/core/module_base.h @@ -57,7 +57,7 @@ class ModuleBase : public EnableReflection, public std::enable_share * Cast ModulePtr to std::shared_ptr where T is the derived Module class */ template, bool> = true> - [[nodiscard]] auto Cast() const -> std::shared_ptr + auto Cast() const -> std::shared_ptr { return std::static_pointer_cast(shared_from_this()); } @@ -82,17 +82,17 @@ class ModuleBase : public EnableReflection, public std::enable_share /* * Generates the generated data using optional data flags */ - [[nodiscard]] virtual auto GenerateData(size_t data_flags = 0) const -> size_t = 0; + virtual auto GenerateData(std::size_t data_flags = 0) const -> std::size_t = 0; /* * Gets the generated data */ - //[[nodiscard]] virtual auto GetGeneratedData() const -> std::shared_ptr = 0; + //virtual auto GetGeneratedData() const -> std::shared_ptr = 0; /* * Gets the Status object for the last import/export/convert */ - [[nodiscard]] auto GetStatus() const -> const Status& { return status_; } + auto GetStatus() const -> const Status& { return status_; } /* * Convenience wrapper for GetStatus().HandleResults() @@ -102,12 +102,12 @@ class ModuleBase : public EnableReflection, public std::enable_share /* * Get the title of the module */ - [[nodiscard]] virtual auto GetTitle() const -> std::string_view = 0; + virtual auto GetTitle() const -> std::string_view = 0; /* * Get the author of the module */ - [[nodiscard]] virtual auto GetAuthor() const -> std::string_view = 0; + virtual auto GetAuthor() const -> std::string_view = 0; protected: // Import() and Export() and Convert() are wrappers for these methods, which must be implemented by a module class: @@ -116,7 +116,7 @@ class ModuleBase : public EnableReflection, public std::enable_share virtual void ExportImpl(const std::string& filename) = 0; virtual void ConvertImpl(const ModulePtr& input) = 0; - [[nodiscard]] auto GetOptions() const -> ConversionOptionsPtr { return options_; } + auto GetOptions() const -> ConversionOptionsPtr { return options_; } Status status_; diff --git a/include/core/note.h b/include/core/note.h index 9a948bb..8400700 100644 --- a/include/core/note.h +++ b/include/core/note.h @@ -13,7 +13,7 @@ namespace d2m { -enum class NotePitch : uint8_t +enum class NotePitch : std::uint8_t { kC=0, kCS, @@ -34,34 +34,34 @@ namespace NoteTypes enum { kEmpty, kNote, kOff }; // The order is important struct Empty {}; - inline constexpr auto operator==(const Empty&, const Empty&) -> bool { return true; }; + constexpr auto operator==(const Empty&, const Empty&) -> bool { return true; }; struct alignas(1) Note { NotePitch pitch : 4; - uint8_t octave : 4; + std::uint8_t octave : 4; constexpr Note() : pitch(NotePitch::kC), octave(0) {} - constexpr Note(NotePitch pitch, uint8_t octave) : pitch(pitch), octave(octave) {} + constexpr Note(NotePitch pitch, std::uint8_t octave) : pitch(pitch), octave(octave) {} auto operator>(Note rhs) const -> bool { - return (this->octave << 4) + static_cast(this->pitch) > (rhs.octave << 4) + static_cast(rhs.pitch); + return (this->octave << 4) + static_cast(this->pitch) > (rhs.octave << 4) + static_cast(rhs.pitch); } auto operator>=(Note rhs) const -> bool { - return (this->octave << 4) + static_cast(this->pitch) >= (rhs.octave << 4) + static_cast(rhs.pitch); + return (this->octave << 4) + static_cast(this->pitch) >= (rhs.octave << 4) + static_cast(rhs.pitch); } auto operator<(Note rhs) const -> bool { - return (this->octave << 4) + static_cast(this->pitch) < (rhs.octave << 4) + static_cast(rhs.pitch); + return (this->octave << 4) + static_cast(this->pitch) < (rhs.octave << 4) + static_cast(rhs.pitch); } auto operator<=(Note rhs) const -> bool { - return (this->octave << 4) + static_cast(this->pitch) <= (rhs.octave << 4) + static_cast(rhs.pitch); + return (this->octave << 4) + static_cast(this->pitch) <= (rhs.octave << 4) + static_cast(rhs.pitch); } auto operator==(Note rhs) const -> bool @@ -76,7 +76,7 @@ namespace NoteTypes }; struct Off {}; - inline constexpr auto operator==(const Off&, const Off&) -> bool { return true; }; + constexpr auto operator==(const Off&, const Off&) -> bool { return true; }; }; using NoteSlot = std::variant; @@ -102,7 +102,7 @@ inline constexpr auto GetNoteRange(const Note& low, const Note& high) -> int // Returns range in semitones. Assumes high >= low. // Range is inclusive on both ends. - return (high.octave - low.octave) * 12 + (static_cast(high.pitch) - static_cast(low.pitch)) + 1; + return (high.octave - low.octave) * 12 + (static_cast(high.pitch) - static_cast(low.pitch)) + 1; } } // namespace d2m diff --git a/include/core/options.h b/include/core/options.h index 573c21f..3f58aa4 100644 --- a/include/core/options.h +++ b/include/core/options.h @@ -114,23 +114,23 @@ class OptionDefinition // Getters and helpers - [[nodiscard]] auto GetOptionType() const -> OptionType { return option_type_; } - [[nodiscard]] auto GetId() const -> int { return id_; } - [[nodiscard]] auto GetValueType() const -> Type { return value_type_; } - [[nodiscard]] auto GetName() const -> std::string_view { return name_; }; - [[nodiscard]] auto GetShortName() const -> char { return short_name_; } - [[nodiscard]] auto GetDisplayName() const -> std::string; - [[nodiscard]] auto GetDefaultValue() const -> ValueType { return default_value_; } - [[nodiscard]] auto GetAcceptedValues() const -> const std::map& { return accepted_values_; } - [[nodiscard]] auto GetAcceptedValuesOrdered() const -> const std::vector& { return accepted_values_ordered_; } - [[nodiscard]] auto GetDescription() const -> std::string_view { return description_; } - - [[nodiscard]] auto HasName() const -> bool { return !name_.empty(); } - [[nodiscard]] auto HasShortName() const -> bool { return short_name_ != '\0'; } - [[nodiscard]] auto UsesAcceptedValues() const -> bool { return accepted_values_.size() > 0; } + auto GetOptionType() const -> OptionType { return option_type_; } + auto GetId() const -> int { return id_; } + auto GetValueType() const -> Type { return value_type_; } + auto GetName() const -> std::string_view { return name_; }; + auto GetShortName() const -> char { return short_name_; } + auto GetDisplayName() const -> std::string; + auto GetDefaultValue() const -> ValueType { return default_value_; } + auto GetAcceptedValues() const -> const std::map& { return accepted_values_; } + auto GetAcceptedValuesOrdered() const -> const std::vector& { return accepted_values_ordered_; } + auto GetDescription() const -> std::string_view { return description_; } + + auto HasName() const -> bool { return !name_.empty(); } + auto HasShortName() const -> bool { return short_name_ != '\0'; } + auto UsesAcceptedValues() const -> bool { return accepted_values_.size() > 0; } // Returns whether the given value can be assigned to an option with this option definition - [[nodiscard]] auto IsValid(const ValueType& value) const -> bool; + auto IsValid(const ValueType& value) const -> bool; // Prints help info void PrintHelp() const; @@ -170,17 +170,17 @@ class OptionDefinitionCollection OptionDefinitionCollection(const OptionDefinitionCollection& other); OptionDefinitionCollection(const std::initializer_list& options); - [[nodiscard]] auto Count() const -> size_t; + auto Count() const -> std::size_t; // Access - [[nodiscard]] auto GetIdMap() const -> const std::map& { return id_options_map_; } + auto GetIdMap() const -> const std::map& { return id_options_map_; } // Find methods - [[nodiscard]] auto FindById(int id) const -> const OptionDefinition*; - [[nodiscard]] auto FindByName(const std::string& name) const -> const OptionDefinition*; - [[nodiscard]] auto FindByShortName(char short_name) const -> const OptionDefinition*; - [[nodiscard]] auto FindIdByName(const std::string& name) const -> int; - [[nodiscard]] auto FindIdByShortName(char short_name) const -> int; + auto FindById(int id) const -> const OptionDefinition*; + auto FindByName(const std::string& name) const -> const OptionDefinition*; + auto FindByShortName(char short_name) const -> const OptionDefinition*; + auto FindIdByName(const std::string& name) const -> int; + auto FindIdByShortName(char short_name) const -> int; // Other void PrintHelp() const; @@ -212,27 +212,27 @@ class Option void SetValueToDefault(); - [[nodiscard]] auto GetValue() const -> const ValueType& { return value_; } + auto GetValue() const -> const ValueType& { return value_; } template - [[nodiscard]] auto GetValue() const -> const T& + auto GetValue() const -> const T& { // Will throw an exception if T is the wrong type return std::get(value_); } - [[nodiscard]] auto GetValueAsIndex() const -> int + auto GetValueAsIndex() const -> int { assert(GetDefinition()->UsesAcceptedValues()); return value_index_; } - [[nodiscard]] auto GetExplicitlyProvided() const -> bool + auto GetExplicitlyProvided() const -> bool { return explicitly_provided_; } - [[nodiscard]] auto GetDefinition() const -> const OptionDefinition*; + auto GetDefinition() const -> const OptionDefinition*; private: @@ -264,37 +264,37 @@ class OptionCollection // Access to definitions void SetDefinitions(const OptionDefinitionCollection* definitions); - [[nodiscard]] auto GetDefinitions() const -> const OptionDefinitionCollection* { return definitions_; } + auto GetDefinitions() const -> const OptionDefinitionCollection* { return definitions_; } // Access to collection - [[nodiscard]] auto GetOptionsMap() const -> const std::map& { return options_map_; } + auto GetOptionsMap() const -> const std::map& { return options_map_; } // Get options based on id, name, or short name - [[nodiscard]] auto GetOption(int id) const -> const Option& { return options_map_.at(id); } + auto GetOption(int id) const -> const Option& { return options_map_.at(id); } auto GetOption(int id) -> Option& { return options_map_[id]; } template && std::is_convertible_v, int>, bool> = true> - [[nodiscard]] auto GetOption(T id) const -> const Option& + auto GetOption(T id) const -> const Option& { return GetOption(static_cast(id)); } template && std::is_convertible_v, int>, bool> = true> - [[nodiscard]] auto GetOption(T id) -> Option& + auto GetOption(T id) -> Option& { return GetOption(static_cast(id)); } - [[nodiscard]] auto GetOption(std::string name) const -> const Option&; + auto GetOption(std::string name) const -> const Option&; auto GetOption(std::string name) -> Option&; - [[nodiscard]] auto GetOption(char short_name) const -> const Option&; + auto GetOption(char short_name) const -> const Option&; auto GetOption(char short_name) -> Option&; // Other - [[nodiscard]] auto ParseArgs(std::vector& args, bool ignore_unknown_args = false) -> bool; + auto ParseArgs(std::vector& args, bool ignore_unknown_args = false) -> bool; void SetValuesToDefault(); private: @@ -311,7 +311,7 @@ class ModuleOptionUtils using ValueType = OptionDefinition::ValueType; // Convert ValueType to a string - [[nodiscard]] static auto ConvertToString(const ValueType& value) -> std::string; + static auto ConvertToString(const ValueType& value) -> std::string; // Convert string + type to a ValueType static auto ConvertToValue(std::string_view value_str, OptionDefinition::Type type, ValueType& return_val) -> bool; diff --git a/include/core/state.h b/include/core/state.h index 319ed14..3725d0b 100644 --- a/include/core/state.h +++ b/include/core/state.h @@ -25,14 +25,14 @@ namespace d2m { // Unique, quickly calculated value encoding order # (not pattern #!) and pattern row #. Easily and quickly comparable. -using OrderRowPosition = int32_t; +using OrderRowPosition = std::int32_t; using GlobalOrderRowPosition = OrderRowPosition; using ChannelOrderRowPosition = OrderRowPosition; // Helpers for conversion: -[[nodiscard]] inline constexpr auto GetOrderRowPosition(OrderIndex order, RowIndex row) -> OrderRowPosition { return (order << 16) | row; }; -[[nodiscard]] inline constexpr auto GetOrderRowPosition(OrderRowPosition pos) -> std::pair { return { pos >> 16, pos & 0x00FF }; }; +constexpr auto GetOrderRowPosition(OrderIndex order, RowIndex row) -> OrderRowPosition { return (order << 16) | row; }; +constexpr auto GetOrderRowPosition(OrderRowPosition pos) -> std::pair { return { pos >> 16, pos & 0x00FF }; }; namespace detail { @@ -57,7 +57,7 @@ template using WrappedStateDataType = typename WrappedStateData::type; template -[[nodiscard]] inline constexpr auto abs(const T x) noexcept -> T +constexpr auto abs(const T x) noexcept -> T { return x == T(0) ? T(0) : (x < T(0) ? -x : x); } @@ -73,14 +73,14 @@ template template struct SoundIndex { - using type = uint8_t; + using type = std::uint8_t; }; template using SoundIndexType = typename SoundIndex::type; -using EffectValueXX = uint8_t; -using EffectValueXXYY = uint8_t; //std::pair; +using EffectValueXX = std::uint8_t; +using EffectValueXXYY = std::uint8_t; //std::pair; // Global state data types @@ -246,13 +246,13 @@ class StateStorageCommon : public CommonDef virtual ~StateStorageCommon() = default; template = true> - [[nodiscard]] constexpr auto Get2() const -> const auto& + constexpr auto Get2() const -> const auto& { return std::get(common_data_); } template = true> - [[nodiscard]] constexpr auto Get2() -> auto& + constexpr auto Get2() -> auto& { return std::get(common_data_); } @@ -279,14 +279,14 @@ class StateStorage : public StateStorageCommon using CombinedStateDataWrapped = detail::WrappedStateDataType; template - [[nodiscard]] constexpr auto Get() const -> const auto& + constexpr auto Get() const -> const auto& { if constexpr (state_data_index >= 0) { return std::get(specialized_data_); } else { return StateStorageCommon::template Get2(); } } template - [[nodiscard]] constexpr auto Get() -> auto& + constexpr auto Get() -> auto& { if constexpr (state_data_index >= 0) { return std::get(specialized_data_); } else { return StateStorageCommon::template Get2(); } @@ -308,13 +308,13 @@ class OneShotStorageCommon : public CommonDef virtual ~OneShotStorageCommon() = default; template = true> - [[nodiscard]] constexpr auto GetOneShot2() const -> const auto& + constexpr auto GetOneShot2() const -> const auto& { return std::get(common_oneshot_data_); } template = true> - [[nodiscard]] constexpr auto GetOneShot2() -> auto& + constexpr auto GetOneShot2() -> auto& { return std::get(common_oneshot_data_); } @@ -341,14 +341,14 @@ class OneShotStorage : public OneShotStorageCommon using CombinedOneShotDataWrapped = detail::WrappedStateDataType; template - [[nodiscard]] constexpr auto GetOneShot() const -> const auto& + constexpr auto GetOneShot() const -> const auto& { if constexpr (oneshot_data_index >= 0) { return std::get(specialized_oneshot_data_); } else { return OneShotStorageCommon::template GetOneShot2(); } } template - [[nodiscard]] constexpr auto GetOneShot() -> auto& + constexpr auto GetOneShot() -> auto& { if constexpr (oneshot_data_index >= 0) { return std::get(specialized_oneshot_data_); } else { return OneShotStorageCommon::template GetOneShot2(); } @@ -398,7 +398,7 @@ namespace detail { enum StateType { kState, kOneShot }; template - inline constexpr int kStorageCommonCount = state_type == kState ? CommonStorage::kCommonCount : CommonStorage::kOneShotCommonCount; + constexpr int kStorageCommonCount = state_type == kState ? CommonStorage::kCommonCount : CommonStorage::kOneShotCommonCount; template using CombinedStorageDataType = std::conditional_t; @@ -496,7 +496,7 @@ class StateReader // Get the specified state data vector (state_data_index) template - [[nodiscard]] inline constexpr auto GetVec() const -> const GetWrappedType& + constexpr auto GetVec() const -> const GetWrappedType& { assert(state_); return state_->template Get(); @@ -504,7 +504,7 @@ class StateReader // Get the specified one-shot data vector (oneshot_data_index) template - [[nodiscard]] inline constexpr auto GetOneShotVec() const -> const GetWrappedType& + constexpr auto GetOneShotVec() const -> const GetWrappedType& { assert(state_); return state_->template GetOneShot(); @@ -512,7 +512,7 @@ class StateReader // Get the specified state data (state_data_index) at the current read position template - [[nodiscard]] inline constexpr auto Get() const -> const GetType& + constexpr auto Get() const -> const GetType& { const int vec_index = cur_indexes_[GetIndex(state_data_index)]; const auto& vec = GetVec(); @@ -522,14 +522,14 @@ class StateReader // Get the specified state data (state_data_index) at the specified read index (vec_index) within the vector template - [[nodiscard]] inline constexpr auto Get(size_t vec_index) const -> const GetType& + constexpr auto Get(size_t vec_index) const -> const GetType& { return GetVec().at(vec_index).second; } // Get the specified one-shot data (oneshot_data_index) at the current read position. Only valid if GetOneShotDelta() returned true. template - [[nodiscard]] inline constexpr auto GetOneShot() const -> const GetType& + constexpr auto GetOneShot() const -> const GetType& { const int vec_index = cur_indexes_oneshot_[GetOneShotIndex(oneshot_data_index)]; assert(vec_index > 0 && "Only call GetOneShot() if GetOneShotDelta() returned true"); @@ -539,7 +539,7 @@ class StateReader // Gets the specified state data (state_data_index) if it is exactly at the current read position. // TODO: This makes a copy. Try using std::reference_wrapper template - [[nodiscard]] inline constexpr auto GetImpulse() const -> std::optional> + constexpr auto GetImpulse() const -> std::optional> { const auto& vec = GetVec(); assert(!vec.empty() && "The initial state must be set before reading"); @@ -552,7 +552,7 @@ class StateReader } // Returns a tuple of all the state values at the current read position - [[nodiscard]] auto Copy() const -> typename State::CombinedStateData + auto Copy() const -> typename State::CombinedStateData { typename State::CombinedStateData return_val; detail::CopyState(this, return_val, @@ -635,13 +635,13 @@ class StateReader * These delta values can then be obtained by calling GetDeltas() or GetOneShotDeltas(). */ template - inline void SetReadPos(OrderIndex order, RowIndex row) + void SetReadPos(OrderIndex order, RowIndex row) { SetReadPos(GetOrderRowPosition(order, row)); } // Returns state data at given position, then restores position to what it was previously - [[nodiscard]] auto ReadAt(OrderRowPosition pos) -> typename State::CombinedStateData + auto ReadAt(OrderRowPosition pos) -> typename State::CombinedStateData { const OrderRowPosition cur_pos_temp = cur_pos_; const auto deltas_temp = deltas_; @@ -663,40 +663,40 @@ class StateReader } // Returns state data at given position, then restores position to what it was previously - [[nodiscard]] inline auto ReadAt(OrderIndex order, RowIndex row) -> typename State::CombinedStateData + auto ReadAt(OrderIndex order, RowIndex row) -> typename State::CombinedStateData { return ReadAt(GetOrderRowPosition(order, row)); } // Get the size of the specified state data vector (state_data_index) template - [[nodiscard]] inline constexpr auto GetSize() const -> size_t + constexpr auto GetSize() const -> std::size_t { return GetVec().size(); } // Returns the deltas from the last SetReadPos() call - [[nodiscard]] inline constexpr auto GetDeltas() const -> const Deltas& { return deltas_; } + constexpr auto GetDeltas() const -> const Deltas& { return deltas_; } - [[nodiscard]] inline constexpr auto GetDelta(int state_data_index) const -> bool { return deltas_[GetIndex(state_data_index)]; } + constexpr auto GetDelta(int state_data_index) const -> bool { return deltas_[GetIndex(state_data_index)]; } // Returns the one-shot deltas from the last SetReadPos() call - [[nodiscard]] inline constexpr auto GetOneShotDeltas() const -> const OneShotDeltas& { return oneshot_deltas_; } + constexpr auto GetOneShotDeltas() const -> const OneShotDeltas& { return oneshot_deltas_; } - [[nodiscard]] inline constexpr auto GetOneShotDelta(int oneshot_data_index) const -> bool { return oneshot_deltas_[GetOneShotIndex(oneshot_data_index)]; } + constexpr auto GetOneShotDelta(int oneshot_data_index) const -> bool { return oneshot_deltas_[GetOneShotIndex(oneshot_data_index)]; } // Only useful for ChannelStateReader - [[nodiscard]] inline auto GetChannel() const -> ChannelIndex { return channel_; } + auto GetChannel() const -> ChannelIndex { return channel_; } // Gets a desired value from CombinedStateData template - [[nodiscard]] static constexpr auto GetValue(const typename State::CombinedStateData& data) -> GetType + static constexpr auto GetValue(const typename State::CombinedStateData& data) -> GetType { return std::get(data); } template - [[nodiscard]] constexpr auto Find(std::function&)> cmp) const -> std::optional>> + constexpr auto Find(std::function&)> cmp) const -> std::optional>> { const auto& vec = GetVec(); assert(!vec.empty() && "The initial state must be set before reading"); @@ -714,10 +714,10 @@ class StateReader protected: // Converts StateEnumCommon or StateEnum variants into a zero-based index of an array. Returns offset if no enum is provided. - [[nodiscard]] static inline constexpr auto GetIndex(int state_data_index = 0) -> int { return State::kCommonCount + state_data_index; } + static constexpr auto GetIndex(int state_data_index = 0) -> int { return State::kCommonCount + state_data_index; } // Converts OneShotEnumCommon or OneShotEnum variants into a zero-based index of an array. Returns offset if no enum is provided. - [[nodiscard]] static inline constexpr auto GetOneShotIndex(int oneshot_data_index = 0) -> int { return State::kOneShotCommonCount + oneshot_data_index; } + static constexpr auto GetOneShotIndex(int oneshot_data_index = 0) -> int { return State::kOneShotCommonCount + oneshot_data_index; } const State* state_ = nullptr; // The state this reader is reading from Deltas deltas_; // An array of bools indicating which (if any) state data values have changed since the last SetReadPos() call @@ -797,7 +797,7 @@ class StateReaderWriter : public StateReader // Set the initial state template - inline void SetInitial(const GetType& val) + void SetInitial(const GetType& val) { GetType val_copy = val; SetInitial(std::move(val_copy)); @@ -837,7 +837,7 @@ class StateReaderWriter : public StateReader // Set the specified state data (state_data_index) at the current write position (the end of the vector) to val template - inline void Set(const GetType& val) + void Set(const GetType& val) { GetType val_copy = val; Set(std::move(val_copy)); @@ -882,7 +882,7 @@ class StateReaderWriter : public StateReader // Set the specified state data (oneshot_data_index) at the current write position (the end of the vector) to val template - inline void SetOneShot(const GetType& val) + void SetOneShot(const GetType& val) { GetType val_copy = val; SetOneShot(std::move(val_copy)); @@ -936,20 +936,20 @@ class StateReaderWriter : public StateReader } // Call this at the start of an inner loop before Set() is called - inline void SetWritePos(OrderRowPosition pos) + void SetWritePos(OrderRowPosition pos) { R::cur_pos_ = pos; } // Call this at the start of an inner loop before Set() is called - inline void SetWritePos(OrderIndex order, RowIndex row) + void SetWritePos(OrderIndex order, RowIndex row) { SetWritePos(GetOrderRowPosition(order, row)); } private: - State* state_write_; // The state this reader is writing to + State* state_write_ = nullptr; // The state this reader is writing to }; // Type aliases for convenience @@ -1031,7 +1031,7 @@ class ModuleState public: // Creates and returns a pointer to a StateReaders object. The readers are valid only for as long as ModuleState is valid. - [[nodiscard]] auto GetReaders() const -> std::shared_ptr> + auto GetReaders() const -> std::shared_ptr> { auto return_val = std::make_shared>(); return_val->global_reader.AssignState(&global_state_); @@ -1051,7 +1051,7 @@ class ModuleState void Initialize(unsigned numChannels) { channel_states_.resize(numChannels); } // Creates and returns a pointer to a StateReaderWriters object. The reader/writers are valid only for as long as ModuleState is valid. - [[nodiscard]] auto GetReaderWriters() -> std::shared_ptr> + auto GetReaderWriters() -> std::shared_ptr> { auto return_val = std::make_shared>(); return_val->global_reader_writer.AssignStateWrite(&global_state_); diff --git a/include/core/status.h b/include/core/status.h index bfbb853..796b66b 100644 --- a/include/core/status.h +++ b/include/core/status.h @@ -63,12 +63,12 @@ class ModuleException : public std::exception kConvert }; - [[nodiscard]] auto what() const noexcept -> const char* override + auto what() const noexcept -> const char* override { return error_message_.c_str(); } - [[nodiscard]] auto str() const -> std::string_view + auto str() const -> std::string_view { return error_message_; } @@ -121,7 +121,7 @@ class ModuleException : public std::exception } protected: - int error_code_; + int error_code_ = 0; std::string error_message_; private: @@ -138,14 +138,14 @@ class Status Status() { Clear(); } - [[nodiscard]] auto ErrorOccurred() const -> bool { return error_.get(); } - [[nodiscard]] auto WarningsIssued() const -> bool { return !warning_messages_.empty(); } + auto ErrorOccurred() const -> bool { return error_.get(); } + auto WarningsIssued() const -> bool { return !warning_messages_.empty(); } void PrintError(bool use_std_err = true) const; void PrintWarnings(bool use_std_err = false) const; // Prints error and warnings that occurred during the last action. Returns true if an error occurred. - [[nodiscard]] auto HandleResults() const -> bool; + auto HandleResults() const -> bool; void Clear() { diff --git a/include/modules/debug.h b/include/modules/debug.h index f74b72f..89325a0 100644 --- a/include/modules/debug.h +++ b/include/modules/debug.h @@ -42,9 +42,9 @@ class DebugConversionOptions : public ConversionOptionsInterface bool { return GetOption(OptionEnum::kDump).GetValue(); } - [[nodiscard]] auto Append() const -> bool { return GetOption(OptionEnum::kAppend).GetValue(); } - [[nodiscard]] auto GenDataFlags() const -> size_t { return static_cast(GetOption(OptionEnum::kGenDataFlags).GetValue()); } + auto Dump() const -> bool { return GetOption(OptionEnum::kDump).GetValue(); } + auto Append() const -> bool { return GetOption(OptionEnum::kAppend).GetValue(); } + auto GenDataFlags() const -> std::size_t { return static_cast(GetOption(OptionEnum::kGenDataFlags).GetValue()); } private: @@ -77,7 +77,7 @@ class Debug final : public ModuleInterface void ImportImpl(const std::string& filename) override; void ExportImpl(const std::string& filename) override; void ConvertImpl(const ModulePtr& input) override; - [[nodiscard]] auto GenerateDataImpl(size_t data_flags) const -> size_t override { return 1; } + auto GenerateDataImpl(std::size_t data_flags) const -> std::size_t override { return 1; } std::string dump_; }; diff --git a/include/modules/dmf.h b/include/modules/dmf.h index 8e62b8d..0721312 100644 --- a/include/modules/dmf.h +++ b/include/modules/dmf.h @@ -47,9 +47,9 @@ struct System }; Type type; - uint8_t id; + std::uint8_t id; std::string name; - uint8_t channels; + std::uint8_t channels; }; } // namespace dmf @@ -57,32 +57,32 @@ struct System template<> struct ModuleGlobalData : public ModuleGlobalDataDefault { - uint8_t dmf_format_version; + std::uint8_t dmf_format_version; dmf::System system; // Visual info - uint8_t highlight_a_patterns; - uint8_t highlight_b_patterns; + std::uint8_t highlight_a_patterns; + std::uint8_t highlight_b_patterns; // Module info - uint8_t frames_mode; - std::optional custom_hz_value; - uint16_t global_tick; + std::uint8_t frames_mode; + std::optional custom_hz_value; + std::uint16_t global_tick; }; template<> struct Row { NoteSlot note; - int16_t volume; + std::int16_t volume; std::array effect; // Deflemask allows four effects columns per channel regardless of the system - int16_t instrument; + std::int16_t instrument; }; template<> struct ChannelMetadata { - uint8_t effect_columns_count; + std::uint8_t effect_columns_count; }; template<> @@ -97,16 +97,16 @@ struct SoundIndex enum Types { kNone, kSquare, kWave, kNoise /*Other options here*/ }; using None = std::monostate; - struct Square { uint8_t id; operator uint8_t() const { return id; } }; - struct Wave { uint8_t id; operator uint8_t() const { return id; } }; - struct Noise { uint8_t id; operator uint8_t() const { return id; } }; // Placeholder + struct Square { std::uint8_t id; operator std::uint8_t() const { return id; } }; + struct Wave { std::uint8_t id; operator std::uint8_t() const { return id; } }; + struct Noise { std::uint8_t id; operator std::uint8_t() const { return id; } }; // Placeholder using type = std::variant; }; -inline constexpr auto operator==(const SoundIndex::Square& lhs, const SoundIndex::Square& rhs) -> bool { return lhs.id == rhs.id; } -inline constexpr auto operator==(const SoundIndex::Wave& lhs, const SoundIndex::Wave& rhs) -> bool { return lhs.id == rhs.id; } -inline constexpr auto operator==(const SoundIndex::Noise& lhs, const SoundIndex::Noise& rhs) -> bool { return lhs.id == rhs.id; } +constexpr auto operator==(const SoundIndex::Square& lhs, const SoundIndex::Square& rhs) -> bool { return lhs.id == rhs.id; } +constexpr auto operator==(const SoundIndex::Wave& lhs, const SoundIndex::Wave& rhs) -> bool { return lhs.id == rhs.id; } +constexpr auto operator==(const SoundIndex::Noise& lhs, const SoundIndex::Noise& rhs) -> bool { return lhs.id == rhs.id; } /////////////////////////////////////////////////////////// // dmf namespace @@ -114,8 +114,8 @@ inline constexpr auto operator==(const SoundIndex::Noise& lhs, const SoundI namespace dmf { -//inline constexpr int kVolumeMax = 15; /* ??? */ -inline constexpr int kGameBoyVolumeMax = 15; +//constexpr int kVolumeMax = 15; /* ??? */ +constexpr int kGameBoyVolumeMax = 15; // Custom dmf2mod internal effect codes (see effects.h) namespace Effects @@ -141,32 +141,32 @@ namespace Effects struct ModuleInfo { - uint8_t time_base, tick_time1, tick_time2; + std::uint8_t time_base, tick_time1, tick_time2; }; struct FMOps { // TODO: Use unions depending on DMF version? - uint8_t am; - uint8_t ar; // Attack - uint8_t dr; // Decay? - uint8_t mult; - uint8_t rr; // Release - uint8_t sl; // Sustain - uint8_t tl; - - uint8_t dt2; - uint8_t rs; - uint8_t dt; - uint8_t d2r; + std::uint8_t am; + std::uint8_t ar; // Attack + std::uint8_t dr; // Decay? + std::uint8_t mult; + std::uint8_t rr; // Release + std::uint8_t sl; // Sustain + std::uint8_t tl; + + std::uint8_t dt2; + std::uint8_t rs; + std::uint8_t dt; + std::uint8_t d2r; union { - uint8_t ssg_mode; - uint8_t egs; // EG-S in SMS OPLL / NES VRC7. 0 if OFF; 8 if ON. + std::uint8_t ssg_mode; + std::uint8_t egs; // EG-S in SMS OPLL / NES VRC7. 0 if OFF; 8 if ON. }; - uint8_t dam, dvb, egt, ksl, sus, vib, ws, ksr; // Exclusive to DMF version 18 (0x12) and older + std::uint8_t dam, dvb, egt, ksl, sus, vib, ws, ksr; // Exclusive to DMF version 18 (0x12) and older }; struct Instrument @@ -186,42 +186,42 @@ struct Instrument // Standard Instruments struct { - uint8_t vol_env_size, arp_env_size, duty_noise_env_size, wavetable_env_size; - int32_t* vol_env_value; - int32_t* arp_env_value; - int32_t* duty_noise_env_value; - int32_t* wavetable_env_value; - int8_t vol_env_loop_pos, arp_env_loop_pos, duty_noise_env_loop_pos, wavetable_env_loop_pos; - uint8_t arp_macro_mode; + std::uint8_t vol_env_size, arp_env_size, duty_noise_env_size, wavetable_env_size; + std::int32_t* vol_env_value; + std::int32_t* arp_env_value; + std::int32_t* duty_noise_env_value; + std::int32_t* wavetable_env_value; + std::int8_t vol_env_loop_pos, arp_env_loop_pos, duty_noise_env_loop_pos, wavetable_env_loop_pos; + std::uint8_t arp_macro_mode; // Commodore 64 exclusive - uint8_t c64_tri_wave_en, c64_saw_wave_en, c64_pulse_wave_en, c64_noise_wave_en, + std::uint8_t c64_tri_wave_en, c64_saw_wave_en, c64_pulse_wave_en, c64_noise_wave_en, c64_attack, c64_decay, c64_sustain, c64_release, c64_pulse_width, c64_ring_mod_en, c64_sync_mod_en, c64_to_filter, c64_vol_macro_to_filter_cutoff_en, c64_use_filter_values_from_inst; - uint8_t c64_filter_resonance, c64_filter_cutoff, c64_filter_high_pass, c64_filter_low_pass, c64_filter_ch2_off; + std::uint8_t c64_filter_resonance, c64_filter_cutoff, c64_filter_high_pass, c64_filter_low_pass, c64_filter_ch2_off; // Game Boy exclusive - uint8_t gb_env_vol, gb_env_dir, gb_env_len, gb_sound_len; + std::uint8_t gb_env_vol, gb_env_dir, gb_env_len, gb_sound_len; } std; // FM Instruments struct { - uint8_t num_operators; + std::uint8_t num_operators; union { - uint8_t alg; - uint8_t sus; // SMS OPLL / NES VRC7 exclusive + std::uint8_t alg; + std::uint8_t sus; // SMS OPLL / NES VRC7 exclusive }; - uint8_t fb; - uint8_t opll_preset; // SMS OPLL / NES VRC7 exclusive + std::uint8_t fb; + std::uint8_t opll_preset; // SMS OPLL / NES VRC7 exclusive union { - struct { uint8_t lfo, lfo2; }; - struct { uint8_t dc, dm; }; // SMS OPLL / NES VRC7 exclusive + struct { std::uint8_t lfo, lfo2; }; + struct { std::uint8_t dc, dm; }; // SMS OPLL / NES VRC7 exclusive }; std::array ops; @@ -231,11 +231,11 @@ struct Instrument struct PCMSample { - uint32_t size; + std::uint32_t size; std::string name; - uint8_t rate, pitch, amp, bits; - uint32_t cut_start, cut_end; - uint16_t* data; + std::uint8_t rate, pitch, amp, bits; + std::uint32_t cut_start, cut_end; + std::uint16_t* data; }; // Deflemask Game Boy channels @@ -291,40 +291,40 @@ class DMF final : public ModuleInterface // Returns the initial BPM of the module void GetBPM(unsigned& numerator, unsigned& denominator) const; - [[nodiscard]] auto GetBPM() const -> double; + auto GetBPM() const -> double; - [[nodiscard]] auto GetSystem() const -> const dmf::System& { return GetGlobalData().system; } - [[nodiscard]] static auto SystemInfo(SystemType system_type) -> const dmf::System&; + auto GetSystem() const -> const dmf::System& { return GetGlobalData().system; } + static auto SystemInfo(SystemType system_type) -> const dmf::System&; // TODO: Create a module-independent storage system for wavetables, PCM samples, instruments, etc. - [[nodiscard]] auto GetTotalWavetables() const -> uint8_t { return total_wavetables_; } - [[nodiscard]] auto GetWavetableValues() const -> uint32_t** { return wavetable_values_; } - [[nodiscard]] auto GetWavetableValue(unsigned wavetable, unsigned index) const -> uint32_t { return wavetable_values_[wavetable][index]; } + auto GetTotalWavetables() const -> std::uint8_t { return total_wavetables_; } + auto GetWavetableValues() const -> std::uint32_t** { return wavetable_values_; } + auto GetWavetableValue(unsigned wavetable, unsigned index) const -> std::uint32_t { return wavetable_values_[wavetable][index]; } private: // Only allow the Factory to construct this class friend class Builder; - DMF(); + DMF() = default; void CleanUp(); void ImportImpl(const std::string& filename) override; void ExportImpl(const std::string& filename) override; void ConvertImpl(const ModulePtr& input) override; - [[nodiscard]] auto GenerateDataImpl(size_t data_flags) const -> size_t override; + auto GenerateDataImpl(std::size_t data_flags) const -> std::size_t override; // Import helper class class Importer; dmf::ModuleInfo module_info_; // TODO: Eventually remove - uint8_t total_instruments_; - dmf::Instrument* instruments_; - uint8_t total_wavetables_; - uint32_t* wavetable_sizes_; - uint32_t** wavetable_values_; - uint8_t total_pcm_samples_; - dmf::PCMSample* pcm_samples_; + std::uint8_t total_instruments_; + dmf::Instrument* instruments_ = nullptr; + std::uint8_t total_wavetables_; + std::uint32_t* wavetable_sizes_ = nullptr; + std::uint32_t** wavetable_values_ = nullptr; + std::uint8_t total_pcm_samples_; + dmf::PCMSample* pcm_samples_ = nullptr; }; } // namespace d2m diff --git a/include/modules/mod.h b/include/modules/mod.h index 3842fe6..a4c6a28 100644 --- a/include/modules/mod.h +++ b/include/modules/mod.h @@ -78,7 +78,7 @@ struct Sample unsigned repeat_offset; unsigned repeat_length; - std::vector data; + std::vector data; }; } // namespace mod @@ -116,13 +116,13 @@ class MODConversionOptions final : public ConversionOptionsInterface bool { return GetOption(OptionEnum::kArpeggio).GetValue(); } - [[nodiscard]] inline auto AllowPortamento() const -> bool { return GetOption(OptionEnum::kPortamento).GetValue(); } - [[nodiscard]] inline auto AllowPort2Note() const -> bool { return GetOption(OptionEnum::kPort2Note).GetValue(); } - [[nodiscard]] inline auto AllowVibrato() const -> bool { return GetOption(OptionEnum::kVibrato).GetValue(); } - [[nodiscard]] inline auto GetTempoType() const -> TempoType { return TempoType{GetOption(OptionEnum::kTempoType).GetValueAsIndex()}; } + auto AllowArpeggio() const -> bool { return GetOption(OptionEnum::kArpeggio).GetValue(); } + auto AllowPortamento() const -> bool { return GetOption(OptionEnum::kPortamento).GetValue(); } + auto AllowPort2Note() const -> bool { return GetOption(OptionEnum::kPort2Note).GetValue(); } + auto AllowVibrato() const -> bool { return GetOption(OptionEnum::kVibrato).GetValue(); } + auto GetTempoType() const -> TempoType { return TempoType{GetOption(OptionEnum::kTempoType).GetValueAsIndex()}; } - [[nodiscard]] inline auto AllowEffects() const -> bool { return AllowArpeggio() || AllowPortamento() || AllowPort2Note() || AllowVibrato(); } + auto AllowEffects() const -> bool { return AllowArpeggio() || AllowPortamento() || AllowPort2Note() || AllowVibrato(); } private: @@ -182,7 +182,7 @@ class MOD final : public ModuleInterface void ImportImpl(const std::string& filename) override; void ExportImpl(const std::string& filename) override; void ConvertImpl(const ModulePtr& input) override; - [[nodiscard]] auto GenerateDataImpl(size_t data_flags) const -> size_t override { return 1; } + auto GenerateDataImpl(std::size_t data_flags) const -> std::size_t override { return 1; } // DMF -> MOD conversion class DMFConverter; @@ -195,7 +195,7 @@ class MOD final : public ModuleInterface void ExportSampleData(std::ofstream& fout) const; // MOD file info: - int8_t total_mod_samples_; + std::int8_t total_mod_samples_ = 0; std::map, mod::Sample> samples_; }; diff --git a/include/utils/hash.h b/include/utils/hash.h index 474b03e..ac691af 100644 --- a/include/utils/hash.h +++ b/include/utils/hash.h @@ -14,8 +14,8 @@ struct PairHash { template - auto operator()(const std::pair& pair) const -> size_t + auto operator()(const std::pair& pair) const noexcept -> std::size_t { - return std::hash()(pair.first) ^ std::hash()(pair.second); + return std::hash{}(pair.first) ^ std::hash{}(pair.second); } }; diff --git a/include/utils/stream_reader.h b/include/utils/stream_reader.h index e6eaf47..9bb634d 100644 --- a/include/utils/stream_reader.h +++ b/include/utils/stream_reader.h @@ -34,10 +34,10 @@ namespace detail { // Adapted from: https://peter.bloomfield.online/using-cpp-templates-for-size-based-type-selection/ template using UIntSelector = - typename std::conditional::type >::type >::type; @@ -55,13 +55,13 @@ class StreamReader private: IStream stream_; - template + template struct LittleEndianReadOperator { - static constexpr uint_fast8_t kShiftAmount = (num_bytes - 1) * 8; + static constexpr std::uint_fast8_t kShiftAmount = (num_bytes - 1) * 8; static_assert(num_bytes > 0); - inline void operator()() + void operator()() { value >>= 8; value |= static_cast(stream_.get()) << kShiftAmount; @@ -73,7 +73,7 @@ class StreamReader template struct BigEndianReadOperator { - inline void operator()() + void operator()() { value <<= 8; value |= static_cast(stream_.get()); @@ -82,8 +82,8 @@ class StreamReader T value{}; }; - template - inline auto ReadIntLittleEndian() -> T + template + auto ReadIntLittleEndian() -> T { LittleEndianReadOperator oper{stream()}; detail::LoopUnroller{}(oper); @@ -99,8 +99,8 @@ class StreamReader } } - template - inline auto ReadIntBigEndian() -> T + template + auto ReadIntBigEndian() -> T { BigEndianReadOperator oper{stream()}; detail::LoopUnroller{}(oper); @@ -143,7 +143,7 @@ class StreamReader auto ReadPStr() -> std::string { // P-Strings (Pascal strings) are prefixed with a 1 byte length - uint8_t string_length = stream_.get(); + std::uint8_t string_length = stream_.get(); return ReadStr(string_length); } @@ -155,10 +155,10 @@ class StreamReader return temp_bytes; } - template + template auto ReadInt() { - using UIntType = std::conditional_t<(num_bytes > 1), detail::UIntSelector, uint8_t>; + using UIntType = std::conditional_t<(num_bytes > 1), detail::UIntSelector, std::uint8_t>; using ReturnType = std::conditional_t, UIntType>; static_assert(num_bytes <= 8 && num_bytes >= 1, "Accepted range for num_bytes: 1 <= num_bytes <= 8"); diff --git a/include/utils/utils.h b/include/utils/utils.h index 205558e..5dc9cfa 100644 --- a/include/utils/utils.h +++ b/include/utils/utils.h @@ -21,22 +21,22 @@ class Utils { public: // File utils - [[nodiscard]] static auto GetBaseNameFromFilename(std::string_view filename) -> std::string; - [[nodiscard]] static auto ReplaceFileExtension(std::string_view filename, std::string_view new_file_extension) -> std::string; - [[nodiscard]] static auto GetFileExtension(std::string_view filename) -> std::string; - [[nodiscard]] static auto FileExists(std::string_view filename) -> bool; + static auto GetBaseNameFromFilename(std::string_view filename) -> std::string; + static auto ReplaceFileExtension(std::string_view filename, std::string_view new_file_extension) -> std::string; + static auto GetFileExtension(std::string_view filename) -> std::string; + static auto FileExists(std::string_view filename) -> bool; // File utils which require Factory initialization - [[nodiscard]] static auto GetTypeFromFilename(std::string_view filename) -> ModuleType; - [[nodiscard]] static auto GetTypeFromFileExtension(std::string_view extension) -> ModuleType; - [[nodiscard]] static auto GetTypeFromCommandName(std::string_view command_name) -> ModuleType; - [[nodiscard]] static auto GetExtensionFromType(ModuleType module_type) -> std::string_view; + static auto GetTypeFromFilename(std::string_view filename) -> ModuleType; + static auto GetTypeFromFileExtension(std::string_view extension) -> ModuleType; + static auto GetTypeFromCommandName(std::string_view command_name) -> ModuleType; + static auto GetExtensionFromType(ModuleType module_type) -> std::string_view; // Command-line arguments and options utils - [[nodiscard]] static auto GetArgsAsVector(int argc, char** argv) -> std::vector; + static auto GetArgsAsVector(int argc, char** argv) -> std::vector; // String utils (borrowed from Stack Overflow) - static inline void StringTrimLeft(std::string& str) + static void StringTrimLeft(std::string& str) { // Trim string from start (in place) str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](unsigned char ch) { @@ -44,7 +44,7 @@ class Utils })); } - static inline void StringTrimRight(std::string& str) + static void StringTrimRight(std::string& str) { // Trim string from end (in place) str.erase(std::find_if(str.rbegin(), str.rend(), [](unsigned char ch) { @@ -52,7 +52,7 @@ class Utils }).base(), str.end()); } - static inline void StringTrimBothEnds(std::string& str) + static void StringTrimBothEnds(std::string& str) { // Trim string from both ends (in place) StringTrimLeft(str); diff --git a/src/core/options.cpp b/src/core/options.cpp index dc82d2d..f8ecffb 100644 --- a/src/core/options.cpp +++ b/src/core/options.cpp @@ -58,7 +58,7 @@ void OptionDefinition::PrintHelp() const str1 += '['; unsigned i = 0; - const size_t total = GetAcceptedValuesOrdered().size(); + const std::size_t total = GetAcceptedValuesOrdered().size(); for (const auto& val : GetAcceptedValuesOrdered()) { switch (option_type) @@ -201,7 +201,7 @@ OptionDefinitionCollection::OptionDefinitionCollection(const std::initializer_li } } -auto OptionDefinitionCollection::Count() const -> size_t +auto OptionDefinitionCollection::Count() const -> std::size_t { return id_options_map_.size(); } @@ -442,7 +442,7 @@ auto OptionCollection::ParseArgs(std::vector& args, bool ignore_unk } const OptionDefinition* def = handling_option; - size_t equals_pos = std::string::npos; + std::size_t equals_pos = std::string::npos; const bool this_arg_is_value = handling_option != nullptr; if (this_arg_is_value) diff --git a/src/modules/dmf.cpp b/src/modules/dmf.cpp index 2ee35ca..78f0549 100644 --- a/src/modules/dmf.cpp +++ b/src/modules/dmf.cpp @@ -32,8 +32,8 @@ using namespace d2m; -static constexpr uint8_t kDMFFileVersionMin = 17; // DMF files as old as version 17 (0x11) are supported -static constexpr uint8_t kDMFFileVersionMax = 27; // DMF files as new as version 27 (0x1b) are supported +static constexpr std::uint8_t kDMFFileVersionMin = 17; // DMF files as old as version 17 (0x11) are supported +static constexpr std::uint8_t kDMFFileVersionMax = 27; // DMF files as new as version 27 (0x1b) are supported // DMF format magic numbers //static constexpr int kDMFNoInstrument = -1; @@ -59,7 +59,7 @@ class DMF::Importer auto LoadInstrument(SystemType system_type) -> dmf::Instrument; void LoadWavetablesData(); void LoadPatternsData(); - auto LoadPatternRow(uint8_t effect_columns_count) -> Row; + auto LoadPatternRow(std::uint8_t effect_columns_count) -> Row; void LoadPCMSamplesData(); auto LoadPCMSample() -> dmf::PCMSample; @@ -147,17 +147,8 @@ static constexpr auto kPeriodTable = []() constexpr static constexpr auto GetPeriod(Note note) -> double { - assert(static_cast(note.pitch) < 12 && note.octave < 9); - return kPeriodTable[static_cast(note.pitch) + 12*note.octave]; -} - -DMF::DMF() -{ - // Initialize pointers to nullptr to prevent segfault when freeing memory if the import fails: - instruments_ = nullptr; - wavetable_sizes_ = nullptr; - wavetable_values_ = nullptr; - pcm_samples_ = nullptr; + assert(static_cast(note.pitch) < 12 && note.octave < 9); + return kPeriodTable[static_cast(note.pitch) + 12 * note.octave]; } DMF::~DMF() @@ -525,7 +516,7 @@ auto DMF::Importer::LoadInstrument(DMF::SystemType system_type) -> dmf::Instrume { // Volume macro inst.std.vol_env_size = fin_.ReadInt(); - inst.std.vol_env_value = new int32_t[inst.std.vol_env_size]; + inst.std.vol_env_value = new std::int32_t[inst.std.vol_env_size]; for (int i = 0; i < inst.std.vol_env_size; i++) { @@ -540,7 +531,7 @@ auto DMF::Importer::LoadInstrument(DMF::SystemType system_type) -> dmf::Instrume { // Volume macro inst.std.vol_env_size = fin_.ReadInt(); - inst.std.vol_env_value = new int32_t[inst.std.vol_env_size]; + inst.std.vol_env_value = new std::int32_t[inst.std.vol_env_size]; for (int i = 0; i < inst.std.vol_env_size; i++) { @@ -556,7 +547,7 @@ auto DMF::Importer::LoadInstrument(DMF::SystemType system_type) -> dmf::Instrume // Arpeggio macro inst.std.arp_env_size = fin_.ReadInt(); - inst.std.arp_env_value = new int32_t[inst.std.arp_env_size]; + inst.std.arp_env_value = new std::int32_t[inst.std.arp_env_size]; for (int i = 0; i < inst.std.arp_env_size; i++) { @@ -573,7 +564,7 @@ auto DMF::Importer::LoadInstrument(DMF::SystemType system_type) -> dmf::Instrume // Duty/Noise macro inst.std.duty_noise_env_size = fin_.ReadInt(); - inst.std.duty_noise_env_value = new int32_t[inst.std.duty_noise_env_size]; + inst.std.duty_noise_env_value = new std::int32_t[inst.std.duty_noise_env_size]; for (int i = 0; i < inst.std.duty_noise_env_size; i++) { @@ -588,7 +579,7 @@ auto DMF::Importer::LoadInstrument(DMF::SystemType system_type) -> dmf::Instrume // Wavetable macro inst.std.wavetable_env_size = fin_.ReadInt(); - inst.std.wavetable_env_value = new int32_t[inst.std.wavetable_env_size]; + inst.std.wavetable_env_value = new std::int32_t[inst.std.wavetable_env_size]; for (int i = 0; i < inst.std.wavetable_env_size; i++) { @@ -690,7 +681,7 @@ auto DMF::Importer::LoadInstrument(DMF::SystemType system_type) -> dmf::Instrume if (system_type == DMF::SystemType::kSMS_OPLL || system_type == DMF::SystemType::kNES_VRC7) { - const uint8_t opll_preset = fin_.ReadInt(); + const std::uint8_t opll_preset = fin_.ReadInt(); if (i == 0) { inst.fm.opll_preset = opll_preset; } inst.fm.ops[i].ksr = fin_.ReadInt(); @@ -738,10 +729,10 @@ void DMF::Importer::LoadWavetablesData() { dmf_.total_wavetables_ = fin_.ReadInt(); - dmf_.wavetable_sizes_ = new uint32_t[dmf_.total_wavetables_]; - dmf_.wavetable_values_ = new uint32_t*[dmf_.total_wavetables_]; + dmf_.wavetable_sizes_ = new std::uint32_t[dmf_.total_wavetables_]; + dmf_.wavetable_values_ = new std::uint32_t*[dmf_.total_wavetables_]; - uint32_t data_mask = 0xFFFFFFFF; + std::uint32_t data_mask = 0xFFFFFFFF; if (dmf_.GetSystem().type == DMF::SystemType::kGameBoy) { data_mask = 0xF; @@ -755,7 +746,7 @@ void DMF::Importer::LoadWavetablesData() { dmf_.wavetable_sizes_[i] = fin_.ReadInt(); - dmf_.wavetable_values_[i] = new uint32_t[dmf_.wavetable_sizes_[i]]; + dmf_.wavetable_values_[i] = new std::uint32_t[dmf_.wavetable_sizes_[i]]; for (unsigned j = 0; j < dmf_.wavetable_sizes_[i]; j++) { @@ -810,12 +801,12 @@ void DMF::Importer::LoadPatternsData() } } -auto DMF::Importer::LoadPatternRow(uint8_t effect_columns_count) -> Row +auto DMF::Importer::LoadPatternRow(std::uint8_t effect_columns_count) -> Row { Row row; - const uint16_t temp_pitch = fin_.ReadInt(); - uint8_t temp_octave = fin_.ReadInt(); // Upper byte is unused + const std::uint16_t temp_pitch = fin_.ReadInt(); + std::uint8_t temp_octave = fin_.ReadInt(); // Upper byte is unused switch (temp_pitch) { @@ -848,9 +839,9 @@ auto DMF::Importer::LoadPatternRow(uint8_t effect_columns_count) -> Row row.volume = fin_.ReadInt(); - for (uint8_t col = 0; col < effect_columns_count; ++col) + for (std::uint8_t col = 0; col < effect_columns_count; ++col) { - const int16_t dmf_effect_code = fin_.ReadInt(); + const std::int16_t dmf_effect_code = fin_.ReadInt(); row.effect[col].value = fin_.ReadInt(); assert(kEffectValueless == kDMFNoEffectVal); // DMF valueless effect magic number is -1, and so must be kEffectValueless @@ -901,7 +892,7 @@ auto DMF::Importer::LoadPatternRow(uint8_t effect_columns_count) -> Row } // Initialize the rest to zero - for (uint8_t col = effect_columns_count; col < 4; ++col) // Max total of 4 effects columns in Deflemask + for (std::uint8_t col = effect_columns_count; col < 4; ++col) // Max total of 4 effects columns in Deflemask { row.effect[col] = {Effects::kNoEffect, 0}; } @@ -975,8 +966,8 @@ auto DMF::Importer::LoadPCMSample() -> dmf::PCMSample sample.data = nullptr; if (sample.size > 0) { - sample.data = new uint16_t[sample.size]; - for (uint32_t i = 0; i < sample.size; i++) + sample.data = new std::uint16_t[sample.size]; + for (std::uint32_t i = 0; i < sample.size; i++) { sample.data[i] = fin_.ReadInt(); } @@ -998,7 +989,7 @@ auto DMF::Importer::LoadPCMSample() -> dmf::PCMSample * 1: Error * 2: An extra "loopback order" is needed */ -auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t +auto DMF::GenerateDataImpl(std::size_t data_flags) const -> std::size_t { auto& gen_data = *GetGeneratedDataMut(); const auto& data = GetData(); @@ -1028,7 +1019,7 @@ auto DMF::GenerateDataImpl(size_t data_flags) const -> size_t gen_data.Get() = data.GetNumOrders(); // Data flags - size_t return_val = 0; + std::size_t return_val = 0; const bool no_port2note_auto_off = data_flags & 0x1; const bool mod_compat_loops = data_flags & 0x2; diff --git a/src/modules/mod.cpp b/src/modules/mod.cpp index 5dd77a4..07b42d1 100644 --- a/src/modules/mod.cpp +++ b/src/modules/mod.cpp @@ -76,9 +76,9 @@ class MOD::DMFConverter void ConvertSamples(SampleMap& sample_map); void ConvertSampleData(const SampleMap& sample_map); void ConvertPatterns(const SampleMap& sample_map); - inline auto ConvertEffects(ChannelStateReader& state) -> PriorityEffect; - inline auto ConvertNote(ChannelStateReader& state, NoteRange& note_range, bool& set_sample, int& set_vol_if_not, const SampleMap& sample_map, PriorityEffect& mod_effect) -> Row; - inline void ApplyEffects(std::array, 4>& row_data, const std::array& mod_effect, std::vector& global_effects); + auto ConvertEffects(ChannelStateReader& state) -> PriorityEffect; + auto ConvertNote(ChannelStateReader& state, NoteRange& note_range, bool& set_sample, int& set_vol_if_not, const SampleMap& sample_map, PriorityEffect& mod_effect) -> Row; + void ApplyEffects(std::array, 4>& row_data, const std::array& mod_effect, std::vector& global_effects); void ConvertInitialBPM(unsigned& tempo, unsigned& speed); MOD& mod_; @@ -92,9 +92,9 @@ class MOD::DMFConverter using MODOptionEnum = MODConversionOptions::OptionEnum; -static auto GenerateSquareWaveSample(unsigned duty_cycle, unsigned length) -> std::vector; -static auto GenerateWavetableSample(uint32_t* wavetable_data, unsigned length) -> std::vector; -static inline auto GetEffectCode(int effect_code) -> uint8_t; +static auto GenerateSquareWaveSample(unsigned duty_cycle, unsigned length) -> std::vector; +static auto GenerateWavetableSample(std::uint32_t* wavetable_data, unsigned length) -> std::vector; +static auto GetEffectCode(int effect_code) -> std::uint8_t; static auto GetWarningMessage(MOD::ConvertWarning warning, const std::string& info = "") -> std::string; /* @@ -104,11 +104,11 @@ static auto GetWarningMessage(MOD::ConvertWarning warning, const std::string& in */ static constexpr auto kProTrackerPeriodTable = std::array{ - std::array{1712, 1616, 1525, 1440, 1357, 1281, 1209, 1141, 1077, 1017, 961, 907}, /* C-0 to B-0 */ - std::array{856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453}, /* C-1 to B-1 */ - std::array{428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226}, /* C-2 to B-2 */ - std::array{214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113}, /* C-3 to B-3 */ - std::array{107, 101, 95, 90, 85, 80, 76, 71, 67, 64, 60, 57} /* C-4 to B-4 */ + std::array{1712, 1616, 1525, 1440, 1357, 1281, 1209, 1141, 1077, 1017, 961, 907}, /* C-0 to B-0 */ + std::array{856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453}, /* C-1 to B-1 */ + std::array{428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226}, /* C-2 to B-2 */ + std::array{214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113}, /* C-3 to B-3 */ + std::array{107, 101, 95, 90, 85, 80, 76, 71, 67, 64, 60, 57} /* C-4 to B-4 */ }; // Effect codes used by the MOD format @@ -209,17 +209,17 @@ class MOD::DMFConverter::SampleMapper auto InitSilence() -> SoundIndexType; auto GetMODNote(const Note& dmf_note, NoteRange& mod_note_range) const -> Note; - [[nodiscard]] auto GetMODNoteRange(const Note& dmf_note) const -> NoteRange; - [[nodiscard]] auto GetMODSampleId(const Note& dmf_note) const -> SoundIndexType; - [[nodiscard]] auto GetMODSampleId(NoteRange mod_note_range) const -> SoundIndexType; - [[nodiscard]] auto GetMODSampleLength(NoteRange mod_note_range) const -> unsigned; - [[nodiscard]] auto GetMODNoteRange(SoundIndexType mod_sound_index) const -> NoteRange; - [[nodiscard]] auto GetMODNoteRangeName(NoteRange mod_note_range) const -> NoteRangeName; - - [[nodiscard]] auto GetNumMODSamples() const -> int { return num_mod_samples_; } - [[nodiscard]] auto GetSampleType() const -> SampleType { return sample_type_; } - [[nodiscard]] auto GetFirstMODSampleId() const -> SoundIndexType { return mod_sound_indexes_[0]; } - [[nodiscard]] auto IsDownsamplingNeeded() const -> bool { return downsampling_needed_; } + auto GetMODNoteRange(const Note& dmf_note) const -> NoteRange; + auto GetMODSampleId(const Note& dmf_note) const -> SoundIndexType; + auto GetMODSampleId(NoteRange mod_note_range) const -> SoundIndexType; + auto GetMODSampleLength(NoteRange mod_note_range) const -> unsigned; + auto GetMODNoteRange(SoundIndexType mod_sound_index) const -> NoteRange; + auto GetMODNoteRangeName(NoteRange mod_note_range) const -> NoteRangeName; + + auto GetNumMODSamples() const -> int { return num_mod_samples_; } + auto GetSampleType() const -> SampleType { return sample_type_; } + auto GetFirstMODSampleId() const -> SoundIndexType { return mod_sound_indexes_[0]; } + auto IsDownsamplingNeeded() const -> bool { return downsampling_needed_; } private: SoundIndexType dmf_sound_index_ = SoundIndex::None{}; @@ -524,7 +524,7 @@ void MOD::DMFConverter::Convert() ///////////////// GET DMF GENERATED DATA - const size_t error_code = dmf_.GenerateData(1 | 2); // MOD-compatibility flags + const std::size_t error_code = dmf_.GenerateData(1 | 2); // MOD-compatibility flags if (error_code & 2) { mod_.status_.AddWarning(GetWarningMessage(ConvertWarning::kLoopbackInaccuracy)); } auto dmf_gen_data = dmf_.GetGeneratedData(); @@ -645,7 +645,7 @@ void MOD::DMFConverter::ConvertSampleData(const SampleMap& sample_map) case SampleType::kSquare: { - const uint8_t duty_cycle = std::get::Square>(dmf_sound_index).id; + const std::uint8_t duty_cycle = std::get::Square>(dmf_sound_index).id; si.name = "SQW, Duty "; switch (duty_cycle) { @@ -661,14 +661,14 @@ void MOD::DMFConverter::ConvertSampleData(const SampleMap& sample_map) case SampleType::kWave: { - const uint8_t wavetable_index = std::get::Wave>(dmf_sound_index).id; + const std::uint8_t wavetable_index = std::get::Wave>(dmf_sound_index).id; si.name = "Wavetable #"; si.name += std::to_string(wavetable_index); si.volume = kVolumeMax; // TODO: Optimize this? - uint32_t* wavetable_data = dmf_.GetWavetableValues()[wavetable_index]; + std::uint32_t* wavetable_data = dmf_.GetWavetableValues()[wavetable_index]; si.data = GenerateWavetableSample(wavetable_data, si.length); break; } @@ -860,7 +860,7 @@ void MOD::DMFConverter::ConvertPatterns(const SampleMap& sample_map) } } -inline auto MOD::DMFConverter::ConvertEffects(ChannelStateReader& state) -> PriorityEffect +auto MOD::DMFConverter::ConvertEffects(ChannelStateReader& state) -> PriorityEffect { // Effects are listed here with highest priority first @@ -909,7 +909,7 @@ inline auto MOD::DMFConverter::ConvertEffects(ChannelStateReader& state) -> return { kEffectPriorityUnsupportedEffect, { Effects::kNoEffect, 0 } }; } -inline auto MOD::DMFConverter::ConvertNote(ChannelStateReader& state, NoteRange& note_range, bool& set_sample, int& set_vol_if_not, const SampleMap& sample_map, PriorityEffect& mod_effect) -> Row +auto MOD::DMFConverter::ConvertNote(ChannelStateReader& state, NoteRange& note_range, bool& set_sample, int& set_vol_if_not, const SampleMap& sample_map, PriorityEffect& mod_effect) -> Row { // Do not call this when on the noise channel @@ -1016,7 +1016,7 @@ inline auto MOD::DMFConverter::ConvertNote(ChannelStateReader& state, NoteR } } -inline void MOD::DMFConverter::ApplyEffects(std::array, 4>& row_data, const std::array& mod_effects, std::vector& global_effects) +void MOD::DMFConverter::ApplyEffects(std::array, 4>& row_data, const std::array& mod_effects, std::vector& global_effects) { // When there are no global (channel-independent) effects: if (global_effects.empty()) @@ -1251,7 +1251,7 @@ void MOD::ExportModuleInfo(std::ofstream& fout) const { fout.put(static_cast(pattern_id)); } - for (uint8_t i = num_orders; i < 128; ++i) + for (std::uint8_t i = num_orders; i < 128; ++i) { fout.put(0); } @@ -1269,11 +1269,11 @@ void MOD::ExportPatterns(std::ofstream& fout) const for (ChannelIndex channel = 0; channel < mod_data.GetNumChannels(); ++channel) { const Row& row_data = pattern[row][channel]; - uint16_t period = 0; + std::uint16_t period = 0; if (NoteHasPitch(row_data.note)) { - const uint8_t octave = GetNote(row_data.note).octave; - const auto pitch = static_cast(GetNote(row_data.note).pitch); + const std::uint8_t octave = GetNote(row_data.note).octave; + const auto pitch = static_cast(GetNote(row_data.note).pitch); period = kProTrackerPeriodTable[octave][pitch]; } @@ -1286,13 +1286,13 @@ void MOD::ExportPatterns(std::ofstream& fout) const //const uint16_t effect = ((uint16_t)rowData.EffectCode << 4) | rowData.EffectValue; // Convert dmf2mod internal effect code to MOD effect code - const uint8_t effect_code = GetEffectCode(row_data.effect.code); + const std::uint8_t effect_code = GetEffectCode(row_data.effect.code); // Sample number (lower 4b); effect code (upper 4b) fout.put((row_data.sample << 4) | (effect_code >> 4)); // Effect code (lower 8 bits) - fout.put(((effect_code << 4) & 0x00FF) | static_cast(row_data.effect.value)); + fout.put(((effect_code << 4) & 0x00FF) | static_cast(row_data.effect.value)); } } } @@ -1303,7 +1303,7 @@ void MOD::ExportSampleData(std::ofstream& fout) const for (const auto& sample_info : samples_) { const auto& sample_data = sample_info.second.data; - for (int8_t value : sample_data) + for (std::int8_t value : sample_data) { fout.put(value); } @@ -1312,11 +1312,11 @@ void MOD::ExportSampleData(std::ofstream& fout) const ///////// OTHER ///////// -static auto GenerateSquareWaveSample(unsigned duty_cycle, unsigned length) -> std::vector +static auto GenerateSquareWaveSample(unsigned duty_cycle, unsigned length) -> std::vector { constexpr auto duty = std::array{1, 2, 4, 6}; - std::vector sample; + std::vector sample; sample.assign(length, 0); // This loop creates a square wave with the correct length and duty cycle: @@ -1335,11 +1335,11 @@ static auto GenerateSquareWaveSample(unsigned duty_cycle, unsigned length) -> st return sample; } -static auto GenerateWavetableSample(uint32_t* wavetable_data, unsigned length) -> std::vector +static auto GenerateWavetableSample(std::uint32_t* wavetable_data, unsigned length) -> std::vector { constexpr float max_vol_cap = 12.f / 15.f; // Set WAVE max volume to 12/15 of potential max volume to emulate DMF wave channel - std::vector sample; + std::vector sample; sample.assign(length, 0); for (unsigned i = 0; i < length; i++) @@ -1349,27 +1349,27 @@ static auto GenerateWavetableSample(uint32_t* wavetable_data, unsigned length) - switch (length) { case 512: // x16 - sample[i] = (int8_t)(((wavetable_data[i / 16] / 15.f * 255.f) - 128.f) * max_vol_cap); break; + sample[i] = (std::int8_t)(((wavetable_data[i / 16] / 15.f * 255.f) - 128.f) * max_vol_cap); break; case 256: // x8 - sample[i] = (int8_t)(((wavetable_data[i / 8] / 15.f * 255.f) - 128.f) * max_vol_cap); break; + sample[i] = (std::int8_t)(((wavetable_data[i / 8] / 15.f * 255.f) - 128.f) * max_vol_cap); break; case 128: // x4 - sample[i] = (int8_t)(((wavetable_data[i / 4] / 15.f * 255.f) - 128.f) * max_vol_cap); break; + sample[i] = (std::int8_t)(((wavetable_data[i / 4] / 15.f * 255.f) - 128.f) * max_vol_cap); break; case 64: // x2 - sample[i] = (int8_t)(((wavetable_data[i / 2] / 15.f * 255.f) - 128.f) * max_vol_cap); break; + sample[i] = (std::int8_t)(((wavetable_data[i / 2] / 15.f * 255.f) - 128.f) * max_vol_cap); break; case 32: // Original length - sample[i] = (int8_t)(((wavetable_data[i] / 15.f * 255.f) - 128.f) * max_vol_cap); break; + sample[i] = (std::int8_t)(((wavetable_data[i] / 15.f * 255.f) - 128.f) * max_vol_cap); break; case 16: // Half length (loss of information from downsampling) { // Take average of every two sample values to make new sample value const unsigned sum = wavetable_data[i * 2] + wavetable_data[(i * 2) + 1]; - sample[i] = (int8_t)(((sum / (15.f * 2) * 255.f) - 128.f) * max_vol_cap); + sample[i] = (std::int8_t)(((sum / (15.f * 2) * 255.f) - 128.f) * max_vol_cap); break; } case 8: // Quarter length (loss of information from downsampling) { // Take average of every four sample values to make new sample value const unsigned sum = wavetable_data[i * 4] + wavetable_data[(i * 4) + 1] + wavetable_data[(i * 4) + 2] + wavetable_data[(i * 4) + 3]; - sample[i] = (int8_t)(((sum / (15.f * 4) * 255.f) - 128.f) * max_vol_cap); + sample[i] = (std::int8_t)(((sum / (15.f * 4) * 255.f) - 128.f) * max_vol_cap); break; } default: @@ -1381,7 +1381,7 @@ static auto GenerateWavetableSample(uint32_t* wavetable_data, unsigned length) - return sample; } -static inline auto GetEffectCode(int effect_code) -> uint8_t +static auto GetEffectCode(int effect_code) -> std::uint8_t { // Maps dmf2mod internal effect code to MOD effect code. switch (effect_code)