Limit on number of ALSA midi devices is causing problems

Following on (kind of) from this thread, my midi setup has two interfaces, one with 16 ports and the other with 9. When SPi starts up it creates an ALSA client mapped to each port on those devices, including two more for ALSA’s own loopback client. That’s 52 clients. Add to this, ALSA’s own three clients for the loopback and my two midi interfaces, and we’re at 55 clients for the system as a whole.

Now, I’ve been writing my own little midi router app to run alongside SPi to switch between the various keyboards and modules that I have. It creates just one ALSA client and sets up a full duplex port for each input device that I want to route. That’s only four or five ports but, for every port that I add to my app, SPi will create two more additional clients and when we get beyond 64 clients in total, we hit problems. Specifically, SPi will attempt to open up all its clients but will fail, reporting “ALSA lib seq_hw.c:466:(snd_seq_hw_open) open /dev/snd/seq failed: Cannot allocate memory” in erlang.log, after which it will close down all its midi devices (and maybe the server shuts down, too, but I haven’t confirmed this).

I’ve searched Google with that error messages and I’ve found comments that there is indeed a limit in ALSA of 64 clients, but I haven’t found it explicitly documented anywhere.

To solve this for myself, I can hack sp_midi.cpp to avoid opening ports my own app, or only open specific ports on my interfaces, or just only open outputs and not inputs, but this is not a solution for everyone.

I think I put in a feature request a while back - either or here or on Github - for a way to selectively enable or disable specific midi ports and not open everything that’s available. At the time I was having problems on Windows with its non-sharable MME driver for class compliant midi devices, which meant that I couldn’t run SPi with anything else that wanted to use midi. This problem was also the primary reason for me now trying to run all midi kit from an RPi :woozy_face: . So, apart from anything else, I’d like to put in another vote for that request.

Of course, in the mean time, if anyone knows a way to increase ALSA’s own resource limits - short of reconfiguring and rebuilding ALSA or the kernel - I’d be very happy :slight_smile:

Thanks for reading this,

BN

1 Like

Hi @BN1701 I’m following this with interest. I’m the person who’s asking for a ‘select which midi devices to use’ option - like is common in DAWs. For me it’s so I can run two midi aware programs on the one PC.

If you’ve found another good reason to do that we should mention it to @samaaron again.

I’m trying to keep out of the coding, to keep focussed on making music instead :slight_smile: So I won’t be hacking any cpp myself. Not because I lack the skill, honest ha ha. Hmmm

Sounds like you’ve got the right stuff to maybe contribute a general solution? :slight_smile: :scream: The universe would thank you.

I would be interested in helping, but for now I’m just hacking about with the the sp_midi library that sits under the Erlang code in the server component. I’m reluctant to suggest any permanent changes as, so far, I’ve stayed clear of the UI itself - written in the Qt framework, I think, and of which I have zero experience - and I’ve only the vaguest idea of the overall services that the UI expects.

1 Like

OK, just testing the water. Just testing if it were pushing on a open door, you know? As a programmer myself, I know that some things are dead easy, some are fiendishly complex and need a lot of getting into the swing. And it’s not obvious from outside which are which. For instance, if your ‘hack’ could be picked up by the core team and incorporated.

I can see that getting changes into the UI would be a big deal, but for instance if there were a config file arrangement. Defaulting to what we have now and with the power to exclude named midi interfaces. Or alternatively only include named ones, if any are named. That would do the trick - i.e. nothing for normal users to worry about, but something good for advanced users.

1 Like

Howdy - I’ve been saturated with client work recently (I have to pay the bills somehow!) so haven’t been able to work on this. However, I can say that making MIDI ports smarter in terms of what they connect or don’t connect to is something we’re actively working on.

I hope that we’ll have something to play with in the next beta within the next month or so.

1 Like

Thanks, @samaaron, I’ll keep an eye out for that.

1 Like

My hacks at the moment simply consist of turning things off that I don’t need. I thought about trying to trace through how I could put a list in init.rb and have it passed to the server on start up, but I then I realised that any identifiers I put there to include/exclude devices would be not only be platform specific, but on Linux at least, are also dependent on the order in which devices are connected (or loaded at boot time). Still, this is already a problem when you reference them directly in SPi script, so I guess we’re no worse off. Like you, though, I’m also quite keen to make some music at the moment, so I’ll be patient and see what the dev team come up with :slight_smile:

1 Like

Yes, with the midi ordering thing, I’ve seen that on Windows too with VCV Rack. But in contrast, the midi device lists in Reaper DON’T rely on a number. Maybe there’s a wildcard mechanism, like within SPi itself when syncing off midi cues.

Last thing - I lost track of the original story about your midi timing problems. Was that also caused by having lots of midi devices? As I mentioned, I’ve not had these problems but my usb-midi-hub has only 4 ports.

I’m a Reaper fan, too. I use it primarily on Windows, but out of interest just checked with it on Ubuntu and there are no midi device identifiers of any kind to be seen. It just lists Midi Input 1, 2, 3 … 62. (And that machine only has one device attached at the moment.) It’s obviously a work in progress and I don’t really trust it.

Of course, on Windows device identification is much more usable but I do have a vague memory of having to disable and reenable existing devices after adding other kit, presumably because the underlying USB IDs had moved. Checking all this out would be another rabbit hole, please don’t tempt me … :frowning:

