graydetroit
Well-known member
Background:
I'm using the Teensy 4.1 to build a MIDI program change sequencer/orchestrator. I wanted a device that acts as the main clock source for various MIDI instruments, and I wanted a device that can sequence program change messages. Most existing sequencers do way more than that, so I thought this would be a good project for a Teensy.
All it really does is send MIDI clock and program change messages over USB MIDI to a max of 4 instruments connected to the Teensy via the USB Host port.
I'm also using a ILI9341 driven display module for the main UI display, specifically this one for now for prototyping: https://www.adafruit.com/product/1480
The rest of the build is just some switches/buttons.
Here's a link to my unfinished code.
Here's a photo of the prototype so far. All the wiring is underneath the perfboard, but I don't think the wiring is the problem.
Here's a video of the MIDI clock working as expected, with no jitter, with no calls to update the display during playback.
Problem 1:
I have some code in XRSequencer.cpp, which gets executed during the main loop if the sequencer is running:
when the commented out part is uncommented, that portion of the code makes calls to update the display while the internal sequencer is running / sending MIDI messages. In this example, the calls to update the display occur on every completed bar (isProgChanging), since this code updates the display to indicate which program is currently playing.
I notice some jitter in the clock. The instruments begin to sound disjointed, like every display update is introducing some delay time to the main sequencer update loop.
See this video for an example of this problem.
Problem 2:
There's another area of the code that I modified to try and allow setting the tempo while sequencer is running, but which causes the clock to get all messed up, more extreme than the previous example. I think the reason it's so messed up is because every time I push the up/down buttons to set the tempo, the display is being updated, causing the clock timing to get messed up somehow.
This is that portion of the code in XRSequencer.cpp, but is currently limited to being executed if the sequencer is not running, so as to not cause this issue:
See this video for an example of this problem.
Solution?
This could be a code issue, but my thought is, what I just offloaded the display processing to a separate Teensy, so that the MIDI processing isn't hindered by the display processing? I'd love to not have to do that, but I'm not sure what else in the code could be causing the MIDI jitter like this.
Thanks in advance!
I'm using the Teensy 4.1 to build a MIDI program change sequencer/orchestrator. I wanted a device that acts as the main clock source for various MIDI instruments, and I wanted a device that can sequence program change messages. Most existing sequencers do way more than that, so I thought this would be a good project for a Teensy.
All it really does is send MIDI clock and program change messages over USB MIDI to a max of 4 instruments connected to the Teensy via the USB Host port.
I'm also using a ILI9341 driven display module for the main UI display, specifically this one for now for prototyping: https://www.adafruit.com/product/1480
The rest of the build is just some switches/buttons.
Here's a link to my unfinished code.
Here's a photo of the prototype so far. All the wiring is underneath the perfboard, but I don't think the wiring is the problem.
Here's a video of the MIDI clock working as expected, with no jitter, with no calls to update the display during playback.
Problem 1:
I have some code in XRSequencer.cpp, which gets executed during the main loop if the sequencer is running:
Code:
[COLOR=#2838B0][I]void[/I][/COLOR] Sequencer[COLOR=#666666]:[/COLOR][COLOR=#666666]:[/COLOR]doStep[COLOR=#888888]([/COLOR][COLOR=#888888])[/COLOR]
[COLOR=#888888]{[/COLOR]
[COLOR=#2838B0]for[/COLOR] [COLOR=#888888]([/COLOR][COLOR=#2838B0]auto[/COLOR] [COLOR=#666666]&[/COLOR][COLOR=#289870]track[/COLOR] [COLOR=#888888]:[/COLOR] [COLOR=#2838B0]this[/COLOR][COLOR=#666666]-[/COLOR][COLOR=#666666]>[/COLOR]instrumentTracks[COLOR=#888888])[/COLOR] [COLOR=#888888]{[/COLOR]
[COLOR=#2838B0]if[/COLOR] [COLOR=#888888]([/COLOR][COLOR=#666666]![/COLOR]track[COLOR=#666666]-[/COLOR][COLOR=#666666]>[/COLOR]deviceActive [COLOR=#666666]|[/COLOR][COLOR=#666666]|[/COLOR] [COLOR=#666666]![/COLOR]track[COLOR=#666666]-[/COLOR][COLOR=#666666]>[/COLOR]trackActive[COLOR=#888888])[/COLOR] [COLOR=#888888]{[/COLOR]
[COLOR=#2838B0]return[/COLOR][COLOR=#888888];[/COLOR]
[COLOR=#888888]}[/COLOR]
[COLOR=#2838B0][I]bool[/I][/COLOR] isProgChanging [COLOR=#666666]=[/COLOR] track[COLOR=#666666]-[/COLOR][COLOR=#666666]>[/COLOR]doStep[COLOR=#888888]([/COLOR][COLOR=#2838B0]this[/COLOR][COLOR=#666666]-[/COLOR][COLOR=#666666]>[/COLOR]usb[COLOR=#888888])[/COLOR][COLOR=#888888];[/COLOR]
[COLOR=#2838B0]if[/COLOR] [COLOR=#888888]([/COLOR][COLOR=#2838B0]this[/COLOR][COLOR=#666666]-[/COLOR][COLOR=#666666]>[/COLOR]hardStart [COLOR=#666666]|[/COLOR][COLOR=#666666]|[/COLOR] isProgChanging[COLOR=#888888])[/COLOR] [COLOR=#888888]{[/COLOR]
[COLOR=#888888][I]// EXPERIMENTAL, highlight program index indicator on step
[/I][/COLOR][COLOR=#888888][I]// this->display->drawMainScreen(
[/I][/COLOR][COLOR=#888888][I]// this->currInstrument,
[/I][/COLOR][COLOR=#888888][I]// this->instrumentTracks,
[/I][/COLOR][COLOR=#888888][I]// true,
[/I][/COLOR][COLOR=#888888][I]// this->tempo,
[/I][/COLOR][COLOR=#888888][I]// this->currCursoredProgramIdx,
[/I][/COLOR][COLOR=#888888][I]// this->cursoringPrograms,
[/I][/COLOR][COLOR=#888888][I]// true
[/I][/COLOR][COLOR=#888888][I]// );
[/I][/COLOR] [COLOR=#888888]}[/COLOR]
[COLOR=#888888]}[/COLOR]
[COLOR=#888888]}[/COLOR]
when the commented out part is uncommented, that portion of the code makes calls to update the display while the internal sequencer is running / sending MIDI messages. In this example, the calls to update the display occur on every completed bar (isProgChanging), since this code updates the display to indicate which program is currently playing.
I notice some jitter in the clock. The instruments begin to sound disjointed, like every display update is introducing some delay time to the main sequencer update loop.
See this video for an example of this problem.
Problem 2:
There's another area of the code that I modified to try and allow setting the tempo while sequencer is running, but which causes the clock to get all messed up, more extreme than the previous example. I think the reason it's so messed up is because every time I push the up/down buttons to set the tempo, the display is being updated, causing the clock timing to get messed up somehow.
This is that portion of the code in XRSequencer.cpp, but is currently limited to being executed if the sequencer is not running, so as to not cause this issue:
Code:
if (upBtnPressed) {
this->tempo++;
this->tempo = min((int)this->tempo, 240);
this->display->drawTempoScreen(this->tempo);
this->doSetTempo();
} else if (downBtnPressed) {
this->tempo--;
this->tempo = max((int)this->tempo, 60);
this->display->drawTempoScreen(this->tempo);
this->doSetTempo();
}
See this video for an example of this problem.
Solution?
This could be a code issue, but my thought is, what I just offloaded the display processing to a separate Teensy, so that the MIDI processing isn't hindered by the display processing? I'd love to not have to do that, but I'm not sure what else in the code could be causing the MIDI jitter like this.
Thanks in advance!