From 8c978328b0d69216a1e60c3330c07d83c1408e12 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Mon, 16 Apr 2018 15:36:14 +0200 Subject: Add velocity code --- arduino/Laserharfe/Laserharfe.ino | 4 +-- engine.c | 57 ++++++++++++++++++++++++++++++--------- midi-sdl.c | 4 +-- midi.h | 2 +- 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/arduino/Laserharfe/Laserharfe.ino b/arduino/Laserharfe/Laserharfe.ino index 1d7adeb..b219951 100644 --- a/arduino/Laserharfe/Laserharfe.ino +++ b/arduino/Laserharfe/Laserharfe.ino @@ -262,9 +262,9 @@ void handle_midi(char *command) { Serial.println("- MIDI SENT"); } -void midi_playnote(int channel, int note, int octave_offset ) { +void midi_playnote(int channel, int note, int octave_offset, int velocity ) { midi_pitchbend(channel, 0); - midiEventPacket_t p = { 0x9, 0x90 | channel, note + 12 * octave_offset, 0x7f }; + midiEventPacket_t p = { 0x9, 0x90 | channel, note + 12 * octave_offset, velocity }; MidiUSB.sendMIDI(p); } diff --git a/engine.c b/engine.c index 1c4e42a..d9b35f7 100644 --- a/engine.c +++ b/engine.c @@ -195,7 +195,7 @@ engine_handle_point(LPoint * p, uint32_t monotime) StringConfig *s;; int dist_max = 1024 * 1024 * 8; int offs, saite = -1, i, oct = 0; - int y_viewfield, pitch_factor = 12; + int y_viewfield, pitch_factor = 256*128; int dv, dt, speed, new_pitch; #ifndef NO_DISPLAY @@ -250,29 +250,42 @@ engine_handle_point(LPoint * p, uint32_t monotime) oct = -oct; switch (s->playing) { - case silent: - midi_playnote(s->channel, s->note, oct); - s->playing = in_attack; + case string_is_silent: + s->playing = string_is_in_attack; s->octave = oct; s->start_off = s->last_off = offs; s->first_time_seen = monotime; break; - case in_attack: + case string_is_in_attack: // test if difference is less than g_settled_dist percent of // line segment length - if (100 * abs(s->last_off - offs) < g_settled_dist << 16) { - s->playing = playing; - s->current_pitch = 0; + dt = monotime - s->first_time_seen; + if (dt > 10 && abs(s->last_off - offs) < g_settled_dist) { + s->playing = string_is_playing; // estimated energy of hand is dv/dt from first seen to settled dv = abs(s->start_off - offs); - dt = monotime - s->first_time_seen; if (!dt) ++dt; speed = 1000 * dv / dt; // in offs_prec per second +// printf("SPEED: %d (%d) for dt %d\n", speed, 64 + speed / 4000, dt); + speed = 64 + speed / 4000; + if (speed > 127) speed = 127; + midi_playnote(s->channel, s->note, s->octave, speed); + + /* XXX TODO report speed as midi command */ + s->start_off = offs; } + s->octave = oct; s->last_off = offs; break; - case playing: + case string_is_playing: + if (monotime - s->first_time_seen < g_pitchbend_delay) + break; + s->start_off = offs; + s->current_pitch = 0; + s->playing = string_is_bending; + break; + case string_is_bending: if (s->pitch_factor) pitch_factor = s->pitch_factor; if (s->modifier == pitch_bend_up) @@ -302,9 +315,29 @@ engine_checksilence(uint32_t monotime) if (s->mode == midi_controller) continue; + + // Play notes in attack that are not visible anymore + if (s->playing == string_is_in_attack && (monotime - s->last_time_seen) > 5) { + int speed, dv, dt = monotime - s->first_time_seen; + if (!dt) ++dt; + s->playing = string_is_playing; + s->current_pitch = 0; + + // estimated energy of hand is dv/dt from first seen to settled + dv = abs(s->start_off - s->last_off); + speed = 1000 * dv / dt; // in offs_prec per second +// printf("SPEED: %d (%d) for dt %d\n", speed, 64 + speed / 4000, dt); + speed = 64 + speed / 4000; + if (speed > 127) speed = 127; + midi_playnote(s->channel, s->note, s->octave, speed); + + s->start_off = s->last_off; + } + if (s->playing && (monotime - s->last_time_seen > tts)) { - midi_silencenote(s->channel, s->note, s->octave); - s->playing = silent; + if (s->playing >= string_is_playing) + midi_silencenote(s->channel, s->note, s->octave); + s->playing = string_is_silent; } } } diff --git a/midi-sdl.c b/midi-sdl.c index 7509859..a458528 100644 --- a/midi-sdl.c +++ b/midi-sdl.c @@ -9,9 +9,9 @@ int midi_init() { return 0; } -void midi_playnote( int channel, int note, int octave_offset ) { +void midi_playnote( int channel, int note, int octave_offset, int velocity ) { char out[32]; - int b = sprintf(out,"M%02X0020\nM%02X%02X%02X\n", 0xe0 | channel, 0x90 | channel, note + 12 * octave_offset, 0x7f); + int b = sprintf(out,"M%02X0020\nM%02X%02X%02X\n", 0xe0 | channel, 0x90 | channel, note + 12 * octave_offset, velocity&127); if (g_harfe_connected && (g_harfe_fd != -1)) write(g_harfe_fd, out, b); } diff --git a/midi.h b/midi.h index 41a29fe..d2331b4 100644 --- a/midi.h +++ b/midi.h @@ -2,7 +2,7 @@ int midi_init(); -void midi_playnote( int channel, int note, int octave_offset ); +void midi_playnote( int channel, int note, int octave_offset, int velocity ); void midi_silencenote( int channel, int note, int octave_offset ); void midi_pitchbend( int channel, int pitch ); //void midi_controller_event( int saite, int value ); -- cgit v1.2.3