diff options
Diffstat (limited to 'engine.c')
| -rw-r--r-- | engine.c | 57 |
1 files changed, 45 insertions, 12 deletions
| @@ -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 | } |
