[alsa-devel] snd_dummy on Centos - Redhat

Takashi Iwai tiwai at suse.de
Thu Sep 3 17:41:42 CEST 2009


At Thu, 3 Sep 2009 17:35:43 +0200,
Giovanni Maruzzelli wrote:
> 
> On Thu, Sep 3, 2009 at 5:29 PM, Takashi Iwai<tiwai at suse.de> wrote:
> >> Sep  3 17:20:20 localhost kernel: giovanni line: 291, dpcm->frac_pos /
> >> HZ=0, jiffies=91837395
> >> Sep  3 17:20:20 localhost kernel: giovanni line: 291, dpcm->frac_pos /
> >> HZ=48, jiffies=91837398
> >> Sep  3 17:20:20 localhost kernel: giovanni line: 291, dpcm->frac_pos /
> >> HZ=48, jiffies=91837398
> >> Sep  3 17:20:20 localhost kernel: giovanni line: 291, dpcm->frac_pos /
> >> HZ=80, jiffies=91837400
> >> Sep  3 17:20:20 localhost kernel: giovanni line: 291, dpcm->frac_pos /
> >> HZ=80, jiffies=91837400
> >
> > So, this is a kernel with the variable HZ.  That's the whole problem.
> > My patch also doesn't take it into account but assumes the constant HZ.
> > We'll need to convert the stuff to msecs_to_jiffies() and co...
> 
> Ah! I was struggling since days on this, you're fast!!!
> 
> Also, I saw you made various modifications that I tried to make (in a
> messy way), to a custom version of snd-dummy made to support 128
> subdevices and use less irq and context switches.
> As soon as you looked into the variable HZ problem, I will see if my
> modifications still make some sense, and in case I will forward it to
> you.

Try the patch below.  It just converts the calculation base to msec
instead of HZ.

The enhancement to max 128 subdevices should be easy.  Isn't it suffice
to define MAX_PCM_SUBSTREAMS to 128?


Takashi

---
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 0a798bd..fd5f753 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -206,9 +206,9 @@ struct dummy_systimer_pcm {
 	spinlock_t lock;
 	struct timer_list timer;
 	unsigned long base_time;
-	unsigned int frac_pos;	/* fractional sample position (based HZ) */
-	unsigned int frac_buffer_size;	/* buffer_size * HZ */
-	unsigned int frac_period_size;	/* period_size * HZ */
+	unsigned int frac_pos;	/* fractional sample position (based in msec) */
+	unsigned int frac_buffer_size;	/* buffer_size * 1000 */
+	unsigned int frac_period_size;	/* period_size * 1000 */
 	unsigned int rate;
 	struct snd_pcm_substream *substream;
 };
@@ -218,8 +218,8 @@ static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
 	unsigned long frac;
 
 	frac = dpcm->frac_pos % dpcm->frac_period_size;
-	dpcm->timer.expires = jiffies +
-		(dpcm->frac_period_size + dpcm->rate - 1) / dpcm->rate;
+	frac = (dpcm->frac_period_size - frac + dpcm->rate - 1) / dpcm->rate;
+	dpcm->timer.expires = jiffies + msecs_to_jiffies(frac);
 	add_timer(&dpcm->timer);
 }
 
@@ -231,6 +231,7 @@ static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm)
 	if (!delta)
 		return;
 	dpcm->base_time = jiffies;
+	delta = jiffies_to_msecs(delta);
 	dpcm->frac_pos += delta * dpcm->rate;
 	while (dpcm->frac_pos >= dpcm->frac_buffer_size)
 		dpcm->frac_pos -= dpcm->frac_buffer_size;
@@ -262,8 +263,8 @@ static int dummy_systimer_prepare(struct snd_pcm_substream *substream)
 
 	dpcm->frac_pos = 0;
 	dpcm->rate = runtime->rate;
-	dpcm->frac_buffer_size = runtime->buffer_size * HZ;
-	dpcm->frac_period_size = runtime->period_size * HZ;
+	dpcm->frac_buffer_size = runtime->buffer_size * 1000;
+	dpcm->frac_period_size = runtime->period_size * 1000;
 
 	return 0;
 }
@@ -288,7 +289,7 @@ dummy_systimer_pointer(struct snd_pcm_substream *substream)
 	spin_lock(&dpcm->lock);
 	dummy_systimer_update(dpcm);
 	spin_unlock(&dpcm->lock);
-	return dpcm->frac_pos / HZ;
+	return dpcm->frac_pos / 1000;
 }
 
 static int dummy_systimer_create(struct snd_pcm_substream *substream)


More information about the Alsa-devel mailing list