Re: snd-usb-audio Buffer Sizes and Round Trip Latency

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 22 Apr 2019 12:50:15 +0200,
Jonathan Liu wrote:
> 
> On Wed, 24 Oct 2018 at 18:13, Takashi Iwai <tiwai@xxxxxxx> wrote:
> >
> > On Tue, 23 Oct 2018 16:08:22 +0200,
> > Pierre-Louis Bossart wrote:
> > >
> > >
> > > >>>> 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.
> > >
> > > ok, so what problem are you trying to fix?
> > >
> > > Are you concerned about the latency numbers (but then they seem lower
> > > on Linux and latency concerns with large buffers are a self-negating
> > > proposition)? are you concerned about the variable delay that doesn't
> > > seem to exist on MacOS or Windows? Are you trying to match the
> > > performance of the RME driver on MacOS?
> > >
> > > I am not sure how this comparison is done btw, the delay includes both
> > > buffering on the device side before reaching the analog parts as well
> > > as buffering on the OS side. While the former should be constant, the
> > > latter depends a great deal on implementation, not sure there are
> > > direct lessons to be applied to ALSA. I also see
> > > inconsistent/non-linear results where with a larger block size the
> > > delay is smaller, e.g.
> > >
> > > 256/2 512 + 650 ~ 24.208 ms
> > > 2048/3 6144 + 633 ~ 141.188 ms
> 
> >
> > Independently from the measurement done in this thread, actually,
> > there is a known latency source in the playback path in USB-audio
> > driver code -- which I mentioned in the audio mini conf in the last
> > year: namely, the USB-audio driver starts streaming at prepare time
> > for playback, not at the trigger-START time.  This is a sort of
> > workaround to make the device looking similar to the standard
> > ring-buffer behavior.
> >
> > Maybe moving the start at trigger (like the capture direction) would
> > reduce this artificial latency, but it makes the driver behaving in an
> > unexpected manner.  Then it may wake up for period_elapsed soon after
> > the stream start with a large runtime->delay value, as the data in
> > in-flight URBs are seen as already "processed".
> 
> I observed that snd_usb_pcm_prepare calls start_endpoints which ends
> up submitting silent urbs (prepared by prepare_silent_urb) until
> ep->prepare_data_urb is set by SNDRV_PCM_TRIGGER_START in
> snd_usb_substream_playback_trigger.
> 
> I tried to moving the start_endpoints call from snd_usb_pcm_prepare to
> snd_usb_substream_playback trigger's SNDRV_PCM_TRIGGER_START case (see
> https://github.com/net147/linux/commit/276eae5481653a2d4034fbae56f0d5bc579ecf67
> - it is enabled using start_playback_on_prepare=0 module option for
> snd-usb-audio) but I get a kernel stall in some cases with the
> following call trace:
> _raw_spin_lock+0x2c/0x30
> _snd_pcm_stream_lock_irqsave+0x31/0x60 [snd_pcm]
> snd_pcm_period_elapsed+0x26/0xb0 [snd_pcm]
> prepare_playback_urb+0x368/0x640 [snd_usb_audio]
> ? usb_submit_urb+0x3cb/0x590
> snd_usb_endpoint_start+0x148/0x300 [snd_usb_audio]
> start_endpoints+0x36/0x160 [snd_usb_audio]
> snd_usb_substream_playback_trigger+0x152/0x1a0 [snd_usb_audio]
> snd_pcm_action+0x117/0x150 [snd_pcm]
> snd_pcm_common_ioctl+0x588/0xdb0 [snd_pcm]
> ? mprotect_fixup+0x1ec/0x2f0
> snd_pcm_ioctl+0x23/0x30 [snd_pcm]
> do_vfs_ioctl+0xa6/0x760
> ? syscall_trace_enter+0x1be/0x2b0
> __x64_sys_ioctl+0x62/0x90
> do_syscall_64+0x5b/0x170
> entry_SYSCALL_64_after_hwframe+0x44/0xa9
> 
> Any ideas?

This is because snd_pcm_period_elapsed() is called from
prepare_data_urb callback that is called also at start_endpoints().

I guess we'd need to move the hwptr accounting and
snd_pcm_period_elapsed() call into retire_data_urb callback in the
case of start-at-trigger for playback.


thanks,

Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
https://mailman.alsa-project.org/mailman/listinfo/alsa-devel



[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux