[alsa-devel] hw_ptr accuracy with intel8x0 -> PulseAudio issue

Raymond Yau superquad.vortex2 at gmail.com
Wed Dec 9 12:55:15 CET 2009


2009/12/8 Takashi Iwai <tiwai at suse.de>

> At Sat, 5 Dec 2009 10:17:07 +0800,
> Raymond Yau wrote:
> >
> > 2009/12/4 pl bossart <bossart.nospam at gmail.com>
> >
> > > >>   17. hwptr 24351 buffer 16384 appl 24332, avail=16403
> > > >
> > > > appl pointer is behind hwprtr (  underrun ) , need timestamp to find
> out
> > > > whether PA is unable to write audio data in time since
> > >
> > >  I commented out the portion of the code that increases the watermark
> and
> > > clamped the number of available samples to the buffer size, and it
> works
> > > just fine, no audio
> > > underflows.
> > >
> >
> > Do you mean that the underrun is related the the portion of code that
> > increase the watermark (i.e It is a pulseaudio bug instead of driver bug
>  )
> > ?
>
> Or, we can try simply to change to periods_min = 2 whether this fixes
> the PA issues.
>
> periods_min = 1 is anyway fairly fragile.  With that setup, apps are
> supposed (implicitly) to wake up frequently enough to get pointers in
> sync.  This is because you can't trust whether the IRQ wake up is
> really fast enough.  There are machines that aren't.
>
>
> thanks,
>
> Takashi
>

The intel8x0 driver has code to handle one period per buffer ,

Is the feature "one period per buffer"  designed for dmix ?

static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct
ichdev *ichdev)
{
	int idx;
	u32 *bdbar = ichdev->bdbar;
	unsigned long port = ichdev->reg_offset;

	iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
	if (ichdev->size == ichdev->fragsize) {
		ichdev->ack_reload = ichdev->ack = 2;
		ichdev->fragsize1 = ichdev->fragsize >> 1;
		for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 4) {
			bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf);
			bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
						     ichdev->fragsize1 >> ichdev->pos_shift);
			bdbar[idx + 2] = cpu_to_le32(ichdev->physbuf + (ichdev->size >> 1));
			bdbar[idx + 3] = cpu_to_le32(0x80000000 | /* interrupt on completion */
						     ichdev->fragsize1 >> ichdev->pos_shift);
		}
		ichdev->frags = 2;
	} else {

The system timer may be running faster or slower than the sound card
on differnt machine

PA only adjust the watermark/sleeping time in one direction only


More information about the Alsa-devel mailing list