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