slow snd_rawmidi_drain() for VirMidi devcies
Stefan Sauer
st_kost at gmx.net
Sun Jan 2 11:18:39 CET 2022
hi,
happy new year every one. During the free days I've tried to link
BitwigStudio to the webapp [1]cables.gl over virmidi. Unfortunately
Bitwig Studio only supports rawmidi. What I discovered is that there is
a strange slowness when sending data to virmidi caused
by snd_rawmidi_drain().
I've posted two tiny, self-contained c apps
to: [2]https://gist.github.com/ensonic/c7588b87fa6c1fa94a8f753b1e0aa394
See some examples below. 2 observations:
* snd_rawmidi_type() is *not* reporting virmidi as VIRTUAL
* snd_rawmidi_drain() takes about 60ms! on virtual vs. less that 0.1 ms
on usb midi (I checked all my hw midi and the worst was avg=1ms on
physical midi image unitor8)
When comparing the implementations:
[3]https://github.com/alsa-project/alsa-lib/blob/master/
src/rawmidi/rawmidi_virt.c#L173
[4]https://github.com/alsa-project/alsa-lib/blob/master/
src/rawmidi/rawmidi_hw.c#L164
I see that the hw one results in an IOCTL (SNDRV_RAWMIDI_IOCTL_DRAIN)
which I can see when strac'ing app and I wonder if this is the root
cause? Why is rawmidi_virt.c not used for virmidi?
From poking at snd_rawmidi_open_conf() I have not yet figured where
this is decided ....
If the IOCTl is the right code path, any idea why it is slow? Is the
virmidi driver not reporting buffer fill status or something like that?
Stefan
> amidi -l
Dir Device Name
IO hw:0,0,0 Scarlett 18i20 USB MIDI 1
IO hw:3,0,0 nanoKEY2 nanoKEY2 _ KEYBOARD
IO hw:5,0,0 nanoKONTROL nanoKONTROL _ SLIDE
IO hw:10,0 Virtual Raw MIDI (16 subdevices)
IO hw:11,0 Virtual Raw MIDI (16 subdevices)
# using direct i/o to virmidi - all good
> ./rawmidi_oss /dev/midi11 0
Using device '/dev/midi11' without draining
write took min= 0.0015 ms, avg= 0.0016 ms, max= 0.0110 ms
> ./rawmidi_oss /dev/midi11 1
Using device '/dev/midi11' with draining
write took min= 0.0015 ms, avg= 0.0017 ms, max= 0.0101 ms
drain took min= 0.0001 ms, avg= 0.0001 ms, max= 0.0008 ms
# using snd_rawmidi to virmidi - slow drain operations
> ./rawmidi_alsa hw:11,0 0
Using device 'hw:11,0' without draining
SND_RAWMIDI_TYPE_HW
write took min= 0.0010 ms, avg= 0.0011 ms, max= 0.0056 ms
> ./rawmidi_alsa hw:11,0 1
Using device 'hw:11,0' with draining
SND_RAWMIDI_TYPE_HW
write took min= 0.0016 ms, avg= 0.0040 ms, max= 0.0077 ms
drain took min= 55.9951 ms, avg= 60.4330 ms, max= 64.0653 ms
# using snd_rawmidi to usb hw - all good
> ./rawmidi_alsa hw:3,0 0
Using device 'hw:3,0' without draining
SND_RAWMIDI_TYPE_HW
write took min= 0.0012 ms, avg= 0.0015 ms, max= 0.0121 ms
> ./rawmidi_alsa hw:3,0 1
Using device 'hw:3,0' with draining
SND_RAWMIDI_TYPE_HW
write took min= 0.0024 ms, avg= 0.0032 ms, max= 0.0110 ms
drain took min= 0.0293 ms, avg= 0.0636 ms, max= 0.2277 ms
References
1. http://cables.gl/
2. https://gist.github.com/ensonic/c7588b87fa6c1fa94a8f753b1e0aa394
3. https://github.com/alsa-project/alsa-lib/blob/master/src/rawmidi/rawmidi_virt.c#L173
4. https://github.com/alsa-project/alsa-lib/blob/master/src/rawmidi/rawmidi_hw.c#L164
More information about the Alsa-devel
mailing list