Subject: kern/3357: Short writes to /dev/audio are padded with silence.
To: None <gnats-bugs@gnats.netbsd.org>
From: Lennart Augustsson <augustss@cs.chalmers.se>
List: netbsd-bugs
Date: 03/19/1997 01:33:19
>Number: 3357
>Category: kern
>Synopsis: Short writes to /dev/audio are padded with silence.
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Tue Mar 18 16:50:02 1997
>Last-Modified:
>Originator: Lennart Augustsson
>Organization:
Department of Computing Science, Chalmers University
>Release: NetBSD-current 970319
>Environment:
System: NetBSD calvin.cs.chalmers.se 1.2D NetBSD 1.2D (CALVIN) #130: Wed Mar 19 00:55:02 MET 1997 augustss@calvin.cs.chalmers.se:/usr/src/sys/arch/i386/compile/CALVIN i386
>Description:
If a write to the audio device is not a multiple of the audio
blocksize it is padded with silence.
This is contrary to the behaviour on most systems (e.g. Solaris
and Linux), and is in my opinion counter-intuitive.
The fix here adds a flag to remove the silence padding. It also
makes this mode (AUMODE_NO_PAD) and the AUMODE_PLAY_ALL the default.
This is a change of behaviour, but there don't seem to be many
NetBSD audio applications out there that would suffer. It will also
make NetBSD much more compatible with other systems.
If we don't make these modes the default then some hacking is
needed in all emulation modes to set these flags when /dev/audio
is opened. I think making them default is a better idea.
This patch together with my previous patch for Linux audio
emulation makes raplayer work nicely.
>How-To-Repeat:
Try this and listen
dd if=some-file.au of=/dev/audio bs=88
>Fix:
Apply this patch:
diff -c -r /usr/src/sys/auold/dev/audio.c /usr/src/sys/dev/audio.c
*** /usr/src/sys/auold/dev/audio.c Wed Mar 19 00:26:54 1997
--- /usr/src/sys/dev/audio.c Wed Mar 19 00:53:35 1997
***************
*** 608,613 ****
--- 608,615 ----
audiostartr(sc);
}
}
+ /* Play all sample, and don't pad short writes by default */
+ sc->sc_mode |= AUMODE_PLAY_ALL | AUMODE_NO_PAD;
splx(s);
return (0);
}
***************
*** 957,962 ****
--- 959,990 ----
error = 0;
while (uio->uio_resid > 0) {
+ if ((sc->sc_mode & AUMODE_NO_PAD) && cb->fill > 0) {
+ if (sc->sc_pbus == 0) {
+ /* playing has stopped, ignore fill */
+ cb->fill = 0;
+ } else {
+ /* Write samples in the silence fill space.
+ * We don't know where the DMA is
+ * happening in the buffer, but if we
+ * are lucky we will fill the buffer before
+ * playing has reached the point we move to.
+ * If we are unlucky some sample will
+ * not be played.
+ */
+ cc = min(cb->fill, uio->uio_resid);
+ error = uiomove(cb->otp, cc, uio);
+ if (error == 0) {
+ if (hw->sw_encode) {
+ hw->sw_encode(sc->hw_hdl, sc->sc_pencoding,
+ cb->otp, cc);
+ }
+ cb->fill -= cc;
+ cb->otp += cc;
+ }
+ continue;
+ }
+ }
if (cb->nblk >= sc->sc_hiwat) {
do {
DPRINTF(("audio_write: nblk=%d hiwat=%d lowat=%d\n", cb->nblk, sc->sc_hiwat, sc->sc_lowat));
***************
*** 1028,1033 ****
--- 1056,1063 ----
/* fill with audio silence */
tp += cc;
cc = blocksize - cc;
+ cb->fill = cc;
+ cb->otp = tp;
audio_fill_silence(sc->sc_pencoding, tp, cc);
DPRINTF(("audio_write: auzero 0x%x %d 0x%x\n",
tp, cc, *(int *)tp));
diff -c -r /usr/src/sys/auold/dev/audiovar.h /usr/src/sys/dev/audiovar.h
*** /usr/src/sys/auold/dev/audiovar.h Wed Mar 19 00:26:54 1997
--- /usr/src/sys/dev/audiovar.h Wed Mar 19 00:54:42 1997
***************
*** 78,83 ****
--- 78,86 ----
u_short cb_pause; /* io paused */
u_long cb_drops; /* missed samples from over/underrun */
u_long cb_pdrops; /* paused samples */
+
+ u_char *otp; /* point where silence padding started */
+ int fill; /* number of silence pad bytes */
};
/*
diff -c -r /usr/src/sys/auold/sys/audioio.h /usr/src/sys/sys/audioio.h
*** /usr/src/sys/auold/sys/audioio.h Wed Jan 22 18:46:50 1997
--- /usr/src/sys/sys/audioio.h Wed Mar 19 00:31:08 1997
***************
*** 74,79 ****
--- 74,80 ----
#define AUMODE_PLAY 0x01
#define AUMODE_RECORD 0x02
#define AUMODE_PLAY_ALL 0x04 /* play all samples--no real-time correction */
+ #define AUMODE_NO_PAD 0x08 /* don't silence pad short writes */
};
typedef struct audio_info audio_info_t;
>Audit-Trail:
>Unformatted: