About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / sound / oss / vwsnd




Custom Search

Based on kernel version 3.13. Page generated on 2014-01-20 22:04 EST.

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 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		}
Hide Line Numbers
About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Information is copyright its respective author. All material is available from the Linux Kernel Source distributed under a GPL License. This page is provided as a free service by mjmwired.net.