[alsa-devel] snd-usb-audio Buffer Sizes and Round Trip Latency

Jonathan Liu net147 at gmail.com
Tue Oct 23 13:59:48 CEST 2018


Hi,

On Tue, 23 Oct 2018 at 02:40, Alan Stern <stern at rowland.harvard.edu> wrote:
>
> On Mon, 22 Oct 2018, Pierre-Louis Bossart wrote:
>
> > On 10/17/18 7:58 AM, Jonathan Liu wrote:
> > > Hi,
> > >
> > > I want to start a discussion regarding round trip latency for class
> > > compliant USB audio interfaces on Linux. In particular, I am noticing
> > > with my USB 2.0 RME Babyface Pro audio interface that the round trip
> > > latency is considerably higher on Linux than on macOS High Sierra and
> > > Windows 10.
> > >
> > > I tested the round trip latency using a loopback audio cable and the
> > > ReaInsert plugin included with Reaper DAW (www.reaper.fm) that can be
> > > downloaded for Windows/macOS/Linux to calculate the additional delay.
> > >
> > > Here are the results for 48000 Hz, 24-bit on my RME Babyface Pro:
> > > ===
> > > block_size/periods block_size*periods + additional_delay ~ round_trip_latency
> > > round_trip_latency = (block_size*periods + additional_delay) / 48000 * 1000
>
> I'm with Pierre-Louis on this; I can't make heads or tails out of these
> formulas.
>
> To begin with, I'm accustomed to talking about frames, periods, and
> buffers.  What are "block"s?  Are they the same as buffers?
>
> What do these formulas mean?  Is the first supposed to be a definition
> of round_trip_latency?  If it isn't, then how do you define or measure
> round_trip_latency?
>
> What is additional_delay?  How is it measured or calculated?

See below.

>
> > > Linux 4.17.14, Class Compliant Mode (snd-usb-audio, ALSA backend):
> > > 16/2 32 + 80 ~ 2.333 ms
>
> What are these numbers?  Are these lines supposed to in the format
> expressed by the first formula above?  If they are, how come
> "block_size/periods" shows up as a pair of numbers "16/2" but
> "block_size*periods" shows up as a single number "32"?
>

To interpret "16/2 32 + 80 ~ 2.333 ms"
Block size: 16 samples
Periods: 2 (one period for playback + one period for recording when
determining round trip latency)
The minimum round trip latency is: 16 * 2 = 32 samples
However, I measured 112 samples round trip latency which is an
additional delay of 80 samples (32 + 80 = 112).
112 samples at 48000 Hz is 112 / 48000 * 1000 is approximately 2.333
ms measured round trip latency.

> > > 16/3 48 + 109 ~ 3.271 ms
> > > 32/2 64 + 129 ~ 4.021 ms
> > > 32/3 96 + 166 ~ 5.458 ms
> > > 64/2 128 + 205 ~ 6.938 ms
> > > 64/3 192 + 242 ~ 9.042 ms
> > > 128/2 256 + 352 ~ 12.667 ms
> > > 128/3 384 + 496 ~ 18.334 ms
> > > 256/2 512 + 650 ~ 24.208 ms
> > > 256/3 768 + 650 ~ 29.542 ms
> > > 512/2 1024 + 634 ~ 34.542 ms
> > > 512/3 1536 + 634 ~ 45.208 ms
> > > 1024/2 2048 + 650 ~ 56.208 ms
> > > 1024/3 3072 + 650 ~ 77.542 ms
> > > 2048/2 4096 + 633 ~ 98.521 ms
> > > 2048/3 6144 + 633 ~ 141.188 ms
> > >
> > > macOS High Sierra, Class Compliant Mode (Apple Driver):
> > > 16/2 32 + 205 ~ 4.938 ms
> > > 32/2 64 + 205 ~ 5.604 ms
> > > 64/2 128 + 205 ~ 6.938 ms
> > > 128/2 256 + 205 ~ 9.604 ms
> > > 256/2 512 + 205 ~ 14.938 ms
> > > 512/2 1024 + 205 ~ 25.604 ms
> > > 1024/2 2048 + 205 ~ 46.938 ms
> > > 2048/2 4096 + 205 ~ 89.604 ms

>
> What are the USB parameters for these tests?  How many bytes/frame?
> What is the endpoint's maxpacket size?  What is the speed of the USB
> bus?
>

How would I determine the USB parameters and bytes/frame?

USB port is Intel USB 3.0 port. Device is USB 2.0 high speed (480 Mbps).

