libremidi update to v5.4.3 and added virtual midi out as default
This commit is contained in:
@@ -12,7 +12,7 @@ struct pw_filter;
|
||||
struct spa_io_position;
|
||||
}
|
||||
|
||||
namespace libremidi
|
||||
NAMESPACE_LIBREMIDI
|
||||
{
|
||||
using pipewire_callback_function = std::function<void(spa_io_position*)>;
|
||||
struct pipewire_callback
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
namespace libremidi
|
||||
NAMESPACE_LIBREMIDI
|
||||
{
|
||||
template <typename K, typename V>
|
||||
using hash_map = std::unordered_map<K, V>;
|
||||
@@ -79,11 +80,11 @@ struct pipewire_context
|
||||
struct graph
|
||||
{
|
||||
mutable std::mutex mtx;
|
||||
libremidi::hash_map<uint32_t, node> physical_audio;
|
||||
libremidi::hash_map<uint32_t, node> physical_midi;
|
||||
libremidi::hash_map<uint32_t, node> software_audio;
|
||||
libremidi::hash_map<uint32_t, node> software_midi;
|
||||
libremidi::hash_map<uint32_t, port_info> port_cache;
|
||||
libremidi::hash_map<uint64_t, node> physical_audio;
|
||||
libremidi::hash_map<uint64_t, node> physical_midi;
|
||||
libremidi::hash_map<uint64_t, node> software_audio;
|
||||
libremidi::hash_map<uint64_t, node> software_midi;
|
||||
libremidi::hash_map<uint64_t, port_info> port_cache;
|
||||
|
||||
void for_each_port(auto func)
|
||||
{
|
||||
@@ -123,7 +124,7 @@ struct pipewire_context
|
||||
}
|
||||
|
||||
explicit pipewire_context(std::shared_ptr<pipewire_instance> inst)
|
||||
: global_instance{inst}
|
||||
: global_instance{std::move(inst)}
|
||||
, owns_main_loop{true}
|
||||
{
|
||||
this->main_loop = pw.main_loop_new(nullptr);
|
||||
@@ -187,13 +188,13 @@ struct pipewire_context
|
||||
pipewire_context& self = *(pipewire_context*)object;
|
||||
if (strcmp(type, PW_TYPE_INTERFACE_Port) == 0)
|
||||
self.register_port(id, type);
|
||||
},
|
||||
},
|
||||
.global_remove =
|
||||
[](void* object, uint32_t id) {
|
||||
pipewire_context& self = *(pipewire_context*)object;
|
||||
self.unregister_port(id);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
// Start listening
|
||||
pw_registry_add_listener(this->registry, &this->registry_listener, ®istry_events, this);
|
||||
@@ -244,8 +245,8 @@ struct pipewire_context
|
||||
// Remove from the listeners
|
||||
auto it
|
||||
= std::find_if(port_listener.begin(), port_listener.end(), [&](const listened_port& l) {
|
||||
return l.id == id;
|
||||
});
|
||||
return l.id == id;
|
||||
});
|
||||
if (it != port_listener.end())
|
||||
{
|
||||
pw.proxy_destroy((pw_proxy*)it->port);
|
||||
@@ -266,14 +267,14 @@ struct pipewire_context
|
||||
static constexpr struct pw_core_events core_events = {
|
||||
.version = PW_VERSION_CORE_EVENTS,
|
||||
.done =
|
||||
[](void* object, uint32_t id, int seq) {
|
||||
[](void* object, uint32_t id, int seq) {
|
||||
auto& self = *(pipewire_context*)object;
|
||||
if(id == PW_ID_CORE && seq == self.pending)
|
||||
if (id == PW_ID_CORE && seq == self.pending)
|
||||
{
|
||||
self.done = 1;
|
||||
libpipewire::instance().main_loop_quit(self.main_loop);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
spa_zero(core_listener);
|
||||
@@ -287,7 +288,7 @@ struct pipewire_context
|
||||
spa_hook_remove(&core_listener);
|
||||
}
|
||||
|
||||
[[nodiscard]] pw_proxy* link_ports(uint32_t out_port, uint32_t in_port)
|
||||
[[nodiscard]] pw_proxy* link_ports(uint64_t out_port, uint64_t in_port)
|
||||
{
|
||||
auto props = pw.properties_new(
|
||||
PW_KEY_LINK_OUTPUT_PORT, std::to_string(out_port).c_str(), PW_KEY_LINK_INPUT_PORT,
|
||||
@@ -361,6 +362,8 @@ struct pipewire_context
|
||||
return &this->current_graph.physical_audio[nid];
|
||||
else if (p.format.find("midi") != p.format.npos)
|
||||
return &this->current_graph.physical_midi[nid];
|
||||
else if (p.format.find("UMP") != p.format.npos)
|
||||
return &this->current_graph.physical_midi[nid];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -368,6 +371,8 @@ struct pipewire_context
|
||||
return &this->current_graph.software_audio[nid];
|
||||
else if (p.format.find("midi") != p.format.npos)
|
||||
return &this->current_graph.software_midi[nid];
|
||||
else if (p.format.find("UMP") != p.format.npos)
|
||||
return &this->current_graph.software_midi[nid];
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
@@ -453,12 +458,12 @@ struct pipewire_filter
|
||||
}* port{};
|
||||
|
||||
explicit pipewire_filter(std::shared_ptr<pipewire_context> loop)
|
||||
: loop{loop}
|
||||
: loop{std::move(loop)}
|
||||
{
|
||||
}
|
||||
|
||||
explicit pipewire_filter(std::shared_ptr<pipewire_context> loop, pw_filter* filter)
|
||||
: loop{loop}
|
||||
: loop{std::move(loop)}
|
||||
, filter{filter}
|
||||
{
|
||||
}
|
||||
@@ -498,7 +503,8 @@ struct pipewire_filter
|
||||
pw.filter_destroy(this->filter);
|
||||
}
|
||||
|
||||
stdx::error create_local_port(std::string_view port_name, spa_direction direction)
|
||||
stdx::error
|
||||
create_local_port(std::string_view port_name, spa_direction direction, const char* format)
|
||||
{
|
||||
// clang-format off
|
||||
this->port = (struct port*)pw.filter_add_port(
|
||||
@@ -507,7 +513,7 @@ struct pipewire_filter
|
||||
PW_FILTER_PORT_FLAG_MAP_BUFFERS,
|
||||
sizeof(struct port),
|
||||
pw.properties_new(
|
||||
PW_KEY_FORMAT_DSP, "8 bit raw midi",
|
||||
PW_KEY_FORMAT_DSP, format,
|
||||
PW_KEY_PORT_NAME, port_name.data(),
|
||||
nullptr),
|
||||
nullptr, 0);
|
||||
@@ -517,7 +523,7 @@ struct pipewire_filter
|
||||
return stdx::error{};
|
||||
}
|
||||
|
||||
void set_port_buffer(int bytes)
|
||||
void set_port_buffer(int64_t bytes)
|
||||
{
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder builder;
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
#include <libremidi/detail/semaphore.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <semaphore>
|
||||
#include <stop_token>
|
||||
#include <thread>
|
||||
|
||||
namespace libremidi
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
NAMESPACE_LIBREMIDI
|
||||
{
|
||||
struct pipewire_helpers
|
||||
{
|
||||
@@ -66,14 +69,14 @@ struct pipewire_helpers
|
||||
{
|
||||
this->filter = std::make_unique<pipewire_filter>(this->global_context, configuration.filter);
|
||||
|
||||
pipewire_callback cbs{
|
||||
libremidi::pipewire_callback cbs{
|
||||
.token = this_instance,
|
||||
.callback = [&self, p = std::weak_ptr{canary}](spa_io_position* nf) -> void {
|
||||
if (auto pt = p.lock())
|
||||
self.process(nf);
|
||||
if (auto pt = p.lock())
|
||||
self.process(nf);
|
||||
|
||||
self.thread_lock.check_client_released();
|
||||
}};
|
||||
self.thread_lock.check_client_released();
|
||||
}};
|
||||
configuration.set_process_func(cbs);
|
||||
}
|
||||
else
|
||||
@@ -84,10 +87,10 @@ struct pipewire_helpers
|
||||
static constexpr struct pw_filter_events filter_events
|
||||
= {.version = PW_VERSION_FILTER_EVENTS,
|
||||
.process = +[](void* _data, struct spa_io_position* position) -> void {
|
||||
// FIXME likely we need the thread_lock check here too
|
||||
Self& self = *static_cast<Self*>(_data);
|
||||
self.process(position);
|
||||
}};
|
||||
// FIXME likely we need the thread_lock check here too
|
||||
Self& self = *static_cast<Self*>(_data);
|
||||
self.process(position);
|
||||
}};
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
this->filter->create_filter(self.configuration.client_name, filter_events, &self);
|
||||
@@ -197,7 +200,8 @@ struct pipewire_helpers
|
||||
}
|
||||
|
||||
template <typename Self>
|
||||
stdx::error create_local_port(Self& self, std::string_view portName, spa_direction direction)
|
||||
stdx::error create_local_port(
|
||||
Self& self, std::string_view portName, spa_direction direction, const char* format)
|
||||
{
|
||||
assert(this->global_context);
|
||||
assert(this->filter);
|
||||
@@ -207,7 +211,7 @@ struct pipewire_helpers
|
||||
|
||||
if (!this->filter->port)
|
||||
{
|
||||
auto ret = this->filter->create_local_port(portName.data(), direction);
|
||||
auto ret = this->filter->create_local_port(portName.data(), direction, format);
|
||||
if (ret != stdx::error{})
|
||||
{
|
||||
self.libremidi_handle_error(self.configuration, "error creating port");
|
||||
@@ -218,11 +222,12 @@ struct pipewire_helpers
|
||||
return stdx::error{};
|
||||
}
|
||||
|
||||
void add_callbacks(const observer_configuration& conf)
|
||||
template <libremidi::API Api>
|
||||
void add_callbacks(std::string format, const observer_configuration& conf)
|
||||
{
|
||||
assert(global_context);
|
||||
global_context->on_port_added = [&conf](const pipewire_context::port_info& port) {
|
||||
if (port.format.find("midi") == std::string::npos)
|
||||
global_context->on_port_added = [format, &conf](const pipewire_context::port_info& port) {
|
||||
if (port.format.find(format) == std::string::npos)
|
||||
return;
|
||||
|
||||
bool unfiltered = conf.track_any;
|
||||
@@ -233,18 +238,18 @@ struct pipewire_helpers
|
||||
if (port.direction == SPA_DIRECTION_INPUT)
|
||||
{
|
||||
if (conf.output_added)
|
||||
conf.output_added(to_port_info<SPA_DIRECTION_INPUT>(port));
|
||||
conf.output_added(to_port_info<SPA_DIRECTION_INPUT, Api>(port));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (conf.input_added)
|
||||
conf.input_added(to_port_info<SPA_DIRECTION_OUTPUT>(port));
|
||||
conf.input_added(to_port_info<SPA_DIRECTION_OUTPUT, Api>(port));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
global_context->on_port_removed = [&conf](const pipewire_context::port_info& port) {
|
||||
if (port.format.find("midi") == std::string::npos)
|
||||
global_context->on_port_removed = [format, &conf](const pipewire_context::port_info& port) {
|
||||
if (port.format.find(format) == std::string::npos)
|
||||
return;
|
||||
|
||||
bool unfiltered = conf.track_any;
|
||||
@@ -255,12 +260,12 @@ struct pipewire_helpers
|
||||
if (port.direction == SPA_DIRECTION_INPUT)
|
||||
{
|
||||
if (conf.output_removed)
|
||||
conf.output_removed(to_port_info<SPA_DIRECTION_INPUT>(port));
|
||||
conf.output_removed(to_port_info<SPA_DIRECTION_INPUT, Api>(port));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (conf.input_removed)
|
||||
conf.input_removed(to_port_info<SPA_DIRECTION_OUTPUT>(port));
|
||||
conf.input_removed(to_port_info<SPA_DIRECTION_OUTPUT, Api>(port));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -408,7 +413,7 @@ struct pipewire_helpers
|
||||
return stdx::error{};
|
||||
}
|
||||
|
||||
template <spa_direction Direction>
|
||||
template <spa_direction Direction, libremidi::API Api>
|
||||
static auto to_port_info(const pipewire_context::port_info& port)
|
||||
-> std::conditional_t<Direction == SPA_DIRECTION_OUTPUT, input_port, output_port>
|
||||
{
|
||||
@@ -425,6 +430,7 @@ struct pipewire_helpers
|
||||
}
|
||||
|
||||
return {{
|
||||
.api = Api,
|
||||
.client = 0,
|
||||
.port = port.id,
|
||||
.manufacturer = "",
|
||||
@@ -436,8 +442,10 @@ struct pipewire_helpers
|
||||
|
||||
// Note: keep in mind that an "input" port for us (e.g. a keyboard that goes to the computer)
|
||||
// is an "output" port from the point of view of pipewire as data will come out of it
|
||||
template <spa_direction Direction>
|
||||
static auto get_ports(const observer_configuration& conf, const pipewire_context& ctx) noexcept
|
||||
template <spa_direction Direction, libremidi::API Api>
|
||||
static auto get_ports(
|
||||
std::string_view format, const observer_configuration& conf,
|
||||
const pipewire_context& ctx) noexcept
|
||||
-> std::vector<
|
||||
std::conditional_t<Direction == SPA_DIRECTION_OUTPUT, input_port, output_port>>
|
||||
{
|
||||
@@ -452,7 +460,8 @@ struct pipewire_helpers
|
||||
for (auto& port :
|
||||
(Direction == SPA_DIRECTION_INPUT ? node.second.inputs : node.second.outputs))
|
||||
{
|
||||
ret.push_back(to_port_info<Direction>(port));
|
||||
if (port.format.find(format) != std::string::npos)
|
||||
ret.push_back(to_port_info<Direction, Api>(port));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +471,8 @@ struct pipewire_helpers
|
||||
for (auto& port :
|
||||
(Direction == SPA_DIRECTION_INPUT ? node.second.inputs : node.second.outputs))
|
||||
{
|
||||
ret.push_back(to_port_info<Direction>(port));
|
||||
if (port.format.find(format) != std::string::npos)
|
||||
ret.push_back(to_port_info<Direction, Api>(port));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -471,3 +481,7 @@ struct pipewire_helpers
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <libremidi/detail/midi_in.hpp>
|
||||
#include <libremidi/detail/midi_stream_decoder.hpp>
|
||||
|
||||
namespace libremidi
|
||||
NAMESPACE_LIBREMIDI
|
||||
{
|
||||
class midi_in_pipewire final
|
||||
: public midi1::in_api
|
||||
@@ -47,7 +47,8 @@ public:
|
||||
|
||||
stdx::error open_port(const input_port& in_port, std::string_view name) override
|
||||
{
|
||||
if (auto err = create_local_port(*this, name, SPA_DIRECTION_INPUT); err != stdx::error{})
|
||||
if (auto err = create_local_port(*this, name, SPA_DIRECTION_INPUT, "8 bit raw midi");
|
||||
err != stdx::error{})
|
||||
return err;
|
||||
|
||||
if (auto err = link_ports(*this, in_port); err != stdx::error{})
|
||||
@@ -59,7 +60,8 @@ public:
|
||||
|
||||
stdx::error open_virtual_port(std::string_view name) override
|
||||
{
|
||||
if (auto err = create_local_port(*this, name, SPA_DIRECTION_INPUT); err != stdx::error{})
|
||||
if (auto err = create_local_port(*this, name, SPA_DIRECTION_INPUT, "8 bit raw midi");
|
||||
err != stdx::error{})
|
||||
return err;
|
||||
|
||||
start_thread();
|
||||
@@ -72,10 +74,7 @@ public:
|
||||
return do_close_port();
|
||||
}
|
||||
|
||||
stdx::error set_port_name(std::string_view port_name) override
|
||||
{
|
||||
return rename_port(port_name);
|
||||
}
|
||||
stdx::error set_port_name(std::string_view port_name) override { return rename_port(port_name); }
|
||||
|
||||
timestamp absolute_timestamp() const noexcept override { return system_ns(); }
|
||||
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
|
||||
#include <readerwriterqueue.h>
|
||||
|
||||
#include <semaphore>
|
||||
|
||||
namespace libremidi
|
||||
NAMESPACE_LIBREMIDI
|
||||
{
|
||||
class midi_out_pipewire
|
||||
: public midi1::out_api
|
||||
@@ -50,7 +48,8 @@ public:
|
||||
|
||||
stdx::error open_port(const output_port& out_port, std::string_view name) override
|
||||
{
|
||||
if (auto err = create_local_port(*this, name, SPA_DIRECTION_OUTPUT); err != stdx::error{})
|
||||
if (auto err = create_local_port(*this, name, SPA_DIRECTION_OUTPUT, "8 bit raw midi");
|
||||
err != stdx::error{})
|
||||
return err;
|
||||
|
||||
this->filter->set_port_buffer(configuration.output_buffer_size);
|
||||
@@ -64,7 +63,8 @@ public:
|
||||
|
||||
stdx::error open_virtual_port(std::string_view name) override
|
||||
{
|
||||
if (auto err = create_local_port(*this, name, SPA_DIRECTION_OUTPUT); err != stdx::error{})
|
||||
if (auto err = create_local_port(*this, name, SPA_DIRECTION_OUTPUT, "8 bit raw midi");
|
||||
err != stdx::error{})
|
||||
return err;
|
||||
|
||||
this->filter->set_port_buffer(configuration.output_buffer_size);
|
||||
@@ -79,10 +79,7 @@ public:
|
||||
return do_close_port();
|
||||
}
|
||||
|
||||
stdx::error set_port_name(std::string_view port_name) override
|
||||
{
|
||||
return rename_port(port_name);
|
||||
}
|
||||
stdx::error set_port_name(std::string_view port_name) override { return rename_port(port_name); }
|
||||
|
||||
int process(spa_io_position* pos)
|
||||
{
|
||||
@@ -121,8 +118,9 @@ public:
|
||||
continue;
|
||||
}
|
||||
|
||||
spa_pod_builder_control(&build, m.timestamp, SPA_CONTROL_Midi);
|
||||
int res = spa_pod_builder_bytes(&build, m.bytes.data(), m.bytes.size());
|
||||
spa_pod_builder_control(&build, static_cast<int32_t>(m.timestamp), SPA_CONTROL_Midi);
|
||||
int res
|
||||
= spa_pod_builder_bytes(&build, m.bytes.data(), static_cast<uint32_t>(m.bytes.size()));
|
||||
|
||||
// Try again next buffer
|
||||
if (res == -ENOSPC)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
namespace libremidi
|
||||
NAMESPACE_LIBREMIDI
|
||||
{
|
||||
class observer_pipewire final
|
||||
: public observer_api
|
||||
@@ -19,24 +19,15 @@ public:
|
||||
{
|
||||
} configuration;
|
||||
|
||||
explicit observer_pipewire(observer_configuration&& conf, pipewire_observer_configuration&& apiconf)
|
||||
explicit observer_pipewire(
|
||||
observer_configuration&& conf, pipewire_observer_configuration&& apiconf)
|
||||
: configuration{std::move(conf), std::move(apiconf)}
|
||||
{
|
||||
create_context(*this);
|
||||
|
||||
// FIXME notify_in_constructor
|
||||
// FIXME port rename callback
|
||||
#if 0
|
||||
// Initialize PipeWire client
|
||||
if (configuration.context)
|
||||
{
|
||||
this->client = configuration.context;
|
||||
set_callbacks();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
this->add_callbacks(configuration);
|
||||
this->add_callbacks<libremidi::API::PIPEWIRE>("midi", configuration);
|
||||
this->start_thread();
|
||||
}
|
||||
|
||||
@@ -56,27 +47,20 @@ public:
|
||||
|
||||
std::vector<libremidi::input_port> get_input_ports() const noexcept override
|
||||
{
|
||||
return get_ports<SPA_DIRECTION_OUTPUT>(this->configuration, *this->global_context);
|
||||
return get_ports<SPA_DIRECTION_OUTPUT, libremidi::API::PIPEWIRE>(
|
||||
"midi", this->configuration, *this->global_context);
|
||||
}
|
||||
|
||||
std::vector<libremidi::output_port> get_output_ports() const noexcept override
|
||||
{
|
||||
return get_ports<SPA_DIRECTION_INPUT>(this->configuration, *this->global_context);
|
||||
return get_ports<SPA_DIRECTION_INPUT, libremidi::API::PIPEWIRE>(
|
||||
"midi", this->configuration, *this->global_context);
|
||||
}
|
||||
|
||||
~observer_pipewire()
|
||||
{
|
||||
stop_thread();
|
||||
destroy_context();
|
||||
#if 0
|
||||
if (client && !configuration.context)
|
||||
{
|
||||
// If we own the client, deactivate it
|
||||
pipewire_deactivate(this->client);
|
||||
pipewire_client_close(this->client);
|
||||
this->client = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> seen_input_ports;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <variant>
|
||||
|
||||
namespace libremidi::pipewire
|
||||
NAMESPACE_LIBREMIDI::pipewire
|
||||
{
|
||||
|
||||
// Create a PipeWire client which will be shared across objects
|
||||
@@ -23,13 +23,10 @@ struct shared_handler : public libremidi::shared_context
|
||||
client = pipewire_client_open(v.data(), PipewireNoStartServer, &status);
|
||||
assert(client);
|
||||
assert(status == 0);
|
||||
pipewire_set_process_callback(
|
||||
client,
|
||||
+[](pipewire_nframes_t cnt, void* ctx) -> int {
|
||||
((shared_handler*)ctx)->pipewire_callback(cnt);
|
||||
return 0;
|
||||
},
|
||||
this);
|
||||
pipewire_set_process_callback(client, +[](pipewire_nframes_t cnt, void* ctx) -> int {
|
||||
((shared_handler*)ctx)->pipewire_callback(cnt);
|
||||
return 0;
|
||||
}, this);
|
||||
}
|
||||
|
||||
virtual void start_processing() override { pipewire_activate(client); }
|
||||
@@ -74,10 +71,10 @@ struct shared_handler : public libremidi::shared_context
|
||||
{
|
||||
case in_callback_added:
|
||||
midiin_callbacks.push_back(
|
||||
std::move(*std::get_if<libremidi::pipewire_callback>(&ev.payload)));
|
||||
std::move(*get_if<libremidi::pipewire_callback>(&ev.payload)));
|
||||
break;
|
||||
case in_callback_removed: {
|
||||
auto idx = *std::get_if<int64_t>(&ev.payload);
|
||||
auto idx = *get_if<int64_t>(&ev.payload);
|
||||
for (auto it = midiin_callbacks.begin(); it != midiin_callbacks.end();)
|
||||
{
|
||||
if (it->token == idx)
|
||||
@@ -94,10 +91,10 @@ struct shared_handler : public libremidi::shared_context
|
||||
}
|
||||
case out_callback_added:
|
||||
midiout_callbacks.push_back(
|
||||
std::move(*std::get_if<libremidi::pipewire_callback>(&ev.payload)));
|
||||
std::move(*get_if<libremidi::pipewire_callback>(&ev.payload)));
|
||||
break;
|
||||
case out_callback_removed:
|
||||
auto idx = *std::get_if<int64_t>(&ev.payload);
|
||||
auto idx = *get_if<int64_t>(&ev.payload);
|
||||
for (auto it = midiout_callbacks.begin(); it != midiout_callbacks.end();)
|
||||
{
|
||||
if (it->token == idx)
|
||||
@@ -141,7 +138,7 @@ struct shared_handler : public libremidi::shared_context
|
||||
struct event
|
||||
{
|
||||
event_type type;
|
||||
std::variant<libremidi::pipewire_callback, int64_t> payload;
|
||||
libremidi_variant_alias::variant<libremidi::pipewire_callback, int64_t> payload;
|
||||
};
|
||||
|
||||
boost::lockfree::spsc_queue<event> events{16};
|
||||
|
||||
Reference in New Issue
Block a user