-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
long sysex again #113
Comments
Hi. I changed the custom MIDI to alsa seq code to use the ALSA function that does that.. and it looks that for this case it fails? I have to dig deeper. I'll let you know if I discover something. Thanks for the report. |
I think there's a compiler option baked into the kernel that (arbitrarily) sets the maximum allowed sysex size. It's not well documented but I read about it somewhere. Would that have something to do with it? |
Has there been any update on this issue? Can you let me know where to look for the code that was changed to I can try rolling it back? Thanks so much. BTW I think I was wrong and at least some of the partial messages were being forwarded to rtpMIDI on Windows, although they still weren't working properly. I just noticed some errors in the Windows rtpMIDI log about invalid messages being received from the TX-81z, but I'll have to do some more solid testing about what exactly is being forwarded. I'm guessing rtpmidid still needs to be handling the message segmentation internally for this to work, right? |
Hi @davidmoreno can you let me know what ALSA function you changed to so I can do some experimenting with this? I'm happy to devote some to it but it would be way easier if I knew where to start. Thanks! |
Hi. The crux should be at the On previous versions I created my own converter between the ALSA seq events and the MIDI streams. Then I discovered that ALSA had their implementation, so I started using it.. but fails on long SysEx. On rtpmidi, long SysEx are split into several packages, and my suspicion is that the ALSA converters do not manage this very well. I have some basic description at the end of https://github.com/davidmoreno/rtpmidid/blob/master/docs/RFC6295_notes.md So ideally I think the best course of action is create some new test that try several options:
As it looks that ALSA doe snot work, somehow we should detect and manage SysEx specially. Maybe internally it should use a buffer where the temporal data is set and used .. maybe it can be on the heap with a 16MB limit or something like that? All this is just ramblings. If you decide to give it a go tell me. If not I will try next week or so.. I also need it. |
Ok great, I'll have a look. I have a couple of pieces of gear that reliably fail with rtpmidid and work with Windows RTPMIDI so I should be able to run some good tests. Thanks! |
A few notes so far:
The first point of failure with sending long sysex is just that In the PipeWire library, the alsaseq.c uses the method Also, I've been using sendmidi and receivemidi, which are based on JUCE, to send sysex files and found that they also choke on very large sysex files with the limit more in the thousands of bytes range, but I think this actually a limitation of JUCE arbitrarily deciding on a maximum size. JUCE does have some MIDI segmentation logic built in, which I've been looking at as well. |
Ok actually RtMidi looks like it does a good job with this. Only issue is the malloc in the realtime path, but I guess if the buffer is set big enough to begin with it really shouldn't be a problem. edit I'm not necessarily suggesting to use the RtMidi library, but it looks good for learning some ALSA MIDI tricks |
So I thought I'd at least send what I have so far, even though it is an absolute mess. It looks like long sysex is being received to rtpmidid from Windows but I'm still having trouble with sending from Linux. I'm sure it's something obvious and I'm still figuring out how all the pieces of rtpmidid fit together, hence the million logging statements I've added. Would you mind taking a look? Let me know if I'm doing something totally stupid or this isn't the direction you want to be going. Obviously, some of the new code is redundant and could be a lot cleaner. I have a few changes to the build process in here to for my benefit, but hopefully they won't break anything on your end. Also, I think one of the things that was getting in the way was that the snd_seq_midi module by default was not setting its internal buffer size high enough. I put
in a .conf file in /etc/modprobe.d and at least at some point it looked like it was making a difference. |
Hi, finally I could make some review. Interesting about input and output sizes, but I dont think they are so important.. maybe they are. I see a lot of unrelated changes like I would do something different, just modify at the I will try to make some tests myself... but to use windows I will have to compile on a rpi4... and that's slow! so it may take me some time. Another option, that I'm delaying but should be done, is give the possiblity of sidestepping totally the alsa sequencer interface, and create a direct to midi (as in |
Looking more into you code I see you do some event size rewrite. Try setting not exactly the size you think it is (the sysex length maybe?) but some more bytes for headers and whatever. Even set it to double. It should never be too big. But maybe check less than 16MB or something like that. |
Also I see I had a |
Ah I was just in the middle of writing another message! Yeah honestly you don't need to pay attention to my code at this point. I've mostly filled it up with a bunch of logging stuff to try to figure out what's happening to the messages, and the malloc thing isn't making much of a difference so far. No matter what I do there's still a bottleneck somewhere. I've mostly come to the same conclusion as you about piecing the segments back together in I then tried a basic sanity test with aseqsend and aseqdump and no rtpmidid involved and found that the ALSA seq situation is just generally unreliable with sysex sizes over ~4096. I then tried using snd_virmidi and had no problem sending large messages. Would a possible solution be to add a config.ini option in rtpmidid to create a specified number of virtual raw MIDI ports to use and which network ports they would correspond to or something? They could then still be routed using the standard ALSA interface, and at least in my case, I'd only need a couple of raw MIDI ports in addition to the standard seq ports. That way it would also be possible to use the standard Linux command-line utilities for loading and sending Sysex files and they would work as intended. Also, try the distcc thing for remote builds on the Pi if you have the patience to get it set up! I have it so that my PC is running a distcc client in WSL and all of the heavy CPU load is happening there, so it takes maybe 30 seconds or so to do a clean build. |
Is it possible that there is a bug in That's totally weird, because it really shouldn't depend on any of the main ALSA buffers, right? Looking at the alsa-lib code, it looks like it's just doing a one-off temporary buffer for longer messages as needed. I might have to try doing my own build of alsa-lib so I can trace what's going on, but it's curious that the official word has been "don't use ALSA seq for long messages, it's unreliable" yet if it's possible to manually set large buffer sizes, why would there be an arbitrary point where it just doesn't work? |
Ok no it's actually failing at line 388 of seq_hw.c in alsa-lib, |
Progress! Maybe... I found this code in the PipeWire source that sets attributes for the input and output |
Hello, so I've definitely made some headway. I'm getting up to around 13000 bytes successfully transferred. I'm still running into trouble with ALSA just dropping messages once they get to a certain size. I thought I had all the buffering figured out, but apparently not. It does at least look like rtpmidid thinks it's sending complete messages of arbitrary size to the sequencer, but aseqdump shows no output beyond a certain threshold. I started a new branch here which you're welcome to check out. It should be much cleaner and easier to follow than the last one, although I still need to remove some hard-coded buffer sizes and make them parameters or something. I tried to avoid unnecessary allocation as much as possible. I did try switching from If you do get a chance, could you let me know if you see any obvious reasons why it's still not working? Thanks! |
A little more debug info-- it looks like the messages are being delivered to the sequencer, but are getting stuck on the queue instead of being read by the poller. If I look at |
Got it! I needed to add I need to go back and tune the buffer sizes to sensible values and clean up the logging, but can you verify that this is working (link here) and let me know if you find any red flags with the implementation? I'll submit a PR if you're happy with how I'm going about this. Thanks! |
That's amazing news! Congratulations! As I understand it, the main changes are the ALSA related bits, nothing out of ALSA is about this SysEx problem, right? Could you prepare a clean patch so I apply it. Al the Makefile things I have to figure out yet how they affect, specially to create the debian packages I use a lot. But should be ok... but better in the other pull request. Thanks! BTW, the devmidi (which is more rawmidi), has support for raw midi devices that should sidestep this problem completely, and work for other scenarios. It also adds some new RPC / client commands to allow create the devices even at runtime, but also ini file support. |
I could not verify working yet, will do ASAP and tell you more, but looks good so far until I do a full review. |
Awesome! Yes I will go back and make a clean PR with just the ALSA stuff. I need the Makefile changes so I can get it to install with Arch packaging but I'll take that out for now. The only other change was related to Arch updating the fmt package yet again and breaking the build. I can submit another PR for that and hopefully it won't need any conditional logic to work with the older fmt. Let me know if you find any other bits I need to rearrange. I'll also try adding something in the .ini for configuring ALSA buffer sizes and rtp message segmentation. Also great news about rawmidi, that's super useful. I'll check that out as well. Thanks! |
Just tested this out at my studio and it's working great up to around message of 50 kbytes in size. Beyond that it still fails, which is not a big deal for anything except for my Electra One controller which sends full Lua scripts (!!) over sysex. So I guess in this case, I'm not sure what options would exist other than to compile a kernel with a larger maximum ALSA pool size or to use Pipewire, which I think implements the same partial sysex logic as the rtpMIDI protocol, or Jack MIDI. It would be great to be able to stick with ALSA though. |
Ok so sorry for the barrage of issues, I've been meaning to log these and never got around to it. It appears that something has changed in the handling of longer sysex messages so that they are not being split into smaller messages where appropriate. So far I've run into this with the use case of a Yamaha TX-81z sending bulk dumps to MioXL -> rtpmidid on Raspberry Pi -> Windows PC, but I'd imagine this would should up for anything that sends messages longer than the ALSA maximum message size. The weird thing is that aseqdump does split bulk messages into smaller chunks but I can see that F0/F7 are not added to the chunks. I guess that means rtpmidid may be interpreting the partial messages as garbage so won't pass them along, right?
The text was updated successfully, but these errors were encountered: