very, very simple WP with midi CC out

This commit is contained in:
Sebastian
2024-10-09 02:01:23 +02:00
commit 3d6fc151f1
126 changed files with 19539 additions and 0 deletions
+114
View File
@@ -0,0 +1,114 @@
#pragma once
#include <libremidi/backends/jack/config.hpp>
#include <libremidi/backends/jack/helpers.hpp>
#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 error_handler
{
public:
struct
: input_configuration
, jack_input_configuration
{
} configuration;
explicit midi_in_jack(input_configuration&& conf, jack_input_configuration&& apiconf)
: configuration{std::move(conf), std::move(apiconf)}
{
auto status = connect(*this);
if (status != jack_status_t{})
warning(configuration, "midi_in_jack: " + std::to_string((int)jack_status_t{}));
}
~midi_in_jack() override
{
midi_in_jack::close_port();
disconnect(*this);
}
void set_client_name(std::string_view) override
{
warning(configuration, "midi_in_jack: set_client_name unsupported");
}
libremidi::API get_current_api() const noexcept override { return libremidi::API::JACK_MIDI; }
bool open_port(const input_port& port, std::string_view portName) override
{
if (!create_local_port(*this, portName, JackPortIsInput))
return false;
if (auto ret = jack_connect(this->client, port.port_name.c_str(), jack_port_name(this->port));
ret != 0)
{
error<invalid_parameter_error>(
configuration, "JACK: could not connect to port: " + port.port_name + " -> "
+ jack_port_name(this->port));
return false;
}
return true;
}
bool open_virtual_port(std::string_view portName) override
{
return create_local_port(*this, portName, JackPortIsInput);
}
void close_port() override { return do_close_port(); }
void set_port_name(std::string_view portName) override
{
jack_port_rename(this->client, this->port, portName.data());
}
timestamp absolute_timestamp() const noexcept override
{
return 1000 * jack_frames_to_time(client, jack_frame_time(client));
}
int process(jack_nframes_t nframes)
{
static constexpr timestamp_backend_info timestamp_info{
.has_absolute_timestamps = true,
.absolute_is_monotonic = true,
.has_samples = true,
};
void* buff = jack_port_get_buffer(this->port, nframes);
// Timing
jack_nframes_t current_frames{};
jack_time_t current_usecs{}; // roughly CLOCK_MONOTONIC
jack_time_t next_usecs{};
float period_usecs{};
jack_get_cycle_times(
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++)
{
jack_midi_event_t event{};
jack_midi_event_get(&event, buff, j);
const auto to_ns
= [=, this] { return 1000 * jack_frames_to_time(client, current_frames + event.time); };
m_processing.on_bytes(
{event.buffer, event.buffer + event.size},
m_processing.timestamp<timestamp_info>(to_ns, event.time));
}
return 0;
}
midi1::input_state_machine m_processing{this->configuration};
};
}