Adds ioctls and defines for OSSv4 compatibility.
The ioctl definitions and accompanying structures were taken from FreeBSD's soundcard.h, hopefully providing some binary compatibility. The ioctls are as follows: SNDCTL_SYSINFO: Returns a structure containing details about the audio device. SNDCTL_ENGINEINFO - SNDCTL_AUDIOINFO: Returns a structure with playback/recording characteristics. SNDCTL_DSP_GETPLAYVOL, SNDCTL_DSP_SETPLAYVOL, SNDCTL_DSP_GETRECVOL, SNDCTL_DSP_SETRECVOL: Retrieves/Sets Playback/Recording volume. SNDCTL_DSP_SKIP - SNDCTL_DSP_SILENCE: These ioctls were intended to manipulate the underlying audio buffer skip or insert silence. These return EINVAL. SOUND_VERSION is unchanged, but is definable, It will be changed when the mixer OSSv4 ioctls are written. Addresses PR 46611 This commit was approved by wiz@.
This commit is contained in:
parent
ba94e92b25
commit
a8ba8ad76b
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ossaudio.c,v 1.28 2012/05/05 15:57:45 christos Exp $ */
|
||||
/* $NetBSD: ossaudio.c,v 1.29 2014/05/17 12:38:42 nat Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: ossaudio.c,v 1.28 2012/05/05 15:57:45 christos Exp $");
|
||||
__RCSID("$NetBSD: ossaudio.c,v 1.29 2014/05/17 12:38:42 nat Exp $");
|
||||
|
||||
/*
|
||||
* This is an OSS (Linux) sound API emulator.
|
||||
|
@ -44,6 +44,9 @@ __RCSID("$NetBSD: ossaudio.c,v 1.28 2012/05/05 15:57:45 christos Exp $");
|
|||
#include <sys/audioio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "soundcard.h"
|
||||
|
@ -93,9 +96,17 @@ audio_ioctl(int fd, unsigned long com, void *argp)
|
|||
struct audio_buf_info bufinfo;
|
||||
struct count_info cntinfo;
|
||||
struct audio_encoding tmpenc;
|
||||
struct oss_sysinfo tmpsysinfo;
|
||||
struct oss_audioinfo *tmpaudioinfo;
|
||||
audio_device_t tmpaudiodev;
|
||||
struct stat tmpstat;
|
||||
dev_t devno;
|
||||
char version[32] = "4.01";
|
||||
char license[16] = "NetBSD";
|
||||
u_int u;
|
||||
int idat, idata;
|
||||
int retval;
|
||||
int i;
|
||||
|
||||
idat = 0;
|
||||
|
||||
|
@ -316,13 +327,21 @@ audio_ioctl(int fd, unsigned long com, void *argp)
|
|||
idat |= AFMT_S8;
|
||||
break;
|
||||
case AUDIO_ENCODING_SLINEAR_LE:
|
||||
if (tmpenc.precision == 16)
|
||||
if (tmpenc.precision == 32)
|
||||
idat |= AFMT_S32_LE;
|
||||
else if (tmpenc.precision == 24)
|
||||
idat |= AFMT_S24_LE;
|
||||
else if (tmpenc.precision == 16)
|
||||
idat |= AFMT_S16_LE;
|
||||
else
|
||||
idat |= AFMT_S8;
|
||||
break;
|
||||
case AUDIO_ENCODING_SLINEAR_BE:
|
||||
if (tmpenc.precision == 16)
|
||||
if (tmpenc.precision == 32)
|
||||
idat |= AFMT_S32_BE;
|
||||
else if (tmpenc.precision == 24)
|
||||
idat |= AFMT_S24_BE;
|
||||
else if (tmpenc.precision == 16)
|
||||
idat |= AFMT_S16_BE;
|
||||
else
|
||||
idat |= AFMT_S8;
|
||||
|
@ -445,6 +464,130 @@ audio_ioctl(int fd, unsigned long com, void *argp)
|
|||
cntinfo.ptr = tmpoffs.offset;
|
||||
*(struct count_info *)argp = cntinfo;
|
||||
break;
|
||||
case SNDCTL_SYSINFO:
|
||||
strncpy(tmpsysinfo.product, "OSS/NetBSD", 31);
|
||||
tmpsysinfo.product[31] = 0;
|
||||
strncpy(tmpsysinfo.version, version, 31);
|
||||
tmpsysinfo.version[31] = 0;
|
||||
strncpy(tmpsysinfo.license, license, 15);
|
||||
tmpsysinfo.license[15] = 0;
|
||||
tmpsysinfo.versionnum = SOUND_VERSION;
|
||||
memset(tmpsysinfo.options, 0, 8);
|
||||
tmpsysinfo.numaudios = OSS_MAX_AUDIO_DEVS;
|
||||
tmpsysinfo.numaudioengines = 1;
|
||||
memset(tmpsysinfo.openedaudio, 0, 8);
|
||||
tmpsysinfo.numsynths = 1;
|
||||
tmpsysinfo.nummidis = -1;
|
||||
tmpsysinfo.numtimers = -1;
|
||||
tmpsysinfo.nummixers = 1;
|
||||
tmpsysinfo.numcards = 1;
|
||||
memset(tmpsysinfo.openedmidi, 0, 8);
|
||||
*(struct oss_sysinfo *)argp = tmpsysinfo;
|
||||
break;
|
||||
case SNDCTL_ENGINEINFO:
|
||||
case SNDCTL_AUDIOINFO:
|
||||
devno = 0;
|
||||
tmpaudioinfo = (struct oss_audioinfo*)argp;
|
||||
if (tmpaudioinfo == NULL)
|
||||
return EINVAL;
|
||||
if (tmpaudioinfo->dev < 0) {
|
||||
fstat(fd, &tmpstat);
|
||||
if ((tmpstat.st_rdev & 0xff00) == 0x2a00)
|
||||
devno = tmpstat.st_rdev & 0xff;
|
||||
if (devno >= 0x80)
|
||||
tmpaudioinfo->dev = devno & 0x7f;
|
||||
}
|
||||
if (tmpaudioinfo->dev < 0)
|
||||
tmpaudioinfo->dev = 0;
|
||||
|
||||
snprintf(tmpaudioinfo->devnode, OSS_DEVNODE_SIZE,
|
||||
"/dev/audio%d", tmpaudioinfo->dev);
|
||||
|
||||
retval = ioctl(fd, AUDIO_GETDEV, &tmpaudiodev);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
retval = ioctl(fd, AUDIO_GETINFO, &tmpinfo);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
retval = ioctl(fd, AUDIO_GETPROPS, &idata);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
idat = DSP_CAP_TRIGGER; /* pretend we have trigger */
|
||||
if (idata & AUDIO_PROP_FULLDUPLEX)
|
||||
idat |= DSP_CAP_DUPLEX;
|
||||
if (idata & AUDIO_PROP_MMAP)
|
||||
idat |= DSP_CAP_MMAP;
|
||||
idat = PCM_CAP_INPUT | PCM_CAP_OUTPUT;
|
||||
strncpy(tmpaudioinfo->name, tmpaudiodev.name, 64);
|
||||
tmpaudioinfo->name[63] = 0;
|
||||
tmpaudioinfo->busy = tmpinfo.play.open;
|
||||
tmpaudioinfo->pid = -1;
|
||||
tmpaudioinfo->caps = idat;
|
||||
ioctl(fd, SNDCTL_DSP_GETFMTS, &tmpaudioinfo->iformats);
|
||||
tmpaudioinfo->oformats = tmpaudioinfo->iformats;
|
||||
tmpaudioinfo->magic = -1;
|
||||
memset(tmpaudioinfo->cmd, 0, 64);
|
||||
tmpaudioinfo->card_number = -1;
|
||||
memset(tmpaudioinfo->song_name, 0, 64);
|
||||
memset(tmpaudioinfo->label, 0, 16);
|
||||
tmpaudioinfo->port_number = tmpinfo.play.port;
|
||||
tmpaudioinfo->mixer_dev = tmpaudioinfo->dev;
|
||||
tmpaudioinfo->legacy_device = -1;
|
||||
tmpaudioinfo->enabled = 1;
|
||||
tmpaudioinfo->flags = -1;
|
||||
tmpaudioinfo->min_rate = tmpinfo.play.sample_rate;
|
||||
tmpaudioinfo->max_rate = tmpinfo.play.sample_rate;
|
||||
tmpaudioinfo->nrates = 2;
|
||||
for (i = 0; i < tmpaudioinfo->nrates; i++)
|
||||
tmpaudioinfo->rates[i] = tmpinfo.play.sample_rate;
|
||||
tmpaudioinfo->min_channels = tmpinfo.play.channels;
|
||||
tmpaudioinfo->max_channels = tmpinfo.play.channels;
|
||||
tmpaudioinfo->binding = -1;
|
||||
tmpaudioinfo->rate_source = -1;
|
||||
memset(tmpaudioinfo->handle, 0, 16);
|
||||
tmpaudioinfo->next_play_engine = 0;
|
||||
tmpaudioinfo->next_rec_engine = 0;
|
||||
argp = tmpaudioinfo;
|
||||
break;
|
||||
case SNDCTL_DSP_GETPLAYVOL:
|
||||
retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
*(uint *)argp = tmpinfo.play.gain;
|
||||
break;
|
||||
case SNDCTL_DSP_SETPLAYVOL:
|
||||
retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
if (*(uint *)argp > 255)
|
||||
tmpinfo.play.gain = 255;
|
||||
else
|
||||
tmpinfo.play.gain = *(uint *)argp;
|
||||
retval = ioctl(fd, AUDIO_SETINFO, &tmpinfo);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
break;
|
||||
case SNDCTL_DSP_GETRECVOL:
|
||||
retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
*(uint *)argp = tmpinfo.record.gain;
|
||||
break;
|
||||
case SNDCTL_DSP_SETRECVOL:
|
||||
retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
if (*(uint *)argp > 255)
|
||||
tmpinfo.record.gain = 255;
|
||||
else
|
||||
tmpinfo.record.gain = *(uint *)argp;
|
||||
retval = ioctl(fd, AUDIO_SETINFO, &tmpinfo);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
break;
|
||||
case SNDCTL_DSP_SKIP:
|
||||
case SNDCTL_DSP_SILENCE:
|
||||
return EINVAL;
|
||||
case SNDCTL_DSP_SETDUPLEX:
|
||||
idat = 1;
|
||||
retval = ioctl(fd, AUDIO_SETFD, &idat);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: soundcard.h,v 1.22 2012/05/05 15:57:45 christos Exp $ */
|
||||
/* $NetBSD: soundcard.h,v 1.23 2014/05/17 12:38:42 nat Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
|
@ -39,7 +39,9 @@
|
|||
#ifndef _SOUNDCARD_H_
|
||||
#define _SOUNDCARD_H_
|
||||
|
||||
#define SOUND_VERSION 0x030001
|
||||
#ifndef SOUND_VERSION
|
||||
#define SOUND_VERSION 0x030001
|
||||
#endif
|
||||
|
||||
#define SNDCTL_DSP_RESET _IO ('P', 0)
|
||||
#define SNDCTL_DSP_SYNC _IO ('P', 1)
|
||||
|
@ -60,6 +62,11 @@
|
|||
#define AFMT_U16_BE 0x00000100
|
||||
#define AFMT_MPEG 0x00000200
|
||||
#define AFMT_AC3 0x00000400
|
||||
#define AFMT_S24_LE 0x00000800
|
||||
#define AFMT_S24_BE 0x00001000
|
||||
#define AFMT_S32_LE 0x00002000
|
||||
#define AFMT_S32_BE 0x00004000
|
||||
#define AFMT_S32_NE 0x00008000
|
||||
#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT
|
||||
#define SOUND_PCM_READ_BITS _IOR ('P', 5, int)
|
||||
#define SNDCTL_DSP_CHANNELS _IOWR('P', 6, int)
|
||||
|
@ -82,6 +89,10 @@
|
|||
# define DSP_CAP_COPROC 0x00000800
|
||||
# define DSP_CAP_TRIGGER 0x00001000
|
||||
# define DSP_CAP_MMAP 0x00002000
|
||||
# define PCM_CAP_INPUT 0x00004000
|
||||
# define PCM_CAP_OUTPUT 0x00008000
|
||||
# define PCM_CAP_MODEM 0x00010000
|
||||
# define PCM_CAP_HIDDEN 0x00020000
|
||||
#define SNDCTL_DSP_GETTRIGGER _IOR ('P', 16, int)
|
||||
#define SNDCTL_DSP_SETTRIGGER _IOW ('P', 16, int)
|
||||
# define PCM_ENABLE_INPUT 0x00000001
|
||||
|
@ -291,6 +302,77 @@ typedef struct buffmem_desc {
|
|||
int size;
|
||||
} buffmem_desc;
|
||||
|
||||
/* Some OSSv4 calls. */
|
||||
|
||||
#define OSS_DEVNODE_SIZE 32
|
||||
#define OSS_LABEL_SIZE 16
|
||||
#define OSS_LONGNAME_SIZE 64
|
||||
#define OSS_MAX_AUDIO_DEVS 64
|
||||
|
||||
#define SNDCTL_SYSINFO _IOR ('P',24, struct oss_sysinfo)
|
||||
#define SNDCTL_AUDIOINFO _IOWR ('P',25, struct oss_audioinfo)
|
||||
#define SNDCTL_ENGINEINFO _IOWR ('P',26, struct oss_audioinfo)
|
||||
#define SNDCTL_DSP_GETPLAYVOL _IOR ('P',27, uint)
|
||||
#define SNDCTL_DSP_SETPLAYVOL _IOW ('P',28, uint)
|
||||
#define SNDCTL_DSP_GETRECVOL _IOR ('P',29, uint)
|
||||
#define SNDCTL_DSP_SETRECVOL _IOW ('P',30, uint)
|
||||
#define SNDCTL_DSP_SKIP _IO ('P',31)
|
||||
#define SNDCTL_DSP_SILENCE _IO ('P',32)
|
||||
|
||||
typedef struct oss_sysinfo {
|
||||
char product[32];
|
||||
char version[32];
|
||||
int versionnum;
|
||||
char options[128]; /* Future use */
|
||||
int numaudios;
|
||||
int openedaudio[8]; /* Obsolete */
|
||||
int numsynths; /* Obsolete */
|
||||
int nummidis;
|
||||
int numtimers;
|
||||
int nummixers;
|
||||
int openedmidi[8];
|
||||
int numcards;
|
||||
int numaudioengines;
|
||||
char license[16];
|
||||
char revision_info[256]; /* Internal Use */
|
||||
int filler[172]; /* For expansion */
|
||||
} oss_sysinfo;
|
||||
|
||||
typedef struct oss_audioinfo {
|
||||
int dev; /* Set by caller */
|
||||
char name[OSS_LONGNAME_SIZE];
|
||||
int busy;
|
||||
int pid;
|
||||
int caps;
|
||||
int iformats;
|
||||
int oformats;
|
||||
int magic; /* Unused */
|
||||
char cmd[OSS_LONGNAME_SIZE];
|
||||
int card_number;
|
||||
int port_number;
|
||||
int mixer_dev;
|
||||
int legacy_device; /* Obsolete */
|
||||
int enabled;
|
||||
int flags; /* Reserved */
|
||||
int min_rate;
|
||||
int max_rate;
|
||||
int min_channels;
|
||||
int max_channels;
|
||||
int binding; /* Reserved */
|
||||
int rate_source;
|
||||
char handle[32];
|
||||
#define OSS_MAX_SAMPLE_RATES 20
|
||||
int nrates;
|
||||
int rates[OSS_MAX_SAMPLE_RATES];
|
||||
char song_name[OSS_LONGNAME_SIZE];
|
||||
char label[OSS_LABEL_SIZE];
|
||||
int latency; /* In usecs -1 = unknown */
|
||||
char devnode[OSS_DEVNODE_SIZE];
|
||||
int next_play_engine;
|
||||
int next_rec_engine;
|
||||
int filler[184]; /* For expansion */
|
||||
} oss_audioinfo;
|
||||
|
||||
#define ioctl _oss_ioctl
|
||||
/*
|
||||
* If we already included <sys/ioctl.h>, then we define our own prototype,
|
||||
|
|
Loading…
Reference in New Issue