Here is the lsusb output:
Bus 001 Device 004: ID 2a39:3fb0
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x2a39
  idProduct          0x3fb0
  bcdDevice            0.01
  iManufacturer           1 RME
  iProduct                2 Babyface Pro (71964099)
  iSerial                 3 EF72ADBCCECA4C8
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x01a7
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         4
      bFunctionClass          1 Audio
      bFunctionSubClass       0
      bFunctionProtocol      32
      iFunction               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
      bInterfaceProtocol     32
      iInterface              0
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               2.00
        bCategory               8
        wTotalLength       0x0055
        bmControls           0x00
      AudioControl Interface Descriptor:
        bLength                 8
        bDescriptorType        36
        bDescriptorSubtype     10 (CLOCK_SOURCE)
        bClockID                1
        bmAttributes            3 Internal programmable clock
        bmControls           0x03
          Clock Frequency Control (read/write)
        bAssocTerminal          0
        iClockSource            0
      AudioControl Interface Descriptor:
        bLength                17
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             3
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bCSourceID              1
        bNrChannels            12
        bmChannelConfig    0x00000000
        iChannelNames           0
        bmControls         0x0000
        iTerminal               0
      AudioControl Interface Descriptor:
        bLength                17
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             5
        wTerminalType      0x0201 Microphone
        bAssocTerminal          0
        bCSourceID              1
        bNrChannels            12
        bmChannelConfig    0x00000000
        iChannelNames           0
        bmControls         0x0000
        iTerminal               0
      AudioControl Interface Descriptor:
        bLength                12
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID             4
        wTerminalType      0x0301 Speaker
        bAssocTerminal          0
        bSourceID               2
        bCSourceID              1
        bmControls         0x0000
        iTerminal               0
      AudioControl Interface Descriptor:
        bLength                12
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID             6
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bSourceID               5
        bCSourceID              1
        bmControls         0x0000
        iTerminal               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32
      iInterface              0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       1
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32
      iInterface              0
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           3
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels             2
        bmChannelConfig    0x00000003
          Front Left (FL)
          Front Right (FR)
        iChannelNames           0
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            3
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0096  1x 150 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         0 Undefined
          wLockDelay         0x0000
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes           17
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Feedback
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       2
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32
      iInterface              0
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           3
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels            12
        bmChannelConfig    0x00000000
        iChannelNames           0
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            3
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0384  1x 900 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         0 Undefined
          wLockDelay         0x0000
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes           17
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Feedback
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32
      iInterface              0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32
      iInterface              0
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           6
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels            12
        bmChannelConfig    0x00000000
        iChannelNames           0
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            3
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0384  1x 900 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         0 Undefined
          wLockDelay         0x0000
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       2
      bNumEndpoints           1
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol     32
      iInterface              0
      AudioStreaming Interface Descriptor:
        bLength                16
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           6
        bmControls           0x00
        bFormatType             1
        bmFormats          0x00000001
          PCM
        bNrChannels             2
        bmChannelConfig    0x00000003
          Front Left (FL)
          Front Right (FR)
        iChannelNames           0
      AudioStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bSubslotSize            3
        bBitResolution         24
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0096  1x 150 bytes
        bInterval               1
        AudioStreaming Endpoint Descriptor:
          bLength                 8
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x00
          bmControls           0x00
          bLockDelayUnits         0 Undefined
          wLockDelay         0x0000
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         1 Audio
      bInterfaceSubClass      3 MIDI Streaming
      bInterfaceProtocol      0
      iInterface              2 Babyface Pro (71964099)
      MIDIStreaming Interface Descriptor:
        bLength                 7
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength       0x0061
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               1 Embedded
        bJackID                 3
        bNrInputPins            1
        baSourceID( 0)          2
        BaSourcePin( 0)         1
        iJack                   4 Port 1
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               2 External
        bJackID                 2
        iJack                   4 Port 1
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               1 Embedded
        bJackID                 7
        bNrInputPins            1
        baSourceID( 0)          6
        BaSourcePin( 0)         1
        iJack                   5 Port 2
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               2 External
        bJackID                 6
        iJack                   5 Port 2
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               1 Embedded
        bJackID                 1
        iJack                   4 Port 1
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               2 External
        bJackID                 4
        bNrInputPins            1
        baSourceID( 0)          1
        BaSourcePin( 0)         1
        iJack                   4 Port 1
      MIDIStreaming Interface Descriptor:
        bLength                 6
        bDescriptorType        36
        bDescriptorSubtype      2 (MIDI_IN_JACK)
        bJackType               1 Embedded
        bJackID                 5
        iJack                   5 Port 2
      MIDIStreaming Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (MIDI_OUT_JACK)
        bJackType               2 External
        bJackID                 8
        bNrInputPins            1
        baSourceID( 0)          5
        BaSourcePin( 0)         1
        iJack                   5 Port 2
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x07  EP 7 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 6
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         2
          baAssocJackID( 0)       1
          baAssocJackID( 1)       5
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x86  EP 6 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
        bRefresh                0
        bSynchAddress           0
        MIDIStreaming Endpoint Descriptor:
          bLength                 6
          bDescriptorType        37
          bDescriptorSubtype      1 (GENERAL)
          bNumEmbMIDIJack         2
          baAssocJackID( 0)       3
          baAssocJackID( 1)       7
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  bNumConfigurations      0
Device Status:     0x0e00
  (Bus Powered)

