Subject: kern/2010: audio driver get unsynchronized when outputting silence
To: None <gnats-bugs@NetBSD.ORG>
From: Lennart Augustsson <augustss@cs.chalmers.se>
List: netbsd-bugs
Date: 02/01/1996 13:19:25
>Number:         2010
>Category:       kern
>Synopsis:       audio driver get unsynchronized when outputting silence
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb  1 07:35:10 1996
>Last-Modified:
>Originator:     Lennart Augustsson
>Organization:
CS at Chalmers University of Technology
>Release:        NetBSD 1.1 current, 1996 Jan 31
>Environment:
System: NetBSD calvin.cs.chalmers.se 1.1A NetBSD 1.1A (CALVIN) #29: Thu Feb 1 12:52:52 MET 1996 augustss@calvin.cs.chalmers.se:/usr/src/sys/arch/i386/compile/CALVIN i386


>Description:
	If, while playing, the audio driver finds that there is nothing
	to play it starts outputting silence.  These silence blocks
	do not come from the ring buffer, but despite this the driver
	counts down the number of blocks in the ring buffer when
	it has finished playing a (dummy) silence block.
>How-To-Repeat:
	Play something and interrupt the write to /dev/audio.
	Listen to the sound sometimes getting "confused" afterwards.
>Fix:

*** dev/audio.c.orig	Thu Feb  1 12:32:38 1996
--- dev/audio.c	Thu Feb  1 12:36:27 1996
***************
*** 1222,1227 ****
--- 1222,1228 ----
      
  	if (sc->pr.nblk > 0) {
  		u_char *hp = sc->pr.hp;
+ 		sc->sc_silence = 0;
  		if (rval = sc->hw_if->start_output(sc->hw_hdl, hp, sc->sc_blksize,
  		    				   audio_pint, (void *)sc)) {
  		    	DPRINTF(("audiostartp: failed: %d\n", rval));
***************
*** 1258,1264 ****
  	 * always fails and the output is always silence after the
  	 * first block.
  	 */
! 	if (--cb->nblk > 0) {
  		hp = cb->hp;
  		if (cb->cb_pause) {
  		    cb->cb_pdrops++;
--- 1259,1267 ----
  	 * always fails and the output is always silence after the
  	 * first block.
  	 */
! 	if (!sc->sc_silence)
! 	    cb->nblk--;
! 	if (cb->nblk > 0) {
  		hp = cb->hp;
  		if (cb->cb_pause) {
  		    cb->cb_pdrops++;
***************
*** 1273,1278 ****
--- 1276,1282 ----
  		    if (audiodebug > 1)
  		    	Dprintf("audio_pint: hp=0x%x cc=%d\n", hp, cc);
  #endif
+ 		    sc->sc_silence = 0;
  		    if (err = hw->start_output(sc->hw_hdl, hp, cc,
  					       audio_pint, (void *)sc)) {
  			    DPRINTF(("audio_pint restart failed: %d\n", err));
***************
*** 1296,1301 ****
--- 1300,1306 ----
  		    Dprintf("audio_pint: drops=%d auzero %d 0x%x\n", cb->cb_drops, cc, *(int *)auzero_block);
  #endif
   psilence:
+ 		sc->sc_silence = 1;
  		if (err = hw->start_output(sc->hw_hdl,
  		    			   auzero_block, cc,
  					   audio_pint, (void *)sc)) {
*** dev/audiovar.h.orig	Sat Oct 14 03:36:59 1995
--- dev/audiovar.h	Thu Feb  1 12:37:34 1996
***************
*** 118,121 ****
--- 118,122 ----
  	int	sc_rblks;	/* number of phantom record blocks */
  	int	sc_pencoding;	/* current encoding; play */
  	int	sc_rencoding;	/* current encoding; record */
+ 	int	sc_silence;	/* currently outputting audio_zero */
  };
>Audit-Trail:
>Unformatted: