Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Jan 2004 13:32:37 +0900
From:      Pyun YongHyeon <yongari@kt-is.co.kr>
To:        multimedia@freebsd.org
Subject:   PCM audio problem on 5.2R(Fix included)
Message-ID:  <20040117043236.GA3223@kt-is.co.kr>

next in thread | raw e-mail | index | archive | help
Hello All

I got two pcm audio problems on FreeBSD 5.2R.(These problems were
not exist in 5.1R.)

 - Selecting a new song in play list of xmms, it takes about
    1 seconds.
 - Output old-buffered cranky sound while terminating xmms if xmms
    playback was paused.(When xmms playback was stopped it does
    not happen.)

The following is truss(1) output while xmms try to change new
song.

...
0.000155886 poll(0x8150000,0x2,0x0)              = 1 (0x1)
0.000131301 write(11,0x822be70,2560)             = 2560 (0xa00)
0.000067327 ioctl(11,SNDCTL_DSP_GETOSPACE,0xbfabaf40) = 0 (0x0)
0.000177676 ioctl(11,SNDCTL_DSP_RESET,0x0)       = 0 (0x0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0.000086882 fstat(11,0xbfabae80)                 = 0 (0x0)
0.000345016 fcntl(0xb,0x3,0x0)                   = 5 (0x5)
0.000165943 fcntl(0xb,0x4,0x1)                   = 0 (0x0)
0.999180343 close(11)                            = 0 (0x0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0.000238298 clock_gettime(0x0,0xbfaedfa8)        = 0 (0x0)
0.000203937 clock_gettime(0x0,0xbfaedfa8)        = 0 (0x0)
0.001563885 write(5,0x816b000,48)                = 48 (0x30)
...

As you can see, close(2) takes about 1 second. So I think previous
SNDCTL_DSP_RESET ioctl was not handled properly.

Here is patch. It seems it solves the above two issues on 5.2R.
The patch adds missing locks and clears buffer(hard + soft)
to ensure to not playing old-buffered data in close(2).
The patch may be appilcable to -current.

--- sys/dev/sound/pcm/dsp.c.ORG	Tue Nov 11 14:38:28 2003
+++ sys/dev/sound/pcm/dsp.c	Fri Jan 16 20:21:27 2004
@@ -664,10 +664,18 @@
 
     	case SNDCTL_DSP_RESET:
 		DEB(printf("dsp reset\n"));
-		if (wrch)
+		if (wrch) {
+			CHN_LOCK(wrch);
 			chn_abort(wrch);
-		if (rdch)
+			chn_resetbuf(wrch);
+			CHN_UNLOCK(wrch);
+		}
+		if (rdch) {
+			CHN_LOCK(rdch);
 			chn_abort(rdch);
+			chn_resetbuf(rdch);
+			CHN_UNLOCK(rdch);
+		}
 		break;
 
     	case SNDCTL_DSP_SYNC:

I'm not subscribed to this list. Please CC me.

Thank you.

Regards,
Pyun YongHeyon
-- 
Pyun YongHyeon <http://www.kr.freebsd.org/~yongari>;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040117043236.GA3223>