> > I couldn't figure out how to analyze your data, not sure what the extra
> > delays mean nor how you conclude that Linux is worse than MacOS or
> > Windows10 for small buffers?
> >
> > At any rate, I looked into this some time back but had to put the work
> > on the back burner due to other priorities. What I do remember is that
> > there is a built-in latency due to the fact that on playback the driver
> > submits a number of zero-filled URBs and will only add valid audio data
> > when the first URB is retired, which means you get a constant startup
> > latency you will never be able to catch up.
>
> In theory the number of zero-filled URBs could be reduced, maybe even
> eliminated.
>
> > I also vaguely remember that at some point the buffer/period sizes don't
> > matter, each period will be broken up in a series of URBs and hence you
> > will have more wake-ups than what is configured by the period size. In
> > short I would look into the way the data is spread on multiple URBs and
> > check how latency is impacted by the software design.
>
> Agreed.
>
> > the last thing I have in mind is that for latency analysis and
> > comparisons, using simple devices make sense. Latency can be affected by
> > extra processing that might be enabled in the USB device depending on
> > user configurations or parameters. Ideally to focus on the ALSA/xHCI
> > interaction/latency we'd want to look at really dumb devices with just
> > an input and output terminal and no processing.
> >
> > -Pierre
> >
> > >
> > > macOS High Sierra, PC Mode (RME Driver v3.08):
> > > 16/2 32 + 59 ~ 1.896 ms
> > > 32/2 64 + 59 ~ 2.563 ms
> > > 64/2 128 + 59 ~ 3.896 ms
> > > 128/2 256 + 59 ~ 6.563 ms
> > > 256/2 512 + 59 ~ 11.596 ms
> > > 512/2 1024 + 59 ~ 22.563 ms
> > > 1024/2 2048 + 59 ~ 43.896 ms
> > > 2048/2 4096 + 59 ~ 86.563 ms
> > >
> > > Windows 10, PC Mode (RME Driver 1.099):
> > > 48/2 96 + 63 ~ 3.313 ms
> > > 64/2 128 + 63 ~ 3.979 ms
> > > 96/2 192 + 63 ~ 5.313 ms
> > > 128/2 256 + 63 ~ 6.646 ms
> > > 256/2 512 + 63 ~ 11.979 ms
> > > 512/2 1024 + 63 ~ 22.646 ms
> > > 1024/2 2048 + 63 ~ 43.979 ms
> > > 2048/2 4096 + 63 ~ 86.646 ms
> > > ===
> > >
> > > Some things in particular I noticed on Linux:
> > > - additional_delay varies a bit if I close and open the audio device again
> > > - additional_delay seems to increase as the block_size increases. I
> > > can make the additional_delay stay about the same rather than
> > > increasing by setting MAX_PACKS and MAX_PACKS_HS to 1 in
> > > sound/usb/card.h. In Linux versions before 3.13 there was a nrpacks
> > > parameter for snd-usb-audio to control this but it was removed with
> > > commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v3.13&id=976b6c064a957445eb0573b270f2d0282630e9b9
> > > - additional_delay is not constant as block_size is increased like on
> > > macOS and Windows
>
> Perhaps this additional_delay is caused by the zero-filled URBs
> mentioned earlier.
>
> We can't say anything about the effect of setting MAX_PACKS to 1
> without knowing how the driver is currently fitting packets into frames
> and URBs.  In any case, you should be able to reduce the number of
> packets in each URB simply by reducing the period size, since the
> driver strives to keep each URB not much larger than a period (as I
> recall -- it's been a long time since I worked on this (2013)).
>
> > > I made a patch to snd-usb-audio to expose the snd-usb-audio constants
> > > as runtime adjustable module parameters
> > > (/sys/module/snd_usb_audio/parameters/) for testing (takes effect when
> > > the device is disconnected+reconnected and logs the parameter values
> > > to dmesg):
> > > https://aur.archlinux.org/cgit/aur.git/plain/parameters.patch?h=snd-usb-audio-lowlatency-dkms
> > >
> > > The patch is used in my Arch Linux AUR package for convenience (using
> > > DKMS to avoid having to recompile entire kernel):
> > > https://aur.archlinux.org/packages/snd-usb-audio-lowlatency-dkms/
> > >
> > > Can snd-usb-audio be improved so the additional_delay is always the
> > > same when closing/opening/reconfiguring the audio device and does not
> > > increase as the block_size increases?
> > >
> > > I noticed using USB audio on Linux at lower latencies (block_size <=
> > > 128) is more prone to audio dropouts under load compared to macOS and
> > > Windows, even with CPU power management disabled (writing 0 to
> > > /dev/cpu_dma_latency). What can be done about this?
>
> You can reduce the CPU load.  :-)
>
> Seriously, how can you compare loads between different operating
> systems?
>
> Also, note the Linux's scheduler has a number of adjustable parameters,
> which I am not familiar with.
>
> Alan Stern
>

Regards,
Jonathan


More information about the Alsa-devel mailing list