Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libossaudio Adds ioctls and defines for OSSv4 compatibil...



details:   https://anonhg.NetBSD.org/src/rev/00ecf20e8a1d
branches:  trunk
changeset: 329268:00ecf20e8a1d
user:      nat <nat%NetBSD.org@localhost>
date:      Sat May 17 12:38:42 2014 +0000

description:
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@.

diffstat:

 lib/libossaudio/ossaudio.c  |  151 ++++++++++++++++++++++++++++++++++++++++++-
 lib/libossaudio/soundcard.h |   86 ++++++++++++++++++++++++-
 2 files changed, 231 insertions(+), 6 deletions(-)

diffs (truncated from 322 to 300 lines):

diff -r 480b9aa663ca -r 00ecf20e8a1d lib/libossaudio/ossaudio.c
--- a/lib/libossaudio/ossaudio.c        Sat May 17 11:31:40 2014 +0000
+++ b/lib/libossaudio/ossaudio.c        Sat May 17 12:38:42 2014 +0000
@@ -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 @@
 #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 @@
        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 @@
                                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 @@
                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);
diff -r 480b9aa663ca -r 00ecf20e8a1d lib/libossaudio/soundcard.h
--- a/lib/libossaudio/soundcard.h       Sat May 17 11:31:40 2014 +0000
+++ b/lib/libossaudio/soundcard.h       Sat May 17 12:38:42 2014 +0000
@@ -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 @@
        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 */



Home | Main Index | Thread Index | Old Index