midi_input_stream
Overview
The midi_input_stream
class facilitates MIDI communication and data transmission of MIDI messages between a MIDI device and an application.
midi_input_stream
dispatches MIDI messages to a MIDI processor: a user-defined construct that follows a specific C++ concept for receiving and interpreting MIDI messages. The MIDI processor acts as an intermediary between MIDI devices and the application. Its purpose is to receive incoming MIDI messages, analyze their content, and extract relevant information. This may include extracting note data, control change values, program change commands, or any other MIDI message content that is of interest to the user. See MIDI Processor
Declaration
class midi_input_stream : non_copyable
{
public:
midi_input_stream();
midi_input_stream(midi_device const& device);
~midi_input_stream();
bool is_valid() const;
template <typename Processor>
requires concepts::midi_1_0::Processor<P>
void process(Processor&& proc);
static void set_default_device(int id);
};
Expressions
Notation
ms
-
Object of type
midi_input_stream
. md
-
Object of type
midi_device
. id
-
A unique MIDI device ID (integer).
proc
-
Object that conforms to the
MIDI Processor
concept.
Constructors
Expression | Semantics |
---|---|
|
Construct a default |
|
Construct a |
Take note that midi_input_stream
is non-copyable.
Default MIDI device
Expression | Semantics |
---|---|
|
Set the default |
Accessor
Expression | Semantics | Return Type |
---|---|---|
|
Check if the |
|
Process MIDI
Expression | Semantics |
---|---|
|
Process incoming MIDI messages, given a user provided MIDI processor |
Call this function in a loop while to process incoming MIDI messages. This function blocks. It is advisable to place this processing loop in a separate thread.
Example
Monitor incoming MIDI messages:
q::midi_input_stream stream; (1)
if (stream.is_valid()) (2)
{
while (true) (3)
stream.process(midi_processor{}); (4)
}
1 | Instantiate a default MIDI stream. |
2 | Check if the MIDI stream is valid. |
3 | Infinite loop, processing incoming MIDI messages from the stream . |
4 | midi_processor is a user defined struct implemented below. |
struct midi_processor : midi::processor
{
using midi::processor::operator();
void operator()(midi::note_on msg, std::size_t time)
{
std::cout
<< "Note On {"
<< "Channel: " << int(msg.channel())
<< ", Key: " << int(msg.key())
<< ", Velocity: " << int(msg.velocity())
<< '}' << std::endl;
}
void operator()(midi::note_off msg, std::size_t time)
{
std::cout
<< "Note Off {"
<< "Channel: " << int(msg.channel())
<< ", Key: " << int(msg.key())
<< ", Velocity: " << int(msg.velocity())
<< '}' << std::endl;
}
void operator()(midi::poly_aftertouch msg, std::size_t time)
{
std::cout
<< "Polyphonic Aftertouch {"
<< "Channel: " << int(msg.channel())
<< ", Key: " << int(msg.key())
<< ", Pressure: " << int(msg.pressure())
<< '}' << std::endl;
}
void operator()(midi::control_change msg, std::size_t time)
{
std::cout
<< "Control Change {"
<< "Channel: " << int(msg.channel())
<< ", Controller: " << int(msg.controller())
<< ", Value: " << int(msg.value())
<< '}' << std::endl;
}
void operator()(midi::program_change msg, std::size_t time)
{
std::cout
<< "Program Change {"
<< "Channel: " << int(msg.channel())
<< ", Preset: " << int(msg.preset())
<< '}' << std::endl;
}
void operator()(midi::channel_aftertouch msg, std::size_t time)
{
std::cout
<< "Channel Aftertouch {"
<< "Channel: " << int(msg.channel())
<< ", Pressure: " << int(msg.pressure())
<< '}' << std::endl;
}
void operator()(midi::pitch_bend msg, std::size_t time)
{
std::cout
<< "Pitch Bend {"
<< "Channel: " << int(msg.channel())
<< ", Value: " << int(msg.value())
<< '}' << std::endl;
}
};