Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | vwsnd - Sound driver for the Silicon Graphics 320 and 540 Visual |
| 2 | Workstations' onboard audio. |
| 3 | |
| 4 | Copyright 1999 Silicon Graphics, Inc. All rights reserved. |
| 5 | |
| 6 | |
| 7 | At the time of this writing, March 1999, there are two models of |
| 8 | Visual Workstation, the 320 and the 540. This document only describes |
| 9 | those models. Future Visual Workstation models may have different |
| 10 | sound capabilities, and this driver will probably not work on those |
| 11 | boxes. |
| 12 | |
| 13 | The Visual Workstation has an Analog Devices AD1843 "SoundComm" audio |
| 14 | codec chip. The AD1843 is accessed through the Cobalt I/O ASIC, also |
Paolo Ornati | 670e9f3 | 2006-10-03 22:57:56 +0200 | [diff] [blame] | 15 | known as Lithium. This driver programs both chips. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 16 | |
| 17 | ============================================================================== |
| 18 | QUICK CONFIGURATION |
| 19 | |
| 20 | # insmod soundcore |
| 21 | # insmod vwsnd |
| 22 | |
| 23 | ============================================================================== |
| 24 | I/O CONNECTIONS |
| 25 | |
| 26 | On the Visual Workstation, only three of the AD1843 inputs are hooked |
| 27 | up. The analog line in jacks are connected to the AD1843's AUX1 |
| 28 | input. The CD audio lines are connected to the AD1843's AUX2 input. |
| 29 | The microphone jack is connected to the AD1843's MIC input. The mic |
| 30 | jack is mono, but the signal is delivered to both the left and right |
| 31 | MIC inputs. You can record in stereo from the mic input, but you will |
| 32 | get the same signal on both channels (within the limits of A/D |
| 33 | accuracy). Full scale on the Line input is +/- 2.0 V. Full scale on |
| 34 | the MIC input is 20 dB less, or +/- 0.2 V. |
| 35 | |
| 36 | The AD1843's LOUT1 outputs are connected to the Line Out jacks. The |
| 37 | AD1843's HPOUT outputs are connected to the speaker/headphone jack. |
| 38 | LOUT2 is not connected. Line out's maximum level is +/- 2.0 V peak to |
| 39 | peak. The speaker/headphone out's maximum is +/- 4.0 V peak to peak. |
| 40 | |
| 41 | The AD1843's PCM input channel and one of its output channels (DAC1) |
| 42 | are connected to Lithium. The other output channel (DAC2) is not |
| 43 | connected. |
| 44 | |
| 45 | ============================================================================== |
| 46 | CAPABILITIES |
| 47 | |
| 48 | The AD1843 has PCM input and output (Pulse Code Modulation, also known |
| 49 | as wavetable). PCM input and output can be mono or stereo in any of |
| 50 | four formats. The formats are 16 bit signed and 8 bit unsigned, |
| 51 | u-Law, and A-Law format. Any sample rate from 4 KHz to 49 KHz is |
| 52 | available, in 1 Hz increments. |
| 53 | |
| 54 | The AD1843 includes an analog mixer that can mix all three input |
| 55 | signals (line, mic and CD) into the analog outputs. The mixer has a |
| 56 | separate gain control and mute switch for each input. |
| 57 | |
| 58 | There are two outputs, line out and speaker/headphone out. They |
| 59 | always produce the same signal, and the speaker always has 3 dB more |
| 60 | gain than the line out. The speaker/headphone output can be muted, |
| 61 | but this driver does not export that function. |
| 62 | |
| 63 | The hardware can sync audio to the video clock, but this driver does |
| 64 | not have a way to specify syncing to video. |
| 65 | |
| 66 | ============================================================================== |
| 67 | PROGRAMMING |
| 68 | |
| 69 | This section explains the API supported by the driver. Also see the |
| 70 | Open Sound Programming Guide at http://www.opensound.com/pguide/ . |
| 71 | This section assumes familiarity with that document. |
| 72 | |
| 73 | The driver has two interfaces, an I/O interface and a mixer interface. |
| 74 | There is no MIDI or sequencer capability. |
| 75 | |
| 76 | ============================================================================== |
| 77 | PROGRAMMING PCM I/O |
| 78 | |
| 79 | The I/O interface is usually accessed as /dev/audio or /dev/dsp. |
| 80 | Using the standard Open Sound System (OSS) ioctl calls, the sample |
| 81 | rate, number of channels, and sample format may be set within the |
| 82 | limitations described above. The driver supports triggering. It also |
| 83 | supports getting the input and output pointers with one-sample |
| 84 | accuracy. |
| 85 | |
| 86 | The 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 | |
| 95 | Memory mapping (mmap) is not implemented. |
| 96 | |
| 97 | The driver permits subdivided fragment sizes from 64 to 4096 bytes. |
| 98 | The number of fragments can be anything from 3 fragments to however |
| 99 | many fragments fit into 124 kilobytes. It is up to the user to |
| 100 | determine how few/small fragments can be used without introducing |
| 101 | glitches with a given workload. Linux is not realtime, so we can't |
| 102 | promise anything. (sigh...) |
| 103 | |
| 104 | When this driver is switched into or out of mu-Law or A-Law mode on |
| 105 | output, it may produce an audible click. This is unavoidable. To |
| 106 | prevent clicking, use signed 16-bit mode instead, and convert from |
| 107 | mu-Law or A-Law format in software. |
| 108 | |
| 109 | ============================================================================== |
| 110 | PROGRAMMING THE MIXER INTERFACE |
| 111 | |
| 112 | The mixer interface is usually accessed as /dev/mixer. It is accessed |
| 113 | through ioctls. The mixer allows the application to control gain or |
| 114 | mute several audio signal paths, and also allows selection of the |
| 115 | recording source. |
| 116 | |
| 117 | Each of the constants described here can be read using the |
| 118 | MIXER_READ(SOUND_MIXER_xxx) ioctl. Those that are not read-only can |
| 119 | also be written using the MIXER_WRITE(SOUND_MIXER_xxx) ioctl. In most |
| 120 | cases, <sys/soundcard.h> defines constants SOUND_MIXER_READ_xxx and |
| 121 | SOUND_MIXER_WRITE_xxx which work just as well. |
| 122 | |
| 123 | SOUND_MIXER_CAPS Read-only |
| 124 | |
| 125 | This is a mask of optional driver capabilities that are implemented. |
| 126 | This driver's only capability is SOUND_CAP_EXCL_INPUT, which means |
| 127 | that only one recording source can be active at a time. |
| 128 | |
| 129 | SOUND_MIXER_DEVMASK Read-only |
| 130 | |
| 131 | This is a mask of the sound channels. This driver's channels are PCM, |
| 132 | LINE, MIC, CD, and RECLEV. |
| 133 | |
| 134 | SOUND_MIXER_STEREODEVS Read-only |
| 135 | |
| 136 | This is a mask of which sound channels are capable of stereo. All |
| 137 | channels are capable of stereo. (But see caveat on MIC input in I/O |
| 138 | CONNECTIONS section above). |
| 139 | |
| 140 | SOUND_MIXER_OUTMASK Read-only |
| 141 | |
| 142 | This is a mask of channels that route inputs through to outputs. |
| 143 | Those are LINE, MIC, and CD. |
| 144 | |
| 145 | SOUND_MIXER_RECMASK Read-only |
| 146 | |
| 147 | This is a mask of channels that can be recording sources. Those are |
| 148 | PCM, LINE, MIC, CD. |
| 149 | |
| 150 | SOUND_MIXER_PCM Default: 0x5757 (0 dB) |
| 151 | |
| 152 | This is the gain control for PCM output. The left and right channel |
| 153 | gain are controlled independently. This gain control has 64 levels, |
| 154 | which range from -82.5 dB to +12.0 dB in 1.5 dB steps. Those 64 |
| 155 | levels are mapped onto 100 levels at the ioctl, see below. |
| 156 | |
| 157 | SOUND_MIXER_LINE Default: 0x4a4a (0 dB) |
| 158 | |
| 159 | This is the gain control for mixing the Line In source into the |
| 160 | outputs. The left and right channel gain are controlled |
| 161 | independently. 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 |
| 163 | 100 levels at the ioctl, see below. |
| 164 | |
| 165 | SOUND_MIXER_MIC Default: 0x4a4a (0 dB) |
| 166 | |
| 167 | This is the gain control for mixing the MIC source into the outputs. |
| 168 | The left and right channel gain are controlled independently. This |
| 169 | gain control has 32 levels, which range from -34.5 dB to +12.0 dB in |
| 170 | 1.5 dB steps. Those 32 levels are mapped onto 100 levels at the |
| 171 | ioctl, see below. |
| 172 | |
| 173 | SOUND_MIXER_CD Default: 0x4a4a (0 dB) |
| 174 | |
| 175 | This is the gain control for mixing the CD audio source into the |
| 176 | outputs. The left and right channel gain are controlled |
| 177 | independently. 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 |
| 179 | 100 levels at the ioctl, see below. |
| 180 | |
| 181 | SOUND_MIXER_RECLEV Default: 0 (0 dB) |
| 182 | |
| 183 | This is the gain control for PCM input (RECording LEVel). The left |
| 184 | and right channel gain are controlled independently. This gain |
| 185 | control has 16 levels, which range from 0 dB to +22.5 dB in 1.5 dB |
| 186 | steps. Those 16 levels are mapped onto 100 levels at the ioctl, see |
| 187 | below. |
| 188 | |
| 189 | SOUND_MIXER_RECSRC Default: SOUND_MASK_LINE |
| 190 | |
| 191 | This is a mask of currently selected PCM input sources (RECording |
| 192 | SouRCes). Because the AD1843 can only have a single recording source |
| 193 | at a time, only one bit at a time can be set in this mask. The |
| 194 | allowable values are SOUND_MASK_PCM, SOUND_MASK_LINE, SOUND_MASK_MIC, |
| 195 | or SOUND_MASK_CD. Selecting SOUND_MASK_PCM sets up internal |
| 196 | resampling which is useful for loopback testing and for hardware |
| 197 | sample rate conversion. But software sample rate conversion is |
| 198 | probably faster, so I don't know how useful that is. |
| 199 | |
| 200 | SOUND_MIXER_OUTSRC DEFAULT: SOUND_MASK_LINE|SOUND_MASK_MIC|SOUND_MASK_CD |
| 201 | |
| 202 | This is a mask of sources that are currently passed through to the |
| 203 | outputs. Those sources whose bits are not set are muted. |
| 204 | |
| 205 | ============================================================================== |
| 206 | GAIN CONTROL |
| 207 | |
| 208 | There are five gain controls listed above. Each has 16, 32, or 64 |
| 209 | steps. Each control has 1.5 dB of gain per step. Each control is |
| 210 | stereo. |
| 211 | |
| 212 | The OSS defines the argument to a channel gain ioctl as having two |
| 213 | components, left and right, each of which ranges from 0 to 100. The |
| 214 | two components are packed into the same word, with the left side gain |
| 215 | in the least significant byte, and the right side gain in the second |
| 216 | least 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 | |
| 226 | So each OSS gain control has 101 steps. But the hardware has 16, 32, |
| 227 | or 64 steps. The hardware steps are spread across the 101 OSS steps |
| 228 | nearly evenly. The conversion formulas are like this, given N equals |
| 229 | 16, 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 | |
| 235 | Here is a snippet of C code that will return the left and right gain |
| 236 | of any channel in dB. Pass it one of the predefined gain_desc_t |
| 237 | structures 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 | |
| 270 | And 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 | |