commit eeec4ad9d1a4658251efc5e120630748c9db756e
parent 473d45aa082af4cd8922bb69631efa52bd9ab296
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Wed, 30 Dec 2020 17:45:41 +0000
simple mono synthesizer
Diffstat:
M | main.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;