Stream Messages
January 31, 2026 ยท View on GitHub
Code examples can be found in stream_message.examples.cpp.
Message Creation
Stream Messages are represented by a
struct stream_message : universal_packet
{
stream_message(status_t, packet_format = packet_format::complete);
packet_format format();
void set_format(packet_format);
};
Instead of using stream_message constructors one can create messages using factory functions:
Endpoint Discovery
stream_message make_endpoint_discovery_message(
uint8_t filter, uint8_t ump_version_major = 1, uint8_t ump_version_minor = 1);
stream_message make_endpoint_info_message(
uint8_t num_function_blocks, bool static_function_blocks,
uint8_t protocols, uint8_t extensions,
uint8_t ump_version_major = 1, uint8_t ump_version_minor = 1);
stream_message make_device_identity_message(const device_identity&);
stream_message make_endpoint_name_message(packet_format, const std::string_view&);
stream_message make_product_instance_id_message(packet_format, const std::string_view&);
For the filter parameter of the Endpoint Discovery message use any combination of
namespace discovery_filter {
constexpr uint8_t endpoint_info = 0b00001;
constexpr uint8_t device_identity = 0b00010;
constexpr uint8_t endpoint_name = 0b00100;
constexpr uint8_t product_instance_id = 0b01000;
constexpr uint8_t stream_configuration = 0b10000;
}
or discovery_filter::endpoint_all (0b11111) to request all available infomation.
protocols can be any combination of protocol::midi1 and protocol::midi2, extensions can be any combination of jitter_reduction_transmit and jitter_reduction_receive or 0.
Endpoint Name and Product Instance ID messages can hold up to 14 characters, if you want to report longer names
do send a sequence of packets using the packet_format mechanism (start, cont, end).
Alternatively use the Multi Part Message helpers described below.
Function Block Discovery
stream_message make_function_block_discovery_message(
uint8_t function_block, uint8_t filter);
stream_message make_function_block_info_message(
uint7_t function_block, uint2_t direction,
group_t first_group, uint4_t num_groups_spanned = 1);
stream_message make_function_block_info_message(
uint7_t function_block, const function_block_options&,
group_t first_group, uint4_t num_groups_spanned = 1);
stream_message make_function_block_name_message(
packet_format, uint7_t function_block, const std::string_view& n);
With the Function Block Discovery message pass 0xFF as function_block to request information for all function blocks
or specify a function block id instead.
As filter you can use any combination of
namespace discovery_filter {
constexpr uint8_t function_block_info = 0b01;
constexpr uint8_t function_block_name = 0b10;
}
or discovery_filter::function_block_all to request all available information.
Use the
struct function_block_options
{
// active
bool active = true;
// directions
static constexpr uint2_t direction_input = 0b01; // Function Block receives MIDI Messages only
static constexpr uint2_t direction_output = 0b10; // Function Block transmits MIDI Messages only
static constexpr uint2_t bidirectional = 0b11; // Bidirectional
uint2_t direction = bidirectional;
// MIDI 1
static constexpr uint2_t not_midi1 = 0b00; // Not MIDI 1.0 aka MIDI 2
static constexpr uint2_t midi1_unrestricted = 0b01; // MIDI 1.0 - don't restrict Bandwidth (USB, Network)
static constexpr uint2_t midi1_31250 = 0b10; // Restrict Bandwidth to 31.25Kbps (5 pin DIN)
uint2_t midi1 = not_midi1;
// ui hints
static constexpr uint2_t ui_hint_as_direction = 0b00;
static constexpr uint2_t ui_hint_receiver = 0b01;
static constexpr uint2_t ui_hint_sender = 0b10;
uint2_t ui_hint = ui_hint_as_direction;
uint8_t ci_message_version = 0x00;
uint8_t max_num_sysex8_streams = 0;
};
helper struct to report the properties of a function block in a Function Block Info message.
Endpoint Name and Product Instance ID Messages can hold up to 14 characters, if you want to report longer strings
do send a sequence of packets using the packet_format mechanism (start, cont, end).
Alternatively use the Multi Part Message helpers described below.
Stream Configuration
Use a Stream Configuration Request to request changes to the MIDI protocol or extensions to be used.
stream_message make_stream_configuration_request(protocol_t, extensions_t = 0);
Reply with a Stream Configuration Notification to report your current protocol and extenensions used.
stream_message make_stream_configuration_notification(protocol_t, extensions_t = 0);
You can send a Stream Configuration Notification message at any time to report configuration changes, not only as a reply to a Stream Configuration Request.
Message Filtering
Filtering of Stream Messages can be done checking universal_packet::type() against
packet_type::stream or use
bool is_stream_message(const universal_packet&);
Multi Part Message helpers
The Multi Part Message template helpers allow to send strings of arbitrary length with a single function call:
template<typename Sender>
void send_endpoint_name(std::string_view, Sender&&);
template<typename Sender>
void send_product_instance_id(std::string_view, Sender&&);
template<typename Sender>
void send_function_block_name(uint7_t function_block, std::string_view, Sender&&);
Provide a Sender function that can send a single packet to a receiver.
Data Views
Different to most other message types there is no generic endpoint_discovery_view available.
Instead every Stream Message has its individual message view.
Endpoint Discovery View
struct endpoint_discovery_view
{
endpoint_discovery_view(const universal_packet&);
uint8_t ump_version_major() const;
uint8_t ump_version_minor() const;
uint16_t ump_version() const;
uint8_t filter() const;
bool requests_info() const;
bool requests_device_identity() const;
bool requests_name() const;
bool requests_product_instance_id() const;
bool requests_stream_configuration() const;
};
std::optional<endpoint_discovery_view> as_endpoint_discovery_view(const universal_packet&);
Endpoint Info View
struct endpoint_info_view
{
endpoint_info_view(const universal_packet&);
uint8_t ump_version_major() const;
uint8_t ump_version_minor() const;
uint16_t ump_version() const;
uint8_t num_function_blocks() const;
bool static_function_blocks() const;
uint8_t protocols() const;
uint8_t extensions() const;
};
std::optional<endpoint_info_view> as_endpoint_info_view(const universal_packet&);
Device Identity View
struct device_identity_view
{
device_identity_view(const universal_packet&);
device_identity identity() const;
};
std::optional<device_identity_view> as_device_identity_view(const universal_packet&);
Endpoint Name View
struct endpoint_name_view
{
endpoint_name_view(const universal_packet&);
packet_format format() const;
std::string payload() const;
};
std::optional<endpoint_name_view> as_endpoint_name_view(const universal_packet&);
Product Instance ID View
struct product_instance_id_view
{
product_instance_id_view(const universal_packet&);
packet_format format() const;
std::string payload() const;
};
std::optional<product_instance_id_view> as_product_instance_id_view(const universal_packet&);
Stream Configuration View
struct stream_configuration_view
{
stream_configuration_view(const universal_packet&);
protocol_t protocol() const;
extensions_t extensions() const;
};
std::optional<stream_configuration_view> as_stream_configuration_view(const universal_packet&);
Function Block Discovery View
struct function_block_discovery_view
{
function_block_discovery_view(const universal_packet&);
uint8_t function_block() const;
uint8_t filter() const;
bool requests_function_block(uint8_t block) const;
bool requests_info() const;
bool requests_name() const;
};
std::optional<function_block_discovery_view> as_function_block_discovery_view(const universal_packet&);
Function Block Info View
struct function_block_info_view
{
function_block_info_view(const universal_packet&);
bool active() const;
uint8_t function_block() const;
uint8_t direction() const;
uint8_t midi1() const;
uint8_t ui_hint() const;
uint8_t first_group() const;
uint8_t num_groups_spanned() const;
uint7_t ci_message_version() const;
uint8_t max_num_sysex8_streams() const;
};
std::optional<function_block_info_view> as_function_block_info_view(const universal_packet&);
Function Block Name View
struct function_block_name_view
{
function_block_name_view(const universal_packet&);
packet_format format() const;
uint8_t function_block() const;
std::string payload() const;
};
std::optional<function_block_name_view> as_function_block_name_view(const universal_packet&);