Bug with midi USB hanging notes - with possible fix #70
Replies: 12 comments 11 replies
-
Hi, thank you for this. The call on Core1 (for example "UsbMidi_ProcessSync") is just to get the slowly collected data in sync with audio task to avoid any glitches or collision by data access by both cores at the same time. For the displays I put data when running Core1 just into an buffer. Core0 checks this buffer for new data and displays it. You can also compare midi_interface.ino to my latest revision. I've fixed a little problem caused by aftertouch messages which might also appear when receiving other messages. I didn't used the USB host for a longer time but I can try it. |
Beta Was this translation helpful? Give feedback.
-
Thanks, I'll look to update to midi_interface.ino. I've been working a lot at trying different ways to get things to run smoothly on Core0. Its totally correct that they don't cause the IC2 audio loop interruptions running from there. Even small delays cause audio glitches. Some libraries are not Core0 friendly on ESP32 such as Wire or the AdafruitGFX or oled but its not on every ESP32?! Confusing. One of the main issues can also be with things like String Objects getting corrupted when handled by different Cores, at least people in forums say that. I don't know if its true but I rewrote things to use char arrays to see if it helped or at least remove that concern during debugging. |
Beta Was this translation helpful? Give feedback.
-
Ok - so I refactored (i've always disliked this term) - or rather incorporated your updates. Not every module but I will. I see you have UsbMidi_Loop(); in core0 and UsbMidi_ProcessSync(); in the main loop (core1). So this was a revelation. My big bug was getting my SSD1306 to run from core0 too - the thing just went corrupt or crashed. I debug it so much I have a #define DISPLAY_CORE (0 or 1) to flick back and forth. So running it as you had set with USBMidi_Loop updates to my display were coming from Core0 and now my display went corrupt running on core1. Boomshanka - so I switched it back to core0 and now its working. I noticed you added this to main page of project Here is a soldered together prototype - i haven't put screen in place it's floating in the air. I also noticed you have a monitor which I remember seeing in a video ... VT100. Your calls to that are const char *variable - Thanks for updating your project - I am glad I spent time updating my fork because I was about to try a different library hoping it might fix the issue with the display running from Core0. I have a feeling it has to do with wire and maybe some change you made improved the situation for my display module. |
Beta Was this translation helpful? Give feedback.
-
Your updated software seems to be efficient but the midi buffer via usb (since I don't have direct midi yet) still drops note offs. I tested with a couple of midi-keyboards. I thought i had fixed it earlier but i still have hanging notes. I increased the frequency of calling So forgive this "thinking out loud" debugging or assuming there is no bug - ask for help in understanding. I started my own queue to capture messages because I want to change performance to arpeggiator etc in my new version and I could see all the messages printed and find the instances where it missed one. So I'm trying to figure out where messages might be lost ... and understand the whole midi interface situation and assume there might be a bug somewhere or an improvement. There is some need to find if there is more left to poll again and I see there is also ... uint8_t USBH_MIDI::RecvData(uint8_t *outBuf, bool isRaw) variation and in the code in the library that version has this ... bit of code that the other one doesn't:
So, I am wondering about this other variation and if it prepares the buffer or has some combination usage? |
Beta Was this translation helpful? Give feedback.
-
Yes, I'm going to do that experiment soon. Thanks for checking back.
I wanT to try dumping unfiltered raw to see if I can find anything parser
missed.
Regards
Michael
…On Tue, Nov 9, 2021, 04:46 Marcel ***@***.***> wrote:
Hm there are some things to do to identify exactly where the data gets
lost. You can also go into the other direction and make things slower to
see if it has any effect.
I think UsbMidi_Poll could be the most time critical function. It pulls
data via SPI from the USB host. There are buffers in use. For example
calling the poll and also the process just once a second may slow things
down but can help to identify if messages are lost because of speed or
maybe that there are unexpected messages misunderstood by the parser and
some data dropped away. I didn't use the host for a long time. Only once to
create a possible interface to use.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#70 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ALTDOQ4EZPMVOI5TCYLKBODULBAMRANCNFSM5GDZZZ4Q>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Beta Was this translation helpful? Give feedback.
-
I've been experimenting and best I can do is reduce the chance of a hanging note or missing noteOn .. So I started to wonder about pull up resistors to the USBMidi. _"Pull-up resistors are ONLY needed when you have open collector/drain bus drive, as in TWI/I2C. SPI is full logic drive, hence GENERALLY not needed. There is, however, one situation in SPI where a pull-up could be useful. When the SPI device(s) is disabled (/S line high), the output pin goes Hi-Z so that any other active SPI device can drive that line. Hi-Z means that it has the electrical characteristics of an input (without being able to actually input anything). You Might add a pull-up resistor to this line so that the state will be defined when nothing is driving it (nothing selected). Few SPI systems bother with this detail, but it would keep the master end of the MISO line away from the voltage area near Vcc/2 where the input circuit will take more current (from power supply to ground) than is usual for a CMOS input circuit."_ (found this in a discussion https://www.avrfreaks.net/forum/why-have-pullup-mosi-and-miso) My circuit does kind of have current issues - my project is unstable unless I add an additional 5v power supply. I have an Oled and a DAC that has a little classD amp onboard ... so if i made too much volume it drained things. I put bypass caps to stabilize. Anyway, it made me wonder if there is a cyclic momentary state in the hardware (perhaps when some other onboard hardware serial communications is active) which is similar. So I'm going to experiment with this to see if it makes any improvement. The code doesn't seem to have any bug (not that I'm sure I would see it) given that it can go a long time without losing a note. Mashing a lot of simultaneous keys presents a very high chance of losing one note. Could that be related to communications too? |
Beta Was this translation helpful? Give feedback.
-
I'm not surprised - i'm starting to think its just a matter of my code
delaying the servicing to the point where it mostly works but
occasionally there is a delay ... or glitch. Still testing.
My only idea left, other than to work on different solutions and code is to
see about this interrupt pin in the USB host shield and make an interrupt
call to poll the USB. I've been putting together soldered versions and trying to stabilize everything the best I can or turn parts off that might cause these pauses.
Thanks for letting me know you were testing it.
Regards
Michael
…On Wed, Dec 1, 2021 at 7:01 PM Marcel ***@***.***> wrote:
Hi, I have some days off and tested the MIDI USB interface today and
yesterday. With the Roland Edirol PCR-800 and also the ESI M4U XL I had no
issues. I am not sure if some kind of fix was integrated in the meantime.
If you like please try the latest version of:
https://github.com/marcel-licence/esp32_esp8266_organ
Hitting multiple keys very quickly should generate output like this:
short: 91 39 64
short: 91 3c 6f
short: 91 3e 6f
short: 91 40 69
short: 81 3c 6a
short: 81 3e 65
short: 81 40 4f
short: 81 39 54
The output is enabled in the project. For ESP32 only the define for
MIDI_VIA_USB_ENABLED needs to be enabled. If you like please let me know
what kind of result you get and also some debug output if problems appear.
Best regards
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#70 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ALTDOQ6WXSE4GPASTUXIPNDUOYFAVANCNFSM5GDZZZ4Q>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Beta Was this translation helpful? Give feedback.
-
It comes down to some kind of pause that happens every now and then such as
a low level memory clean up or some delay and wait state that happens
intermittently ... because when I would test all would be find, just as you
show ... i mean you have to play for a while and a note or many notes come
suddenly hanging. What shouldn't happen ... happens because the system
pauses.
With the current changes that seems to happen less frequently.
Regards
Michael
…On Fri, Dec 10, 2021 at 3:44 AM Marcel ***@***.***> wrote:
Hm I am not sure why you get different results. I do not use the interrupt
pin. Using two tasks on core0 might decrease the performance because only
one could be active at the time. That was the reason to put all into one
function to ensure that there are no unexpected delays.
I made a test with the organ project putting a delay(500); in the loop
function. It looks like the USB host can buffer some messages (enough for a
complete chord). Only if I play two many notes in the short time I can get
losses and also see cc cc cc in the debug output:
short: 91 46 4d
short: 91 46 4d
short: 81 46 1a
short: 81 46 1a
short: 81 43 6f
short: 81 43 6f
short: 81 40 6a
short: 91 43 5c
short: 81 40 6a
short: 91 43 5c
short: 81 3c 42
short: 91 46 4d
short: 81 3c 42
short: 91 46 4d
short: cc cc cc
short: 81 46 1a
short: cc cc cc
short: 81 46 1a
short: cc cc cc
short: 81 43 6f
short: 81 43 6f
Adding an OLED should be feasable. In most designs I am using OLED + SPI
controlled by core0 with a good performance.
The SS connection is requied I think. If chip select would be floating you
could get random results. I am not sure but I think it also helps to
identify the first bit of transmission and avoiding communication problems
especially with a high SPI frequency.
I pushed a little change on GitHub. I tested this with two changes in the
config.h and the following defines active:
#define BOARD_ESP32_DOIT /* activate this when using the DOIT ESP32 DEVKIT
V1 board */
#define MIDI_VIA_USB_ENABLED
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#70 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ALTDOQ6QPQVSLXLXIMIDPNDUQEIMBANCNFSM5GDZZZ4Q>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Beta Was this translation helpful? Give feedback.
-
Thanks for your attention: I'm ending this here.
I think the extra time polling is perhaps only helpful for the power shortage drop outs and its therefore not the correct approach. So a better power supply and well done bypass caps will improve the USB stability as one would expect. Regards |
Beta Was this translation helpful? Give feedback.
-
Yes - i either powered it with an additional psu, or I powered it from the
vin pin. On testing systems I have a 5v 2A PSU that routes in parallel to
USB +5 rail (which I cut the track on the USB_HOST so it doesn't share
power with the Vss of the USB_HOST as shown in some demos) that way the
3.3v is independent.
What I haven't done yet is run 3.3v from a regulator of my own AND 5v. I
rely on the ESP_32 dev board regulator and it is supplying the oled,
usb_host, DAC and some buttons. So - yeah, it can be perhaps sagging at
times.
So I have now some more regulators to make a better PSU for it.
Regards
Michael
…On Tue, Dec 14, 2021 at 2:03 AM Marcel ***@***.***> wrote:
Hi Michael,
just a short question, did you also provide 5V to the USB host module?
I've added a second power source to provide the 5V for the attached device
for supply.
Best regards,
Marcel
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#70 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ALTDOQ3KQRBFTPNZ45F6WMLUQY7PVANCNFSM5GDZZZ4Q>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Beta Was this translation helpful? Give feedback.
-
Incase you get back to this thread here are some new observations: So I have made a bunch of synths ... and I keep going slowly playing around. The last few all went to Serial MIDI so this thread was kind of quiet. Next I loaded my last version of ESP32_Basic_Synth code and ... perfect, no problem with lost notes and that code has the extra iterations in the midi_poll() function. Another consideration is that I'm using the ADC Module in my implementation of the ml_synth_organ as well as a 7seg display that I've specifically built. These are running in the same I've written very quick shift register (shift_out) function so that doesn't create much overhead. The reading of the analogue does seem to take enough time to impact the reliability of getting midi notes. Its all about polling fast enough and polling with the loop to catch up on the queue in case a lot of notes trigger together. I changed it to just read one analogue potentiometer and I service that only once ever 10 times (so I guess 12 milliseconds) which has no negative impact on usability. I can probably do it far less frequently or even just process one analogue channel per call instead of looping through them all.
So ... what i'm saying is that
Finally:
|
Beta Was this translation helpful? Give feedback.
-
I'm going to try and make an interrupt service routine that is very fast
for the USB_Host.
I was using the USB_Midi as per your code in this situation but had to
start playing to make it playable. Anyway, I'm happy to merely report what
I find.
…On Thu, Feb 17, 2022 at 2:11 AM Marcel ***@***.***> wrote:
Hm, hard topic. The delay(1) and yield() is maybe not the perfect
solution. It shouldn't harm the code but it is required otherwise the core
might crash.
I couldn't see any serious difference. One important feature is missing: a
buffer overflow indication. That would help to identify to slow code. In
all other cases the usb host should be able to store messages until they
are pulled out.
Finally I do not use the RTOS as it is designed. The while true does not
allow the RTOS to do its thing and take care of different tasks. I have
only two tasks designed. The rest will be handled by DMA or interrupts.
I think I will try to make a little USB to MIDI host project which can be
connected to the synth. There are some possibilities.
—
Reply to this email directly, view it on GitHub
<#70 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ALTDOQ3JY2QTYBSPTYMDWIDU3PZEPANCNFSM5GDZZZ4Q>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you authored the thread.Message ID:
<marcel-licence/esp32_basic_synth/repo-discussions/70/comments/2191100@
github.com>
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
So I just wanted to put this here - not sure if it belongs here or elsewhere but its more a solution (possibly) with the known bug. Assuming its not fixed in some versions.
Short story: calling other things from USBMidi_HandleShortMessage that do communications seems to cause a communications loss and consequently notes don't turn off.
So the behaviour is hanging notes (note off not triggering)
The cause is assumed to be inefficiency causing lost communications.
My observation while debugging a different issue with a SSD1306 that wouldn't work on Core0 on one version I wired up even though it works on my seemingly identical ESP32 on the breadboard. I had to fix something that was causing a lot of noise/buffer under-run in the sound processing when the screen was being refreshed too much. I ended up turning off this:
So basically if you are writing a string to where-ever (in this case to a little OLED or to Serial then you stand to lose some messages if your routing takes too long. So something I did was left a flag in my own call to this miniScreenString not to refresh the screen but just update the string that will later be written when the screen updates.
So now when its like this - i stopped getting dropped notes or at least it happens far less often so far.
The call is in the usbMidiHost library of this project and this is my forked version
So you could perhaps make some kind of defined term to switch off calling something external during this. Particularly if it triggers wire or serial comms while you are still processing more items in the USBMidi.
I was experiencing issues with hanging notes using a midikeyboard via the USBmidihost to trigger notes before I put the screen on but the way it is now its not using Serial.printf and its very fast to write a string into another library. If I bypass any call out and figure out another way to monitor notes.
The bigger issue I face is making my SSD1306 work reliably (not display garbage) when I use it on Core0 but that's not part of this project its just something I'm working through.
Beta Was this translation helpful? Give feedback.
All reactions