aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/soundlib/MIDIMacros.h
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/soundlib/MIDIMacros.h
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/MIDIMacros.h')
-rw-r--r--Src/external_dependencies/openmpt-trunk/soundlib/MIDIMacros.h228
1 files changed, 228 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/MIDIMacros.h b/Src/external_dependencies/openmpt-trunk/soundlib/MIDIMacros.h
new file mode 100644
index 00000000..935660a9
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/soundlib/MIDIMacros.h
@@ -0,0 +1,228 @@
+/*
+ * MIDIMacros.h
+ * ------------
+ * Purpose: Helper functions / classes for MIDI Macro functionality.
+ * Notes : (currently none)
+ * Authors: OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
+ */
+
+
+#pragma once
+
+#include "openmpt/all/BuildSettings.hpp"
+
+#include "openmpt/base/Endian.hpp"
+
+OPENMPT_NAMESPACE_BEGIN
+
+enum
+{
+ kGlobalMacros = 9, // Number of global macros
+ kSFxMacros = 16, // Number of parametered macros
+ kZxxMacros = 128, // Number of fixed macros
+ kMacroLength = 32, // Max number of chars per macro
+};
+
+OPENMPT_NAMESPACE_END
+
+#ifdef MODPLUG_TRACKER
+#include "plugins/PluginStructs.h"
+#endif // MODPLUG_TRACKER
+
+OPENMPT_NAMESPACE_BEGIN
+
+// Parametered macro presets
+enum ParameteredMacro
+{
+ kSFxUnused = 0,
+ kSFxCutoff, // Z00 - Z7F controls resonant filter cutoff
+ kSFxReso, // Z00 - Z7F controls resonant filter resonance
+ kSFxFltMode, // Z00 - Z7F controls resonant filter mode (lowpass / highpass)
+ kSFxDryWet, // Z00 - Z7F controls plugin Dry / Wet ratio
+ kSFxPlugParam, // Z00 - Z7F controls a plugin parameter
+ kSFxCC, // Z00 - Z7F controls MIDI CC
+ kSFxChannelAT, // Z00 - Z7F controls Channel Aftertouch
+ kSFxPolyAT, // Z00 - Z7F controls Poly Aftertouch
+ kSFxPitch, // Z00 - Z7F controls Pitch Bend
+ kSFxProgChange, // Z00 - Z7F controls MIDI Program Change
+ kSFxCustom,
+
+ kSFxMax
+};
+
+
+// Fixed macro presets
+enum FixedMacro
+{
+ kZxxUnused = 0,
+ kZxxReso4Bit, // Z80 - Z8F controls resonant filter resonance
+ kZxxReso7Bit, // Z80 - ZFF controls resonant filter resonance
+ kZxxCutoff, // Z80 - ZFF controls resonant filter cutoff
+ kZxxFltMode, // Z80 - ZFF controls resonant filter mode (lowpass / highpass)
+ kZxxResoFltMode, // Z80 - Z9F controls resonance + filter mode
+ kZxxChannelAT, // Z80 - ZFF controls Channel Aftertouch
+ kZxxPolyAT, // Z80 - ZFF controls Poly Aftertouch
+ kZxxPitch, // Z80 - ZFF controls Pitch Bend
+ kZxxProgChange, // Z80 - ZFF controls MIDI Program Change
+ kZxxCustom,
+
+ kZxxMax
+};
+
+
+// Global macro types
+enum GlobalMacro
+{
+ MIDIOUT_START = 0,
+ MIDIOUT_STOP,
+ MIDIOUT_TICK,
+ MIDIOUT_NOTEON,
+ MIDIOUT_NOTEOFF,
+ MIDIOUT_VOLUME,
+ MIDIOUT_PAN,
+ MIDIOUT_BANKSEL,
+ MIDIOUT_PROGRAM,
+};
+
+
+struct MIDIMacroConfigData
+{
+ struct Macro
+ {
+ public:
+ Macro &operator=(const Macro &other) = default;
+ Macro &operator=(const std::string_view other) noexcept
+ {
+ const size_t copyLength = std::min({m_data.size() - 1u, other.size(), other.find('\0')});
+ std::copy(other.begin(), other.begin() + copyLength, m_data.begin());
+ m_data[copyLength] = '\0';
+ Sanitize();
+ return *this;
+ }
+
+ bool operator==(const Macro &other) const noexcept
+ {
+ return m_data == other.m_data; // Don't care about data past null-terminator as operator= and Sanitize() ensure there is no data behind it.
+ }
+ bool operator!=(const Macro &other) const noexcept
+ {
+ return !(*this == other);
+ }
+
+ operator mpt::span<const char>() const noexcept
+ {
+ return {m_data.data(), Length()};
+ }
+ operator std::string_view() const noexcept
+ {
+ return {m_data.data(), Length()};
+ }
+ operator std::string() const
+ {
+ return {m_data.data(), Length()};
+ }
+
+ MPT_CONSTEXPR20_FUN size_t Length() const noexcept
+ {
+ return static_cast<size_t>(std::distance(m_data.begin(), std::find(m_data.begin(), m_data.end(), '\0')));
+ }
+
+ MPT_CONSTEXPR20_FUN void Clear() noexcept
+ {
+ m_data.fill('\0');
+ }
+
+ // Remove blanks and other unwanted characters from macro strings for internal usage.
+ std::string NormalizedString() const;
+
+ void Sanitize() noexcept;
+ void UpgradeLegacyMacro() noexcept;
+
+ private:
+ std::array<char, kMacroLength> m_data;
+ };
+
+ std::array<Macro, kGlobalMacros> Global;
+ std::array<Macro, kSFxMacros> SFx; // Parametered macros for Z00...Z7F
+ std::array<Macro, kZxxMacros> Zxx; // Fixed macros Z80...ZFF
+
+ constexpr Macro *begin() noexcept {return Global.data(); }
+ constexpr const Macro *begin() const noexcept { return Global.data(); }
+ constexpr Macro *end() noexcept { return Zxx.data() + Zxx.size(); }
+ constexpr const Macro *end() const noexcept { return Zxx.data() + Zxx.size(); }
+};
+
+// This is directly written to files, so the size must be correct!
+MPT_BINARY_STRUCT(MIDIMacroConfigData::Macro, 32)
+MPT_BINARY_STRUCT(MIDIMacroConfigData, 4896)
+
+class MIDIMacroConfig : public MIDIMacroConfigData
+{
+
+public:
+
+ MIDIMacroConfig() { Reset(); }
+
+ // Get macro type from a macro string
+ ParameteredMacro GetParameteredMacroType(uint32 macroIndex) const;
+ FixedMacro GetFixedMacroType() const;
+
+ // Create a new macro
+protected:
+ void CreateParameteredMacro(Macro &parameteredMacro, ParameteredMacro macroType, int subType) const;
+public:
+ void CreateParameteredMacro(uint32 macroIndex, ParameteredMacro macroType, int subType = 0)
+ {
+ if(macroIndex < std::size(SFx))
+ CreateParameteredMacro(SFx[macroIndex], macroType, subType);
+ }
+ std::string CreateParameteredMacro(ParameteredMacro macroType, int subType = 0) const;
+
+protected:
+ void CreateFixedMacro(std::array<Macro, kZxxMacros> &fixedMacros, FixedMacro macroType) const;
+public:
+ void CreateFixedMacro(FixedMacro macroType)
+ {
+ CreateFixedMacro(Zxx, macroType);
+ }
+
+ bool operator==(const MIDIMacroConfig &other) const;
+ bool operator!=(const MIDIMacroConfig &other) const { return !(*this == other); }
+
+#ifdef MODPLUG_TRACKER
+
+ // Translate macro type or macro string to macro name
+ CString GetParameteredMacroName(uint32 macroIndex, IMixPlugin *plugin = nullptr) const;
+ CString GetParameteredMacroName(ParameteredMacro macroType) const;
+ CString GetFixedMacroName(FixedMacro macroType) const;
+
+ // Extract information from a parametered macro string.
+ PlugParamIndex MacroToPlugParam(uint32 macroIndex) const;
+ int MacroToMidiCC(uint32 macroIndex) const;
+
+ // Check if any macro can automate a given plugin parameter
+ int FindMacroForParam(PlugParamIndex param) const;
+
+#endif // MODPLUG_TRACKER
+
+ // Check if a given set of macros is the default IT macro set.
+ bool IsMacroDefaultSetupUsed() const;
+
+ // Reset MIDI macro config to default values.
+ void Reset();
+
+ // Clear all Zxx macros so that they do nothing.
+ void ClearZxxMacros();
+
+ // Sanitize all macro config strings.
+ void Sanitize();
+
+ // Fix old-format (not conforming to IT's MIDI macro definitions) MIDI config strings.
+ void UpgradeMacros();
+};
+
+static_assert(sizeof(MIDIMacroConfig) == sizeof(MIDIMacroConfigData)); // this is directly written to files, so the size must be correct!
+
+
+OPENMPT_NAMESPACE_END