Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp1770667imm; Thu, 18 Oct 2018 04:04:45 -0700 (PDT) X-Google-Smtp-Source: ACcGV62P2vrEstGXkiYH4uTsx0HW0QdTd0bHKY2cXZJUgZFUAzDKD4Xl8AW1QU7L0H90HayA6cuU X-Received: by 2002:a62:cac4:: with SMTP id y65-v6mr29918129pfk.27.1539860685049; Thu, 18 Oct 2018 04:04:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539860685; cv=none; d=google.com; s=arc-20160816; b=n8a6ThJt16N+0X+pSGof6JVLQj9sQTLBFGIX++uLcAgYAWICaxU5vgmLn1A+pqJKgm 5WO4aBXUDAeUy220ea+ZYawIzTdX4sig54kgmVr5rYdiQBHGnrRN7MrcPv7mhw14qGFA PfpIFGXX7ggKzbqjgyYRP6DcZ+sJdi8ljzFjA6oH4fSM22Maxjx6kps1iF5Hd2vGeUP6 2Ch6Ry9aSwNqKcuY6VTChTpLme1m3P30OipcnjtgHfFkfB+7cqA+nvnQ/7xq42oyTrUD LDuK94H5A39KVRrnuCfdbEnDpxYOZGMUASZCV/UdJ6woWwo5WhrIilN61BhODxPC/sS1 2AcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:subject:cc:to:from:message-id:date; bh=NMln2MgSdNmwg4QTNmwncXOJfnuZmh8aUQ+5Bg9Y8JM=; b=T7//9TJtqnTN/u+jnqvTowQsgtTUak2zCr8hWP46ZYArQOwfTsyFIUPAQ7Aot1D/8g /cY8VWf+mRry0nxmFJ/0f8P4jBSQMlNz2G9NHmplfWHfPcJtx6Mdvu52ySwrvfhfFAI2 QpW/48PEPoZEa0fvJjOC58cJTXKs1DvEpjgffwYFc+kzQyMRhxH2SV8u4ky4o/f7a4Fj P1eAf7zpCiLvVOygbzsHxIEQvGTgedwBvuPefsNqXPCoHbPil5rDIGzURrPv5pJ/FVg1 EnEIKGvSTbBP6IfWEOPBii+VjsSoEkqlIO2y2fYiV9vy4Hk3oEHbJgMAAfoy1X4X+g0W I1WQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 1-v6si21305193plk.405.2018.10.18.04.04.28; Thu, 18 Oct 2018 04:04:45 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727738AbeJRTCi (ORCPT + 99 others); Thu, 18 Oct 2018 15:02:38 -0400 Received: from mx2.suse.de ([195.135.220.15]:40544 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727470AbeJRTCi (ORCPT ); Thu, 18 Oct 2018 15:02:38 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 448D7B0C0; Thu, 18 Oct 2018 11:02:08 +0000 (UTC) Date: Thu, 18 Oct 2018 13:02:06 +0200 Message-ID: From: Takashi Iwai To: Mike Brady Cc: eric@anholt.net, stefan.wahren@i2se.com, gregkh@linuxfoundation.org, f.fainelli@gmail.com, nishka.dasgupta_ug18@ashoka.edu.in, julia.lawall@lip6.fr, k.marinushkin@gmail.com, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] staging: bcm2835-audio: interpolate audio delay In-Reply-To: <20181018105715.GA6660@ubuntu> References: <20181018105715.GA6660@ubuntu> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL/10.8 Emacs/26 (x86_64-suse-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 18 Oct 2018 12:57:15 +0200, Mike Brady wrote: > > When the BCM2835 audio output is used, userspace sees a jitter up to 10ms > in the audio position, aka "delay" -- the number of frames that must > be output before a new frame would be played. > Make this a bit nicer for userspace by interpolating the position > using the CPU clock. > The overhead is small -- an extra ktime_get() every time a GPU message > is sent -- and another call and a few calculations whenever the delay > is sought from userland. > At 48,000 frames per second, i.e. approximately 20 microseconds per > frame, it would take a clock inaccuracy of > 20 microseconds in 10 milliseconds -- 2,000 parts per million -- > to result in an inaccurate estimate, whereas > crystal- or resonator-based clocks typically have an > inaccuracy of 10s to 100s of parts per million. > > Signed-off-by: Mike Brady This is rather about ALSA stuff, so please put alsa-devel to Cc. And the addition of BATCH flag has nothing to do with this change. If it's really needed, split the changes and give rationale. thanks, Takashi > --- > .../vc04_services/bcm2835-audio/bcm2835-pcm.c | 23 ++++++++++++++++++- > .../vc04_services/bcm2835-audio/bcm2835.h | 1 + > 2 files changed, 23 insertions(+), 1 deletion(-) > > diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c > index e66da11af5cf..250adf82385a 100644 > --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c > +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c > @@ -12,7 +12,8 @@ > static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { > .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | > SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | > - SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), > + SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_DRAIN_TRIGGER | > + SNDRV_PCM_INFO_SYNC_APPLPTR), > .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, > .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, > .rate_min = 8000, > @@ -74,6 +75,7 @@ void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream, > atomic_set(&alsa_stream->pos, pos); > > alsa_stream->period_offset += bytes; > + alsa_stream->interpolate_start = ktime_get(); > if (alsa_stream->period_offset >= alsa_stream->period_size) { > alsa_stream->period_offset %= alsa_stream->period_size; > snd_pcm_period_elapsed(substream); > @@ -243,6 +245,7 @@ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) > atomic_set(&alsa_stream->pos, 0); > alsa_stream->period_offset = 0; > alsa_stream->draining = false; > + alsa_stream->interpolate_start = ktime_get(); > > return 0; > } > @@ -292,6 +295,24 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) > { > struct snd_pcm_runtime *runtime = substream->runtime; > struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; > + ktime_t now = ktime_get(); > + > + /* Give userspace better delay reporting by interpolating between GPU > + * notifications, assuming audio speed is close enough to the clock > + * used for ktime > + */ > + > + if ((ktime_to_ns(alsa_stream->interpolate_start)) && > + (ktime_compare(alsa_stream->interpolate_start, now) < 0)) { > + u64 interval = > + (ktime_to_ns(ktime_sub(now, > + alsa_stream->interpolate_start))); > + u64 frames_output_in_interval = > + div_u64((interval * runtime->rate), 1000000000); > + snd_pcm_sframes_t frames_output_in_interval_sized = > + -frames_output_in_interval; > + runtime->delay = frames_output_in_interval_sized; > + } > > return snd_pcm_indirect_playback_pointer(substream, > &alsa_stream->pcm_indirect, > diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h > index e13435d1c205..595ad584243f 100644 > --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h > +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h > @@ -78,6 +78,7 @@ struct bcm2835_alsa_stream { > unsigned int period_offset; > unsigned int buffer_size; > unsigned int period_size; > + ktime_t interpolate_start; > > struct bcm2835_audio_instance *instance; > int idx; > -- > 2.17.1 >