alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
From: Curtis Malainey <cujomalainey@chromium.org>
To: alsa-devel@alsa-project.org
Cc: Oder Chiou <oder_chiou@realtek.com>,
	Takashi Iwai <tiwai@suse.com>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Ben Zhang <benzh@chromium.org>, Mark Brown <broonie@kernel.org>,
	Bard Liao <bardliao@realtek.com>,
	Curtis Malainey <cujomalainey@chromium.org>
Subject: [alsa-devel] [RFC 12/15] ASoC: rt5677: Transfer one period at a time over SPI
Date: Fri,  6 Sep 2019 12:46:34 -0700	[thread overview]
Message-ID: <20190906194636.217881-13-cujomalainey@chromium.org> (raw)
In-Reply-To: <20190906194636.217881-1-cujomalainey@chromium.org>

From: Ben Zhang <benzh@chromium.org>

Rewrite the ring buffer transfer functions to copy one period
at a time then call snd_pcm_period_elapsed(). This reduces the
latency of transferring the initial ~2sec of audio after hotword
detect since audio samples are available for userspace earlier.

Signed-off-by: Ben Zhang <benzh@chromium.org>
Signed-off-by: Curtis Malainey <cujomalainey@chromium.org>
---
 sound/soc/codecs/rt5677-spi.c | 91 +++++++++++++++++++++++------------
 1 file changed, 60 insertions(+), 31 deletions(-)

diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c
index 25d75a803cb5..b9b0f646127d 100644
--- a/sound/soc/codecs/rt5677-spi.c
+++ b/sound/soc/codecs/rt5677-spi.c
@@ -51,7 +51,8 @@
 #define RT5677_BUF_BYTES_TOTAL		0x20000
 #define RT5677_MIC_BUF_ADDR		0x60030000
 #define RT5677_MODEL_ADDR		0x5FFC9800
-#define RT5677_MIC_BUF_BYTES		(RT5677_BUF_BYTES_TOTAL - sizeof(u32))
+#define RT5677_MIC_BUF_BYTES		((u32)(RT5677_BUF_BYTES_TOTAL - \
+					sizeof(u32)))
 #define RT5677_MIC_BUF_FIRST_READ_SIZE	0x10000
 
 static struct spi_device *g_spi;
@@ -205,15 +206,15 @@ static int rt5677_spi_mic_write_offset(u32 *mic_write_offset)
 }
 
 /*
- * Copy a block of audio samples from the DSP mic buffer to the dma_area of
- * the pcm runtime. The receiving buffer may wrap around.
+ * Copy one contiguous block of audio samples from the DSP mic buffer to the
+ * dma_area of the pcm runtime. The receiving buffer may wrap around.
  * @begin: start offset of the block to copy, in bytes.
  * @end:   offset of the first byte after the block to copy, must be greater
  *         than or equal to begin.
  *
  * Return: Zero if successful, or a negative error code on failure.
  */
