@@ -26,16 +26,20 @@ static bool need_bytes(synthio_miditrack_obj_t *self, size_t count) {
2626 return true;
2727}
2828
29- static mp_obj_t parse_note (synthio_miditrack_obj_t * self ) {
29+ // Returns the note in the low 8 bits and the velocity in the next 8, or -1
30+ // if the pair could not be read.
31+ static int parse_note (synthio_miditrack_obj_t * self ) {
3032 uint8_t * buffer = self -> track .buf ;
3133 if (!need_bytes (self , 2 )) {
32- return MP_OBJ_NEW_SMALL_INT ( 0 ) ;
34+ return -1 ;
3335 }
34- uint8_t note = buffer [(self -> pos )++ ];
35- if (note > 127 || buffer [(self -> pos )++ ] > 127 ) {
36+ uint8_t note = buffer [self -> pos ++ ];
37+ uint8_t velocity = buffer [self -> pos ++ ];
38+ if (note > 127 || velocity > 127 ) {
3639 record_midi_stream_error (self );
40+ return -1 ;
3741 }
38- return MP_OBJ_NEW_SMALL_INT ( note );
42+ return note | ( velocity << 8 );
3943}
4044
4145// MIDI variable-length quantity: up to 4 bytes of 7 bits each.
@@ -115,14 +119,17 @@ static void decode_until_pause(synthio_miditrack_obj_t *self) {
115119 }
116120 }
117121 switch (status >> 4 ) {
118- case 8 : { // Note Off
119- mp_obj_t note = parse_note (self );
120- synthio_span_change_note (& self -> synth , note , SYNTHIO_SILENCE );
121- break ;
122- }
123- case 9 : { // Note On
124- mp_obj_t note = parse_note (self );
125- synthio_span_change_note (& self -> synth , SYNTHIO_SILENCE , note );
122+ case 8 : // Note Off
123+ case 9 : { // Note On, but a velocity of zero means Note Off
124+ int parsed = parse_note (self );
125+ if (parsed >= 0 ) {
126+ mp_obj_t note = MP_OBJ_NEW_SMALL_INT (parsed & 0xff );
127+ if ((status >> 4 ) == 9 && (parsed >> 8 ) != 0 ) {
128+ synthio_span_change_note (& self -> synth , SYNTHIO_SILENCE , note );
129+ } else {
130+ synthio_span_change_note (& self -> synth , note , SYNTHIO_SILENCE );
131+ }
132+ }
126133 break ;
127134 }
128135 case 10 :
0 commit comments