Control Surface  1.2.0
MIDI Control Surface library for Arduino
Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes | List of all members
MIDI_Pipe Class Reference

Class that routes MIDI messages from a MIDI_Source to a MIDI_Sink. More...

#include <MIDI_Interfaces/MIDI_Pipes.hpp>

+ Inheritance diagram for MIDI_Pipe:
+ Collaboration diagram for MIDI_Pipe:

Public Member Functions

 MIDI_Pipe ()=default
 Default constructor. More...
 
 MIDI_Pipe (const MIDI_Pipe &)=delete
 Copy constructor (copying not allowed). More...
 
MIDI_Pipeoperator= (const MIDI_Pipe &)=delete
 Copy assignment (copying not allowed). More...
 
 MIDI_Pipe (MIDI_Pipe &&)=delete
 Move constructor. More...
 
MIDI_Pipeoperator= (MIDI_Pipe &&)=delete
 Move assignment. More...
 
virtual ~MIDI_Pipe ()
 Destructor. More...
 
bool hasSink () const
 Check if this pipe is connected to a sink. More...
 
bool hasSource () const
 Check if this pipe is connected to a source. More...
 
bool hasThroughOut () const
 Check if this pipe has a "through" output that sends all incoming messages from the input (source) to another pipe. More...
 
bool hasThroughIn () const
 Check if this pipe has a "through" input that merges all messages from another pipe into the output (sink). More...
 
void disconnect ()
 Disconnect this pipe from all other pipes, sources and sinks. More...
 
MIDI_SinkgetFinalSink () override
 Get the sink this pipe eventually sinks to, following the chain recursively. More...
 
MIDI_SourcegetInitialSource () override
 Get the original source that sources to this pipe, following the chain recursively. More...
 
bool disconnect (TrueMIDI_Sink &sink)
 Disconnect the given sink from this pipe. More...
 
bool disconnect (TrueMIDI_Source &source)
 Disconnect the given source from this pipe. More...
 
void exclusive (cn_t cn, bool exclusive=true)
 Enter or exit exclusive mode for the given cable number. More...
 
bool isLocked (cn_t cn) const
 Check if this pipe is locked for a given cable number. More...
 
bool isAvailableForWrite (cn_t cn) const
 Check if any of the sinks or outputs of this chain of pipes are locked for the given cable number. More...
 

Protected Member Functions

