Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Alexander Toth <alexandertoth96@gmail.com>
To: linux-sound@vger.kernel.org
Cc: Takashi Iwai <tiwai@suse.com>, Jaroslav Kysela <perex@perex.cz>
Subject: ALSA: usb-audio: lowlatency playback runs 25% slow, no xrun (Scarlett 2i2)
Date: Sat, 14 Nov 2026 09:38:33 -0500	[thread overview]
Message-ID: <avhyadCiNUguBI-P@xhanost> (raw)

Hi,

On a Focusrite Scarlett 2i2 3rd Gen (1235:8210), playback with
lowlatency=1 (the default) and a two-period ring runs at about 75% of
the nominal rate when the application does some work between
snd_pcm_wait() and snd_pcm_writei(). No xrun is reported; hw_ptr just
advances slower than real time. With lowlatency=0 every case runs at
the full rate.

Setup: S32_LE, 2 ch, 48 kHz on hw:CARD=USB,DEV=0 (EP 0x01 OUT, sync
type SYNC, 125 us packets). Kernel 6.14.0-24-generic (Ubuntu 24.04),
alsa-lib 1.2.9.

The test loop is: snd_pcm_wait() for a free period, busy-wait N us,
then write one period of silence. The rate is frames written minus
snd_pcm_delay(), over 5 s. Frames consumed per second:

  period x n    work    lowlatency=1   lowlatency=0
  128 x 2       0 us       47,999         47,999
  128 x 2     300 us       36,159         47,997
  128 x 2    1500 us       36,569         47,999
  128 x 3     300 us       48,002         47,999
  256 x 2     300 us       41,090         47,999
  512 x 2     300 us       48,010         47,999

Other observations:
- SCHED_RR priority 20 doesn't help, so it isn't late wakeups.
- Writing the previous period first and computing afterwards holds 48k.
- The loss doesn't scale with the work: a run is either at 48k or at
  about 36k (one period in four lost). Near 50 us, runs flip between
  the two.
- At 128x2, delay is 510 frames with lowlatency=1 and 512 with
  lowlatency=0, so low-latency mode gains nothing on this card.

From reading sound/usb in v6.14 (not traced): snd_usb_pcm_playback_ack()
only queues pending output URBs when !ep->active_mask. If the write
lands after one URB has completed short of data but while the other is
still in flight, the new data waits for a whole URB. With two URBs per
ring the stream loses time, but submitted_urbs never reaches zero, so
notify_xrun() never fires. Is it intended that ack only queues URBs
when none are in flight?

I'm happy to test a patch or collect traces. The reproducer is a short
alsa-lib program, and I can send it if it helps.

This was investigated with Claude Code (Anthropic's Claude Opus 5.5
model). It ran the measurements, wrote the test program, read the
sound/usb source and drafted this mail. I steered and approved each
step, ran the lowlatency=0 tests myself and reviewed this mail before
sending it. No fix has been written, no trace taken, and only this one
device has been tested.

Thanks,
Alexander Toth

                 reply	other threads:[~2026-11-14 14:38 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=avhyadCiNUguBI-P@xhanost \
    --to=alexandertoth96@gmail.com \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox