#include <MIDI_Interfaces/MIDI_Pipes.hpp>
Class that routes MIDI messages from a MIDI_Source to a MIDI_Sink.
A pipe has at least two, at most four connections. In the simplest case, a pipe just has a source and a sink. The source sends MIDI messages down the pipe, and the pipe sends them to the sink. A mapping or filter can be applied to the messages traveling down the pipe.
To be able to connect multiple pipes to a single sink or source, a pipe also has a “through” output and a “through” input. Both are pipes, not sinks or sources. All data that comes from the source is sent to the “through” output as well, and all input that comes in from the “through” input is sent to the sink as well. The mapping or filter is not applied to the data going from/to the “through” connections.
Merging data from multiple sources into a single sink can cause problems because messages can be interleaved (e.g. RPN/NRPN or chunked system exclusive messages). To circumvent this issue, a source can request exclusive access to the pipe it's connected to. This stalls all other pipes that sink into the same sinks as the exclusive source.
When other sources try to send to a stalled pipe, this will automatically call back the source that originally stalled the pipes, so it can finish its message, and then un-stall the pipes so the other pipe can send its data.
Pipe model
For example, if you have one source that should connect to two sinks, the configuration is as follows:
If you have two sources that should connect to the same sink, a possible configuration is:
Each connection between a source and a sink has its own pipe, and no two pipes are connected in series (only through the “through“ inputs/outputs).
Definition at line 335 of file MIDI_Pipes.hpp.
Dealing with stalled pipes | |
bool | isStalled () const |
Check if this pipe is stalled. | |
MIDIStaller * | getSinkStaller () const |
Get the staller (cause of the stall) that causes the sink of this pipe to be stalled. | |
const char * | getSinkStallerName () const |
Get the name of the staller (cause of the stall) that causes the sink of this pipe to be stalled. | |
MIDIStaller * | getThroughStaller () const |
Get the staller (cause of the stall) that causes the “through” output of this pipe to be stalled. | |
const char * | getThroughStallerName () const |
Get the name of the staller (cause of the stall) that causes the “through” output of this pipe to be stalled. | |
MIDIStaller * | getStaller () const |
Get any staller: returns getSinkStaller() if it's not null, getThroughStaller() otherwise. | |
const char * | getStallerName () const |
Get the name of any staller. | |
bool | sinkIsUnstalledOrStalledBy (MIDIStaller *cause) |
Returns true if this pipe is either not stalled at all, or if the pipe is stalled by the given staller (cause). | |
bool | throughIsUnstalledOrStalledBy (MIDIStaller *cause) |
Returns true if this pipe is either not stalled at all, or if the pipe is stalled by the given staller (cause). | |
void | handleStallers () const |
Give the code that is stalling the MIDI pipe the opportunity to do its job and unstall the pipe. | |
Check connections | |
bool | hasSink () const |
Check if this pipe is connected to a sink. | |
bool | hasSource () const |
Check if this pipe is connected to a source. | |
bool | hasThroughOut () const |
Check if this pipe has a “through” output that sends all incoming messages from the input (source) to another pipe. | |
bool | hasThroughIn () const |
Check if this pipe has a “through” input that merges all messages from another pipe into the output (sink). | |
MIDI Pipe connection management and inspection | |
void | disconnect () |
Disconnect this pipe from all other pipes, sources and sinks. | |
bool | disconnect (TrueMIDI_Sink &sink) |
Disconnect the given sink from this pipe. | |
bool | disconnect (TrueMIDI_Source &source) |
Disconnect the given source from this pipe. | |
bool | disconnect (MIDI_Pipe &)=delete |
MIDI_Source * | getSource () const |
Get the immediate source of this pipe. | |
MIDI_Sink * | getSink () const |
Get the immediate sink of this pipe. | |
MIDI_Pipe * | getThroughOut () const |
Get the pipe connected to the “through” output of this pipe. | |
MIDI_Pipe * | getThroughIn () const |
Get the pipe connected to the “through” input of this pipe. | |
MIDI_Sink * | getFinalSink () override |
Get the sink this pipe eventually sinks to, following the chain recursively. | |
MIDI_Source * | getInitialSource () override |
Get the original source that sources to this pipe, following the chain recursively. | |
Mapping and filtering | |
virtual void | mapForwardMIDI (ChannelMessage msg) |
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe. | |
virtual void | mapForwardMIDI (SysExMessage msg) |
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe. | |
virtual void | mapForwardMIDI (SysCommonMessage msg) |
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe. | |
virtual void | mapForwardMIDI (RealTimeMessage msg) |
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe. | |
Private functions to connect and disconnect sinks and sources | |
void | connectSink (MIDI_Sink *sink) |
Set the sink pointer to point to the given sink. | |
void | disconnectSink () |
Set the sink pointer to null. | |
void | connectSource (MIDI_Source *source) |
Set the source pointer to point to the given source. | |
void | disconnectSource () |
Set the source pointer to null. | |
Private functions to stall and un-stall pipes | |
void | stallDownstream (MIDIStaller *cause, MIDI_Source *stallsrc) override |
Stall this pipe and all other pipes further downstream (following the path of the sink and the “through” output). | |
void | unstallDownstream (MIDIStaller *cause, MIDI_Source *stallsrc) override |
Undoes the stalling by stallDownstream. | |
void | stallUpstream (MIDIStaller *cause, MIDI_Sink *stallsrc) override |
Stall this pipe and all other pipes further upstream (following the path of the "trough" input). | |
void | unstallUpstream (MIDIStaller *cause, MIDI_Sink *stallsrc) override |
Undoes the stalling by stallUpstream. | |
Connecting and disconnecting MIDI Pipes | |
void | connectSourcePipe (MIDI_Pipe *source) |
Fully connect a source pipe to this sink. | |
void | disconnectSourcePipes () |
Disconnect all source pipes that sink to this sink (recursively). | |
bool | hasSourcePipe () const |
Check if this sink is connected to a source pipe. | |
MIDI_Pipe * | getSourcePipe () const |
Get a pointer to the pipe this sink is connected to, or nullptr if not connected. | |
Sending data over a MIDI Pipe | |
void | sourceMIDItoPipe (ChannelMessage) |
Send a MIDI Channel Message down the pipe. | |
void | sourceMIDItoPipe (SysExMessage) |
Send a MIDI System Exclusive message down the pipe. | |
void | sourceMIDItoPipe (SysCommonMessage) |
Send a MIDI System Common message down the pipe. | |
void | sourceMIDItoPipe (RealTimeMessage) |
Send a MIDI Real-Time message down the pipe. | |
Stalling the sink pipes and exclusive access | |
void | stall (MIDIStaller *cause=eternal_stall) |
Stall this MIDI source. | |
void | unstall (MIDIStaller *cause=eternal_stall) |
Un-stall the pipes connected to this source, so other sources are allowed to send again. | |
Connecting and disconnecting MIDI Pipes | |
void | connectSinkPipe (MIDI_Pipe *sink) |
Fully connect a sink pipe to this source. | |
void | disconnectSinkPipes () |
Disconnect all sink pipes that this source sinks to (recursively). | |
bool | hasSinkPipe () const |
Check if this source is connected to a sink pipe. | |
MIDI_Pipe * | getSinkPipe () |
Get a pointer to the pipe this source is connected to, or nullptr if not connected. | |
Public Member Functions | |
MIDI_Pipe ()=default | |
Default constructor. | |
MIDI_Pipe (const MIDI_Pipe &)=delete | |
Copy constructor (copying not allowed). | |
MIDI_Pipe & | operator= (const MIDI_Pipe &)=delete |
Copy assignment (copying not allowed). | |
MIDI_Pipe (MIDI_Pipe &&)=delete | |
Move constructor. | |
MIDI_Pipe & | operator= (MIDI_Pipe &&)=delete |
Move assignment. | |
virtual | ~MIDI_Pipe () |
Destructor. | |
Protected Member Functions | |
template<class Message > | |
void | sourceMIDItoSink (Message msg) |
Send the given MIDI message to the sink of this pipe. | |
template<class Message > | |
void | acceptMIDIfromSource (Message msg) |
Accept a MIDI message from the source, forward it to the “through” output if necessary, map or filter the MIDI message if necessary, and send it to the sink. | |
Private Member Functions | |
void | sinkMIDIfromPipe (ChannelMessage msg) override |
Called when data arrives from an upstream pipe connected to our “through” input, this function forwards it to the sink. | |
void | sinkMIDIfromPipe (SysExMessage msg) override |
Called when data arrives from an upstream pipe connected to our “through” input, this function forwards it to the sink. | |
void | sinkMIDIfromPipe (SysCommonMessage msg) override |
Called when data arrives from an upstream pipe connected to our “through” input, this function forwards it to the sink. | |
void | sinkMIDIfromPipe (RealTimeMessage msg) override |
Called when data arrives from an upstream pipe connected to our “through” input, this function forwards it to the sink. | |
void | disconnectSourcePipesShallow () |
Disconnect only the first pipe connected to this sink. | |
void | disconnectSinkPipesShallow () |
Disconnect only the first pipe connected to this source. | |
Static Private Member Functions | |
static void | swap (MIDI_Sink &a, MIDI_Sink &b) |
static void | swap (MIDI_Source &a, MIDI_Source &b) |
Private Attributes | |
MIDI_Sink * | sink = nullptr |
MIDI_Source * | source = nullptr |
MIDIStaller * | sink_staller = nullptr |
MIDIStaller * | through_staller = nullptr |
MIDI_Pipe * | sourcePipe = nullptr |
MIDI_Pipe * | sinkPipe = nullptr |
|
default |
Default constructor.
|
virtual |
Destructor.
Definition at line 238 of file MIDI_Pipes.cpp.
|
inlineprivatevirtual |
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
The MIDI_Pipe base class just forwards the messages to the sink, but you can override this method to create pipes that filter out some messages, transposes notes, changes the channel, etc.
Definition at line 364 of file MIDI_Pipes.hpp.
|
inlineprivatevirtual |
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
The MIDI_Pipe base class just forwards the messages to the sink, but you can override this method to create pipes that filter out some messages, transposes notes, changes the channel, etc.
Definition at line 366 of file MIDI_Pipes.hpp.
|
inlineprivatevirtual |
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
The MIDI_Pipe base class just forwards the messages to the sink, but you can override this method to create pipes that filter out some messages, transposes notes, changes the channel, etc.
Definition at line 368 of file MIDI_Pipes.hpp.
|
inlineprivatevirtual |
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
The MIDI_Pipe base class just forwards the messages to the sink, but you can override this method to create pipes that filter out some messages, transposes notes, changes the channel, etc.
Definition at line 370 of file MIDI_Pipes.hpp.
|
inline |
Check if this pipe is stalled.
Definition at line 379 of file MIDI_Pipes.hpp.
|
inline |
Get the staller (cause of the stall) that causes the sink of this pipe to be stalled.
This pipe could sink to more than one stalled sink, this function just returns one of the causes.
Definition at line 384 of file MIDI_Pipes.hpp.
const char * getSinkStallerName | ( | ) | const |
Get the name of the staller (cause of the stall) that causes the sink of this pipe to be stalled.
Definition at line 325 of file MIDI_Pipes.cpp.
|
inline |
Get the staller (cause of the stall) that causes the “through” output of this pipe to be stalled.
The “through” output of this pipe could sink to more than one stalled sink, this function just returns one of the causes.
Definition at line 392 of file MIDI_Pipes.hpp.
const char * getThroughStallerName | ( | ) | const |
Get the name of the staller (cause of the stall) that causes the “through” output of this pipe to be stalled.
Definition at line 329 of file MIDI_Pipes.cpp.
MIDIStaller * getStaller | ( | ) | const |
Get any staller: returns getSinkStaller() if it's not null, getThroughStaller() otherwise.
Definition at line 333 of file MIDI_Pipes.cpp.
const char * getStallerName | ( | ) | const |
|
inline |
Returns true if this pipe is either not stalled at all, or if the pipe is stalled by the given staller (cause).
Definition at line 405 of file MIDI_Pipes.hpp.
|
inline |
Returns true if this pipe is either not stalled at all, or if the pipe is stalled by the given staller (cause).
Definition at line 411 of file MIDI_Pipes.hpp.
void handleStallers | ( | ) | const |
Give the code that is stalling the MIDI pipe the opportunity to do its job and unstall the pipe.
Definition at line 341 of file MIDI_Pipes.cpp.
|
inline |
Check if this pipe is connected to a sink.
Definition at line 426 of file MIDI_Pipes.hpp.
|
inline |
Check if this pipe is connected to a source.
Definition at line 428 of file MIDI_Pipes.hpp.
|
inline |
Check if this pipe has a “through” output that sends all incoming messages from the input (source) to another pipe.
Definition at line 431 of file MIDI_Pipes.hpp.
|
inline |
Check if this pipe has a “through” input that merges all messages from another pipe into the output (sink).
Definition at line 434 of file MIDI_Pipes.hpp.
void disconnect | ( | ) |
Disconnect this pipe from all other pipes, sources and sinks.
If the “through” input and/or output were in use, they are reconnected to their original sink and/or source respectively, their behavior doesn't change.
Definition at line 213 of file MIDI_Pipes.cpp.
|
inline |
Disconnect the given sink from this pipe.
The sink can be connected directly, or via the “through” output. Returns true if the sink was found and disconnected, false if the given sink was not a direct or indirect sink of this pipe.
Definition at line 450 of file MIDI_Pipes.hpp.
|
inline |
Disconnect the given source from this pipe.
The source can be connected directly, or via the “through” input. Returns true if the source was found and disconnected, false if the given source was not a direct or indirect source to this pipe.
Definition at line 464 of file MIDI_Pipes.hpp.
|
delete |
|
inline |
Get the immediate source of this pipe.
Definition at line 477 of file MIDI_Pipes.hpp.
|
inline |
Get the immediate sink of this pipe.
Definition at line 479 of file MIDI_Pipes.hpp.
|
inline |
Get the pipe connected to the “through” output of this pipe.
Definition at line 481 of file MIDI_Pipes.hpp.
|
inline |
Get the pipe connected to the “through” input of this pipe.
Definition at line 483 of file MIDI_Pipes.hpp.
|
inlineoverridevirtual |
Get the sink this pipe eventually sinks to, following the chain recursively.
Reimplemented from MIDI_Sink.
Definition at line 487 of file MIDI_Pipes.hpp.
|
inlineoverridevirtual |
Get the original source that sources to this pipe, following the chain recursively.
Reimplemented from MIDI_Source.
Definition at line 492 of file MIDI_Pipes.hpp.
|
private |
Set the sink pointer to point to the given sink.
Does not connect this pipe to the sink. Initiate the connection from the sink.
Definition at line 193 of file MIDI_Pipes.cpp.
|
private |
Set the sink pointer to null.
Does not disconnect this pipe from the sink. Initiate the disconnection from the sink.
Definition at line 201 of file MIDI_Pipes.cpp.
|
private |
Set the source pointer to point to the given source.
Does not connect this pipe to the source. Initiate the connection from the source.
Definition at line 203 of file MIDI_Pipes.cpp.
|
private |
Set the source pointer to null.
Does not disconnect this pipe from the source. Initiate the disconnection from the source.
Definition at line 211 of file MIDI_Pipes.cpp.
|
inlineprotected |
Send the given MIDI message to the sink of this pipe.
Useful when overriding mapForwardMIDI.
Definition at line 521 of file MIDI_Pipes.hpp.
|
inlineprotected |
Accept a MIDI message from the source, forward it to the “through” output if necessary, map or filter the MIDI message if necessary, and send it to the sink.
This function transfers messages from a MIDI_Source to its MIDI_Pipe.
Definition at line 532 of file MIDI_Pipes.hpp.
|
inlineoverrideprivatevirtual |
Called when data arrives from an upstream pipe connected to our “through” input, this function forwards it to the sink.
Implements MIDI_Sink.
Definition at line 541 of file MIDI_Pipes.hpp.
|
inlineoverrideprivatevirtual |
Called when data arrives from an upstream pipe connected to our “through” input, this function forwards it to the sink.
Implements MIDI_Sink.
Definition at line 545 of file MIDI_Pipes.hpp.
|
inlineoverrideprivatevirtual |
Called when data arrives from an upstream pipe connected to our “through” input, this function forwards it to the sink.
Implements MIDI_Sink.
Definition at line 547 of file MIDI_Pipes.hpp.
|
inlineoverrideprivatevirtual |
Called when data arrives from an upstream pipe connected to our “through” input, this function forwards it to the sink.
Implements MIDI_Sink.
Definition at line 551 of file MIDI_Pipes.hpp.
|
overrideprivatevirtual |
Stall this pipe and all other pipes further downstream (following the path of the sink and the “through” output).
Operates recursively until the end of the chain is reached, and then continues upstream (using stallUpstream) to stall all pipes that connect to sources that sink to the same sink as this pipe and its “through” output. In short: stall all pipes that sink to the same sink as this pipe, and then stall all pipes that source to this first set of pipes.
Reimplemented from MIDI_Sink.
Definition at line 240 of file MIDI_Pipes.cpp.
|
overrideprivatevirtual |
Undoes the stalling by stallDownstream.
Reimplemented from MIDI_Sink.
Definition at line 283 of file MIDI_Pipes.cpp.
|
overrideprivatevirtual |
Stall this pipe and all other pipes further upstream (following the path of the "trough" input).
Operates recursively until the end of the chain is reached. This function is called in the second stage of stallDownstream.
Reimplemented from MIDI_Source.
Definition at line 265 of file MIDI_Pipes.cpp.
|
overrideprivatevirtual |
Undoes the stalling by stallUpstream.
Reimplemented from MIDI_Source.
Definition at line 307 of file MIDI_Pipes.cpp.
|
inherited |
Fully connect a source pipe to this sink.
Definition at line 17 of file MIDI_Pipes.cpp.
|
inherited |
Disconnect all source pipes that sink to this sink (recursively).
Definition at line 26 of file MIDI_Pipes.cpp.
|
inlineinherited |
Check if this sink is connected to a source pipe.
Definition at line 121 of file MIDI_Pipes.hpp.
|
inlineinherited |
Get a pointer to the pipe this sink is connected to, or nullptr
if not connected.
Definition at line 124 of file MIDI_Pipes.hpp.
|
privateinherited |
Disconnect only the first pipe connected to this sink.
Leaves the other pipes connected to the original pipe, which doesn't have a sink anymore when this function finishes. Used to disconnect a MIDI_Pipe while preserving the connections of its “through” inputs.
Definition at line 34 of file MIDI_Pipes.cpp.
Definition at line 57 of file MIDI_Pipes.cpp.
|
inherited |
Send a MIDI Channel Message down the pipe.
Definition at line 133 of file MIDI_Pipes.cpp.
|
inherited |
Send a MIDI System Exclusive message down the pipe.
Definition at line 139 of file MIDI_Pipes.cpp.
|
inherited |
Send a MIDI System Common message down the pipe.
Definition at line 145 of file MIDI_Pipes.cpp.
|
inherited |
Send a MIDI Real-Time message down the pipe.
Definition at line 151 of file MIDI_Pipes.cpp.
|
inherited |
Stall this MIDI source.
This means that this becomes the only source that can sink to the sinks connected to this source. Other sources have to wait until this source un-stalls the pipe before they can send again.
cause | Pointer to the reason for this stall, can be called back to un-stall the pipes. |
Definition at line 158 of file MIDI_Pipes.cpp.
|
inherited |
Un-stall the pipes connected to this source, so other sources are allowed to send again.
cause | Pointer to the reason for the stall (this has to be the same one that was used to stall). |
Definition at line 164 of file MIDI_Pipes.cpp.
|
inherited |
Fully connect a sink pipe to this source.
Definition at line 76 of file MIDI_Pipes.cpp.
|
inherited |
Disconnect all sink pipes that this source sinks to (recursively).
Definition at line 85 of file MIDI_Pipes.cpp.
|
inlineinherited |
Check if this source is connected to a sink pipe.
Definition at line 237 of file MIDI_Pipes.hpp.
|
inlineinherited |
Get a pointer to the pipe this source is connected to, or nullptr
if not connected.
Definition at line 240 of file MIDI_Pipes.hpp.
|
privateinherited |
Disconnect only the first pipe connected to this source.
Leaves the other pipes connected to the original pipe, which doesn't have a source anymore when this function finishes. Used to disconnect a MIDI_Pipe while preserving the connections of its “through” outputs.
Definition at line 93 of file MIDI_Pipes.cpp.
|
staticinherited |
Definition at line 114 of file MIDI_Pipes.cpp.
|
private |
Definition at line 581 of file MIDI_Pipes.hpp.
|
private |
Definition at line 582 of file MIDI_Pipes.hpp.
|
private |
Definition at line 583 of file MIDI_Pipes.hpp.
|
private |
Definition at line 584 of file MIDI_Pipes.hpp.
|
protectedinherited |
Definition at line 146 of file MIDI_Pipes.hpp.
|
protectedinherited |
Definition at line 262 of file MIDI_Pipes.hpp.