aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/sound/oss/vwsnd
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/sound/oss/vwsnd')
-rw-r--r--Documentation/sound/oss/vwsnd293
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 @@
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 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