| 394 | } |
| 395 | |
| 396 | void processMessage(const midi::Message& msg) { |
| 397 | // DEBUG("MIDI: %ld %s", msg.getFrame(), msg.toString().c_str()); |
| 398 | |
| 399 | switch (msg.getStatus()) { |
| 400 | // note off |
| 401 | case 0x8: { |
| 402 | releaseNote(msg.getNote(), msg.getChannel(), msg.getValue()); |
| 403 | } break; |
| 404 | // note on |
| 405 | case 0x9: { |
| 406 | uint8_t velocity = msg.getValue(); |
| 407 | if (velocity > 0) { |
| 408 | pressNote(msg.getNote(), msg.getChannel(), velocity); |
| 409 | } |
| 410 | else { |
| 411 | // Note-on event with velocity 0 is an alternative for note-off event. |
| 412 | releaseNote(msg.getNote(), msg.getChannel(), -1); |
| 413 | } |
| 414 | } break; |
| 415 | // key pressure |
| 416 | case 0xa: { |
| 417 | // Set the aftertouches with the same note |
| 418 | // TODO Should we handle the MPE case differently? |
| 419 | for (uint8_t c = 0; c < MAX_CHANNELS; c++) { |
| 420 | if (notes[c] == msg.getNote()) |
| 421 | aftertouches[c] = msg.getValue(); |
| 422 | } |
| 423 | } break; |
| 424 | // cc |
| 425 | case 0xb: { |
| 426 | processCC(msg); |
| 427 | } break; |
| 428 | // channel pressure |
| 429 | case 0xd: { |
| 430 | if (channels > 1 && polyMode == MPE_MODE) { |
| 431 | // Set the channel aftertouch |
| 432 | aftertouches[msg.getChannel()] = msg.getNote(); |
| 433 | } |
| 434 | else { |
| 435 | // Set all aftertouches |
| 436 | for (uint8_t c = 0; c < MAX_CHANNELS; c++) { |
| 437 | aftertouches[c] = msg.getNote(); |
| 438 | } |
| 439 | } |
| 440 | } break; |
| 441 | // pitch wheel |
| 442 | case 0xe: { |
| 443 | uint8_t c = (channels > 1 && polyMode == MPE_MODE) ? msg.getChannel() : 0; |
| 444 | int16_t pw = msg.getValue(); |
| 445 | pw <<= 7; |
| 446 | pw |= msg.getNote(); |
| 447 | pw -= 8192; |
| 448 | pws[c] = pw; |
| 449 | } break; |
| 450 | case 0xf: { |
| 451 | processSystem(msg); |
| 452 | } break; |
| 453 | default: break; |
nothing calls this directly
no test coverage detected