jack-tools

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

commit f5f0369625d186ad69f968453b7dfcb10f9543de
parent 48f965ae8a00b74431d6498baae4cd900010900f
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Wed, 30 Dec 2020 23:18:52 +0000

attack, delay, release & sustain

Diffstat:
Mmain.cpp | 59++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 46 insertions(+), 13 deletions(-)

diff --git a/main.cpp b/main.cpp @@ -167,28 +167,43 @@ int cb_sample_rate(jack_nframes_t nframes, void* arg) static struct voice { float envelope, freq, sample; + unsigned char active : 1, velocity : 7, state : 2; } voices[128]; int cb_process(jack_nframes_t nframes, void* arg) { + static char sustain; 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; - + auto& voice = voices[event.buffer[1]]; switch (event.buffer[0] >> 4 & 0x7) { case 0: // Note off - voices[event.buffer[1]].envelope = 0; - break; + voice.active = 0; + continue; case 1: // Note on - voices[event.buffer[1]].envelope = event.buffer[2] / 128.f; - break; + voice.active = 1; + voice.state = 2; + voice.velocity = event.buffer[2]; + continue; + case 3: // Controller change + switch (event.buffer[1]) + { + case 0x40: // Sustain + sustain = event.buffer[2] > 63; + if (not sustain) + for (auto& v : voices) + if (not v.active and v.state == 1) + v.state = 0; + continue; + } + /* FALLTHROUGH */ default: - ; + midi_data.write(event.buffer, event.size); + ++midi_events; } } @@ -201,13 +216,33 @@ int cb_process(jack_nframes_t nframes, void* arg) float accum = 0; for (auto& v : voices) { - if (v.envelope < .02f) - continue; - accum += std::sin(v.sample * 6.28318530718f / srate) * v.envelope; v.sample += v.freq; if (v.sample >= srate) v.sample -= srate; + + float velocity = v.velocity / 127.f; + + if (v.state == 2) + { + v.envelope += velocity / 5000.f; + if (v.envelope >= velocity) + { + v.envelope = velocity; + v.state = 1; + } + } + else if (v.state == 1) + { + v.envelope -= (v.envelope - velocity * 0.2f) * 0.00005f; + if (not (sustain || v.active)) + v.state = 0; + } + else + { + v.velocity = 0; + v.envelope *= 0.9998f; + } } audio_buf[i] = 2 / (1 + std::exp(accum)) - 1; } @@ -261,8 +296,6 @@ int main() { v.envelope = 0; v.freq = 440 * std::pow(std::pow(2.f, 1.f/12), note++ - 69); - - std::cout << v.freq << "Hz\n"; } client.set_process_callback(cb_process, nullptr);