Subject: port-i386/2581: linux audio emulation not good enough for realaudio
To: None <gnats-bugs@NetBSD.ORG>
From: Bill Sommerfeld <sommerfeld@orchard.medford.ma.us>
List: netbsd-bugs
Date: 06/30/1996 14:49:55
>Number: 2581
>Category: port-i386
>Synopsis: linux audio emulation not good enough for realaudio
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Jun 30 11:05:01 1996
>Last-Modified:
>Originator: Bill Sommerfeld
>Organization:
none
>Release: current as of 6/29/96
>Environment:
System: NetBSD orchard.medford.ma.us 1.2_BETA NetBSD 1.2_BETA (ORCHARD) #17: Sat Jun 29 22:54:07 EDT 1996 sommerfeld@orchard.medford.ma.us:/home/src/netbsd-krb5/sys/arch/i386/compile/ORCHARD i386
>Description:
the linux realaudio doesn't work on netbsd under emulation
>How-To-Repeat:
see http://www.realaudio.com for the bits; download the linux bits
and try running it on the sample included in the tarfile
>Fix:
The following changes were made while I was attempting to get
realaudio to work on my NetBSD/i386 system.
realaudio also wants to open up /dev/mixer and do a bunch of linux
mixer ioctls, but I haven't implemented those (there appear to be a
lot of them...); the ioctl failure doesn't cause realaudio to give
up..
Note that the following also fixes LINUX_SNDCTL_DSP_SETFMT to return
the actual format set just like what Linux does. This wasn't
necessary to get realaudio working but I didn't realize that until
*after* I made the change..
I've got an sb pro, which only does 8-bit samples; realaudio asks for
linear 16-bit samples and unfortunately doesn't look at which format
it actually gets back. You may need to select "8 bit" instead of "16
bit" audio in this case.
I also needed to set the AUMODE_PLAY_ALL bit on /dev/sound using a
separate program in order to avoid silence-stuffing when realaudio got
behind..
Only the 14.4kbit version seems to work OK on my system; I did the
work on a 486/33 which evidently doesn't have the horsepower for the
28.8 coder.
Charles and/or Christos and/or whoever "owns" the linux emulation
code: please let me know if there's a problem with this fix or any
reason why you can't put this into the post-1.2 tree.
- Bill
===================================================================
RCS file: /usr/cvs/sys/compat/linux/linux_audio.h,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 linux_audio.h
*** linux_audio.h 1996/03/12 00:03:08 1.1.1.1
--- linux_audio.h 1996/06/30 00:00:42
***************
*** 17,22 ****
- --- 17,23 ----
#define LINUX_SNDCTL_DSP_STEREO _LINUX_IOWR('P', 3, int)
#define LINUX_SNDCTL_DSP_GETBLKSIZE _LINUX_IOWR('P', 4, int)
#define LINUX_SNDCTL_DSP_SETFMT _LINUX_IOWR('P', 5, int)
+ #define LINUX_SNDCTL_DSP_WRITE_CHANNELS _LINUX_IOWR('P', 6, int)
#define LINUX_SNDCTL_DSP_POST _LINUX_IO('P', 8)
#define LINUX_SNDCTL_DSP_SETFRAGMENT _LINUX_IOWR('P', 10, int)
#define LINUX_SNDCTL_DSP_GETFMTS _LINUX_IOR('P', 11, int)
===================================================================
RCS file: /usr/cvs/sys/compat/linux/linux_audio.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 linux_audio.c
*** linux_audio.c 1996/03/12 00:03:08 1.1.1.1
--- linux_audio.c 1996/06/30 14:33:41
***************
*** 71,76 ****
--- 71,91 ----
if (error)
return error;
break;
+ case LINUX_SNDCTL_DSP_WRITE_CHANNELS:
+ AUDIO_INITINFO(&tmpinfo);
+ error = copyin(SCARG(uap, data), &idat, sizeof idat);
+ if (error)
+ return error;
+ tmpinfo.play.channels = idat;
+ (void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
+ error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
+ if (error)
+ return error;
+ idat = tmpinfo.play.channels;
+ error = copyout(&idat, SCARG(uap, data), sizeof idat);
+ if (error)
+ return error;
+ break;
case LINUX_SNDCTL_DSP_STEREO:
AUDIO_INITINFO(&tmpinfo);
error = copyin(SCARG(uap, data), &idat, sizeof idat);
***************
*** 133,139 ****
error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
if (error)
return error;
! /*XXXX*/
break;
case LINUX_SNDCTL_DSP_SETFRAGMENT:
AUDIO_INITINFO(&tmpinfo);
--- 148,173 ----
error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
if (error)
return error;
! switch(tmpinfo.play.encoding) {
! case AUDIO_ENCODING_LINEAR:
! if (tmpinfo.play.precision == 8)
! idat = LINUX_AFMT_U8;
! else if (tmpinfo.play.precision == 16)
! idat = LINUX_AFMT_S16_LE;
! else return EINVAL;
! break;
! case AUDIO_ENCODING_ULAW:
! idat = LINUX_AFMT_MU_LAW;
! break;
! case AUDIO_ENCODING_ALAW:
! idat = LINUX_AFMT_A_LAW;
! break;
! default:
! return EINVAL;
! }
! error = copyout(&idat, SCARG(uap, data), sizeof idat);
! if (error)
! return error;
break;
case LINUX_SNDCTL_DSP_SETFRAGMENT:
AUDIO_INITINFO(&tmpinfo);
>Audit-Trail:
>Unformatted: