I'm using the USBhost_t36 lib to connect the popular Arturia minilab mk II midi keyboard/controller to a synth I have developed for Teensy 3.6. Unfortunately note on and off events are lost when I play keys and move the "modwheel" (really a touch slider) quickly at the same time. Interestingly, I see the issue only with the modwheel and not other controllers, including the pitch wheel which is also a touch slider. Maybe the minilab is sending modwheel data at a higher rate, but it seems a bit odd to me that the USBhost_t36 would not be able to keep up with any midi controller. I have tested the synth with the (non-host) USB midi connection, connectng the minilab to a computer and then the computer passing the data on to the Teensy via midiOX, and it works just fine via that midi path.
So the problem appears to be with the USBhost_t36 lib code rather than my software. And indeed I can replicate the same problem using the "InputFunctions" example code provided in the library. I stripped that example down to the bare minimum and left in only the callbacks for midi note on/off and modwheel CC. I added one variable that keeps track of the number of notes being held down (NumNotes) that is incremented for note on events and decremented for note off (or 0-velocity note on) events. When I release all the keys on the controller, that number should then be 0, but it is not always when I move the modwheel quickly whilst playing notes. The serial print shows that both note off and on events can be lost during modwheel movements. It even happens when I do nothing inside the modwheel callback (commenting out its serial print messages).
Any suggestions for things to try are appreciated. I reinstalled the latest versions of Arduino / Teensyduino jus in case, but no change.
Here is the modified example code:
And here is an example of a section of the the Serial output showing the problem for a missing note-on event:
Note On, ch=1, note=59, velocity=95
>>>>>>>> 1
Note Off, ch=1, note=59, velocity=0
>>>>>>>> 0
Note On, ch=1, note=62, velocity=125
>>>>>>>> 1
Note Off, ch=1, note=60, velocity=0
>>>>>>>> 0
Note Off, ch=1, note=62, velocity=0
>>>>>>>> -1
p.s. In this library example code, what is the purpose of myusb.Task() in the main loop? I can comment it out with no effect on the code's function, so I'm unclear on when this line would be needed and when it would not.
So the problem appears to be with the USBhost_t36 lib code rather than my software. And indeed I can replicate the same problem using the "InputFunctions" example code provided in the library. I stripped that example down to the bare minimum and left in only the callbacks for midi note on/off and modwheel CC. I added one variable that keeps track of the number of notes being held down (NumNotes) that is incremented for note on events and decremented for note off (or 0-velocity note on) events. When I release all the keys on the controller, that number should then be 0, but it is not always when I move the modwheel quickly whilst playing notes. The serial print shows that both note off and on events can be lost during modwheel movements. It even happens when I do nothing inside the modwheel callback (commenting out its serial print messages).
Any suggestions for things to try are appreciated. I reinstalled the latest versions of Arduino / Teensyduino jus in case, but no change.
Here is the modified example code:
Code:
#include <USBHost_t36.h>
USBHost myusb;
MIDIDevice midi1(myusb);
void setup() {
Serial.begin(115200);
delay(1500);
myusb.begin();
midi1.setHandleNoteOn(myNoteOn);
midi1.setHandleNoteOff(myNoteOff);
midi1.setHandleControlChange(myControlChange);
}
int NumNotes=0;
void loop() {
myusb.Task();
midi1.read();
}
void myNoteOn(byte channel, byte note, byte velocity) {
Serial.print("Note On, ch=");
Serial.print(channel, DEC);
Serial.print(", note=");
Serial.print(note, DEC);
Serial.print(", velocity=");
Serial.println(velocity, DEC);
Serial.print(">>>>>>>> ");
if(velocity>0)
Serial.println(++NumNotes);
else
Serial.println(--NumNotes);
}
void myNoteOff(byte channel, byte note, byte velocity) {
Serial.print("Note Off, ch=");
Serial.print(channel, DEC);
Serial.print(", note=");
Serial.print(note, DEC);
Serial.print(", velocity=");
Serial.println(velocity, DEC);
Serial.print(">>>>>>>> ");
Serial.println(--NumNotes);
}
And here is an example of a section of the the Serial output showing the problem for a missing note-on event:
Note On, ch=1, note=59, velocity=95
>>>>>>>> 1
Note Off, ch=1, note=59, velocity=0
>>>>>>>> 0
Note On, ch=1, note=62, velocity=125
>>>>>>>> 1
Note Off, ch=1, note=60, velocity=0
>>>>>>>> 0
Note Off, ch=1, note=62, velocity=0
>>>>>>>> -1
p.s. In this library example code, what is the purpose of myusb.Task() in the main loop? I can comment it out with no effect on the code's function, so I'm unclear on when this line would be needed and when it would not.
Last edited: