On Fri, Aug 03, 2007 at 08:06:08PM +0200, Tim van der Molen wrote:

> > I looked over esound, and the following patch is all I can see that
> > could even remotely be a problem with the audio interface.
> 
> I tested your patch using ogg123 and libao's esd module.
> 
> The stuttering is almost completely gone, but ogg123 has problems to
> start playing music.
> 
> If I run ogg123, its time counter counts very fast for a while.
> Meanwhile, I hear no sound. At some point, the time count is normal and
> I hear the music stuttering for a moment, but after that it is fine. The
> music stutters very seldomly.
> 
> The duration of the `fast time count' depends on the time I haven't used
> esound. The longer the time between two ogg123 invocations, the longer
> the fast time count goes on. Waiting 10 seconds results in the fast time
> count going to ~ 6 seconds; waiting ~ 5 minutes results in the fast time
> count going to ~ 2.5 minutes.

I think I finally figured out what's happening here.

esound quits sending data to the audio device.

audio(4) says that if you let the buffer run out, then you
have to "catch up" before it will start playing back, unless
you are in AUMODE_PLAY_ALL mode, and this is indeed enforced
in the audio layer.

I don't know if previous versions of esound sent silence to
/dev/audio instead of pausing, or what, but 0.2.38 definitely
quits sending audio data.

this fixes the problem where clients "skip" through the
first bit of playback, length of skip depending on time
since esd's last activity (since it's trying to "catch up").

it may also fix some "crackling" which could be produced by
quick starts and stops because of timing discrepencies, which could
happen if esound is not quite correct in it's delay calculations, or
if the audio device is not actually consuming data at the rate it
should.  in such a case, the audio layer will pad in some silence
to keep things smooth in AUMODE_PLAY_ALL mode.

I'm also including the previous patch I sent to ports@, because
it was reported to help.  however, it could actually work against
the AUMODE_PLAY_ALL change, because there could possibly be
fewer times padding will happen (but then there should also
be less time when it need to be padded as well ...).  if this
patch in it's entirety does not fix the crackling, please try
again without the last chunk.

-- 
[EMAIL PROTECTED]
SDF Public Access UNIX System - http://sdf.lonestar.org

Index: Makefile
===================================================================
RCS file: /home/cvs/OpenBSD/ports/audio/esound/Makefile,v
retrieving revision 1.40
diff -u -r1.40 Makefile
--- Makefile    26 Jun 2007 17:10:29 -0000      1.40
+++ Makefile    8 Aug 2007 10:52:52 -0000
@@ -4,6 +4,7 @@
 COMMENT=       "sound library for Enlightenment"
 
 DISTNAME=      esound-0.2.38
+PKGNAME=       ${DISTNAME}p0
 SHARED_LIBS += esd                  2.38     # .2.38
 CATEGORIES=    audio
 MASTER_SITES=  ${MASTER_SITE_GNOME:=sources/esound/0.2/}
Index: files/audio_sun.c
===================================================================
RCS file: /home/cvs/OpenBSD/ports/audio/esound/files/audio_sun.c,v
retrieving revision 1.3
diff -u -r1.3 audio_sun.c
--- files/audio_sun.c   25 Jan 2004 22:07:28 -0000      1.3
+++ files/audio_sun.c   8 Aug 2007 10:52:52 -0000
@@ -58,13 +58,11 @@
     /* set the appropriate mode */
     if((esd_audio_format & ESD_MASK_FUNC) == ESD_RECORD) {
         mode = O_RDWR;
-       info.mode = AUMODE_PLAY | AUMODE_RECORD;
+       info.mode = AUMODE_PLAY_ALL | AUMODE_RECORD;
     } else {
-       info.mode = AUMODE_PLAY;
+       info.mode = AUMODE_PLAY_ALL;
     }
 
-    mode |= O_NONBLOCK;
-
     /* open the sound device */
     device = esd_audio_device ? esd_audio_device : "/dev/audio";
     if ((afd = open(device, mode, 0)) == -1) {
@@ -72,10 +70,6 @@
         return( -2 );
     }
 
-    mode = fcntl(afd, F_GETFL);
-    mode &= ~O_NONBLOCK;
-    fcntl(afd, F_SETFL, mode);
-
     /* set the requested mode */
     if(ioctl(afd, AUDIO_SETINFO, &info) < 0) {
        sun_panic(afd, "AUDIO_SETINFO");
@@ -132,6 +126,20 @@
     if(ioctl(afd, AUDIO_SETINFO, &info) < 0 || 
        fabs(info.play.sample_rate - esd_audio_rate) > esd_audio_rate * 0.05) {
        fprintf(stderr, "Unsupported rate: %i Hz\n", esd_audio_rate);
+       sun_panic(afd, "SETINFO");
+       return(-1);
+    }
+
+    /* OSS interface sets the blocksize to 256 bytes, but esound
+     * actually uses 8192 byte blocks for 16-bit encodings and 4096
+     * byte blocks for 8-bit encodings.
+     */
+    if (enc.precision == 16)
+        info.blocksize = 8192;
+    else
+        info.blocksize = 4096;
+    if(ioctl(afd, AUDIO_SETINFO, &info) == -1) {
+       fprintf(stderr, "Unsupported blocksize: %d\n", info.blocksize);
        sun_panic(afd, "SETINFO");
        return(-1);
     }

Reply via email to