The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
5.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce::midi_ci
  19. {
  20. /**
  21. Holds a profile ID, along with the number of supported and active channels
  22. corresponding to that profile.
  23. @tags{Audio}
  24. */
  25. struct ProfileStateEntry
  26. {
  27. Profile profile; ///< A MIDI-CI profile ID
  28. SupportedAndActive state; ///< The number of channels corresponding to the profile
  29. bool operator< (const Profile& other) const { return profile < other; }
  30. bool operator< (const ProfileStateEntry& other) const { return profile < other.profile; }
  31. };
  32. //==============================================================================
  33. /**
  34. Holds the number of channels that are supported and activated for all profiles
  35. at a particular channel address.
  36. @tags{Audio}
  37. */
  38. class ChannelProfileStates
  39. {
  40. public:
  41. using Entry = ProfileStateEntry;
  42. /** Returns the number of channels that are supported and active for the
  43. given profile.
  44. */
  45. SupportedAndActive get (const Profile& profile) const;
  46. /** Returns all profiles that are active at this address. */
  47. std::vector<Profile> getActive() const;
  48. /** Returns all profiles that are supported but inactive at this address. */
  49. std::vector<Profile> getInactive() const;
  50. /** Sets the number of channels that are supported/active for a given profile. */
  51. void set (const Profile& profile, SupportedAndActive state);
  52. /** Removes the record of a particular profile, equivalent to removing support. */
  53. void erase (const Profile& profile);
  54. /** Gets a const iterator over all profiles, for range-for compatibility. */
  55. auto begin() const { return entries.begin(); }
  56. /** Gets a const iterator over all profiles, for range-for compatibility. */
  57. auto end() const { return entries.end(); }
  58. /** Returns true if no profiles are supported. */
  59. auto empty() const { return entries.empty(); }
  60. /** Returns the number of profiles that are supported at this address. */
  61. auto size() const { return entries.size(); }
  62. private:
  63. std::vector<Entry> entries;
  64. };
  65. //==============================================================================
  66. /**
  67. Contains profile states for each channel in a group, along with the state
  68. of profiles that apply to the group itself.
  69. @tags{Audio}
  70. */
  71. class GroupProfileStates
  72. {
  73. template <typename This>
  74. static auto getStateForDestinationImpl (This& t, ChannelInGroup destination) -> decltype (&t.groupState)
  75. {
  76. if (destination == ChannelInGroup::wholeGroup)
  77. return &t.groupState;
  78. if (const auto index = (size_t) destination; index < t.channelStates.size())
  79. return &t.channelStates[index];
  80. return nullptr;
  81. }
  82. public:
  83. /** Returns the profile state for the group or a contained channel as appropriate.
  84. Returns nullptr if ChannelInGroup refers to a whole function block.
  85. */
  86. auto* getStateForDestination (ChannelInGroup d) { return getStateForDestinationImpl (*this, d); }
  87. /** Returns the profile state for the group or a contained channel as appropriate.
  88. Returns nullptr if ChannelInGroup refers to a whole function block.
  89. */
  90. auto* getStateForDestination (ChannelInGroup d) const { return getStateForDestinationImpl (*this, d); }
  91. std::array<ChannelProfileStates, 16> channelStates; ///< Profile states for each channel in the group
  92. ChannelProfileStates groupState; ///< Profile states for the group itself
  93. };
  94. //==============================================================================
  95. /**
  96. Contains profile states for each group and channel in a function block, along with the state
  97. of profiles that apply to the function block itself.
  98. @tags{Audio}
  99. */
  100. class BlockProfileStates
  101. {
  102. template <typename This>
  103. static auto getStateForDestinationImpl (This& t, ChannelAddress address) -> decltype (&t.blockState)
  104. {
  105. if (address.isBlock())
  106. return &t.blockState;
  107. if (const auto index = (size_t) address.getGroup(); index < t.groupStates.size())
  108. return t.groupStates[index].getStateForDestination (address.getChannel());
  109. return nullptr;
  110. }
  111. public:
  112. /** Returns the profile state for the function block, group, or channel as appropriate.
  113. Returns nullptr if the address refers to a non-existent channel or group.
  114. */
  115. auto* getStateForDestination (ChannelAddress address) { return getStateForDestinationImpl (*this, address); }
  116. /** Returns the profile state for the function block, group, or channel as appropriate.
  117. Returns nullptr if the address refers to a non-existent channel or group.
  118. */
  119. auto* getStateForDestination (ChannelAddress address) const { return getStateForDestinationImpl (*this, address); }
  120. std::array<GroupProfileStates, 16> groupStates; ///< Profile states for each group in the function block
  121. ChannelProfileStates blockState; ///< Profile states for the whole function block
  122. };
  123. } // namespace juce::midi_ci