Loading...
Searching...
No Matches
juce_MPEZoneLayout.h
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
struct MPEZone
{
enum class Type { lower, upper };
MPEZone() = default;
MPEZone (Type type, int memberChannels = 0, int perNotePitchbend = 48, int masterPitchbend = 2)
: zoneType (type),
numMemberChannels (memberChannels),
perNotePitchbendRange (perNotePitchbend),
masterPitchbendRange (masterPitchbend)
{}
bool isLowerZone() const noexcept { return zoneType == Type::lower; }
bool isUpperZone() const noexcept { return zoneType == Type::upper; }
bool isActive() const noexcept { return numMemberChannels > 0; }
int getMasterChannel() const noexcept { return isLowerZone() ? lowerZoneMasterChannel : upperZoneMasterChannel; }
int getFirstMemberChannel() const noexcept { return isLowerZone() ? lowerZoneMasterChannel + 1 : upperZoneMasterChannel - 1; }
int getLastMemberChannel() const noexcept { return isLowerZone() ? (lowerZoneMasterChannel + numMemberChannels)
: (upperZoneMasterChannel - numMemberChannels); }
bool isUsingChannelAsMemberChannel (int channel) const noexcept
{
return isLowerZone() ? (lowerZoneMasterChannel < channel && channel <= getLastMemberChannel())
: (channel < upperZoneMasterChannel && getLastMemberChannel() <= channel);
}
bool isUsing (int channel) const noexcept
{
return isUsingChannelAsMemberChannel (channel) || channel == getMasterChannel();
}
static auto tie (const MPEZone& z)
{
return std::tie (z.zoneType,
z.numMemberChannels,
z.perNotePitchbendRange,
z.masterPitchbendRange);
}
bool operator== (const MPEZone& other) const
{
return tie (*this) == tie (other);
}
bool operator!= (const MPEZone& other) const
{
return tie (*this) != tie (other);
}
//==============================================================================
static constexpr int lowerZoneMasterChannel = 1,
upperZoneMasterChannel = 16;
Type zoneType = Type::lower;
int numMemberChannels = 0;
int perNotePitchbendRange = 48;
int masterPitchbendRange = 2;
};
//==============================================================================
class JUCE_API MPEZoneLayout
{
public:
//==============================================================================
MPEZoneLayout() = default;
MPEZoneLayout (MPEZone lower, MPEZone upper);
MPEZoneLayout (MPEZone singleZone);
MPEZoneLayout (const MPEZoneLayout& other);
MPEZoneLayout& operator= (const MPEZoneLayout& other);
bool operator== (const MPEZoneLayout& other) const { return lowerZone == other.lowerZone && upperZone == other.upperZone; }
bool operator!= (const MPEZoneLayout& other) const { return ! operator== (other); }
//==============================================================================
MPEZone getLowerZone() const noexcept { return lowerZone; }
MPEZone getUpperZone() const noexcept { return upperZone; }
void setLowerZone (int numMemberChannels = 0,
int perNotePitchbendRange = 48,
int masterPitchbendRange = 2) noexcept;
void setUpperZone (int numMemberChannels = 0,
int perNotePitchbendRange = 48,
int masterPitchbendRange = 2) noexcept;
void clearAllZones();
bool isActive() const { return lowerZone.isActive() || upperZone.isActive(); }
//==============================================================================
void processNextMidiEvent (const MidiMessage& message);
void processNextMidiBuffer (const MidiBuffer& buffer);
//==============================================================================
class Listener
{
public:
virtual ~Listener() = default;
virtual void zoneLayoutChanged (const MPEZoneLayout& layout) = 0;
};
//==============================================================================
void addListener (Listener* const listenerToAdd) noexcept;
void removeListener (Listener* const listenerToRemove) noexcept;
#ifndef DOXYGEN
using Zone = MPEZone;
#endif
private:
//==============================================================================
MPEZone lowerZone { MPEZone::Type::lower, 0 };
MPEZone upperZone { MPEZone::Type::upper, 0 };
MidiRPNDetector rpnDetector;
ListenerList<Listener> listeners;
//==============================================================================
void setZone (bool, int, int, int) noexcept;
void processRpnMessage (MidiRPNMessage);
void processZoneLayoutRpnMessage (MidiRPNMessage);
void processPitchbendRangeRpnMessage (MidiRPNMessage);
void updateMasterPitchbend (MPEZone&, int);
void updatePerNotePitchbendRange (MPEZone&, int);
void sendLayoutChangeMessage();
void checkAndLimitZoneParameters (int, int, int&) noexcept;
};
} // namespace juce
juce::MPEZoneLayout::Listener
Definition juce_MPEZoneLayout.h:198
juce::MPEZoneLayout::Listener::zoneLayoutChanged
virtual void zoneLayoutChanged(const MPEZoneLayout &layout)=0
juce::MPEZoneLayout::Listener::~Listener
virtual ~Listener()=default
juce::MPEZoneLayout
Definition juce_MPEZoneLayout.h:123
juce::MPEZoneLayout::getUpperZone
MPEZone getUpperZone() const noexcept
Definition juce_MPEZoneLayout.h:146
juce::MPEZoneLayout::MPEZoneLayout
MPEZoneLayout()=default
juce::MPEZoneLayout::removeListener
void removeListener(Listener *const listenerToRemove) noexcept
Definition juce_MPEZoneLayout.cpp:189
juce::MPEZoneLayout::addListener
void addListener(Listener *const listenerToAdd) noexcept
Definition juce_MPEZoneLayout.cpp:184
juce::MPEZoneLayout::isActive
bool isActive() const
Definition juce_MPEZoneLayout.h:164
juce::MPEZoneLayout::getLowerZone
MPEZone getLowerZone() const noexcept
Definition juce_MPEZoneLayout.h:143
juce::MidiBuffer
Definition juce_MidiBuffer.h:145
juce::MidiMessage
Definition juce_MidiMessage.h:35
juce::MPEZone
Definition juce_MPEZoneLayout.h:42