Control Surface  1.2.0
MIDI Control Surface library for Arduino
MIDI_Pipes.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 #include <AH/STL/utility>
7 #include <Settings/NamespaceSettings.hpp>
8 
10 
12 
14 using cn_t = uint8_t;
15 
46 class MIDI_Pipe;
47 struct TrueMIDI_Sink;
48 struct TrueMIDI_Source;
49 
51 class MIDI_Sink {
52  public:
54  MIDI_Sink() = default;
55 
57  MIDI_Sink(const MIDI_Sink &) = delete;
59  MIDI_Sink &operator=(const MIDI_Sink &) = delete;
60 
62  MIDI_Sink(MIDI_Sink &&other);
64  MIDI_Sink &operator=(MIDI_Sink &&other);
65 
67  virtual ~MIDI_Sink();
68 
71 
73  virtual void sinkMIDIfromPipe(ChannelMessage) = 0;
75  virtual void sinkMIDIfromPipe(SysExMessage) = 0;
77  virtual void sinkMIDIfromPipe(RealTimeMessage) = 0;
78 
80 
83 
85  void connectSourcePipe(MIDI_Pipe *source);
87  void disconnectSourcePipes();
92  bool disconnect(TrueMIDI_Source &source);
94  bool hasSourcePipe() const { return sourcePipe != nullptr; }
95 
96 #ifndef ARDUINO
97  MIDI_Pipe *getSourcePipe() { return sourcePipe; }
98 #endif
99 
101 
102  private:
105  virtual void lockDownstream(cn_t cn, bool lock) { (void)cn, (void)lock; }
108  virtual MIDI_Sink *getFinalSink() { return this; }
114  void disconnectSourcePipesShallow();
115 
116  protected:
117  MIDI_Pipe *sourcePipe = nullptr;
118 
119  friend class MIDI_Pipe;
120 };
121 
122 // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
123 
125 class MIDI_Source {
126  public:
129 
136 
148  void exclusive(cn_t cn, bool exclusive = true);
156  bool canWrite(cn_t cn) const;
157 
159 
161  MIDI_Source() = default;
162 
164  MIDI_Source(const MIDI_Source &) = delete;
166  MIDI_Source &operator=(const MIDI_Source &) = delete;
167 
169  MIDI_Source(MIDI_Source &&other);
172 
174  virtual ~MIDI_Source();
175 
178 
180  void connectSinkPipe(MIDI_Pipe *sink);
182  void disconnectSinkPipes();
187  bool disconnect(TrueMIDI_Sink &sink);
189  bool hasSinkPipe() const { return sinkPipe != nullptr; }
190 
191 #ifndef ARDUINO
192  MIDI_Pipe *getSinkPipe() { return sinkPipe; }
193 #endif
194 
196 
197  private:
200  virtual MIDI_Source *getInitialSource() { return this; }
207 
208  protected:
209  MIDI_Pipe *sinkPipe = nullptr;
210 
211  friend class MIDI_Pipe;
212 };
213 
214 // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
215 
220 
221 // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
222 
270 class MIDI_Pipe : private MIDI_Sink, private MIDI_Source {
271  public:
273  MIDI_Pipe() = default;
274 
276  MIDI_Pipe(const MIDI_Pipe &) = delete;
278  MIDI_Pipe &operator=(const MIDI_Pipe &) = delete;
279 
282  MIDI_Pipe(MIDI_Pipe &&) = delete;
286 
288  virtual ~MIDI_Pipe();
289 
290  private:
293  void connectSink(MIDI_Sink *sink);
296  void disconnectSink();
302  void disconnectSource();
303 
304  public:
306  bool hasSink() const { return sink != nullptr; }
308  bool hasSource() const { return source != nullptr; }
311  bool hasThroughOut() const { return throughOut != nullptr; }
314  bool hasThroughIn() const { return throughIn != nullptr; }
315 
316  protected:
321  // Forward
322  if (hasThroughOut())
323  throughOut->pipeMIDI(msg);
324  mapForwardMIDI(msg);
325  }
327  void pipeMIDI(SysExMessage msg) {
328  if (hasThroughOut())
329  throughOut->pipeMIDI(msg);
330  mapForwardMIDI(msg);
331  }
334  if (hasThroughOut())
335  throughOut->pipeMIDI(msg);
336  mapForwardMIDI(msg);
337  }
338 
339  protected:
342  if (hasSink())
343  sink->sinkMIDIfromPipe(msg);
344  }
345 
348  if (hasSink())
349  sink->sinkMIDIfromPipe(msg);
350  }
351 
354  if (hasSink())
355  sink->sinkMIDIfromPipe(msg);
356  }
357 
358  private:
361  virtual void mapForwardMIDI(ChannelMessage msg) {
362  // Optionally edit the message before passing it on
363  sourceMIDItoSink(msg);
364  }
365 
367  virtual void mapForwardMIDI(SysExMessage msg) {
368  // Optionally edit the message before passing it on
369  sourceMIDItoSink(msg);
370  }
371 
373  virtual void mapForwardMIDI(RealTimeMessage msg) {
374  // Optionally edit the message before passing it on
375  sourceMIDItoSink(msg);
376  }
377 
378  private:
379  void sinkMIDIfromPipe(ChannelMessage msg) override {
380  // Called when data from Through In arrives, forward it to the sink
381  sourceMIDItoSink(msg);
382  }
383  void sinkMIDIfromPipe(SysExMessage msg) override {
384  // Called when data from Through In arrives, forward it to the sink
385  sourceMIDItoSink(msg);
386  }
387  void sinkMIDIfromPipe(RealTimeMessage msg) override {
388  // Called when data from Through In arrives, forward it to the sink
389  sourceMIDItoSink(msg);
390  }
391 
392  private:
396  void lockDownstream(cn_t cn, bool lock) override {
397  lockSelf(cn, lock);
398  if (hasSink())
399  sink->lockDownstream(cn, lock);
400  }
401 
405  void lockUpstream(cn_t cn, bool lock) {
406  lockSelf(cn, lock);
407  if (hasThroughIn())
408  throughIn->lockUpstream(cn, lock);
409  }
410 
412  void lockSelf(cn_t cn, bool lock) { locks.set(cn, lock); }
413 
414  public:
418  void disconnect();
419 
422  MIDI_Sink *getFinalSink() override {
423  return hasSink() ? sink->getFinalSink() : nullptr;
424  }
428  return hasSource() ? source->getInitialSource() : nullptr;
429  }
430 
436  if (getFinalSink() == &sink) {
437  disconnect();
438  return true;
439  }
440  if (hasThroughOut()) {
441  return throughOut->disconnect(sink);
442  }
443  return false;
444  }
445 
451  if (getInitialSource() == &source) {
452  disconnect();
453  return true;
454  }
455  if (hasThroughIn()) {
456  return throughIn->disconnect(source);
457  }
458  return false;
459  }
460 
461 #ifdef ARDUINO
462  protected:
463 #endif
466  MIDI_Source *getSource() { return source; }
467  MIDI_Sink *getSink() { return sink; }
468 
469  public:
471  void exclusive(cn_t cn, bool exclusive = true);
472 
474  bool isLocked(cn_t cn) const { return locks.get(cn); }
475 
482  bool isAvailableForWrite(cn_t cn) const {
483  return !isLocked(cn) &&
485  }
486 
487  private:
488  MIDI_Sink *sink = nullptr;
489  MIDI_Source *source = nullptr;
493 
494  friend class MIDI_Sink;
495  friend class MIDI_Source;
496 };
497 
498 // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
499 
502 
504 using BidirectionalMIDI_Pipe = std::pair<MIDI_Pipe, MIDI_Pipe>;
505 
508  source.connectSinkPipe(&pipe);
509  return pipe;
510 }
511 
514  sink.connectSourcePipe(&pipe);
515  return sink;
516 }
517 
520  sink.connectSourcePipe(&pipe);
521  return pipe;
522 }
523 
526  source.connectSinkPipe(&pipe);
527  return source;
528 }
529 
532  TrueMIDI_SinkSource &sinksource) {
533  sinksource.connectSinkPipe(&pipe.first);
534  sinksource.connectSourcePipe(&pipe.second);
535  return sinksource;
536 }
537 
540  BidirectionalMIDI_Pipe &pipe) {
541  sinksource.connectSinkPipe(&pipe.second);
542  sinksource.connectSourcePipe(&pipe.first);
543  return pipe;
544 }
545 
546 // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //
547 
556 template <size_t N, class Pipe = MIDI_Pipe>
558  Pipe pipes[N];
559  size_t index = 0;
560 
561  Pipe &getNext() {
562  if (index >= N)
563  FATAL_ERROR(F("Not enough pipes available"), 0x2459);
564  return pipes[index++];
565  }
566  Pipe &operator[](size_t i) { return pipes[i]; }
567  const Pipe &operator[](size_t i) const { return pipes[i]; }
568 };
569 
570 template <size_t N>
573 
574 template <size_t N, class Pipe>
576  MIDI_PipeFactory<N, Pipe> &pipe_fact) {
577  return source >> pipe_fact.getNext();
578 }
579 
580 template <size_t N, class Pipe>
582  TrueMIDI_Sink &sink) {
583  return pipe_fact.getNext() >> sink;
584 }
585 
586 template <size_t N, class Pipe>
588  MIDI_PipeFactory<N, Pipe> &pipe_fact) {
589  return sink << pipe_fact.getNext();
590 }
591 
592 template <size_t N, class Pipe>
594  TrueMIDI_Source &source) {
595  return pipe_fact.getNext() << source;
596 }
597 
598 template <size_t N>
599 inline TrueMIDI_SinkSource &
601  TrueMIDI_SinkSource &sinksource) {
602  return pipe_fact.getNext() | sinksource;
603 }
604 
605 template <size_t N>
606 inline BidirectionalMIDI_Pipe &
609  return sinksource | pipe_fact.getNext();
610 }
611 
613 
615 
MIDI_Source::connectSinkPipe
void connectSinkPipe(MIDI_Pipe *sink)
Fully connect a sink pipe to this source.
Definition: MIDI_Pipes.cpp:70
MIDI_Pipe::isLocked
bool isLocked(cn_t cn) const
Check if this pipe is locked for a given cable number.
Definition: MIDI_Pipes.hpp:474
MIDI_Pipe::sourceMIDItoSink
void sourceMIDItoSink(SysExMessage msg)
Send the given MIDI message to the sink of this pipe.
Definition: MIDI_Pipes.hpp:347
MIDI_Pipe::pipeMIDI
void pipeMIDI(RealTimeMessage msg)
Accept a MIDI message from the source, forward it to the "through" output if necessary,...
Definition: MIDI_Pipes.hpp:333
MIDI_Pipe
Class that routes MIDI messages from a MIDI_Source to a MIDI_Sink.
Definition: MIDI_Pipes.hpp:270
MIDI_Pipe::mapForwardMIDI
virtual void mapForwardMIDI(RealTimeMessage msg)
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
Definition: MIDI_Pipes.hpp:373
MIDI_Pipe::source
MIDI_Source * source
Definition: MIDI_Pipes.hpp:489
MIDI_Pipe::~MIDI_Pipe
virtual ~MIDI_Pipe()
Destructor.
Definition: MIDI_Pipes.cpp:195
MIDI_Source
Class that can send MIDI messages to a MIDI pipe.
Definition: MIDI_Pipes.hpp:125
Warnings.hpp
TrueMIDI_Source
A MIDI_Source that is not a MIDI_Pipe.
Definition: MIDI_Pipes.hpp:219
MIDI_Source::MIDI_Source
MIDI_Source()=default
Default constructor.
SysExMessage
Definition: MIDI_MessageTypes.hpp:138
MIDI_Source::MIDI_Source
MIDI_Source(const MIDI_Source &)=delete
Copy constructor (copying not allowed).
MIDI_Pipe::sinkMIDIfromPipe
void sinkMIDIfromPipe(SysExMessage msg) override
Accept an incoming MIDI System Exclusive message.
Definition: MIDI_Pipes.hpp:383
MIDI_Pipe::throughIn
MIDI_Pipe *& throughIn
Definition: MIDI_Pipes.hpp:491
MIDI_Pipe::getFinalSink
MIDI_Sink * getFinalSink() override
Get the sink this pipe eventually sinks to, following the chain recursively.
Definition: MIDI_Pipes.hpp:422
MIDI_Pipe::hasThroughOut
bool hasThroughOut() const
Check if this pipe has a "through" output that sends all incoming messages from the input (source) to...
Definition: MIDI_Pipes.hpp:311
MIDI_Pipe::MIDI_Pipe
MIDI_Pipe()=default
Default constructor.
MIDI_Pipe::connectSource
void connectSource(MIDI_Source *source)
Set the source pointer to point to the given source.
Definition: MIDI_Pipes.cpp:160
MIDI_Pipe::getSource
MIDI_Source * getSource()
Definition: MIDI_Pipes.hpp:466
MIDI_Sink::sinkMIDIfromPipe
virtual void sinkMIDIfromPipe(RealTimeMessage)=0
Accept an incoming MIDI Real-Time message.
MIDI_Source::hasSinkPipe
bool hasSinkPipe() const
Check if this source is connected to a sink pipe.
Definition: MIDI_Pipes.hpp:189
MIDI_Pipe::sourceMIDItoSink
void sourceMIDItoSink(ChannelMessage msg)
Send the given MIDI message to the sink of this pipe.
Definition: MIDI_Pipes.hpp:341
MIDI_Pipe::throughOut
MIDI_Pipe *& throughOut
Definition: MIDI_Pipes.hpp:490
MIDI_Pipe::isAvailableForWrite
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.
Definition: MIDI_Pipes.hpp:482
MIDI_Sink::getFinalSink
virtual MIDI_Sink * getFinalSink()
Base case for recursive function.
Definition: MIDI_Pipes.hpp:108
MIDI_Sink::MIDI_Sink
MIDI_Sink()=default
Default constructor.
MIDI_PipeFactory
Class that produces multiple MIDI_Pipes.
Definition: MIDI_Pipes.hpp:557
MIDI_Pipe::disconnectSource
void disconnectSource()
Set the source pointer to null.
Definition: MIDI_Pipes.cpp:168
MIDI_Pipe::sourceMIDItoSink
void sourceMIDItoSink(RealTimeMessage msg)
Send the given MIDI message to the sink of this pipe.
Definition: MIDI_Pipes.hpp:353
MIDI_PipeFactory::index
size_t index
Definition: MIDI_Pipes.hpp:559
BitArray.hpp
MIDI_Pipe::sinkMIDIfromPipe
void sinkMIDIfromPipe(ChannelMessage msg) override
Accept an incoming MIDI Channel message.
Definition: MIDI_Pipes.hpp:379
MIDI_PipeFactory::operator[]
const Pipe & operator[](size_t i) const
Definition: MIDI_Pipes.hpp:567
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
MIDI_Pipe::sinkMIDIfromPipe
void sinkMIDIfromPipe(RealTimeMessage msg) override
Accept an incoming MIDI Real-Time message.
Definition: MIDI_Pipes.hpp:387
AH_DIAGNOSTIC_POP
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:36
MIDI_Source::operator=
MIDI_Source & operator=(const MIDI_Source &)=delete
Copy assignment (copying not allowed).
MIDI_Source::disconnectSinkPipes
void disconnectSinkPipes()
Disconnect all sink pipes that this source sinks to (recursively).
Definition: MIDI_Pipes.cpp:79
AH::BitArray::set
void set(uint8_t bitIndex)
Set the value of the given bit to 1.
Definition: BitArray.hpp:43
MIDI_Pipe::operator=
MIDI_Pipe & operator=(const MIDI_Pipe &)=delete
Copy assignment (copying not allowed).
MIDI_Pipe::pipeMIDI
void pipeMIDI(ChannelMessage msg)
Accept a MIDI message from the source, forward it to the "through" output if necessary,...
Definition: MIDI_Pipes.hpp:320
MIDI_Sink::hasSourcePipe
bool hasSourcePipe() const
Check if this sink is connected to a source pipe.
Definition: MIDI_Pipes.hpp:94
FATAL_ERROR
#define FATAL_ERROR(msg, errc)
Print the error message and error code, and stop the execution.
Definition: Error.hpp:60
MIDI_Sink::sourcePipe
MIDI_Pipe * sourcePipe
Definition: MIDI_Pipes.hpp:117
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
MIDI_Pipe::lockDownstream
void lockDownstream(cn_t cn, bool lock) override
Lock this pipe and all other pipes further downstream (following the path of the sink).
Definition: MIDI_Pipes.hpp:396
MIDI_Pipe::operator=
MIDI_Pipe & operator=(MIDI_Pipe &&)=delete
Move assignment.
AH::BitArray::get
bool get(uint8_t bitIndex) const
Get the value of the given bit.
Definition: BitArray.hpp:33
MIDI_Pipe::MIDI_Pipe
MIDI_Pipe(MIDI_Pipe &&)=delete
Move constructor.
TrueMIDI_Sink
A MIDI_Sink that is not a MIDI_Pipe.
Definition: MIDI_Pipes.hpp:217
MIDI_Pipe::mapForwardMIDI
virtual void mapForwardMIDI(SysExMessage msg)
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
Definition: MIDI_Pipes.hpp:367
TrueMIDI_SinkSource
A struct that is both a TrueMIDI_Sink and a TrueMIDI_Source.
Definition: MIDI_Pipes.hpp:501
MIDI_Sink::sinkMIDIfromPipe
virtual void sinkMIDIfromPipe(ChannelMessage)=0
Accept an incoming MIDI Channel message.
MIDI_Sink::lockDownstream
virtual void lockDownstream(cn_t cn, bool lock)
Base case for recursive lock function.
Definition: MIDI_Pipes.hpp:105
MIDI_Pipe::lockUpstream
void lockUpstream(cn_t cn, bool lock)
Lock this pipe and all other pipes further upstream (following the path of the "trough" input).
Definition: MIDI_Pipes.hpp:405
MIDI_Pipe::getThroughOut
MIDI_Pipe * getThroughOut()
Definition: MIDI_Pipes.hpp:464
MIDI_Pipe::pipeMIDI
void pipeMIDI(SysExMessage msg)
Accept a MIDI message from the source, forward it to the "through" output if necessary,...
Definition: MIDI_Pipes.hpp:327
MIDI_Source::sinkPipe
MIDI_Pipe * sinkPipe
Definition: MIDI_Pipes.hpp:209
MIDI_Source::sourceMIDItoPipe
void sourceMIDItoPipe(ChannelMessage)
Send a MIDI Channel Message.
Definition: MIDI_Pipes.cpp:132
MIDI_PipeFactory::pipes
Pipe pipes[N]
Definition: MIDI_Pipes.hpp:558
RealTimeMessage
Definition: MIDI_MessageTypes.hpp:173
MIDI_Source::disconnectSinkPipesShallow
void disconnectSinkPipesShallow()
Disconnect only the first pipe connected to this source.
Definition: MIDI_Pipes.cpp:87
MIDI_PipeFactory::operator[]
Pipe & operator[](size_t i)
Definition: MIDI_Pipes.hpp:566
MIDI_Sink::sinkMIDIfromPipe
virtual void sinkMIDIfromPipe(SysExMessage)=0
Accept an incoming MIDI System Exclusive message.
operator|
TrueMIDI_SinkSource & operator|(BidirectionalMIDI_Pipe &pipe, TrueMIDI_SinkSource &sinksource)
Connect a pipe to a sink+source (pipe | source+sink).
Definition: MIDI_Pipes.hpp:531
MIDI_Sink::connectSourcePipe
void connectSourcePipe(MIDI_Pipe *source)
Fully connect a source pipe to this sink.
Definition: MIDI_Pipes.cpp:15
MIDI_Sink::operator=
MIDI_Sink & operator=(const MIDI_Sink &)=delete
Copy assignment (copying not allowed).
MIDI_Pipe::hasSource
bool hasSource() const
Check if this pipe is connected to a source.
Definition: MIDI_Pipes.hpp:308
MIDI_Pipe::hasSink
bool hasSink() const
Check if this pipe is connected to a sink.
Definition: MIDI_Pipes.hpp:306
MIDI_Pipe::mapForwardMIDI
virtual void mapForwardMIDI(ChannelMessage msg)
Function that maps, edits or filters MIDI messages, and then forwards them to the sink of the pipe.
Definition: MIDI_Pipes.hpp:361
MIDI_Source::exclusive
void exclusive(cn_t cn, bool exclusive=true)
Enter or exit exclusive mode for the given cable number.
Definition: MIDI_Pipes.cpp:123
MIDI_PipeFactory::getNext
Pipe & getNext()
Definition: MIDI_Pipes.hpp:561
MIDI_Source::getInitialSource
virtual MIDI_Source * getInitialSource()
Base case for recursive function.
Definition: MIDI_Pipes.hpp:200
cn_t
uint8_t cn_t
Data type for cable numbers.
Definition: MIDI_Pipes.hpp:14
MIDI_Notes::F
constexpr int8_t F
Definition: Notes.hpp:23
MIDI_Pipe::disconnect
bool disconnect(TrueMIDI_Sink &sink)
Disconnect the given sink from this pipe.
Definition: MIDI_Pipes.hpp:435
MIDI_Source::canWrite
bool canWrite(cn_t cn) const
Check if this source can write to the sinks it connects to.
Definition: MIDI_Pipes.cpp:128
operator>>
MIDI_Pipe & operator>>(TrueMIDI_Source &source, MIDI_Pipe &pipe)
Connect a source to a pipe (source >> pipe).
Definition: MIDI_Pipes.hpp:507
MIDI_Source::~MIDI_Source
virtual ~MIDI_Source()
Destructor.
Definition: MIDI_Pipes.cpp:121
MIDI_Pipe::locks
AH::BitArray< 16 > locks
Definition: MIDI_Pipes.hpp:492
AH_DIAGNOSTIC_WERROR
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:35
ChannelMessage
Definition: MIDI_MessageTypes.hpp:72
MIDI_Pipe::disconnect
void disconnect()
Disconnect this pipe from all other pipes, sources and sinks.
Definition: MIDI_Pipes.cpp:170
MIDI_Pipe::getSink
MIDI_Sink * getSink()
Definition: MIDI_Pipes.hpp:467
MIDI_Pipe::MIDI_Pipe
MIDI_Pipe(const MIDI_Pipe &)=delete
Copy constructor (copying not allowed).
MIDI_Sink
Class that can receive MIDI messages from a MIDI pipe.
Definition: MIDI_Pipes.hpp:51
MIDI_MessageTypes.hpp
MIDI_Pipe::disconnectSink
void disconnectSink()
Set the sink pointer to null.
Definition: MIDI_Pipes.cpp:158
MIDI_Pipe::getInitialSource
MIDI_Source * getInitialSource() override
Get the original source that sources to this pipe, following the chain recursively.
Definition: MIDI_Pipes.hpp:427
AH::BitArray< 16 >
MIDI_Source::disconnect
bool disconnect(TrueMIDI_Sink &sink)
Disconnect the given sink from this source.
Definition: MIDI_Pipes.cpp:94
MIDI_Pipe::disconnect
bool disconnect(TrueMIDI_Source &source)
Disconnect the given source from this pipe.
Definition: MIDI_Pipes.hpp:450
AH::Quaternion::operator<<
Print & operator<<(Print &os, Quaternion e)
Printing.
Definition: Quaternion.cpp:28
MIDI_Pipe::getThroughIn
MIDI_Pipe * getThroughIn()
Definition: MIDI_Pipes.hpp:465
MIDI_Pipe::connectSink
void connectSink(MIDI_Sink *sink)
Set the sink pointer to point to the given sink.
Definition: MIDI_Pipes.cpp:150
MIDI_Pipe::sink
MIDI_Sink * sink
Definition: MIDI_Pipes.hpp:488
BidirectionalMIDI_Pipe
std::pair< MIDI_Pipe, MIDI_Pipe > BidirectionalMIDI_Pipe
A bidirectional pipe consists of two unidirectional pipes.
Definition: MIDI_Pipes.hpp:504
MIDI_Pipe::lockSelf
void lockSelf(cn_t cn, bool lock)
Lock this pipe, so sources cannot send messages through it.
Definition: MIDI_Pipes.hpp:412
MIDI_Pipe::hasThroughIn
bool hasThroughIn() const
Check if this pipe has a "through" input that merges all messages from another pipe into the output (...
Definition: MIDI_Pipes.hpp:314
MIDI_Sink::MIDI_Sink
MIDI_Sink(const MIDI_Sink &)=delete
Copy constructor (copying not allowed).
MIDI_Pipe::exclusive
void exclusive(cn_t cn, bool exclusive=true)
Enter or exit exclusive mode for the given cable number.
Definition: MIDI_Pipes.cpp:201