linux/Documentation/sound/oss/vwsnd
<<
>>
Prefs
   1vwsnd - Sound driver for the Silicon Graphics 320 and 540 Visual
   2Workstations' onboard audio.
   3
   4Copyright 1999 Silicon Graphics, Inc.  All rights reserved.
   5
   6
   7At the time of this writing, March 1999, there are two models of
   8Visual Workstation, the 320 and the 540.  This document only describes
   9those models.  Future Visual Workstation models may have different
  10sound capabilities, and this driver will probably not work on those
  11boxes.
  12
  13The Visual Workstation has an Analog Devices AD1843 "SoundComm" audio
  14codec chip.  The AD1843 is accessed through the Cobalt I/O ASIC, also
  15known as Lithium.  This driver programs both chips.
  16
  17==============================================================================
  18QUICK CONFIGURATION
  19
  20        # insmod soundcore
  21        # insmod vwsnd
  22
  23==============================================================================
  24I/O CONNECTIONS
  25
  26On the Visual Workstation, only three of the AD1843 inputs are hooked
  27up.  The analog line in jacks are connected to the AD1843's AUX1
  28input.  The CD audio lines are connected to the AD1843's AUX2 input.
  29The microphone jack is connected to the AD1843's MIC input.  The mic
  30jack is mono, but the signal is delivered to both the left and right
  31MIC inputs.  You can record in stereo from the mic input, but you will
  32get the same signal on both channels (within the limits of A/D
  33accuracy).  Full scale on the Line input is +/- 2.0 V.  Full scale on
  34the MIC input is 20 dB less, or +/- 0.2 V.
  35
  36The AD1843's LOUT1 outputs are connected to the Line Out jacks.  The
  37AD1843's HPOUT outputs are connected to the speaker/headphone jack.
  38LOUT2 is not connected.  Line out's maximum level is +/- 2.0 V peak to
  39peak.  The speaker/headphone out's maximum is +/- 4.0 V peak to peak.
  40
  41The AD1843's PCM input channel and one of its output channels (DAC1)
  42are connected to Lithium.  The other output channel (DAC2) is not
  43connected.
  44
  45==============================================================================
  46CAPABILITIES
  47
  48The AD1843 has PCM input and output (Pulse Code Modulation, also known
  49as wavetable).  PCM input and output can be mono or stereo in any of
  50four formats.  The formats are 16 bit signed and 8 bit unsigned,
  51u-Law, and A-Law format.  Any sample rate from 4 KHz to 49 KHz is
  52available, in 1 Hz increments.
  53
  54The AD1843 includes an analog mixer that can mix all three input
  55signals (line, mic and CD) into the analog outputs.  The mixer has a
  56separate gain control and mute switch for each input.
  57
  58There are two outputs, line out and speaker/headphone out.  They
  59always produce the same signal, and the speaker always has 3 dB more
  60gain than the line out.  The speaker/headphone output can be muted,
  61but this driver does not export that function.
  62
  63The hardware can sync audio to the video clock, but this driver does
  64not have a way to specify syncing to video.
  65
  66==============================================================================
  67PROGRAMMING
  68
  69This section explains the API supported by the driver.  Also see the
  70Open Sound Programming Guide at http://www.opensound.com/pguide/ .
  71This section assumes familiarity with that document.
  72
  73The driver has two interfaces, an I/O interface and a mixer interface.
  74There is no MIDI or sequencer capability.
  75
  76==============================================================================
  77PROGRAMMING PCM I/O
  78
  79The I/O interface is usually accessed as /dev/audio or /dev/dsp.
  80Using the standard Open Sound System (OSS) ioctl calls, the sample
  81rate, number of channels, and sample format may be set within the
  82limitations described above.  The driver supports triggering.  It also
  83supports getting the input and output pointers with one-sample
  84accuracy.
  85
  86The SNDCTL_DSP_GETCAP ioctl returns these capabilities.
  87
  88        DSP_CAP_DUPLEX - driver supports full duplex.
  89
  90        DSP_CAP_TRIGGER - driver supports triggering.
  91
  92        DSP_CAP_REALTIME - values returned by SNDCTL_DSP_GETIPTR
  93        and SNDCTL_DSP_GETOPTR are accurate to a few samples.
  94
  95Memory mapping (mmap) is not implemented.
  96
  97The driver permits subdivided fragment sizes from 64 to 4096 bytes.
  98The number of fragments can be anything from 3 fragments to however
  99many fragments fit into 124 kilobytes.  It is up to the user to
 100determine how few/small fragments can be used without introducing
 101glitches with a given workload.  Linux is not realtime, so we can't
 102promise anything.  (sigh...)
 103
 104When this driver is switched into or out of mu-Law or A-Law mode on
 105output, it may produce an audible click.  This is unavoidable.  To
 106prevent clicking, use signed 16-bit mode instead, and convert from
 107mu-Law or A-Law format in software.
 108
 109==============================================================================
 110PROGRAMMING THE MIXER INTERFACE
 111
 112The mixer interface is usually accessed as /dev/mixer.  It is accessed
 113through ioctls.  The mixer allows the application to control gain or
 114mute several audio signal paths, and also allows selection of the
 115recording source.
 116
 117Each of the constants described here can be read using the
 118MIXER_READ(SOUND_MIXER_xxx) ioctl.  Those that are not read-only can
 119also be written using the MIXER_WRITE(SOUND_MIXER_xxx) ioctl.  In most
 120cases, <sys/soundcard.h> defines constants SOUND_MIXER_READ_xxx and
 121SOUND_MIXER_WRITE_xxx which work just as well.
 122
 123SOUND_MIXER_CAPS        Read-only
 124
 125This is a mask of optional driver capabilities that are implemented.
 126This driver's only capability is SOUND_CAP_EXCL_INPUT, which means
 127that only one recording source can be active at a time.
 128
 129SOUND_MIXER_DEVMASK     Read-only
 130
 131This is a mask of the sound channels.  This driver's channels are PCM,
 132LINE, MIC, CD, and RECLEV.
 133
 134SOUND_MIXER_STEREODEVS  Read-only
 135
 136This is a mask of which sound channels are capable of stereo.  All
 137channels are capable of stereo.  (But see caveat on MIC input in I/O
 138CONNECTIONS section above).
 139
 140SOUND_MIXER_OUTMASK     Read-only
 141
 142This is a mask of channels that route inputs through to outputs.
 143Those are LINE, MIC, and CD.
 144
 145SOUND_MIXER_RECMASK     Read-only
 146
 147This is a mask of channels that can be recording sources.  Those are
 148PCM, LINE, MIC, CD.
 149
 150SOUND_MIXER_PCM         Default: 0x5757 (0 dB)
 151
 152This is the gain control for PCM output.  The left and right channel
 153gain are controlled independently.  This gain control has 64 levels,
 154which range from -82.5 dB to +12.0 dB in 1.5 dB steps.  Those 64
 155levels are mapped onto 100 levels at the ioctl, see below.
 156
 157SOUND_MIXER_LINE        Default: 0x4a4a (0 dB)
 158
 159This is the gain control for mixing the Line In source into the
 160outputs.  The left and right channel gain are controlled
 161independently.  This gain control has 32 levels, which range from
 162-34.5 dB to +12.0 dB in 1.5 dB steps.  Those 32 levels are mapped onto
 163100 levels at the ioctl, see below.
 164
 165SOUND_MIXER_MIC         Default: 0x4a4a (0 dB)
 166
 167This is the gain control for mixing the MIC source into the outputs.
 168The left and right channel gain are controlled independently.  This
 169gain control has 32 levels, which range from -34.5 dB to +12.0 dB in
 1701.5 dB steps.  Those 32 levels are mapped onto 100 levels at the
 171ioctl, see below.
 172
 173SOUND_MIXER_CD          Default: 0x4a4a (0 dB)
 174
 175This is the gain control for mixing the CD audio source into the
 176outputs.  The left and right channel gain are controlled
 177independently.  This gain control has 32 levels, which range from
 178-34.5 dB to +12.0 dB in 1.5 dB steps.  Those 32 levels are mapped onto
 179100 levels at the ioctl, see below.
 180
 181SOUND_MIXER_RECLEV       Default: 0 (0 dB)
 182
 183This is the gain control for PCM input (RECording LEVel).  The left
 184and right channel gain are controlled independently.  This gain
 185control has 16 levels, which range from 0 dB to +22.5 dB in 1.5 dB
 186steps.  Those 16 levels are mapped onto 100 levels at the ioctl, see
 187below.
 188
 189SOUND_MIXER_RECSRC       Default: SOUND_MASK_LINE
 190
 191This is a mask of currently selected PCM input sources (RECording
 192SouRCes).  Because the AD1843 can only have a single recording source
 193at a time, only one bit at a time can be set in this mask.  The
 194allowable values are SOUND_MASK_PCM, SOUND_MASK_LINE, SOUND_MASK_MIC,
 195or SOUND_MASK_CD.  Selecting SOUND_MASK_PCM sets up internal
 196resampling which is useful for loopback testing and for hardware
 197sample rate conversion.  But software sample rate conversion is
 198probably faster, so I don't know how useful that is.
 199
 200SOUND_MIXER_OUTSRC      DEFAULT: SOUND_MASK_LINE|SOUND_MASK_MIC|SOUND_MASK_CD
 201
 202This is a mask of sources that are currently passed through to the
 203outputs.  Those sources whose bits are not set are muted.
 204
 205==============================================================================
 206GAIN CONTROL
 207
 208There are five gain controls listed above.  Each has 16, 32, or 64
 209steps.  Each control has 1.5 dB of gain per step.  Each control is
 210stereo.
 211
 212The OSS defines the argument to a channel gain ioctl as having two
 213components, left and right, each of which ranges from 0 to 100.  The
 214two components are packed into the same word, with the left side gain
 215in the least significant byte, and the right side gain in the second
 216least significant byte.  In C, we would say this.
 217
 218        #include <assert.h>
 219
 220        ...
 221
 222                assert(leftgain >= 0 && leftgain <= 100);
 223                assert(rightgain >= 0 && rightgain <= 100);
 224                arg = leftgain | rightgain << 8;
 225
 226So each OSS gain control has 101 steps.  But the hardware has 16, 32,
 227or 64 steps.  The hardware steps are spread across the 101 OSS steps
 228nearly evenly.  The conversion formulas are like this, given N equals
 22916, 32, or 64.
 230
 231        int round = N/2 - 1;
 232        OSS_gain_steps = (hw_gain_steps * 100 + round) / (N - 1);
 233        hw_gain_steps = (OSS_gain_steps * (N - 1) + round) / 100;
 234
 235Here is a snippet of C code that will return the left and right gain
 236of any channel in dB.  Pass it one of the predefined gain_desc_t
 237structures to access any of the five channels' gains.
 238
 239        typedef struct gain_desc {
 240                float min_gain;
 241                float gain_step;
 242                int nbits;
 243                int chan;
 244        } gain_desc_t;
 245
 246        const gain_desc_t gain_pcm    = { -82.5, 1.5, 6, SOUND_MIXER_PCM    };
 247        const gain_desc_t gain_line   = { -34.5, 1.5, 5, SOUND_MIXER_LINE   };
 248        const gain_desc_t gain_mic    = { -34.5, 1.5, 5, SOUND_MIXER_MIC    };
 249        const gain_desc_t gain_cd     = { -34.5, 1.5, 5, SOUND_MIXER_CD     };
 250        const gain_desc_t gain_reclev = {   0.0, 1.5, 4, SOUND_MIXER_RECLEV };
 251
 252        int get_gain_dB(int fd, const gain_desc_t *gp,
 253                        float *left, float *right)
 254        {
 255                int word;
 256                int lg, rg;
 257                int mask = (1 << gp->nbits) - 1;
 258
 259                if (ioctl(fd, MIXER_READ(gp->chan), &word) != 0)
 260                        return -1;      /* fail */
 261                lg = word & 0xFF;
 262                rg = word >> 8 & 0xFF;
 263                lg = (lg * mask + mask / 2) / 100;
 264                rg = (rg * mask + mask / 2) / 100;
 265                *left = gp->min_gain + gp->gain_step * lg;
 266                *right = gp->min_gain + gp->gain_step * rg;
 267                return 0;
 268        }       
 269
 270And here is the corresponding routine to set a channel's gain in dB.
 271
 272        int set_gain_dB(int fd, const gain_desc_t *gp, float left, float right)
 273        {
 274                float max_gain =
 275                        gp->min_gain + (1 << gp->nbits) * gp->gain_step;
 276                float round = gp->gain_step / 2;
 277                int mask = (1 << gp->nbits) - 1;
 278                int word;
 279                int lg, rg;
 280
 281                if (left < gp->min_gain || right < gp->min_gain)
 282                        return EINVAL;
 283                lg = (left - gp->min_gain + round) / gp->gain_step;
 284                rg = (right - gp->min_gain + round) / gp->gain_step;
 285                if (lg >= (1 << gp->nbits) || rg >= (1 << gp->nbits))
 286                        return EINVAL;
 287                lg = (100 * lg + mask / 2) / mask;
 288                rg = (100 * rg + mask / 2) / mask;
 289                word = lg | rg << 8;
 290
 291                return ioctl(fd, MIXER_WRITE(gp->chan), &word);
 292        }
 293
 294