1 |
1275 |
phoenix |
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, 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
|
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 |
|
|
|