3#include <Settings/SettingsWrapper.hpp>
7#include <AH/STL/cstdint>
8#include <AH/STL/limits>
9#include <AH/STL/utility>
11#include <Settings/NamespaceSettings.hpp>
17 reinterpret_cast<MIDIStaller *
>(std::numeric_limits<std::uintptr_t>::max());
520 template <
class Message>
531 template <
class Message>
658template <
size_t N,
class Pipe = MIDI_Pipe>
665 FATAL_ERROR(F(
"Not enough pipes available"), 0x2459);
676template <
size_t N,
class Pipe>
679 return source >> pipe_fact.
getNext();
682template <
size_t N,
class Pipe>
685template <
size_t N,
class Pipe>
688 return pipe_fact.
getNext() >> sink;
691template <
size_t N,
class Pipe>
694template <
size_t N,
class Pipe>
697 return sink << pipe_fact.
getNext();
700template <
size_t N,
class Pipe>
703 return pipe_fact.
getNext() << source;
710 return pipe_fact.
getNext() | sinksource;
717 return sinksource | pipe_fact.
getNext();
729 template <
class... Args>
730 void sourceMIDItoPipe(Args &&...) {}
MIDIStaller *const eternal_stall
#define BEGIN_CS_NAMESPACE
Class that routes MIDI messages from a MIDI_Source to a MIDI_Sink.
MIDI_Sink * getSink() const
Get the immediate sink of this pipe.
void acceptMIDIfromSource(Message msg)
Accept a MIDI message from the source, forward it to the “through” output if necessary,...
bool hasSink() const
Check if this pipe is connected to a sink.
void sourceMIDItoSink(Message msg)
Send the given MIDI message to the sink of this pipe.
const char * getStallerName() const
Get the name of any staller.
MIDI_Pipe(MIDI_Pipe &&)=delete
Move constructor.
MIDIStaller * getStaller() const
Get any staller: returns getSinkStaller() if it's not null, getThroughStaller() otherwise.
virtual void mapForwardMIDI(SysExMessage msg)
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
bool disconnect(MIDI_Pipe &)=delete
void connectSource(MIDI_Source *source)
Set the source pointer to point to the given source.
MIDI_Pipe(const MIDI_Pipe &)=delete
Copy constructor (copying not allowed).
virtual void mapForwardMIDI(RealTimeMessage msg)
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
void sinkMIDIfromPipe(SysCommonMessage msg) override
Called when data arrives from an upstream pipe connected to our “through” input, this function forwar...
virtual void mapForwardMIDI(SysCommonMessage msg)
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
void unstallDownstream(MIDIStaller *cause, MIDI_Source *stallsrc) override
Undoes the stalling by stallDownstream.
bool hasSource() const
Check if this pipe is connected to a source.
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 “throu...
MIDI_Pipe & operator=(MIDI_Pipe &&)=delete
Move assignment.
bool hasThroughOut() const
Check if this pipe has a “through” output that sends all incoming messages from the input (source) to...
MIDIStaller * getThroughStaller() const
Get the staller (cause of the stall) that causes the “through” output of this pipe to be stalled.
MIDIStaller * through_staller
void connectSink(MIDI_Sink *sink)
Set the sink pointer to point to the given sink.
const char * getSinkStallerName() const
Get the name of the staller (cause of the stall) that causes the sink of this pipe to be stalled.
MIDI_Pipe * getThroughOut() const
Get the pipe connected to the “through” output of this pipe.
MIDI_Pipe & operator=(const MIDI_Pipe &)=delete
Copy assignment (copying not allowed).
void sinkMIDIfromPipe(RealTimeMessage msg) override
Called when data arrives from an upstream pipe connected to our “through” input, this function forwar...
bool isStalled() const
Check if this pipe is stalled.
MIDIStaller * sink_staller
virtual ~MIDI_Pipe()
Destructor.
const char * getThroughStallerName() const
Get the name of the staller (cause of the stall) that causes the “through” output of this pipe to be ...
void unstallUpstream(MIDIStaller *cause, MIDI_Sink *stallsrc) override
Undoes the stalling by stallUpstream.
void disconnect()
Disconnect this pipe from all other pipes, sources and sinks.
bool disconnect(TrueMIDI_Sink &sink)
Disconnect the given sink from this pipe.
void sinkMIDIfromPipe(ChannelMessage msg) override
Called when data arrives from an upstream pipe connected to our “through” input, this function forwar...
virtual void mapForwardMIDI(ChannelMessage msg)
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
MIDI_Sink * getFinalSink() override
Get the sink this pipe eventually sinks to, following the chain recursively.
void handleStallers() const
Give the code that is stalling the MIDI pipe the opportunity to do its job and unstall the pipe.
MIDI_Source * getSource() const
Get the immediate source of this pipe.
void disconnectSink()
Set the sink pointer to null.
MIDIStaller * getSinkStaller() const
Get the staller (cause of the stall) that causes the sink of this pipe to be stalled.
bool hasThroughIn() const
Check if this pipe has a “through” input that merges all messages from another pipe into the output (...
MIDI_Pipe()=default
Default constructor.
bool throughIsUnstalledOrStalledBy(MIDIStaller *cause)
Returns true if this pipe is either not stalled at all, or if the pipe is stalled by the given stalle...
void disconnectSource()
Set the source pointer to null.
bool disconnect(TrueMIDI_Source &source)
Disconnect the given source from this pipe.
MIDI_Source * getInitialSource() override
Get the original source that sources to this pipe, following the chain recursively.
bool sinkIsUnstalledOrStalledBy(MIDIStaller *cause)
Returns true if this pipe is either not stalled at all, or if the pipe is stalled by the given stalle...
void sinkMIDIfromPipe(SysExMessage msg) override
Called when data arrives from an upstream pipe connected to our “through” input, this function forwar...
void stallUpstream(MIDIStaller *cause, MIDI_Sink *stallsrc) override
Stall this pipe and all other pipes further upstream (following the path of the "trough" input).
MIDI_Pipe * getThroughIn() const
Get the pipe connected to the “through” input of this pipe.
Receives MIDI messages from a MIDI pipe.
virtual void sinkMIDIfromPipe(RealTimeMessage)=0
Accept an incoming MIDI Real-Time message.
void connectSourcePipe(MIDI_Pipe *source)
Fully connect a source pipe to this sink.
virtual void stallDownstream(MIDIStaller *, MIDI_Source *)
Base case for recursive stall function.
bool disconnect(MIDI_Pipe &)=delete
virtual ~MIDI_Sink()
Destructor.
MIDI_Sink(const MIDI_Sink &)=delete
Copy constructor (copying not allowed).
friend void swap(MIDI_Sink &a, MIDI_Sink &b)
virtual void unstallDownstream(MIDIStaller *, MIDI_Source *)
Base case for recursive un-stall function.
virtual void sinkMIDIfromPipe(SysCommonMessage)=0
Accept an incoming MIDI System Common message.
MIDI_Sink()=default
Default constructor.
MIDI_Pipe * getSourcePipe() const
Get a pointer to the pipe this sink is connected to, or nullptr if not connected.
virtual MIDI_Sink * getFinalSink()
Base case for recursive function.
void disconnectSourcePipes()
Disconnect all source pipes that sink to this sink (recursively).
virtual void sinkMIDIfromPipe(ChannelMessage)=0
Accept an incoming MIDI Channel message.
void disconnectSourcePipesShallow()
Disconnect only the first pipe connected to this sink.
bool disconnect(TrueMIDI_Source &source)
Disconnect the given source from this sink.
virtual void sinkMIDIfromPipe(SysExMessage)=0
Accept an incoming MIDI System Exclusive message.
bool hasSourcePipe() const
Check if this sink is connected to a source pipe.
MIDI_Sink & operator=(const MIDI_Sink &)=delete
Copy assignment (copying not allowed).
Class that can send MIDI messages to a MIDI pipe.
MIDI_Pipe * getSinkPipe()
Get a pointer to the pipe this source is connected to, or nullptr if not connected.
virtual MIDI_Source * getInitialSource()
Base case for recursive function.
const char * getStallerName() const
Get the name of whatever is causing this MIDI source to be stalled.
void connectSinkPipe(MIDI_Pipe *sink)
Fully connect a sink pipe to this source.
virtual ~MIDI_Source()
Destructor.
MIDIStaller * getStaller() const
Get a pointer to whatever is causing this MIDI source to be stalled.
bool disconnect(MIDI_Pipe &)=delete
MIDI_Source()=default
Default constructor.
void sourceMIDItoPipe(ChannelMessage)
Send a MIDI Channel Message down the pipe.
void stall(MIDIStaller *cause=eternal_stall)
Stall this MIDI source.
virtual void stallUpstream(MIDIStaller *, MIDI_Sink *)
Base case for recursive stall function.
bool isStalled() const
Check if this source can write to the sinks it connects to.
friend void swap(MIDI_Source &a, MIDI_Source &b)
void disconnectSinkPipesShallow()
Disconnect only the first pipe connected to this source.
bool disconnect(TrueMIDI_Sink &sink)
Disconnect the given sink from this source.
void disconnectSinkPipes()
Disconnect all sink pipes that this source sinks to (recursively).
MIDI_Source & operator=(const MIDI_Source &)=delete
Copy assignment (copying not allowed).
void handleStallers() const
Give the code that is stalling the MIDI sink pipes the opportunity to do its job and un-stall the pip...
virtual void unstallUpstream(MIDIStaller *, MIDI_Sink *)
Base case for recursive un-stall function.
MIDI_Source(const MIDI_Source &)=delete
Copy constructor (copying not allowed).
bool hasSinkPipe() const
Check if this source is connected to a sink pipe.
void unstall(MIDIStaller *cause=eternal_stall)
Un-stall the pipes connected to this source, so other sources are allowed to send again.
#define FATAL_ERROR(msg, errc)
Print the error message and error code, and stop the execution.
TrueMIDI_SinkSource & operator|(BidirectionalMIDI_Pipe &pipe, TrueMIDI_SinkSource &sinksource)
Connect a pipe to a sink+source (pipe | source+sink).
std::pair< MIDI_Pipe, MIDI_Pipe > BidirectionalMIDI_Pipe
A bidirectional pipe consists of two unidirectional pipes.
MIDI_Pipe & operator>>(TrueMIDI_Source &source, MIDI_Pipe &pipe)
Connect a source to a pipe (source >> pipe).
MIDI_Pipe & operator<<(TrueMIDI_Sink &sink, MIDI_Pipe &pipe)
Connect a sink to a pipe (sink << pipe).
Struct that can cause a MIDI_Pipe to be stalled.
Class that produces multiple MIDI_Pipes.
Pipe & operator[](size_t i)
const Pipe & operator[](size_t i) const
A struct that is both a TrueMIDI_Sink and a TrueMIDI_Source.