git subrepo clone --branch=sono6good https://github.com/essej/JUCE.git deps/juce
subrepo: subdir: "deps/juce" merged: "b13f9084e" upstream: origin: "https://github.com/essej/JUCE.git" branch: "sono6good" commit: "b13f9084e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
225
deps/juce/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h
vendored
Normal file
225
deps/juce/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.h
vendored
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - 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
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This class represents the current MPE zone layout of a device capable of handling MPE.
|
||||
|
||||
An MPE device can have up to two zones: a lower zone with master channel 1 and
|
||||
allocated MIDI channels increasing from channel 2, and an upper zone with master
|
||||
channel 16 and allocated MIDI channels decreasing from channel 15. MPE mode is
|
||||
enabled on a device when one of these zones is active and disabled when both
|
||||
are inactive.
|
||||
|
||||
Use the MPEMessages helper class to convert the zone layout represented
|
||||
by this object to MIDI message sequences that you can send to an Expressive
|
||||
MIDI device to set its zone layout, add zones etc.
|
||||
|
||||
@see MPEInstrument
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API MPEZoneLayout
|
||||
{
|
||||
public:
|
||||
/** Default constructor.
|
||||
|
||||
This will create a layout with inactive lower and upper zones, representing
|
||||
a device with MPE mode disabled.
|
||||
|
||||
You can set the lower or upper MPE zones using the setZone() method.
|
||||
|
||||
@see setZone
|
||||
*/
|
||||
MPEZoneLayout() noexcept;
|
||||
|
||||
/** Copy constuctor.
|
||||
This will not copy the listeners registered to the MPEZoneLayout.
|
||||
*/
|
||||
MPEZoneLayout (const MPEZoneLayout& other);
|
||||
|
||||
/** Copy assignment operator.
|
||||
This will not copy the listeners registered to the MPEZoneLayout.
|
||||
*/
|
||||
MPEZoneLayout& operator= (const MPEZoneLayout& other);
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This struct represents an MPE zone.
|
||||
|
||||
It can either be a lower or an upper zone, where:
|
||||
- A lower zone encompasses master channel 1 and an arbitrary number of ascending
|
||||
MIDI channels, increasing from channel 2.
|
||||
- An upper zone encompasses master channel 16 and an arbitrary number of descending
|
||||
MIDI channels, decreasing from channel 15.
|
||||
|
||||
It also defines a pitchbend range (in semitones) to be applied for per-note pitchbends and
|
||||
master pitchbends, respectively.
|
||||
*/
|
||||
struct Zone
|
||||
{
|
||||
Zone (const Zone& other) = default;
|
||||
|
||||
bool isLowerZone() const noexcept { return lowerZone; }
|
||||
bool isUpperZone() const noexcept { return ! lowerZone; }
|
||||
|
||||
bool isActive() const noexcept { return numMemberChannels > 0; }
|
||||
|
||||
int getMasterChannel() const noexcept { return lowerZone ? 1 : 16; }
|
||||
int getFirstMemberChannel() const noexcept { return lowerZone ? 2 : 15; }
|
||||
int getLastMemberChannel() const noexcept { return lowerZone ? (1 + numMemberChannels)
|
||||
: (16 - numMemberChannels); }
|
||||
|
||||
bool isUsingChannelAsMemberChannel (int channel) const noexcept
|
||||
{
|
||||
return lowerZone ? (channel > 1 && channel <= 1 + numMemberChannels)
|
||||
: (channel < 16 && channel >= 16 - numMemberChannels);
|
||||
}
|
||||
|
||||
bool isUsing (int channel) const noexcept
|
||||
{
|
||||
return isUsingChannelAsMemberChannel (channel) || channel == getMasterChannel();
|
||||
}
|
||||
|
||||
bool operator== (const Zone& other) const noexcept { return lowerZone == other.lowerZone
|
||||
&& numMemberChannels == other.numMemberChannels
|
||||
&& perNotePitchbendRange == other.perNotePitchbendRange
|
||||
&& masterPitchbendRange == other.masterPitchbendRange; }
|
||||
|
||||
bool operator!= (const Zone& other) const noexcept { return ! operator== (other); }
|
||||
|
||||
int numMemberChannels;
|
||||
int perNotePitchbendRange;
|
||||
int masterPitchbendRange;
|
||||
|
||||
private:
|
||||
friend class MPEZoneLayout;
|
||||
|
||||
Zone (bool lower, int memberChans = 0, int perNotePb = 48, int masterPb = 2) noexcept
|
||||
: numMemberChannels (memberChans),
|
||||
perNotePitchbendRange (perNotePb),
|
||||
masterPitchbendRange (masterPb),
|
||||
lowerZone (lower)
|
||||
{
|
||||
}
|
||||
|
||||
bool lowerZone;
|
||||
};
|
||||
|
||||
/** Sets the lower zone of this layout. */
|
||||
void setLowerZone (int numMemberChannels = 0,
|
||||
int perNotePitchbendRange = 48,
|
||||
int masterPitchbendRange = 2) noexcept;
|
||||
|
||||
/** Sets the upper zone of this layout. */
|
||||
void setUpperZone (int numMemberChannels = 0,
|
||||
int perNotePitchbendRange = 48,
|
||||
int masterPitchbendRange = 2) noexcept;
|
||||
|
||||
/** Returns a struct representing the lower MPE zone. */
|
||||
const Zone getLowerZone() const noexcept { return lowerZone; }
|
||||
|
||||
/** Returns a struct representing the upper MPE zone. */
|
||||
const Zone getUpperZone() const noexcept { return upperZone; }
|
||||
|
||||
/** Clears the lower and upper zones of this layout, making them both inactive
|
||||
and disabling MPE mode.
|
||||
*/
|
||||
void clearAllZones();
|
||||
|
||||
//==============================================================================
|
||||
/** Pass incoming MIDI messages to an object of this class if you want the
|
||||
zone layout to properly react to MPE RPN messages like an
|
||||
MPE device.
|
||||
|
||||
MPEMessages::rpnNumber will add or remove zones; RPN 0 will
|
||||
set the per-note or master pitchbend ranges.
|
||||
|
||||
Any other MIDI messages will be ignored by this class.
|
||||
|
||||
@see MPEMessages
|
||||
*/
|
||||
void processNextMidiEvent (const MidiMessage& message);
|
||||
|
||||
/** Pass incoming MIDI buffers to an object of this class if you want the
|
||||
zone layout to properly react to MPE RPN messages like an
|
||||
MPE device.
|
||||
|
||||
MPEMessages::rpnNumber will add or remove zones; RPN 0 will
|
||||
set the per-note or master pitchbend ranges.
|
||||
|
||||
Any other MIDI messages will be ignored by this class.
|
||||
|
||||
@see MPEMessages
|
||||
*/
|
||||
void processNextMidiBuffer (const MidiBuffer& buffer);
|
||||
|
||||
//==============================================================================
|
||||
/** Listener class. Derive from this class to allow your class to be
|
||||
notified about changes to the zone layout.
|
||||
*/
|
||||
class Listener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
virtual ~Listener() = default;
|
||||
|
||||
/** Implement this callback to be notified about any changes to this
|
||||
MPEZoneLayout. Will be called whenever a zone is added, zones are
|
||||
removed, or any zone's master or note pitchbend ranges change.
|
||||
*/
|
||||
virtual void zoneLayoutChanged (const MPEZoneLayout& layout) = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a listener. */
|
||||
void addListener (Listener* const listenerToAdd) noexcept;
|
||||
|
||||
/** Removes a listener. */
|
||||
void removeListener (Listener* const listenerToRemove) noexcept;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Zone lowerZone { true, 0 };
|
||||
Zone upperZone { false, 0 };
|
||||
|
||||
MidiRPNDetector rpnDetector;
|
||||
ListenerList<Listener> listeners;
|
||||
|
||||
//==============================================================================
|
||||
void setZone (bool, int, int, int) noexcept;
|
||||
|
||||
void processRpnMessage (MidiRPNMessage);
|
||||
void processZoneLayoutRpnMessage (MidiRPNMessage);
|
||||
void processPitchbendRangeRpnMessage (MidiRPNMessage);
|
||||
|
||||
void updateMasterPitchbend (Zone&, int);
|
||||
void updatePerNotePitchbendRange (Zone&, int);
|
||||
|
||||
void sendLayoutChangeMessage();
|
||||
void checkAndLimitZoneParameters (int, int, int&) noexcept;
|
||||
};
|
||||
|
||||
} // namespace juce
|
Reference in New Issue
Block a user