-static int rt5677_spi_append_data(struct rt5677_dsp *rt5677_dsp,
+static int rt5677_spi_copy_block(struct rt5677_dsp *rt5677_dsp,
 		u32 begin, u32 end)
 {
 	struct snd_pcm_runtime *runtime = rt5677_dsp->substream->runtime;
@@ -269,6 +270,38 @@ static int rt5677_spi_append_data(struct rt5677_dsp *rt5677_dsp,
 	return ret;
 }
 
+/*
+ * Copy a given amount of audio samples from the DSP mic buffer starting at
+ * mic_read_offset, to the dma_area of the pcm runtime. The source buffer may
+ * wrap around. mic_read_offset is updated after successful copy.
+ * @amount: amount of samples to copy, in bytes.
+ *
+ * Return: Zero if successful, or a negative error code on failure.
+ */
+static int rt5677_spi_copy(struct rt5677_dsp *rt5677_dsp, u32 amount)
+{
+	int ret = 0;
+	u32 target;
+
+	if (amount == 0)
+		return ret;
+
+	target = rt5677_dsp->mic_read_offset + amount;
+	/* Copy the first chunk in DSP's mic buffer */
+	ret |= rt5677_spi_copy_block(rt5677_dsp, rt5677_dsp->mic_read_offset,
+			min(target, RT5677_MIC_BUF_BYTES));
+
+	if (target >= RT5677_MIC_BUF_BYTES) {
+		/* Wrap around, copy the second chunk */
+		target -= RT5677_MIC_BUF_BYTES;
+		ret |= rt5677_spi_copy_block(rt5677_dsp, 0, target);
+	}
+
+	if (!ret)
+		rt5677_dsp->mic_read_offset = target;
+	return ret;
+}
+
 /*
  * A delayed work that streams audio samples from the DSP mic buffer to the
  * dma_area of the pcm runtime via SPI.
@@ -279,7 +312,7 @@ static void rt5677_spi_copy_work(struct work_struct *work)
 		container_of(work, struct rt5677_dsp, copy_work.work);
 	struct snd_pcm_runtime *runtime;
 	u32 mic_write_offset;
-	size_t bytes_copied, period_bytes;
+	size_t new_bytes, copy_bytes, period_bytes;
 	int ret = 0;
 
 	/* Ensure runtime->dma_area buffer does not go away while copying. */
@@ -312,35 +345,31 @@ static void rt5677_spi_copy_work(struct work_struct *work)
 					RT5677_MIC_BUF_FIRST_READ_SIZE;
 	}
 
-	/* Copy all new samples from DSP's mic buffer to dma_area */
-	bytes_copied = 0;
-	if (rt5677_dsp->mic_read_offset < mic_write_offset) {
-		/* One chunk in DSP's mic buffer */
-		ret |= rt5677_spi_append_data(rt5677_dsp,
-				rt5677_dsp->mic_read_offset, mic_write_offset);
-		bytes_copied = mic_write_offset - rt5677_dsp->mic_read_offset;
-	} else if (rt5677_dsp->mic_read_offset > mic_write_offset) {
-		/* Wrap around, two chunks in DSP's mic buffer */
-		ret |= rt5677_spi_append_data(rt5677_dsp,
-				rt5677_dsp->mic_read_offset,
-				RT5677_MIC_BUF_BYTES);
-		ret |= rt5677_spi_append_data(rt5677_dsp, 0, mic_write_offset);
-		bytes_copied = RT5677_MIC_BUF_BYTES -
-				rt5677_dsp->mic_read_offset + mic_write_offset;
-	}
-	if (ret) {
-		dev_err(rt5677_dsp->dev, "Copy failed %d\n", ret);
-		goto done;
-	}
+	/* Calculate the amount of new samples in bytes */
+	if (rt5677_dsp->mic_read_offset <= mic_write_offset)
+		new_bytes = mic_write_offset - rt5677_dsp->mic_read_offset;
+	else
+		new_bytes = RT5677_MIC_BUF_BYTES + mic_write_offset
+				- rt5677_dsp->mic_read_offset;
 
-	rt5677_dsp->mic_read_offset = mic_write_offset;
-	rt5677_dsp->avail_bytes += bytes_copied;
+	/* Copy all new samples from DSP mic buffer, one period at a time */
 	period_bytes = snd_pcm_lib_period_bytes(rt5677_dsp->substream);
-
-	if (rt5677_dsp->avail_bytes >= period_bytes) {
-		snd_pcm_period_elapsed(rt5677_dsp->substream);
-		rt5677_dsp->avail_bytes = 0;
+	while (new_bytes) {
+		copy_bytes = min(new_bytes, period_bytes
+				- rt5677_dsp->avail_bytes);
+		ret = rt5677_spi_copy(rt5677_dsp, copy_bytes);
+		if (ret) {
+			dev_err(rt5677_dsp->dev, "Copy failed %d\n", ret);
+			goto done;
+		}
+		rt5677_dsp->avail_bytes += copy_bytes;
+		if (rt5677_dsp->avail_bytes >= period_bytes) {
+			snd_pcm_period_elapsed(rt5677_dsp->substream);
+			rt5677_dsp->avail_bytes = 0;
+		}
+		new_bytes -= copy_bytes;
 	}
+
 	/* TODO benzh: use better delay time based on period_bytes */
 	schedule_delayed_work(&rt5677_dsp->copy_work, msecs_to_jiffies(5));
 done:
-- 
2.23.0.187.g17f5b7556c-goog

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

  parent reply	other threads:[~2019-09-06 19:57 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-06 19:46 [alsa-devel] [RFC 00/15] Add Samus Hotwording for RT5677 Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 01/15] ASoC: rt5677: Remove magic number register writes Curtis Malainey
2019-09-09 10:07   ` [alsa-devel] Applied "ASoC: rt5677: Remove magic number register writes" to the asoc tree Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 02/15] ASoC: rt5677: keep analog power register at SND_SOC_BIAS_OFF Curtis Malainey
2019-09-09  9:54   ` Mark Brown
2019-09-09 15:50     ` Curtis Malainey
2019-09-09 12:23   ` [alsa-devel] Applied "ASoC: rt5677: keep analog power register at SND_SOC_BIAS_OFF" to the asoc tree Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 03/15] ASoC: rt5677: Add a PCM device for streaming hotword via SPI Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 04/15] ASoC: rt5677: Load firmware " Curtis Malainey
2019-09-11 10:24   ` Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 05/15] ASoC: rt5677: Auto enable/disable DSP for hotwording Curtis Malainey
2019-09-11 10:25   ` Mark Brown
2019-09-11 20:22     ` Curtis Malainey
2019-09-12  9:26       ` Mark Brown
2019-09-16 21:29         ` Curtis Malainey
2019-09-16 21:55           ` Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 06/15] ASoC: bdw-rt5677: Add a DAI link for rt5677 SPI PCM device Curtis Malainey
2019-09-09  0:18   ` Kuninori Morimoto
2019-09-09 16:53     ` Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 07/15] ASoC: rt5677: Enable jack detect while DSP is running Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 08/15] ASoC: rt5677: Use delayed work for DSP firmware load Curtis Malainey
2019-09-11 10:28   ` Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 09/15] ASoC: rt5677: Add DAPM audio path for hotword stream Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 10/15] ASoC: rt5677: Mark reg RT5677_PWR_ANLG2 as volatile Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 11/15] ASoC: rt5677: Stop and restart DSP over suspend/resume Curtis Malainey
2019-09-06 19:46 ` Curtis Malainey [this message]
2019-09-11 10:54   ` [alsa-devel] [RFC 12/15] ASoC: rt5677: Transfer one period at a time over SPI Mark Brown
2019-09-11 18:09     ` Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 13/15] ASoC: rt5677: Disable irq at suspend Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 14/15] ASoC: rt5677: Allow VAD to be shut on/off at all times Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 15/15] ASoC: rt5677: Turn on MCLK1 for DSP via DAPM Curtis Malainey
2019-09-06 20:40 ` [alsa-devel] [RFC 00/15] Add Samus Hotwording for RT5677 Pierre-Louis Bossart
2019-09-06 21:09   ` Curtis Malainey
2019-09-06 22:13     ` Pierre-Louis Bossart
2019-09-09 16:52       ` Curtis Malainey

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=20190906194636.217881-13-cujomalainey@chromium.org \
    --to=cujomalainey@chromium.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=bardliao@realtek.com \
    --cc=benzh@chromium.org \
    --cc=broonie@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=oder_chiou@realtek.com \
    --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;
as well as URLs for NNTP newsgroup(s).