Subject: lib/12796: ossaudio's ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) doesn't properly update "info.fragments".
To: None <gnats-bugs@gnats.netbsd.org>
From: Frederick Bruckman <fb@enteract.com>
List: netbsd-bugs
Date: 04/30/2001 15:11:54
>Number: 12796
>Category: lib
>Synopsis: ossaudio's ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) doesn't properly update "info.fragments".
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Apr 30 13:12:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Frederick Bruckman
>Release: NetBSD-1.5.1_BETA
>Organization:
>Environment:
System: NetBSD fiona.amberites.invalid 1.5.1_BETA NetBSD 1.5.1_BETA (FIONA) #0:
Thu Apr 5 23:18:39 CDT 2001 fredb@fiona.amberites.invalid:
/usr/src/sys/arch/i386/compile/FIONA i386
>Description:
After...
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
int fd, len;
size_t someSize;
void *someBuffer;
audio_buf_info oss_buf_info;
/* ... */
fd= open("/dev/audio", O_WRONLY);
while (...)
write=(fd, someBuffer, someSize);
/* ... */
ioctl(fd, SNDCTL_DSP_GETOSPACE, &oss_buf_info)
"oss_buf_info.fragments" and "oss_buf_info.fragstotal" always return
the maximum blocks that could possibly be available, without regard for
either the actual state of the audio device, or it's current blocksize.
This causes "squeak-3.0", which evidently depends on
"oss_buf_info.fragments" on Linux to tell it when it's safe to write,
to wedge hard after playing any sound on NetBSD (with ossaudio).
I suggest we can calculate the requested information using the audio
device's "audio->seek" and "audio->hiwat". Moreover,
"oss_buf_info.fragstotal" looks to me like it should relate to
"oss_buf_info.fragments", that is, it should be the highest value that
"oss_buf_info.fragments" could obtain given the current settings, and
not the highest value that could be stuffed into "audio->play->buffer_size"
== "oss_buf_info.bytes" for any combination of settings.
The following patches allow "squeak", with little modification, to retain
interactive performance during and after audio playback. Of course, I'll
need to find another work-around for the "squeak" package, for non-current
systems, which is why this is low priority. The bump in "SOUND_VERSION"
is so we can work around this bug only if necessary (conditionally).
>How-To-Repeat:
Build and run the "squeak", and watch it appear to hang after
playing any sound. The current package has possibly a different
problem with sound -- it hangs _before_ it even plays the sound,
but it may be the same thing (just haven't tried it yet).
You can get the current "squeak" VM from
ftp://ftp.inria.fr/INRIA/Projects/SOR/users/piumarta/squeak/
and I will share my (unfinished) squeak-3.0pre2 package with anyone
who asks.
>Fix:
Index: ossaudio.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libossaudio/ossaudio.c,v
retrieving revision 1.12
diff -c -r1.12 ossaudio.c
*** ossaudio.c 2000/08/16 16:14:33 1.12
--- ossaudio.c 2001/04/30 20:10:36
***************
*** 339,346 ****
return retval;
setblocksize(fd, &tmpinfo);
bufinfo.fragsize = tmpinfo.blocksize;
! bufinfo.fragments = /* XXX */
! bufinfo.fragstotal = tmpinfo.play.buffer_size / bufinfo.fragsize;
bufinfo.bytes = tmpinfo.play.buffer_size;
*(struct audio_buf_info *)argp = bufinfo;
break;
--- 339,346 ----
return retval;
setblocksize(fd, &tmpinfo);
bufinfo.fragsize = tmpinfo.blocksize;
! bufinfo.fragments = tmpinfo.hiwat - tmpinfo.play.seek / bufinfo.fragsize;
! bufinfo.fragstotal = tmpinfo.hiwat;
bufinfo.bytes = tmpinfo.play.buffer_size;
*(struct audio_buf_info *)argp = bufinfo;
break;
Index: soundcard.h
===================================================================
RCS file: /cvsroot/basesrc/lib/libossaudio/soundcard.h,v
retrieving revision 1.10
diff -c -r1.10 soundcard.h
*** soundcard.h 1999/11/16 23:56:42 1.10
--- soundcard.h 2001/04/30 20:10:37
***************
*** 46,52 ****
#ifndef _SOUNDCARD_H_
#define _SOUNDCARD_H_
! #define SOUND_VERSION 0x030000
#define SNDCTL_DSP_RESET _IO ('P', 0)
#define SNDCTL_DSP_SYNC _IO ('P', 1)
--- 46,52 ----
#ifndef _SOUNDCARD_H_
#define _SOUNDCARD_H_
! #define SOUND_VERSION 0x030001
#define SNDCTL_DSP_RESET _IO ('P', 0)
#define SNDCTL_DSP_SYNC _IO ('P', 1)
>Release-Note:
>Audit-Trail:
>Unformatted: