Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | |
670e9f34 | 15 | known as Lithium. This driver programs both chips. |
1da177e4 LT |
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 |