upgrade to libremidi 5.1, raylib and raygui latest

This commit is contained in:
Sebastian @ HfG
2025-06-13 19:16:35 +02:00
parent 62454960d1
commit 2cc6839009
112 changed files with 6484 additions and 1946 deletions
+89 -11
View File
@@ -5,7 +5,9 @@
#include <libremidi/detail/semaphore.hpp>
#include <atomic>
#include <semaphore>
#include <cstdint>
#include <cstring>
#include <memory>
namespace libremidi
{
@@ -54,16 +56,16 @@ struct jack_client
}
template <bool Input>
static auto
get_ports(jack_client_t* client, const char* pattern, const JackPortFlags flags) noexcept
-> std::vector<std::conditional_t<Input, input_port, output_port>>
static auto get_ports(
jack_client_t* client, const char* pattern, const char* type, const JackPortFlags flags,
bool midi2) noexcept -> std::vector<std::conditional_t<Input, input_port, output_port>>
{
std::vector<std::conditional_t<Input, input_port, output_port>> ret;
if (!client)
return {};
const char** ports = jack_get_ports(client, pattern, JACK_DEFAULT_MIDI_TYPE, flags);
const char** ports = jack_get_ports(client, pattern, type, flags);
if (ports == nullptr)
return {};
@@ -73,7 +75,11 @@ struct jack_client
{
// FIXME this does not take into account filtering sw / hw ports
auto port = jack_port_by_name(client, ports[i]);
ret.push_back(to_port_info<Input>(client, port));
if (port)
{
if (bool(midi2) == bool(jack_port_flags(port) & 0x20))
ret.push_back(to_port_info<Input>(client, port));
}
i++;
}
@@ -132,7 +138,7 @@ struct jack_helpers : jack_client
{.token = this_instance,
.callback = [&self, p = std::weak_ptr{this->port.impl}](jack_nframes_t nf) -> int {
if (auto pt = p.lock())
if (auto ppt = pt->load())
if (pt->load())
self.process(nf);
self.thread_lock.check_client_released();
@@ -192,8 +198,8 @@ struct jack_helpers : jack_client
self.client_open_ = std::errc::not_connected;
}
stdx::error
create_local_port(const auto& self, std::string_view portName, JackPortFlags flags)
stdx::error create_local_port(
const auto& self, std::string_view portName, const char* type, JackPortFlags flags)
{
// full name: "client_name:port_name\0"
if (portName.empty())
@@ -209,8 +215,7 @@ struct jack_helpers : jack_client
if (!this->port)
{
this->port
= jack_port_register(this->client, portName.data(), JACK_DEFAULT_MIDI_TYPE, flags, 0);
this->port = jack_port_register(this->client, portName.data(), type, flags, 0);
}
if (!this->port)
@@ -238,4 +243,77 @@ struct jack_helpers : jack_client
return from_errc(err);
}
};
struct jack_queue
{
public:
static constexpr auto size_sz = sizeof(int32_t);
jack_queue() = default;
jack_queue(const jack_queue&) = delete;
jack_queue(jack_queue&&) = delete;
jack_queue& operator=(const jack_queue&) = delete;
jack_queue& operator=(jack_queue&& other) noexcept
{
ringbuffer = other.ringbuffer;
ringbuffer_space = other.ringbuffer_space;
other.ringbuffer = nullptr;
return *this;
}
explicit jack_queue(int64_t sz) noexcept
{
ringbuffer = jack_ringbuffer_create(sz);
ringbuffer_space = jack_ringbuffer_write_space(ringbuffer);
}
~jack_queue() noexcept
{
if (ringbuffer)
jack_ringbuffer_free(ringbuffer);
}
stdx::error write(const unsigned char* data, int64_t sz) const noexcept
{
if (static_cast<std::size_t>(sz + size_sz) > ringbuffer_space)
return std::errc::no_buffer_space;
while (jack_ringbuffer_write_space(ringbuffer) < sz + size_sz)
sched_yield();
jack_ringbuffer_write(ringbuffer, reinterpret_cast<char*>(&sz), size_sz);
jack_ringbuffer_write(ringbuffer, reinterpret_cast<const char*>(data), sz);
return stdx::error{};
}
void read(void* jack_events) const noexcept
{
int32_t sz;
while (jack_ringbuffer_peek(ringbuffer, reinterpret_cast<char*>(&sz), size_sz) == size_sz
&& jack_ringbuffer_read_space(ringbuffer) >= size_sz + sz)
{
jack_ringbuffer_read_advance(ringbuffer, size_sz);
if (auto midi = jack_midi_event_reserve(jack_events, 0, sz))
jack_ringbuffer_read(ringbuffer, reinterpret_cast<char*>(midi), sz);
else
jack_ringbuffer_read_advance(ringbuffer, sz);
}
}
jack_ringbuffer_t* ringbuffer{};
std::size_t ringbuffer_space{}; // actual writable size, usually 1 less than ringbuffer
};
struct jack_midi1
{
static constexpr const char* port_type = "8 bit raw midi";
};
struct jack_midi2
{
static constexpr const char* port_type = "32 bit raw UMP";
};
}
+6 -6
View File
@@ -4,13 +4,12 @@
#include <libremidi/detail/midi_in.hpp>
#include <libremidi/detail/midi_stream_decoder.hpp>
#include <chrono>
namespace libremidi
{
class midi_in_jack final
: public midi1::in_api
, public jack_helpers
, public jack_midi1
, public error_handler
{
public:
@@ -46,7 +45,8 @@ public:
stdx::error open_port(const input_port& port, std::string_view portName) override
{
if (auto err = create_local_port(*this, portName, JackPortIsInput); err != stdx::error{})
if (auto err = create_local_port(*this, portName, port_type, JackPortIsInput);
err != stdx::error{})
return err;
if (int err = jack_connect(this->client, port.port_name.c_str(), jack_port_name(this->port));
@@ -62,7 +62,7 @@ public:
stdx::error open_virtual_port(std::string_view portName) override
{
return create_local_port(*this, portName, JackPortIsInput);
return create_local_port(*this, portName, port_type, JackPortIsInput);
}
stdx::error close_port() override { return do_close_port(); }
@@ -96,8 +96,8 @@ public:
this->client, &current_frames, &current_usecs, &next_usecs, &period_usecs);
// We have midi events in buffer
uint32_t evCount = jack_midi_get_event_count(buff);
for (uint32_t j = 0; j < evCount; j++)
uint32_t ev_count = jack_midi_get_event_count(buff);
for (uint32_t j = 0; j < ev_count; j++)
{
jack_midi_event_t event{};
jack_midi_event_get(&event, buff, j);
+8 -71
View File
@@ -3,76 +3,12 @@
#include <libremidi/backends/jack/helpers.hpp>
#include <libremidi/detail/midi_out.hpp>
#include <semaphore>
namespace libremidi
{
struct jack_queue
{
public:
static constexpr auto size_sz = sizeof(int32_t);
jack_queue() = default;
jack_queue(const jack_queue&) = delete;
jack_queue(jack_queue&&) = delete;
jack_queue& operator=(const jack_queue&) = delete;
jack_queue& operator=(jack_queue&& other) noexcept
{
ringbuffer = other.ringbuffer;
ringbuffer_space = other.ringbuffer_space;
other.ringbuffer = nullptr;
return *this;
}
explicit jack_queue(int64_t sz) noexcept
{
ringbuffer = jack_ringbuffer_create(sz);
ringbuffer_space = jack_ringbuffer_write_space(ringbuffer);
}
~jack_queue() noexcept
{
if (ringbuffer)
jack_ringbuffer_free(ringbuffer);
}
stdx::error write(const unsigned char* data, int64_t sz) const noexcept
{
if (static_cast<std::size_t>(sz + size_sz) > ringbuffer_space)
return std::errc::no_buffer_space;
while (jack_ringbuffer_write_space(ringbuffer) < sz + size_sz)
sched_yield();
jack_ringbuffer_write(ringbuffer, reinterpret_cast<char*>(&sz), size_sz);
jack_ringbuffer_write(ringbuffer, reinterpret_cast<const char*>(data), sz);
return stdx::error{};
}
void read(void* jack_events) const noexcept
{
int32_t sz;
while (jack_ringbuffer_peek(ringbuffer, reinterpret_cast<char*>(&sz), size_sz) == size_sz
&& jack_ringbuffer_read_space(ringbuffer) >= size_sz + sz)
{
jack_ringbuffer_read_advance(ringbuffer, size_sz);
if (auto midi = jack_midi_event_reserve(jack_events, 0, sz))
jack_ringbuffer_read(ringbuffer, reinterpret_cast<char*>(midi), sz);
else
jack_ringbuffer_read_advance(ringbuffer, sz);
}
}
jack_ringbuffer_t* ringbuffer{};
std::size_t ringbuffer_space{}; // actual writable size, usually 1 less than ringbuffer
};
class midi_out_jack
: public midi1::out_api
, public jack_helpers
, public jack_midi1
, public error_handler
{
public:
@@ -94,7 +30,8 @@ public:
stdx::error open_port(const output_port& port, std::string_view portName) override
{
if (auto err = create_local_port(*this, portName, JackPortIsOutput); err != stdx::error{})
if (auto err = create_local_port(*this, portName, port_type, JackPortIsOutput);
err != stdx::error{})
return err;
// Connecting to the output
@@ -111,7 +48,7 @@ public:
stdx::error open_virtual_port(std::string_view portName) override
{
return create_local_port(*this, portName, JackPortIsOutput);
return create_local_port(*this, portName, port_type, JackPortIsOutput);
}
stdx::error close_port() override { return do_close_port(); }
@@ -128,7 +65,7 @@ class midi_out_jack_queued final : public midi_out_jack
public:
midi_out_jack_queued(output_configuration&& conf, jack_output_configuration&& apiconf)
: midi_out_jack{std::move(conf), std::move(apiconf)}
, queue{configuration.ringbuffer_size}
, m_queue{configuration.ringbuffer_size}
{
auto status = connect(*this);
if (!this->client)
@@ -150,7 +87,7 @@ public:
stdx::error send_message(const unsigned char* message, std::size_t size) override
{
return queue.write(message, size);
return m_queue.write(message, size);
}
int process(jack_nframes_t nframes)
@@ -158,13 +95,13 @@ public:
void* buff = jack_port_get_buffer(this->port, nframes);
jack_midi_clear_buffer(buff);
this->queue.read(buff);
this->m_queue.read(buff);
return 0;
}
private:
jack_queue queue;
jack_queue m_queue;
};
class midi_out_jack_direct final : public midi_out_jack
+6 -7
View File
@@ -10,6 +10,7 @@ namespace libremidi
class observer_jack final
: public observer_api
, private jack_client
, public jack_midi1
, private error_handler
{
public:
@@ -48,8 +49,7 @@ public:
void initial_callback()
{
{
const char** ports
= jack_get_ports(client, nullptr, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput);
const char** ports = jack_get_ports(client, nullptr, port_type, JackPortIsOutput);
if (ports != nullptr)
{
@@ -80,8 +80,7 @@ public:
}
{
const char** ports
= jack_get_ports(client, nullptr, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput);
const char** ports = jack_get_ports(client, nullptr, port_type, JackPortIsInput);
if (ports != nullptr)
{
@@ -119,7 +118,7 @@ public:
if (reg)
{
std::string_view type = jack_port_type(port);
if (type != JACK_DEFAULT_MIDI_TYPE)
if (type != port_type)
return;
bool physical = flags & JackPortIsPhysical;
@@ -199,12 +198,12 @@ public:
std::vector<libremidi::input_port> get_input_ports() const noexcept override
{
return get_ports<true>(this->client, nullptr, JackPortIsOutput);
return get_ports<true>(this->client, nullptr, port_type, JackPortIsOutput, false);
}
std::vector<libremidi::output_port> get_output_ports() const noexcept override
{
return get_ports<false>(this->client, nullptr, JackPortIsInput);
return get_ports<false>(this->client, nullptr, port_type, JackPortIsInput, false);
}
~observer_jack()