jack-tools

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

commit eeec4ad9d1a4658251efc5e120630748c9db756e
parent 473d45aa082af4cd8922bb69631efa52bd9ab296
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Wed, 30 Dec 2020 17:45:41 +0000

simple mono synthesizer

Diffstat:
Mmain.cpp | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 102 insertions(+), 17 deletions(-)

diff --git a/main.cpp b/main.cpp @@ -5,6 +5,8 @@ #include <memory> #include <cassert> +#include <cmath> + #include <thread> #include <chrono> #include <iostream> @@ -30,6 +32,14 @@ struct client { jack_set_process_callback(**this, cb, arg); } + void set_buffer_size_callback(JackBufferSizeCallback cb, void* arg) + { + jack_set_buffer_size_callback(**this, cb, arg); + } + void set_sample_rate_callback(JackSampleRateCallback cb, void* arg) + { + jack_set_sample_rate_callback(**this, cb, arg); + } private: static jack_client_t* create(char const* name, jack_options_t options) @@ -135,48 +145,123 @@ private: } jack::client client("h-synth", JackNoStartServer); -jack::port p1(client, "port1", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0); +jack::port p1(client, "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); +jack::port p2(client, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); jack::ringbuffer midi_data(1024); std::atomic_int midi_events; +std::atomic<jack_nframes_t> buffer_size, sample_rate; + +int cb_buffer_size(jack_nframes_t nframes, void* arg) +{ + buffer_size = nframes; + return 0; +} +int cb_sample_rate(jack_nframes_t nframes, void* arg) +{ + sample_rate = nframes; + return 0; +} int cb_process(jack_nframes_t nframes, void* arg) { void* buf = jack_port_get_buffer(*p1, nframes); + static float envelope, freq; + static unsigned char note = 0xFF; 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; + + switch (event.buffer[0] >> 4 & 0x7) + { + case 0: // Note off + if (event.buffer[1] == note) + envelope = 0; + break; + case 1: // Note on + note = event.buffer[1]; + freq = 440 * pow(pow(2.f, 1.f/12), note - 69); + envelope = event.buffer[2]; + envelope /= 128; + break; + default: + ; + } + } + + auto audio_buf = static_cast<float*>(jack_port_get_buffer(*p2, nframes)); + + int srate = sample_rate; + static float sample; + + for (unsigned i = 0; i < buffer_size; ++i) + { + audio_buf[i] = std::sin(static_cast<float>(sample) * 6.28318530718f / srate) * envelope; + sample += freq; + if (sample >= srate) + sample -= srate; + //sample %= srate; } -// midi_events.notify_all(); return 0; } -int main() +void print_midi_events(void) { - client.set_process_callback(cb_process, nullptr); - client.activate(); + static int last = 0; + int current = midi_events; - int last = 0, current; + if (current == last) + return; - for (;;) - { - current = midi_events; - if (current == last) - continue; + last = current; + std::cout << "processed " << current << " 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'; +} + +void print_buffer_size(void) +{ + static int last = 0; + int current = buffer_size; + + if (current == last) + return; - last = current; + last = current; + std::cout << "Buffer size changed to: " << current << '\n'; +} +void print_sample_rate(void) +{ + static int last = 0; + int current = sample_rate; -// midi_events.wait(); - std::cout << "processed " << midi_events << " MIDI events:\n" << std::hex; + if (current == last) + return; - for (unsigned char buf; midi_data.read(&buf, sizeof(buf)); /**/) - std::cout << std::setw(3) << +buf; + last = current; + std::cout << "Sample rate changed to: " << current << '\n'; +} + +int main() +{ + client.set_process_callback(cb_process, nullptr); + client.set_buffer_size_callback(cb_buffer_size, nullptr); + client.set_sample_rate_callback(cb_sample_rate, nullptr); + client.activate(); - std::cout << std::dec << '\n'; + for (;;) + { + std::this_thread::sleep_for(5ms); + print_buffer_size(); + print_sample_rate(); + print_midi_events(); } return 0;