2024-10-09 02:01:23 +02:00
|
|
|
#pragma once
|
|
|
|
|
#include <libremidi/config.hpp>
|
|
|
|
|
#include <libremidi/error.hpp>
|
|
|
|
|
#include <libremidi/message.hpp>
|
|
|
|
|
#include <libremidi/ump.hpp>
|
|
|
|
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
|
|
namespace libremidi
|
|
|
|
|
{
|
|
|
|
|
//! Specify how timestamps are handled in the system
|
|
|
|
|
enum timestamp_mode
|
|
|
|
|
{
|
|
|
|
|
//! No timestamping at all, all timestamps are zero
|
|
|
|
|
NoTimestamp,
|
|
|
|
|
|
|
|
|
|
//! In nanoseconds, timestamp is the time since the previous event (or zero)
|
|
|
|
|
Relative,
|
|
|
|
|
|
|
|
|
|
//! In nanoseconds, as per an arbitrary reference which may be provided by the host API,
|
|
|
|
|
//! e.g. since the JACK cycle start, ALSA sequencer queue creation, through AudioHostTime on macOS.
|
|
|
|
|
//! It offers the most precise ordering between events as it's the closest to the real timestamp of
|
|
|
|
|
//! the event as provided by the host API.
|
|
|
|
|
//! If the API does not provide any timing, it will be mapped to SystemMonotonic instead.
|
|
|
|
|
Absolute,
|
|
|
|
|
|
|
|
|
|
//! In nanoseconds, as per std::steady_clock::now() or equivalent (raw if possible).
|
|
|
|
|
//! May be less precise than Absolute as timestamping is done within the library,
|
|
|
|
|
//! but is more useful for system-wide synchronization.
|
|
|
|
|
//! Note: depending on the backend, Absolute and SystemMonotonic may be the same.
|
|
|
|
|
SystemMonotonic,
|
|
|
|
|
|
|
|
|
|
//! For APIs which are based on audio process cycles such as JACK, timestamps will be in frames since
|
|
|
|
|
//! the beginning of the current cycle's audio buffer
|
|
|
|
|
AudioFrame,
|
|
|
|
|
|
|
|
|
|
//! Will call the custom timestamping function provided by the user in the input configuration.
|
|
|
|
|
Custom
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using timestamp = int64_t;
|
|
|
|
|
using message_callback = std::function<void(message&& message)>;
|
2024-10-28 19:24:18 +01:00
|
|
|
using raw_callback = std::function<void(std::span<const uint8_t>, timestamp)>;
|
2024-10-09 02:01:23 +02:00
|
|
|
using timestamp_callback = std::function<timestamp(timestamp)>;
|
|
|
|
|
struct input_configuration
|
|
|
|
|
{
|
|
|
|
|
//! Set a callback function to be invoked for incoming MIDI messages.
|
2024-10-28 19:24:18 +01:00
|
|
|
//! Either this or on_raw_message must be set
|
|
|
|
|
message_callback on_message{};
|
|
|
|
|
|
|
|
|
|
//! Invoked for incoming MIDI bytes. No transformation, no filtering, no packetization,
|
|
|
|
|
//! just the MIDI data straight from the source.
|
|
|
|
|
raw_callback on_raw_data{};
|
2024-10-09 02:01:23 +02:00
|
|
|
|
|
|
|
|
//! Set a custom callback function to be invoked for timestamping MIDI messages.
|
|
|
|
|
//! Input: the API provided timestamp in nanoseconds, if available, for reference.
|
|
|
|
|
//! (e.g. the same as "Absolute").
|
|
|
|
|
//! Mandatory if timestamps == timestamp_mode::Custom, unused otherwise.
|
2024-10-28 19:24:18 +01:00
|
|
|
timestamp_callback get_timestamp{};
|
2024-10-09 02:01:23 +02:00
|
|
|
|
|
|
|
|
//! Set an error callback function to be invoked when an error has occured.
|
|
|
|
|
/*!
|
|
|
|
|
The callback function will be called whenever an error has occured. It is
|
|
|
|
|
best to set the error callback function before opening a port.
|
|
|
|
|
*/
|
|
|
|
|
midi_error_callback on_error{};
|
2024-10-28 19:24:18 +01:00
|
|
|
midi_warning_callback on_warning{};
|
2024-10-09 02:01:23 +02:00
|
|
|
|
|
|
|
|
//! Specify whether certain MIDI message types should be queued or ignored
|
|
|
|
|
//! during input.
|
|
|
|
|
/*!
|
|
|
|
|
By default, MIDI timing and active sensing messages are ignored
|
|
|
|
|
during message input because of their relative high data rates.
|
|
|
|
|
MIDI sysex messages are ignored by default as well. Variable
|
|
|
|
|
values of "true" imply that the respective message type will be
|
|
|
|
|
ignored.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t ignore_sysex : 1 = true;
|
|
|
|
|
uint32_t ignore_timing : 1 = true;
|
|
|
|
|
uint32_t ignore_sensing : 1 = true;
|
|
|
|
|
|
|
|
|
|
//! Timestamp mode. See @libremidi::timestamp_mode
|
|
|
|
|
uint32_t timestamps : 3 = timestamp_mode::Absolute;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using ump_callback = std::function<void(ump&&)>;
|
2024-10-28 19:24:18 +01:00
|
|
|
using raw_ump_callback = std::function<void(std::span<const uint32_t>, timestamp)>;
|
2024-10-09 02:01:23 +02:00
|
|
|
struct ump_input_configuration
|
|
|
|
|
{
|
|
|
|
|
//! Set a callback function to be invoked for incoming UMP messages.
|
2024-10-28 19:24:18 +01:00
|
|
|
//! Either this or on_raw_message must be set
|
|
|
|
|
ump_callback on_message{};
|
|
|
|
|
|
|
|
|
|
//! Invoked for incoming UMP bytes. No transformation, no filtering, no packetization,
|
|
|
|
|
//! just the UMP data straight from the source.
|
|
|
|
|
raw_ump_callback on_raw_data{};
|
2024-10-09 02:01:23 +02:00
|
|
|
|
|
|
|
|
//! Set a custom callback function to be invoked for timestamping MIDI messages.
|
|
|
|
|
//! Input: the API provided timestamp in nanoseconds, if available, for reference.
|
|
|
|
|
//! (e.g. the same as "Absolute").
|
|
|
|
|
//! Mandatory if timestamps == timestamp_mode::Custom, unused otherwise.
|
2024-10-28 19:24:18 +01:00
|
|
|
timestamp_callback get_timestamp{};
|
2024-10-09 02:01:23 +02:00
|
|
|
|
|
|
|
|
//! Set an error callback function to be invoked when an error has occured.
|
|
|
|
|
/*!
|
|
|
|
|
The callback function will be called whenever an error has occured. It is
|
|
|
|
|
best to set the error callback function before opening a port.
|
|
|
|
|
*/
|
|
|
|
|
midi_error_callback on_error{};
|
2024-10-28 19:24:18 +01:00
|
|
|
midi_warning_callback on_warning{};
|
2024-10-09 02:01:23 +02:00
|
|
|
|
|
|
|
|
//! Specify whether certain MIDI message types should be queued or ignored
|
|
|
|
|
//! during input.
|
|
|
|
|
/*!
|
|
|
|
|
By default, MIDI timing and active sensing messages are ignored
|
|
|
|
|
during message input because of their relative high data rates.
|
|
|
|
|
MIDI sysex messages are ignored by default as well. Variable
|
|
|
|
|
values of "true" imply that the respective message type will be
|
|
|
|
|
ignored.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t ignore_sysex : 1 = true;
|
|
|
|
|
uint32_t ignore_timing : 1 = true;
|
|
|
|
|
uint32_t ignore_sensing : 1 = true;
|
|
|
|
|
|
|
|
|
|
uint32_t timestamps : 3 = timestamp_mode::Absolute;
|
|
|
|
|
};
|
|
|
|
|
}
|