summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arduino/Laserharfe/Laserharfe.ino4
-rw-r--r--engine.c57
-rw-r--r--midi-sdl.c4
-rw-r--r--midi.h2
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) {
262 Serial.println("- MIDI SENT"); 262 Serial.println("- MIDI SENT");
263} 263}
264 264
265void midi_playnote(int channel, int note, int octave_offset ) { 265void midi_playnote(int channel, int note, int octave_offset, int velocity ) {
266 midi_pitchbend(channel, 0); 266 midi_pitchbend(channel, 0);
267 midiEventPacket_t p = { 0x9, 0x90 | channel, note + 12 * octave_offset, 0x7f }; 267 midiEventPacket_t p = { 0x9, 0x90 | channel, note + 12 * octave_offset, velocity };
268 MidiUSB.sendMIDI(p); 268 MidiUSB.sendMIDI(p);
269} 269}
270 270
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)
195 StringConfig *s;; 195 StringConfig *s;;
196 int dist_max = 1024 * 1024 * 8; 196 int dist_max = 1024 * 1024 * 8;
197 int offs, saite = -1, i, oct = 0; 197 int offs, saite = -1, i, oct = 0;
198 int y_viewfield, pitch_factor = 12; 198 int y_viewfield, pitch_factor = 256*128;
199 int dv, dt, speed, new_pitch; 199 int dv, dt, speed, new_pitch;
200 200
201#ifndef NO_DISPLAY 201#ifndef NO_DISPLAY
@@ -250,29 +250,42 @@ engine_handle_point(LPoint * p, uint32_t monotime)
250 oct = -oct; 250 oct = -oct;
251 251
252 switch (s->playing) { 252 switch (s->playing) {
253 case silent: 253 case string_is_silent:
254 midi_playnote(s->channel, s->note, oct); 254 s->playing = string_is_in_attack;
255 s->playing = in_attack;
256 s->octave = oct; 255 s->octave = oct;
257 s->start_off = s->last_off = offs; 256 s->start_off = s->last_off = offs;
258 s->first_time_seen = monotime; 257 s->first_time_seen = monotime;
259 break; 258 break;
260 case in_attack: 259 case string_is_in_attack:
261 // test if difference is less than g_settled_dist percent of 260 // test if difference is less than g_settled_dist percent of
262 // line segment length 261 // line segment length
263 if (100 * abs(s->last_off - offs) < g_settled_dist << 16) { 262 dt = monotime - s->first_time_seen;
264 s->playing = playing; 263 if (dt > 10 && abs(s->last_off - offs) < g_settled_dist) {
265 s->current_pitch = 0; 264 s->playing = string_is_playing;
266 265
267 // estimated energy of hand is dv/dt from first seen to settled 266 // estimated energy of hand is dv/dt from first seen to settled
268 dv = abs(s->start_off - offs); 267 dv = abs(s->start_off - offs);
269 dt = monotime - s->first_time_seen;
270 if (!dt) ++dt; 268 if (!dt) ++dt;
271 speed = 1000 * dv / dt; // in offs_prec per second 269 speed = 1000 * dv / dt; // in offs_prec per second
270// printf("SPEED: %d (%d) for dt %d\n", speed, 64 + speed / 4000, dt);
271 speed = 64 + speed / 4000;
272 if (speed > 127) speed = 127;
273 midi_playnote(s->channel, s->note, s->octave, speed);
274
275 /* XXX TODO report speed as midi command */
276 s->start_off = offs;
272 } 277 }
278 s->octave = oct;
273 s->last_off = offs; 279 s->last_off = offs;
274 break; 280 break;
275 case playing: 281 case string_is_playing:
282 if (monotime - s->first_time_seen < g_pitchbend_delay)
283 break;
284 s->start_off = offs;
285 s->current_pitch = 0;
286 s->playing = string_is_bending;
287 break;
288 case string_is_bending:
276 if (s->pitch_factor) 289 if (s->pitch_factor)
277 pitch_factor = s->pitch_factor; 290 pitch_factor = s->pitch_factor;
278 if (s->modifier == pitch_bend_up) 291 if (s->modifier == pitch_bend_up)
@@ -302,9 +315,29 @@ engine_checksilence(uint32_t monotime)
302 315
303 if (s->mode == midi_controller) 316 if (s->mode == midi_controller)
304 continue; 317 continue;
318
319 // Play notes in attack that are not visible anymore
320 if (s->playing == string_is_in_attack && (monotime - s->last_time_seen) > 5) {
321 int speed, dv, dt = monotime - s->first_time_seen;
322 if (!dt) ++dt;
323 s->playing = string_is_playing;
324 s->current_pitch = 0;
325
326 // estimated energy of hand is dv/dt from first seen to settled
327 dv = abs(s->start_off - s->last_off);
328 speed = 1000 * dv / dt; // in offs_prec per second
329// printf("SPEED: %d (%d) for dt %d\n", speed, 64 + speed / 4000, dt);
330 speed = 64 + speed / 4000;
331 if (speed > 127) speed = 127;
332 midi_playnote(s->channel, s->note, s->octave, speed);
333
334 s->start_off = s->last_off;
335 }
336
305 if (s->playing && (monotime - s->last_time_seen > tts)) { 337 if (s->playing && (monotime - s->last_time_seen > tts)) {
306 midi_silencenote(s->channel, s->note, s->octave); 338 if (s->playing >= string_is_playing)
307 s->playing = silent; 339 midi_silencenote(s->channel, s->note, s->octave);
340 s->playing = string_is_silent;
308 } 341 }
309 } 342 }
310} 343}
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() {
9 return 0; 9 return 0;
10} 10}
11 11
12void midi_playnote( int channel, int note, int octave_offset ) { 12void midi_playnote( int channel, int note, int octave_offset, int velocity ) {
13 char out[32]; 13 char out[32];
14 int b = sprintf(out,"M%02X0020\nM%02X%02X%02X\n", 0xe0 | channel, 0x90 | channel, note + 12 * octave_offset, 0x7f); 14 int b = sprintf(out,"M%02X0020\nM%02X%02X%02X\n", 0xe0 | channel, 0x90 | channel, note + 12 * octave_offset, velocity&127);
15 if (g_harfe_connected && (g_harfe_fd != -1)) 15 if (g_harfe_connected && (g_harfe_fd != -1))
16 write(g_harfe_fd, out, b); 16 write(g_harfe_fd, out, b);
17} 17}
diff --git a/midi.h b/midi.h
index 41a29fe..d2331b4 100644
--- a/midi.h
+++ b/midi.h
@@ -2,7 +2,7 @@
2 2
3int midi_init(); 3int midi_init();
4 4
5void midi_playnote( int channel, int note, int octave_offset ); 5void midi_playnote( int channel, int note, int octave_offset, int velocity );
6void midi_silencenote( int channel, int note, int octave_offset ); 6void midi_silencenote( int channel, int note, int octave_offset );
7void midi_pitchbend( int channel, int pitch ); 7void midi_pitchbend( int channel, int pitch );
8//void midi_controller_event( int saite, int value ); 8//void midi_controller_event( int saite, int value );