summaryrefslogtreecommitdiff
path: root/engine.c
diff options
context:
space:
mode:
Diffstat (limited to 'engine.c')
-rw-r--r--engine.c57
1 files changed, 45 insertions, 12 deletions
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}