void pipeMIDI (ChannelMessage 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. More...
 
void pipeMIDI (SysExMessage 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. More...
 
void pipeMIDI (RealTimeMessage 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. More...
 
void sourceMIDItoSink (ChannelMessage msg)
 Send the given MIDI message to the sink of this pipe. More...
 
void sourceMIDItoSink (SysExMessage msg)
 Send the given MIDI message to the sink of this pipe. More...
 
void sourceMIDItoSink (RealTimeMessage msg)
 Send the given MIDI message to the sink of this pipe. More...
 
MIDI_PipegetThroughOut ()
 
MIDI_PipegetThroughIn ()
 
MIDI_SourcegetSource ()
 
MIDI_SinkgetSink ()
 

Private Member Functions

void connectSink (MIDI_Sink *sink)
 Set the sink pointer to point to the given sink. More...
 
void disconnectSink ()
 Set the sink pointer to null. More...
 
void connectSource (MIDI_Source *source)
 Set the source pointer to point to the given source. More...
 
void disconnectSource ()
 Set the source pointer to null. More...
 
virtual void mapForwardMIDI (ChannelMessage msg)
 Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe. More...
 
virtual void mapForwardMIDI (SysExMessage msg)
 Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe. More...
 
virtual void mapForwardMIDI (RealTimeMessage msg)
 Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe. More...
 
void sinkMIDIfromPipe (ChannelMessage msg) override
 Accept an incoming MIDI Channel message. More...
 
void sinkMIDIfromPipe (SysExMessage msg) override
 Accept an incoming MIDI System Exclusive message. More...
 
void sinkMIDIfromPipe (RealTimeMessage msg) override
 Accept an incoming MIDI Real-Time message. More...
 
void lockDownstream (cn_t cn, bool lock) override
 Lock this pipe and all other pipes further downstream (following the path of the sink). More...
 
void lockUpstream (cn_t cn, bool lock)
 Lock this pipe and all other pipes further upstream (following the path of the "trough" input). More...
 
void lockSelf (cn_t cn, bool lock)
 Lock this pipe, so sources cannot send messages through it. More...
 
void disconnectSourcePipesShallow ()
 Disconnect only the first pipe connected to this sink. More...
 
void disconnectSinkPipesShallow ()
 Disconnect only the first pipe connected to this source. More...
 

Private Attributes

MIDI_Sinksink = nullptr
 
MIDI_Sourcesource = nullptr
 
MIDI_Pipe *& throughOut = MIDI_Source::sinkPipe
 
MIDI_Pipe *& throughIn = MIDI_Sink::sourcePipe
 
AH::BitArray< 16 > locks
 
MIDI_PipesourcePipe = nullptr
 
MIDI_PipesinkPipe = nullptr
 

Connecting and disconnecting MIDI Pipes

void connectSourcePipe (MIDI_Pipe *source)
 Fully connect a source pipe to this sink. More...
 
void disconnectSourcePipes ()
 Disconnect all source pipes that sink to this sink (recursively). More...
 
bool hasSourcePipe () const
 Check if this sink is connected to a source pipe. More...
 

Sending data over a MIDI Pipe

void sourceMIDItoPipe (ChannelMessage)
 Send a MIDI Channel Message. More...
 
void sourceMIDItoPipe (SysExMessage)
 Send a MIDI System Exclusive message. More...
 
void sourceMIDItoPipe (RealTimeMessage)
 Send a MIDI Real-Time message. More...
 
bool canWrite (cn_t cn) const
 Check if this source can write to the sinks it connects to. More...
 

Connecting and disconnecting MIDI Pipes

void connectSinkPipe (MIDI_Pipe *sink)
 Fully connect a sink pipe to this source. More...
 
void disconnectSinkPipes ()
 Disconnect all sink pipes that this source sinks to (recursively). More...
 
bool hasSinkPipe () const
 Check if this source is connected to a sink pipe. More...
 

Detailed Description

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 sourca and a sink. The source sends data down the pipe, and the pipe sends it to the sink. A mapping or filter can be applied to the data 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 messages). To circumvent this issue, a source can request exclusive access to the pipe it's connected to. This locks all other pipes that sink into the same sinks as the exclusive source.
Other sources must then query its pipe before sending, to make sure it's not locked by another source that has exclusive access.

Pipe model

╭────────────────> through out
│ ┌────────┐
source >━━━━┷━┥ filter ┝━┯━━━> sink
└────────┘ │
through in >─────────────────╯

For example, if you have one source that should connect to two sinks, the configuration is as follows:

through out × ┌────────┐
╭────────────────> >━━━━┷━┥ pipe 2 ┝━┯━━━> sink 2
│ ┌────────┐ └────────┘ ×
source >━━━━┷━┥ pipe 1 ┝━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━> sink 1
└────────┘ ×

Each connection between a source and a sink has its own pipe, and no two pipes are connected in series.

Definition at line 270 of file MIDI_Pipes.hpp.

Constructor & Destructor Documentation

◆ MIDI_Pipe() [1/3]

MIDI_Pipe ( )
default

Default constructor.

◆ MIDI_Pipe() [2/3]

MIDI_Pipe ( const MIDI_Pipe )
delete

Copy constructor (copying not allowed).

◆ MIDI_Pipe() [3/3]

MIDI_Pipe ( MIDI_Pipe &&  )
delete

Move constructor.

Todo:
Add move constructor.

◆ ~MIDI_Pipe()

~MIDI_Pipe ( )
virtual

Destructor.

Definition at line 195 of file MIDI_Pipes.cpp.

Member Function Documentation

◆ operator=() [1/2]

MIDI_Pipe& operator= ( const MIDI_Pipe )
delete

Copy assignment (copying not allowed).

◆ operator=() [2/2]

MIDI_Pipe& operator= ( MIDI_Pipe &&  )
delete

Move assignment.

Todo:
Add move assignment.

◆ connectSink()

void connectSink ( MIDI_Sink sink)
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 150 of file MIDI_Pipes.cpp.

◆ disconnectSink()

void disconnectSink ( )
private

Set the sink pointer to null.

Does not disconnect this pipe from the sink. Initiate the disconnection from the sink.

Definition at line 158 of file MIDI_Pipes.cpp.

◆ connectSource()

void connectSource ( MIDI_Source source)
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 160 of file MIDI_Pipes.cpp.

◆ disconnectSource()

void disconnectSource ( )
private

Set the source pointer to null.

Does not disconnect this pipe from the source. Initiate the disconnection from the source.

Definition at line 168 of file MIDI_Pipes.cpp.

◆ hasSink()

bool hasSink ( ) const
inline

Check if this pipe is connected to a sink.

Definition at line 306 of file MIDI_Pipes.hpp.

◆ hasSource()

bool hasSource ( ) const
inline

Check if this pipe is connected to a source.

Definition at line 308 of file MIDI_Pipes.hpp.

◆ hasThroughOut()

bool hasThroughOut ( ) const
inline

Check if this pipe has a "through" output that sends all incoming messages from the input (source) to another pipe.

Definition at line 311 of file MIDI_Pipes.hpp.

◆ hasThroughIn()

bool hasThroughIn ( ) const
inline

Check if this pipe has a "through" input that merges all messages from another pipe into the output (sink).

Definition at line 314 of file MIDI_Pipes.hpp.

◆ pipeMIDI() [1/3]

void pipeMIDI ( ChannelMessage  msg)
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.

Definition at line 320 of file MIDI_Pipes.hpp.

◆ pipeMIDI() [2/3]

void pipeMIDI ( SysExMessage  msg)
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.

Definition at line 327 of file MIDI_Pipes.hpp.

◆ pipeMIDI() [3/3]

void pipeMIDI ( RealTimeMessage  msg)
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.

Definition at line 333 of file MIDI_Pipes.hpp.

◆ sourceMIDItoSink() [1/3]

void sourceMIDItoSink ( ChannelMessage  msg)
inlineprotected

Send the given MIDI message to the sink of this pipe.

Definition at line 341 of file MIDI_Pipes.hpp.

◆ sourceMIDItoSink() [2/3]

void sourceMIDItoSink ( SysExMessage  msg)
inlineprotected

Send the given MIDI message to the sink of this pipe.

Definition at line 347 of file MIDI_Pipes.hpp.

◆ sourceMIDItoSink() [3/3]

void sourceMIDItoSink ( RealTimeMessage  msg)
inlineprotected

Send the given MIDI message to the sink of this pipe.

Definition at line 353 of file MIDI_Pipes.hpp.

◆ mapForwardMIDI() [1/3]

virtual void mapForwardMIDI ( ChannelMessage  msg)
inlineprivatevirtual

Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.

Definition at line 361 of file MIDI_Pipes.hpp.

◆ mapForwardMIDI() [2/3]

virtual void mapForwardMIDI ( SysExMessage  msg)
inlineprivatevirtual

Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.

Definition at line 367 of file MIDI_Pipes.hpp.

◆ mapForwardMIDI() [3/3]

virtual void mapForwardMIDI ( RealTimeMessage  msg)
inlineprivatevirtual

Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.

Definition at line 373 of file MIDI_Pipes.hpp.

◆ sinkMIDIfromPipe() [1/3]

void sinkMIDIfromPipe ( ChannelMessage  )
inlineoverrideprivatevirtual

Accept an incoming MIDI Channel message.

Implements MIDI_Sink.

Definition at line 379 of file MIDI_Pipes.hpp.

◆ sinkMIDIfromPipe() [2/3]

void sinkMIDIfromPipe ( SysExMessage  )
inlineoverrideprivatevirtual

Accept an incoming MIDI System Exclusive message.

Implements MIDI_Sink.

Definition at line 383 of file MIDI_Pipes.hpp.

◆ sinkMIDIfromPipe() [3/3]

void sinkMIDIfromPipe ( RealTimeMessage  )
inlineoverrideprivatevirtual

Accept an incoming MIDI Real-Time message.

Implements MIDI_Sink.

Definition at line 387 of file MIDI_Pipes.hpp.

◆ lockDownstream()

void lockDownstream ( cn_t  cn,
bool  lock 
)
inlineoverrideprivatevirtual

Lock this pipe and all other pipes further downstream (following the path of the sink).

Operates recursively until the end of the chain is reached.

Reimplemented from MIDI_Sink.

Definition at line 396 of file MIDI_Pipes.hpp.

◆ lockUpstream()

void lockUpstream ( cn_t  cn,
bool  lock 
)
inlineprivate

Lock 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.

Definition at line 405 of file MIDI_Pipes.hpp.

◆ lockSelf()

void lockSelf ( cn_t  cn,
bool  lock 
)
inlineprivate

Lock this pipe, so sources cannot send messages through it.

Definition at line 412 of file MIDI_Pipes.hpp.

◆ disconnect() [1/3]

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 the original sink and/or source respectively.

Definition at line 170 of file MIDI_Pipes.cpp.

◆ getFinalSink()

MIDI_Sink* getFinalSink ( )
inlineoverridevirtual

Get the sink this pipe eventually sinks to, following the chain recursively.

Reimplemented from MIDI_Sink.

Definition at line 422 of file MIDI_Pipes.hpp.

◆ getInitialSource()

MIDI_Source* getInitialSource ( )
inlineoverridevirtual

Get the original source that sources to this pipe, following the chain recursively.

Reimplemented from MIDI_Source.

Definition at line 427 of file MIDI_Pipes.hpp.

◆ disconnect() [2/3]

bool disconnect ( TrueMIDI_Sink sink)
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 435 of file MIDI_Pipes.hpp.

◆ disconnect() [3/3]

bool disconnect ( TrueMIDI_Source source)
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 450 of file MIDI_Pipes.hpp.

◆ getThroughOut()

MIDI_Pipe* getThroughOut ( )
inlineprotected

Definition at line 464 of file MIDI_Pipes.hpp.

◆ getThroughIn()

MIDI_Pipe* getThroughIn ( )
inlineprotected

Definition at line 465 of file MIDI_Pipes.hpp.

◆ getSource()

MIDI_Source* getSource ( )
inlineprotected

Definition at line 466 of file MIDI_Pipes.hpp.

◆ getSink()

MIDI_Sink* getSink ( )
inlineprotected

Definition at line 467 of file MIDI_Pipes.hpp.

◆ exclusive()

void exclusive ( cn_t  cn,
bool  exclusive = true 
)

Enter or exit exclusive mode for the given cable number.

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 exits exclusive mode until they can send again.

Parameters
cnCable number to set the exclusive mode for [0, 15].
exclusiveTrue to enable exclusive mode, false to disable.

Definition at line 201 of file MIDI_Pipes.cpp.

◆ isLocked()

bool isLocked ( cn_t  cn) const
inline

Check if this pipe is locked for a given cable number.

Definition at line 474 of file MIDI_Pipes.hpp.

◆ isAvailableForWrite()

bool isAvailableForWrite ( cn_t  cn) const
inline

Check if any of the sinks or outputs of this chain of pipes are locked for the given cable number.

Parameters
cnThe cable number to check.

Definition at line 482 of file MIDI_Pipes.hpp.

◆ connectSourcePipe()

void connectSourcePipe ( MIDI_Pipe source)
inherited

Fully connect a source pipe to this sink.

Definition at line 15 of file MIDI_Pipes.cpp.

◆ disconnectSourcePipes()

void disconnectSourcePipes ( )
inherited

Disconnect all source pipes that sink to this sink (recursively).

Definition at line 24 of file MIDI_Pipes.cpp.

◆ hasSourcePipe()

bool hasSourcePipe ( ) const
inlineinherited

Check if this sink is connected to a source pipe.

Definition at line 94 of file MIDI_Pipes.hpp.

◆ disconnectSourcePipesShallow()

void disconnectSourcePipesShallow ( )
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 32 of file MIDI_Pipes.cpp.

◆ sourceMIDItoPipe() [1/3]

void sourceMIDItoPipe ( ChannelMessage  msg)
inherited

Send a MIDI Channel Message.

Definition at line 132 of file MIDI_Pipes.cpp.

◆ sourceMIDItoPipe() [2/3]

void sourceMIDItoPipe ( SysExMessage  msg)
inherited

Send a MIDI System Exclusive message.

Definition at line 137 of file MIDI_Pipes.cpp.

◆ sourceMIDItoPipe() [3/3]

void sourceMIDItoPipe ( RealTimeMessage  msg)
inherited

Send a MIDI Real-Time message.

Definition at line 142 of file MIDI_Pipes.cpp.

◆ canWrite()

bool canWrite ( cn_t  cn) const
inherited

Check if this source can write to the sinks it connects to.

Returns false if any of the sinks have another source that is in exclusive mode.

Parameters
cnCable number to check [0, 15].

Definition at line 128 of file MIDI_Pipes.cpp.

◆ connectSinkPipe()

void connectSinkPipe ( MIDI_Pipe sink)
inherited

Fully connect a sink pipe to this source.

Definition at line 70 of file MIDI_Pipes.cpp.

◆ disconnectSinkPipes()

void disconnectSinkPipes ( )
inherited

Disconnect all sink pipes that this source sinks to (recursively).

Definition at line 79 of file MIDI_Pipes.cpp.

◆ hasSinkPipe()

bool hasSinkPipe ( ) const
inlineinherited

Check if this source is connected to a sink pipe.

Definition at line 189 of file MIDI_Pipes.hpp.

◆ disconnectSinkPipesShallow()

void disconnectSinkPipesShallow ( )
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 87 of file MIDI_Pipes.cpp.

Member Data Documentation

◆ sink

MIDI_Sink* sink = nullptr
private

Definition at line 488 of file MIDI_Pipes.hpp.

◆ source

MIDI_Source* source = nullptr
private

Definition at line 489 of file MIDI_Pipes.hpp.

◆ throughOut

MIDI_Pipe*& throughOut = MIDI_Source::sinkPipe
private

Definition at line 490 of file MIDI_Pipes.hpp.

◆ throughIn

MIDI_Pipe*& throughIn = MIDI_Sink::sourcePipe
private

Definition at line 491 of file MIDI_Pipes.hpp.

◆ locks

AH::BitArray<16> locks
private

Definition at line 492 of file MIDI_Pipes.hpp.

◆ sourcePipe

MIDI_Pipe* sourcePipe = nullptr
protectedinherited

Definition at line 117 of file MIDI_Pipes.hpp.

◆ sinkPipe

MIDI_Pipe* sinkPipe = nullptr
protectedinherited

Definition at line 209 of file MIDI_Pipes.hpp.


The documentation for this class was generated from the following files:
MIDI_Pipe::source
MIDI_Source * source
Definition: MIDI_Pipes.hpp:489
MIDI_Pipe::sink
MIDI_Sink * sink
Definition: MIDI_Pipes.hpp:488