jack-tools

A handful of JACK audio tools
git clone git://henryandlizzy.uk/jack-tools
Log | Files | Refs

commit 473d45aa082af4cd8922bb69631efa52bd9ab296
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Wed, 30 Dec 2020 11:56:52 +0000

Initial commit

Diffstat:
A.gitignore | 2++
Amain.cpp | 183+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amakefile | 4++++
3 files changed, 189 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +*.[od] +main diff --git a/main.cpp b/main.cpp @@ -0,0 +1,183 @@ +#include <jack/jack.h> +#include <jack/midiport.h> +#include <jack/ringbuffer.h> + +#include <memory> +#include <cassert> + +#include <thread> +#include <chrono> +#include <iostream> +#include <iomanip> + +using namespace std::literals::chrono_literals; + +namespace jack { + +struct client +{ + client() = default; + client(char const* name, jack_options_t options) + : handle(create(name, options), deleter) + {} + + void activate(void) + { + assert(not jack_activate(**this)); + } + + void set_process_callback(JackProcessCallback cb, void* arg) + { + jack_set_process_callback(**this, cb, arg); + } + +private: + static jack_client_t* create(char const* name, jack_options_t options) + { + jack_status_t status; + jack_client_t *ptr = jack_client_open(name, options, &status);; + if (ptr) + return ptr; + + std::exit(1); + } + + static void deleter(jack_client_t* const p) + { + assert(not jack_deactivate(p)); + } + + std::unique_ptr<jack_client_t, void (*)(jack_client_t*)> handle = {nullptr, deleter}; + + jack_client_t* operator *(void) + { + return handle.get(); + } + + friend struct port; +}; + +struct port +{ + port() = default; + + port(client& _c, char const* name, char const* type, unsigned long flags, unsigned long buffer_size) + : c(*_c) + , p(jack_port_register(c, name, type, flags, buffer_size)) + { + assert(p); + } + ~port() + { + if (p) + jack_port_unregister(c, p); + } + port(port const&) = delete; + port& operator =(port const&) = delete; + + port(port&& old) + : c(old.c) + , p(old.p) + { + old.p = nullptr; + } + port& operator =(port&& old) + { + if (this != &old) + { + if (p) + jack_port_unregister(c, p); + + c = old.c; + p = old.p; + + old.p = nullptr; + } + return *this; + } + + jack_port_t* operator *(void) + { + return p; + } + +private: + jack_client_t* c = nullptr; + jack_port_t* p = nullptr; +}; + +struct ringbuffer +{ + ringbuffer() = default; + ringbuffer(size_t size) + : handle(jack_ringbuffer_create(size), jack_ringbuffer_free) + {} + + size_t write(void const* src, size_t size) + { + return jack_ringbuffer_write(**this, static_cast<char const*>(src), size); + } + + size_t read(void* dst, size_t size) + { + return jack_ringbuffer_read(**this, static_cast<char*>(dst), size); + } + +private: + std::unique_ptr<jack_ringbuffer_t, void (*)(jack_ringbuffer_t*)> handle = {nullptr, jack_ringbuffer_free}; + + jack_ringbuffer_t* operator *(void) + { + return handle.get(); + } +}; + +} + +jack::client client("h-synth", JackNoStartServer); +jack::port p1(client, "port1", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0); + +jack::ringbuffer midi_data(1024); + +std::atomic_int midi_events; + +int cb_process(jack_nframes_t nframes, void* arg) +{ + void* buf = jack_port_get_buffer(*p1, nframes); + + jack_midi_event_t event; + for (uint32_t i = 0; not jack_midi_event_get(&event, buf, i); ++i) + { + midi_data.write(event.buffer, event.size); + ++midi_events; + } +// midi_events.notify_all(); + return 0; +} + +int main() +{ + client.set_process_callback(cb_process, nullptr); + client.activate(); + + int last = 0, current; + + for (;;) + { + current = midi_events; + if (current == last) + continue; + + last = current; + +// midi_events.wait(); + std::cout << "processed " << midi_events << " MIDI events:\n" << std::hex; + + for (unsigned char buf; midi_data.read(&buf, sizeof(buf)); /**/) + std::cout << std::setw(3) << +buf; + + std::cout << std::dec << '\n'; + } + + return 0; +} diff --git a/makefile b/makefile @@ -0,0 +1,4 @@ +CXXFLAGS := -std=c++20 +LDLIBS := -ljack + +main: