All of lore.kernel.org
 help / color / mirror / Atom feed
From: sutar.mounesh@gmail.com
To: patch@alsa-project.org
Cc: alsa-devel@alsa-project.org,
	"mahendran.k" <mahendran.kuppusamy@in.bosch.com>,
	mounesh_sutar@mentor.com
Subject: [PATCH 4/6] alsa-lib:pcm: fix the hw_ptr update until the boundary available.
Date: Fri, 30 Dec 2016 11:59:27 +0530	[thread overview]
Message-ID: <1483079367-28931-1-git-send-email-sutar.mounesh@gmail.com> (raw)

From: mahendran.k <mahendran.kuppusamy@in.bosch.com>

For long time test case, the slave_hw_ptr will exceed the boundary
and wraparound the slave_hw_ptr. This slave boundary wraparound will
cause the rate->hw_ptr to wraparound irrespective of the rate->boundary
availability and due to that the available size goes wrong.

Hence, To get the correct available size,
- Its necessary to increment the rate->hw_ptr upto the rate->boundary
and then wraparound the rate->hw_ptr.
- While handling fraction part of slave period, rounded value will be
introduced by input_frames(). To eliminate rounding issue on rate->hw_ptr,
subtract last rounded value from rate->hw_ptr and add new rounded value
of present slave_hw_ptr fraction part to rate->hw_ptr.

Signed-off-by: mahendran.k <mahendran.kuppusamy@in.bosch.com>
Signed-off-by: Mounesh Sutar <mounesh_sutar@mentor.com>

diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c
index 1f830dd..5bee77c 100644
--- a/src/pcm/pcm_rate.c
+++ b/src/pcm/pcm_rate.c
@@ -50,7 +50,7 @@ typedef struct _snd_pcm_rate snd_pcm_rate_t;
 
 struct _snd_pcm_rate {
 	snd_pcm_generic_t gen;
-	snd_pcm_uframes_t appl_ptr, hw_ptr;
+	snd_pcm_uframes_t appl_ptr, hw_ptr, last_slave_hw_ptr;
 	snd_pcm_uframes_t last_commit_ptr;
 	snd_pcm_uframes_t orig_avail_min;
 	snd_pcm_sw_params_t sw_params;
@@ -563,14 +563,28 @@ static inline void snd_pcm_rate_sync_hwptr0(snd_pcm_t *pcm, snd_pcm_uframes_t sl
 {
 	snd_pcm_rate_t *rate = pcm->private_data;
 
+	snd_pcm_sframes_t slave_hw_ptr_diff = slave_hw_ptr - rate->last_slave_hw_ptr;
+	snd_pcm_sframes_t last_slave_hw_ptr_frac;
+
 	if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
 		return;
-	/* FIXME: boundary overlap of slave hw_ptr isn't evaluated here!
-	 *        e.g. if slave rate is small... 
-	 */
-	rate->hw_ptr =
-		(slave_hw_ptr / rate->gen.slave->period_size) * pcm->period_size +
-		rate->ops.input_frames(rate->obj, slave_hw_ptr % rate->gen.slave->period_size);
+
+	if (slave_hw_ptr_diff < 0)
+		slave_hw_ptr_diff += rate->gen.slave->boundary; /* slave boundary wraparound */
+	else if (slave_hw_ptr_diff == 0)
+		return;
+	last_slave_hw_ptr_frac = rate->last_slave_hw_ptr % rate->gen.slave->period_size;
+	/* While handling fraction part fo slave period, rounded value will be introduced by input_frames().
+	 * To eliminate rounding issue on rate->hw_ptr, subtract last rounded value from rate->hw_ptr and
+	 * add new rounded value of present slave_hw_ptr fraction part to rate->hw_ptr. Hence,
+	 * rate->hw_ptr += [ (no. of updated slave periods * pcm rate period size) -
+	 * 				fractional part of last_slave_hw_ptr rounded value +
+	 * 				fractional part of updated slave hw ptr's rounded value ] */
+	rate->hw_ptr += (
+			(((last_slave_hw_ptr_frac + slave_hw_ptr_diff) / rate->gen.slave->period_size) * pcm->period_size) -
+			rate->ops.input_frames(rate->obj, last_slave_hw_ptr_frac) +
+			rate->ops.input_frames(rate->obj, (last_slave_hw_ptr_frac + slave_hw_ptr_diff) % rate->gen.slave->period_size));
+	rate->last_slave_hw_ptr = slave_hw_ptr;
 
 	rate->hw_ptr %= pcm->boundary;
 }
@@ -635,6 +649,7 @@ static int snd_pcm_rate_prepare(snd_pcm_t *pcm)
 		return err;
 	*pcm->hw.ptr = 0;
 	*pcm->appl.ptr = 0;
+	rate->last_slave_hw_ptr = 0;
 	err = snd_pcm_rate_init(pcm);
 	if (err < 0)
 		return err;
@@ -650,6 +665,7 @@ static int snd_pcm_rate_reset(snd_pcm_t *pcm)
 		return err;
 	*pcm->hw.ptr = 0;
 	*pcm->appl.ptr = 0;
+	rate->last_slave_hw_ptr = 0;
 	err = snd_pcm_rate_init(pcm);
 	if (err < 0)
 		return err;
-- 
1.7.9.5

             reply	other threads:[~2016-12-30  6:29 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-30  6:29 sutar.mounesh [this message]
2017-01-02 13:58 ` [PATCH 4/6] alsa-lib:pcm: fix the hw_ptr update until the boundary available Takashi Iwai
2018-01-19  5:56   ` Mahendran Kuppusamy (RBEI/ECF3)

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=1483079367-28931-1-git-send-email-sutar.mounesh@gmail.com \
    --to=sutar.mounesh@gmail.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=mahendran.kuppusamy@in.bosch.com \
    --cc=mounesh_sutar@mentor.com \
    --cc=patch@alsa-project.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.