diff options
Diffstat (limited to 'Documentation/sound/oss/vwsnd')
-rw-r--r-- | Documentation/sound/oss/vwsnd | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/Documentation/sound/oss/vwsnd b/Documentation/sound/oss/vwsnd new file mode 100644 index 000000000000..a6ea0a1df9e4 --- /dev/null +++ b/Documentation/sound/oss/vwsnd | |||
@@ -0,0 +1,293 @@ | |||
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 | ||
15 | known as Lithium. This driver programs both both chips. | ||
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 | |||