![](https://secure.gravatar.com/avatar/5b19e9d0e834ea10ef75803718ad564b.jpg?s=120&d=mm&r=g)
At Thu, 3 Sep 2009 17:35:43 +0200, Giovanni Maruzzelli wrote:
On Thu, Sep 3, 2009 at 5:29 PM, Takashi Iwaitiwai@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)