[nas] Re: got a handle on it: nas enabled mpg123 sounds slow and scratchy?

Jon Trulson jon at radscan.com
Tue Mar 4 23:54:19 MST 2003


On Tue, 4 Mar 2003, Scott Presnell wrote:

> Date: Tue, 04 Mar 2003 12:01:10 -0800
> From: Scott Presnell <srp at tworoads.net>
> To: jon at radscan.com
> Cc: netbsd-help at netbsd.org, nas at radscan.com,
>      Frederick Bruckman <fredb at immanent.net>
> Subject: got a handle on it: nas enabled mpg123 sounds slow and scratchy?
>
> Jon Trulson wrote:
> >>
> >>from NetBSD sys/audioio.h
> >>
> >>u_char	error;		/* non-zero if underflow/overflow ocurred */
> >>
> >>So it sounds like the driver is responding with "overflow ocurred"?
> >
> >
> > 	Or underflow.  Sure would be nice to know which ;-) ...
> > Definitely a good hint... Anyway to tell which it is?
> >
>
> Eureka!
>
> Taking your lead on a possible underflow I played with the following:
>
> at server/dda/voxware/auvoxware.c:  line 536 we have
>
>     timer_ms = (auMinibufSamples * 700) / rate;
>     ntval.it_interval.tv_sec = 0;
>     ntval.it_interval.tv_usec = timer_ms * 1000;
>     ntval.it_value.tv_sec = 0;
>     ntval.it_value.tv_usec = timer_ms * 10 ;
>
> Listening how the song was "extended" in realtime time, and fairly
> "regularly" choppy, and looking at old code/patches included in the
> BUILDNOTES I took a shot and reduced:
>
> 	ntval.it_interval.tv_usec = timer_ms * 1000;
> to:
> 	ntval.it_interval.tv_usec = timer_ms * 100;
>
> And that solved the issue @44100hz! (PIII + PCI audio card).
> Can you explain further, the math you are using to setup this timer?
>

	Well I didn't write the original code, I'm just the maintenance
monkey ;-)

	The idea is that a timer is setup to trigger just before
auMinibufSamples has finished playing.  So in the above code, with
auMinibufSamples = 1024:

	usec = ((1024 * 700) / 44100) * 1000
	     = 16253

	Since it should take approx

	usec = ((1024 * 1000) / 44100) * 1000
	     = 23219

	to eat these samples, this should be sufficient for the timer.

	The hpux server is using an even more conservative value, at about
11609us per timer [((1024 * 500) / 44100) * 1000].

	What you've done is divide that by 100, so in your case it's only
waiting 1625us, which seems far too short.  The write can block, so it
probably isn't 'hurting' much by doing this, except perhaps being not as
efficient.  It best to write-block as little as possible, so that other
things can happen (like handling client requests, etc).

	It seems your hardware is consuming samples alot faster than it
should, or the timer isn't timing out as fast as it's being told to.  I
don't know which.  You might take the original code (timer_ms * 1000), and
change the '700' term to '500' and see if that yields better results...
Maybe your just seeing a marginal case here, and timing out at approx
auMinibufSamples/2 might yield better results.  Keep decreasing this term
until you get something workable at 44.1khz.



> This is probably irrelevant, but I note atleast one other place you are
> doing math apparently with a 1/2 second buffer expectation, but from
> audio(4) in NetBSD:
>
>         blocksize sets the current audio blocksize.  The generic audio
>         driver layer and the hardware driver have the opportunity to ad-
>         just this block size to get it within implementation-required
>         limits.  Upon return from an AUDIO_SETINFO call, the actual
>         blocksize set is returned in this field.  Normally the blocksize
>         is calculated to correspond to 50ms of sound and it is recalcu-
>         lated when the encoding parameter changes, but if the blocksize
>         is set explicitely this value becomes sticky, i.e., it is remains
>         even when the encoding is changed.  The stickyness can be cleared
>         by reopening the device or setting the blocksize to 0.
>

	AUDIO_SETINFO only appears to be used when dealing with a pc
speaker in auvoxware...  Perhaps this needs to be used (or at least
intialized to blocksize 0) on device open (before specifying format/sample
rate) for netbsd?  Might be worth trying in the device open code...

> Does this imply something about the fragsize, or number of fragments required
> to keep the pipe filled, or is it completely about the timer above?
>

	It seems (at least to me) to be something with the timer... I
suspect nasd has enough data, it just seems that either your hardware is
consuming samples faster than nasd is expecting, or there is some problem
with the resolution/handling of the timer (ie, it expires, but some time
passes before nasd is informed of this, or intervalProc isn't working
properly for netbsd (signal problem?)...?).

	Glad it's working for you, but I don't think a 1625us timer is
something I'd want to add permantly in auvoxware.c for everyone... ;-)
The fact that it works though definitely points to underflow.

-- 
Jon Trulson    mailto:jon at radscan.com
ID: 1A9A2B09, FP: C23F328A721264E7 B6188192EC733962
PGP keys at http://radscan.com/~jon/PGPKeys.txt
#include <std/disclaimer.h>
You talk like a Ferengi.




More information about the Nas mailing list