Broadly speaking, yes. There’s a timing loop in the Erlang code which fires every five seconds checking for new devices attached and this coincided with the glitches. The volume of data it retrieves from sp_midi seemed to be the root of the problem. My final post in that thread has the details. A couple of members of the core team posted to say they had picked up the problem and I’m happy to wait and see what they come up with. In the mean time I’ve turned off that bit of code, too, as I’m not changing my hardware and I have all the relevant identifiers in a text file. The rest of SPi’s midi sequencing doesn’t seem any the worse for this.

1 Like

Hi @BN1701 I said I wasn’t going to do any hacking, but with lockdown restrictions lifting I’m gearing up to go portable, and realised my setup with lots of devices is going to be a bit tricky to transport - so I’m seeing if I can have fewer…

…I’d like to try running SPi on the same PC as VCV Rack for which I need to stop SPi grabbing the midi keyboard. Can you point me at roughly where the erlang code is where I could have go at that? Or if it’s not possible, let me know so no wild goose chase.

Many thanks.

Hi Guy,

Assuming that your source tree starts in a folder named ‘sonic-pi’, the relevant bits of Erlang code are here:

sonic-pi\app\server\erlang\sonic_pi_server\src\pi_server\pi_server_midi.erl

This is where I found the code that I turned off to avoid my timing glitches. It’s in the ‘{timeout, _Timer, update_midi_ports}’ section of the loop() function. In truth, I let it run once and just disabled the scheduling of the timer callback to prevent it repeating. (I’m assuming you’re familiar with the erl interpreter and know that you have to recompile the updated module before changes will take effect, placing it in the ebin folder afterwards.)

However, I don’t believe this will prevent the ports being opened in the first place. This seems to happen automatically in the sp_midi lib. To get around the problem I had with running out of ALSA clients, I completely disabled the call to prepareMidiInputs() in sp_midi_init(). This is here:

sonic-pi\app\external\sp_midi\src\sp_midi.cpp

At the time I didn’t actually need any midi input, but I’m actually at a point in my current noodlings where I do need midi input after all, so I’m thinking I’ll just hard code a list of inputs and outputs that I need and prevent SPi from opening anything else. I haven’t actually tried this yet, but my hope is that I can do it in prepareMidiInputs() and prepareMidiOutputs(). The former is in sp_midi.cpp, the latter in midisendprocessor.cpp.

Anyway, since you’ve asked, I’ll probably have a go at that myself this evening. I’ll let you know how I get on. And of course, I’ll be curious to hear how you get on.

By the way, after our previous exchanges I looked you up. Assuming you’re based in Oxford, I’m actually not far from you. I’m in Wendover near Aylesbury. If you do get going with any gigs I’d be curious to come and see what you’re up to :slight_smile:

Barry

Update, as a test I just changed my version of prepareMidiOutputs() to include this code fragment, and it ignores everything else:

try {
    cout << "Checking output: " << output.portName << " (" << output.normalizedPortName << ")" << endl;
    if ( output.normalizedPortName.find("midisport_8x8") == 0 )
    {
        auto midiOut = make_unique(output.portName, output.normalizedPortName, output.portId);
        m_outputs.push_back(std::move(midiOut));
    }
}

BN

Thank you. I was really hoping that it was a script change rather than needing a rebuild. A bit lazy I know, but this is a practical thing rather than out of interest. Getting tooled up to do a build - I know it’s fine but my heart sinks, you know? :no_mouth:

Re gigs - yes I’m in Abingdon, so not a million miles away! Honestly, who knows what’s going to happen so it’s more in hope than expectation. I play in a few conventional groups, and we are just about to try some practising in each others gardens. That seemed like a good idea when we had the two day heat wave last week. Right now, brrrrrrr. I’m feeling a bit negative at the minute TBH - while the papers are full of joy at the pubs about to open, just reminds me it’s been over a year since we could do our music activity properly.

You do realise you don’t need to build all of SPi to make this change? Or, at least, I don’t think you do. I just run make in sonic-pi\app\external\sp_midi\build. Come to think of it, though, I did set up the entire build tree while I was finding out where to look so I think maybe a lot of the work was already done for me. Plus, you’re doing this on Windows and I’ve been on Ubuntu/Pi. (Which is ironic as I’ve spent most of my C++ life on Win32!) Oh, I hate hacking big build systems. I never feel like I understand all I’d like to :frowning:

BN

1 Like

Thanks for the tip. Sounds like we have similar views on build systems. Don’t mind me, I’m just feeling a bit negative at the moment. And I’ve quite enjoyed being a user rather than immediately reaching for the compiler.

This morning I tried some alternatives - firstly using Jack/QjackCtl on windows to see if I could route the midi nicely. I’ve found that so good on the Raspberry Pi, but it didn’t work out the same on Windows at all.

So then I tried SPi and PureData on the Rpi with QjackCtl. PureData instead of VCV Rack for the synthy voices. That’s pretty good actually: they coexist nicely, the midi goes where I want it. OK it’s not one self-contained laptop, so needs keyboard/mouse/screen/audio interface, but that may be a good compromise.

Maybe I’ll look at prepping an Ubuntu laptop with everything on.

1 Like

I did install Ubuntu Studio and it’s looking good, read about my adventure here… Latest Setup - Portable all-in-one Instrument with Ubuntu Studio