23#ifndef CORSIX_TH_MIDI_PLAYER_H
24#define CORSIX_TH_MIDI_PLAYER_H
28#ifdef WITH_MIDI_DEVICE
29#include <rtmidi/RtMidi.h>
33#include <condition_variable>
46constexpr unsigned int midi_virtual_port_index = UINT_MAX;
51const char*
const midi_external_port_name =
"midi_out";
66 open_midi_port(RtMidiOut& midi_out,
unsigned int port)
67 : midi_out(midi_out), port(port) {
68 if (port == midi_virtual_port_index) {
69 midi_out.openVirtualPort(midi_external_port_name);
71 midi_out.openPort(port, midi_external_port_name);
74 open_midi_port(
const open_midi_port&) =
delete;
75 open_midi_port& operator=(
const open_midi_port&) =
delete;
76 open_midi_port(
const open_midi_port&&) =
delete;
77 open_midi_port& operator=(
const open_midi_port&&) =
delete;
82 ~open_midi_port() { midi_out.closePort(); }
87 bool is_virtual()
const {
return port == midi_virtual_port_index; }
92 unsigned int get_port()
const {
return port; }
105enum class player_command {
128class player_command_queue {
134 void push(player_command command);
145 player_command pop(
bool blocking);
157 std::queue<player_command> queue{};
160 std::condition_variable cv{};
194 midi_player(std::string_view api, std::string_view port_name,
195 bool use_master_volume_sysex);
203 static std::vector<std::string> api_list();
208 std::vector<std::string> port_list()
const;
215 void set_port(std::string_view port_name);
221 void set_volume(
double volume);
228 void play_xmi(
const unsigned char* xmi_data,
size_t xmi_length);
253 void open_default_port();
262 bool is_port_open()
const;
270 static void init_playback(playback_state& state);
278 static void playback_loop(playback_state&& state);
281 std::unique_ptr<RtMidiOut> midi_out;
284 std::optional<open_midi_port> port;
287 std::thread playback_thread{};
290 player_command_queue command_queue{};
293 std::atomic<double> volume{1.0};
297 bool use_master_volume_sysex{
false};
300 std::mutex midi_out_mutex{};
Definition midi_player.h:305