upgrade to libremidi 5.1, raylib and raygui latest
This commit is contained in:
@@ -46,19 +46,19 @@ namespace
|
||||
{
|
||||
inline constexpr port_handle seq_to_port_handle(uint64_t client, uint64_t port) noexcept
|
||||
{
|
||||
return (client << 32) + port;
|
||||
return (port << 32) + client;
|
||||
}
|
||||
|
||||
inline constexpr std::pair<int, int> seq_from_port_handle(port_handle p) noexcept
|
||||
{
|
||||
int client = p >> 32;
|
||||
int port = p & 0xFFFFFFFF;
|
||||
int port = p >> 32;
|
||||
int client = p & 0xFFFFFFFF;
|
||||
return {client, port};
|
||||
}
|
||||
|
||||
inline void for_all_ports(
|
||||
const libasound& snd, snd_seq_t* seq,
|
||||
std::function<void(snd_seq_client_info_t&, snd_seq_port_info_t&)> func)
|
||||
const std::function<void(snd_seq_client_info_t&, snd_seq_port_info_t&)>& func)
|
||||
{
|
||||
snd_seq_client_info_t* cinfo{};
|
||||
snd_seq_client_info_alloca(&cinfo);
|
||||
|
||||
@@ -212,7 +212,7 @@ public:
|
||||
.count();
|
||||
}
|
||||
|
||||
int process_event(const snd_seq_event_t& ev)
|
||||
int64_t process_event(const snd_seq_event_t& ev)
|
||||
{
|
||||
if constexpr (ConfigurationImpl::midi_version == 1)
|
||||
{
|
||||
@@ -258,17 +258,17 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int process_events()
|
||||
int64_t process_events()
|
||||
{
|
||||
if constexpr (ConfigurationImpl::midi_version == 1)
|
||||
{
|
||||
snd_seq_event_t* ev{};
|
||||
event_handle handle{snd};
|
||||
int result = 0;
|
||||
int64_t result = 0;
|
||||
if ((result = snd.seq.event_input(seq, &ev)) > 0)
|
||||
{
|
||||
handle.reset(ev);
|
||||
if (int err = process_event(*ev); err < 0)
|
||||
if (auto err = process_event(*ev); err < 0)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
@@ -353,7 +353,7 @@ public:
|
||||
midi_in_alsa_threaded(ConfigurationBase&& conf, ConfigurationImpl&& apiconf)
|
||||
: midi_in_impl<ConfigurationBase, ConfigurationImpl>{std::move(conf), std::move(apiconf)}
|
||||
{
|
||||
if (this->termination_event < 0)
|
||||
if (this->m_termination_event < 0)
|
||||
{
|
||||
this->libremidi_handle_error(this->configuration, "error creating eventfd.");
|
||||
return;
|
||||
@@ -364,7 +364,7 @@ public:
|
||||
|
||||
~midi_in_alsa_threaded()
|
||||
{
|
||||
this->close_port();
|
||||
midi_in_alsa_threaded::close_port();
|
||||
this->client_open_ = std::errc::not_connected;
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ private:
|
||||
{
|
||||
try
|
||||
{
|
||||
this->thread = std::thread([this] { thread_handler(); });
|
||||
this->m_thread = std::thread([this] { thread_handler(); });
|
||||
return stdx::error{};
|
||||
}
|
||||
catch (const std::system_error& e)
|
||||
@@ -415,12 +415,12 @@ private:
|
||||
|
||||
stdx::error stop_thread()
|
||||
{
|
||||
termination_event.notify();
|
||||
m_termination_event.notify();
|
||||
|
||||
if (this->thread.joinable())
|
||||
this->thread.join();
|
||||
if (this->m_thread.joinable())
|
||||
this->m_thread.join();
|
||||
|
||||
termination_event.consume();
|
||||
m_termination_event.consume();
|
||||
return stdx::error{};
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private:
|
||||
{
|
||||
int poll_fd_count = alsa_data::snd.seq.poll_descriptors_count(this->seq, POLLIN) + 1;
|
||||
auto poll_fds = (struct pollfd*)alloca(poll_fd_count * sizeof(struct pollfd));
|
||||
poll_fds[0] = this->termination_event;
|
||||
poll_fds[0] = this->m_termination_event;
|
||||
alsa_data::snd.seq.poll_descriptors(this->seq, poll_fds + 1, poll_fd_count - 1, POLLIN);
|
||||
|
||||
const auto period
|
||||
@@ -439,10 +439,10 @@ private:
|
||||
if (alsa_data::snd.seq.event_input_pending(this->seq, 1) == 0)
|
||||
{
|
||||
// No data pending
|
||||
if (poll(poll_fds, poll_fd_count, period) >= 0)
|
||||
if (poll(poll_fds, poll_fd_count, static_cast<int32_t>(period)) >= 0)
|
||||
{
|
||||
// We got our stop-thread signal
|
||||
if (termination_event.ready(poll_fds[0]))
|
||||
if (m_termination_event.ready(poll_fds[0]))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -450,7 +450,7 @@ private:
|
||||
continue;
|
||||
}
|
||||
|
||||
int res{};
|
||||
int64_t res{};
|
||||
if constexpr (ConfigurationImpl::midi_version == 1)
|
||||
{
|
||||
res = this->process_events();
|
||||
@@ -467,8 +467,8 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
std::thread thread{};
|
||||
eventfd_notifier termination_event{};
|
||||
std::thread m_thread{};
|
||||
eventfd_notifier m_termination_event{};
|
||||
};
|
||||
|
||||
template <typename ConfigurationBase, typename ConfigurationImpl>
|
||||
@@ -497,7 +497,7 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
~midi_in_alsa_manual() { this->close_port(); }
|
||||
~midi_in_alsa_manual() { midi_in_alsa_manual::close_port(); }
|
||||
|
||||
stdx::error open_port(const input_port& pt, std::string_view local_port_name) override
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (snd.midi.event_new(this->bufferSize, &this->coder) < 0)
|
||||
if (snd.midi.event_new(this->m_bufferSize, &this->coder) < 0)
|
||||
{
|
||||
libremidi_handle_error(this->configuration, "error initializing MIDI event parser.");
|
||||
return;
|
||||
@@ -68,8 +68,9 @@ public:
|
||||
|
||||
stdx::error open_port(const output_port& p, std::string_view portName) override
|
||||
{
|
||||
unsigned int nSrc = this->get_port_count(SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE);
|
||||
if (nSrc < 1)
|
||||
unsigned int n_src
|
||||
= this->get_port_count(SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE);
|
||||
if (n_src < 1)
|
||||
{
|
||||
libremidi_handle_error(this->configuration, "no MIDI output sources found!");
|
||||
return make_error_code(std::errc::no_such_device);
|
||||
@@ -122,9 +123,9 @@ public:
|
||||
stdx::error send_message(const unsigned char* message, std::size_t size) override
|
||||
{
|
||||
int64_t result{};
|
||||
if (size > this->bufferSize)
|
||||
if (size > this->m_bufferSize)
|
||||
{
|
||||
this->bufferSize = size;
|
||||
this->m_bufferSize = size;
|
||||
result = snd.midi.event_resize_buffer(this->coder, size);
|
||||
if (result != 0)
|
||||
{
|
||||
@@ -146,8 +147,8 @@ public:
|
||||
// FIXME direct is set but snd_seq_event_output_direct is not used...
|
||||
snd_seq_ev_set_direct(&ev);
|
||||
|
||||
const int64_t nBytes = size; // signed to avoir potential overflow with size - offset below
|
||||
result = snd.midi.event_encode(this->coder, message + offset, (long)(nBytes - offset), &ev);
|
||||
const int64_t n_bytes = size; // signed to avoir potential overflow with size - offset below
|
||||
result = snd.midi.event_encode(this->coder, message + offset, (long)(n_bytes - offset), &ev);
|
||||
if (result < 0)
|
||||
{
|
||||
libremidi_handle_warning(this->configuration, "event parsing error!");
|
||||
@@ -174,6 +175,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t bufferSize{32};
|
||||
uint64_t m_bufferSize{32};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include <bitset>
|
||||
#if LIBREMIDI_HAS_UDEV
|
||||
#include <libremidi/backends/linux/udev.hpp>
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace libremidi::alsa_seq
|
||||
@@ -21,6 +24,8 @@ struct port_info
|
||||
int port{};
|
||||
bool isInput{};
|
||||
bool isOutput{};
|
||||
std::optional<int> card{};
|
||||
libremidi::port_information::port_type type{};
|
||||
};
|
||||
|
||||
template <typename ConfigurationImpl>
|
||||
@@ -107,13 +112,19 @@ public:
|
||||
const auto tp = snd.seq.port_info_get_type(pinfo);
|
||||
bool ok = this->configuration.track_any;
|
||||
|
||||
static constexpr auto virtual_port
|
||||
= SND_SEQ_PORT_TYPE_SOFTWARE | SND_SEQ_PORT_TYPE_SYNTHESIZER;
|
||||
static constexpr auto virtual_port = SND_SEQ_PORT_TYPE_SOFTWARE | SND_SEQ_PORT_TYPE_SYNTHESIZER
|
||||
| SND_SEQ_PORT_TYPE_APPLICATION;
|
||||
|
||||
if ((tp & SND_SEQ_PORT_TYPE_HARDWARE) && this->configuration.track_hardware)
|
||||
{
|
||||
p.type = libremidi::port_information::port_type::hardware;
|
||||
ok = true;
|
||||
}
|
||||
else if ((tp & virtual_port) && this->configuration.track_virtual)
|
||||
{
|
||||
p.type = libremidi::port_information::port_type::software;
|
||||
ok = true;
|
||||
}
|
||||
if (!ok)
|
||||
return {};
|
||||
|
||||
@@ -123,7 +134,10 @@ public:
|
||||
if (auto name = snd.seq.port_info_get_name(pinfo))
|
||||
p.port_name = name;
|
||||
|
||||
auto cap = snd.seq.port_info_get_capability(pinfo);
|
||||
if (int card = snd.seq.client_info_get_card(cinfo); card >= 0)
|
||||
p.card = card;
|
||||
|
||||
const auto cap = snd.seq.port_info_get_capability(pinfo);
|
||||
p.isInput = (cap & SND_SEQ_PORT_CAP_DUPLEX) | (cap & SND_SEQ_PORT_CAP_READ);
|
||||
p.isOutput = (cap & SND_SEQ_PORT_CAP_DUPLEX) | (cap & SND_SEQ_PORT_CAP_WRITE);
|
||||
|
||||
@@ -131,18 +145,34 @@ public:
|
||||
}
|
||||
|
||||
template <bool Input>
|
||||
auto to_port_info(port_info p) const noexcept
|
||||
auto to_port_info(const port_info& p) const noexcept
|
||||
-> std::conditional_t<Input, input_port, output_port>
|
||||
{
|
||||
static_assert(sizeof(this->seq) <= sizeof(libremidi::client_handle));
|
||||
static_assert(sizeof(std::uintptr_t) <= sizeof(libremidi::client_handle));
|
||||
|
||||
container_identifier container{};
|
||||
device_identifier device{};
|
||||
libremidi::port_information::port_type type = p.type;
|
||||
#if LIBREMIDI_HAS_UDEV
|
||||
if (p.card)
|
||||
{
|
||||
auto res = get_udev_soundcard_info(m_udev, *p.card);
|
||||
container = res.container;
|
||||
device = res.path;
|
||||
type = res.type;
|
||||
}
|
||||
#endif
|
||||
return {
|
||||
{.client = std::uintptr_t(this->seq),
|
||||
.container = container,
|
||||
.device = device,
|
||||
.port = alsa_seq::seq_to_port_handle(p.client, p.port),
|
||||
.manufacturer = "",
|
||||
.device_name = p.client_name,
|
||||
.port_name = p.port_name,
|
||||
.display_name = p.port_name}};
|
||||
.display_name = p.port_name,
|
||||
.type = type}};
|
||||
}
|
||||
|
||||
void init_all_ports()
|
||||
@@ -200,7 +230,7 @@ public:
|
||||
if (p.client == snd.seq.client_id(seq))
|
||||
return;
|
||||
|
||||
knownClients_[{p.client, p.port}] = p;
|
||||
m_knownClients[{p.client, p.port}] = p;
|
||||
if (p.isInput && configuration.input_added)
|
||||
{
|
||||
configuration.input_added(to_port_info<true>(p));
|
||||
@@ -214,11 +244,11 @@ public:
|
||||
|
||||
void unregister_port(int client, int port)
|
||||
{
|
||||
auto it = knownClients_.find({client, port});
|
||||
if (it != knownClients_.end())
|
||||
auto it = m_knownClients.find({client, port});
|
||||
if (it != m_knownClients.end())
|
||||
{
|
||||
auto p = it->second;
|
||||
knownClients_.erase(it);
|
||||
m_knownClients.erase(it);
|
||||
|
||||
if (p.isInput && configuration.input_removed)
|
||||
{
|
||||
@@ -263,7 +293,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::pair<int, int>, port_info> knownClients_;
|
||||
std::map<std::pair<int, int>, port_info> m_knownClients;
|
||||
|
||||
#if LIBREMIDI_HAS_UDEV
|
||||
udev_helper m_udev{};
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename ConfigurationImpl>
|
||||
@@ -275,9 +309,9 @@ public:
|
||||
{
|
||||
// Create relevant descriptors
|
||||
auto& snd = alsa_data::snd;
|
||||
const auto N = snd.seq.poll_descriptors_count(this->seq, POLLIN);
|
||||
descriptors_.resize(N + 1);
|
||||
snd.seq.poll_descriptors(this->seq, descriptors_.data(), N, POLLIN);
|
||||
const auto n = snd.seq.poll_descriptors_count(this->seq, POLLIN);
|
||||
descriptors_.resize(n + 1);
|
||||
snd.seq.poll_descriptors(this->seq, descriptors_.data(), n, POLLIN);
|
||||
descriptors_.back() = this->termination_event;
|
||||
|
||||
// Start the listening thread
|
||||
@@ -288,7 +322,7 @@ public:
|
||||
.count();
|
||||
for (;;)
|
||||
{
|
||||
int err = poll(descriptors_.data(), descriptors_.size(), period);
|
||||
int err = poll(descriptors_.data(), descriptors_.size(), static_cast<int32_t>(period));
|
||||
if (err >= 0)
|
||||
{
|
||||
// We got our stop-thread signal
|
||||
|
||||
@@ -61,7 +61,7 @@ struct shared_handler : public libremidi::shared_context
|
||||
{
|
||||
auto clt = std::make_shared<shared_handler>(client_name);
|
||||
|
||||
auto cb = [client = std::weak_ptr{clt}](const libremidi::alsa_seq::poll_parameters& params) {
|
||||
auto cb = [client = std::weak_ptr{clt}](libremidi::alsa_seq::poll_parameters params) {
|
||||
if (auto clt = client.lock())
|
||||
{
|
||||
clt->events.push(
|
||||
@@ -74,8 +74,7 @@ struct shared_handler : public libremidi::shared_context
|
||||
auto stop_cb = [client = std::weak_ptr{clt}](snd_seq_addr_t id) {
|
||||
if (auto clt = client.lock())
|
||||
{
|
||||
clt->events.push(
|
||||
{.type = shared_handler::event_type::callback_removed, .payload = std::move(id)});
|
||||
clt->events.push({.type = shared_handler::event_type::callback_removed, .payload = id});
|
||||
clt->queue_event.notify();
|
||||
}
|
||||
return true;
|
||||
@@ -134,7 +133,7 @@ struct shared_handler : public libremidi::shared_context
|
||||
break;
|
||||
}
|
||||
case callback_removed:
|
||||
auto addr = std::move(*std::get_if<snd_seq_addr_t>(&ev.payload));
|
||||
auto addr = *std::get_if<snd_seq_addr_t>(&ev.payload);
|
||||
if (auto index = index_of_address(addr); index >= 0)
|
||||
{
|
||||
addresses.erase(addresses.begin() + index);
|
||||
@@ -146,15 +145,14 @@ struct shared_handler : public libremidi::shared_context
|
||||
}
|
||||
|
||||
// Look for who's ready
|
||||
for (int64_t i = 0, N = std::ssize(fds) - 2; i < N; i++)
|
||||
for (int64_t i = 0, n = std::ssize(fds) - 2; i < n; i++)
|
||||
{
|
||||
if (fds[i].revents & POLLIN)
|
||||
{
|
||||
// Read alsa event
|
||||
snd_seq_event_t* ev{};
|
||||
event_handle handle{snd};
|
||||
int result = 0;
|
||||
while ((result = snd.seq.event_input(client, &ev)) > 0)
|
||||
while (snd.seq.event_input(client, &ev) > 0)
|
||||
{
|
||||
handle.reset(ev);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user