audio.c revision 1.1 1 1.1 kardel /* $NetBSD: audio.c,v 1.1 2009/12/13 16:55:01 kardel Exp $ */
2 1.1 kardel
3 1.1 kardel /*
4 1.1 kardel * audio.c - audio interface for reference clock audio drivers
5 1.1 kardel */
6 1.1 kardel #ifdef HAVE_CONFIG_H
7 1.1 kardel # include <config.h>
8 1.1 kardel #endif
9 1.1 kardel
10 1.1 kardel #if defined(HAVE_SYS_AUDIOIO_H) || defined(HAVE_SUN_AUDIOIO_H) || \
11 1.1 kardel defined(HAVE_SYS_SOUNDCARD_H) || defined(HAVE_MACHINE_SOUNDCARD_H)
12 1.1 kardel
13 1.1 kardel #include "audio.h"
14 1.1 kardel #include "ntp_stdlib.h"
15 1.1 kardel #include "ntp_syslog.h"
16 1.1 kardel #ifdef HAVE_UNISTD_H
17 1.1 kardel # include <unistd.h>
18 1.1 kardel #endif
19 1.1 kardel #include <stdio.h>
20 1.1 kardel #include "ntp_string.h"
21 1.1 kardel
22 1.1 kardel #ifdef HAVE_SYS_AUDIOIO_H
23 1.1 kardel # include <sys/audioio.h>
24 1.1 kardel #endif /* HAVE_SYS_AUDIOIO_H */
25 1.1 kardel
26 1.1 kardel #ifdef HAVE_SUN_AUDIOIO_H
27 1.1 kardel # include <sys/ioccom.h>
28 1.1 kardel # include <sun/audioio.h>
29 1.1 kardel #endif /* HAVE_SUN_AUDIOIO_H */
30 1.1 kardel
31 1.1 kardel #ifdef HAVE_SYS_IOCTL_H
32 1.1 kardel # include <sys/ioctl.h>
33 1.1 kardel #endif /* HAVE_SYS_IOCTL_H */
34 1.1 kardel
35 1.1 kardel #include <fcntl.h>
36 1.1 kardel
37 1.1 kardel #ifdef HAVE_MACHINE_SOUNDCARD_H
38 1.1 kardel # include <machine/soundcard.h>
39 1.1 kardel # define PCM_STYLE_SOUND
40 1.1 kardel #else
41 1.1 kardel # ifdef HAVE_SYS_SOUNDCARD_H
42 1.1 kardel # include <sys/soundcard.h>
43 1.1 kardel # define PCM_STYLE_SOUND
44 1.1 kardel # endif
45 1.1 kardel #endif
46 1.1 kardel
47 1.1 kardel #ifdef PCM_STYLE_SOUND
48 1.1 kardel # include <ctype.h>
49 1.1 kardel #endif
50 1.1 kardel
51 1.1 kardel /*
52 1.1 kardel * Global variables
53 1.1 kardel */
54 1.1 kardel #ifdef HAVE_SYS_AUDIOIO_H
55 1.1 kardel static struct audio_device device; /* audio device ident */
56 1.1 kardel #endif /* HAVE_SYS_AUDIOIO_H */
57 1.1 kardel #ifdef PCM_STYLE_SOUND
58 1.1 kardel # define INIT_FILE "/etc/ntp.audio"
59 1.1 kardel int agc = SOUND_MIXER_WRITE_RECLEV; /* or IGAIN or LINE */
60 1.1 kardel int monitor = SOUND_MIXER_WRITE_VOLUME; /* or OGAIN */
61 1.1 kardel int devmask = 0;
62 1.1 kardel int recmask = 0;
63 1.1 kardel char cf_c_dev[100], cf_i_dev[100], cf_agc[100], cf_monitor[100];
64 1.1 kardel
65 1.1 kardel const char *m_names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
66 1.1 kardel #else /* not PCM_STYLE_SOUND */
67 1.1 kardel static struct audio_info info; /* audio device info */
68 1.1 kardel #endif /* not PCM_STYLE_SOUND */
69 1.1 kardel static int ctl_fd; /* audio control file descriptor */
70 1.1 kardel
71 1.1 kardel #ifdef PCM_STYLE_SOUND
72 1.1 kardel static void audio_config_read (int, char **, char **);
73 1.1 kardel static int mixer_name (const char *, int);
74 1.1 kardel
75 1.1 kardel
76 1.1 kardel int
77 1.1 kardel mixer_name(
78 1.1 kardel const char *m_name,
79 1.1 kardel int m_mask
80 1.1 kardel )
81 1.1 kardel {
82 1.1 kardel int i;
83 1.1 kardel
84 1.1 kardel for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i)
85 1.1 kardel if (((1 << i) & m_mask)
86 1.1 kardel && !strcmp(m_names[i], m_name))
87 1.1 kardel break;
88 1.1 kardel
89 1.1 kardel return (SOUND_MIXER_NRDEVICES == i)
90 1.1 kardel ? -1
91 1.1 kardel : i
92 1.1 kardel ;
93 1.1 kardel }
94 1.1 kardel
95 1.1 kardel
96 1.1 kardel /*
97 1.1 kardel * Check:
98 1.1 kardel *
99 1.1 kardel * /etc/ntp.audio# where # is the unit number
100 1.1 kardel * /etc/ntp.audio.# where # is the unit number
101 1.1 kardel * /etc/ntp.audio
102 1.1 kardel *
103 1.1 kardel * for contents of the form:
104 1.1 kardel *
105 1.1 kardel * idev /dev/input_device
106 1.1 kardel * cdev /dev/control_device
107 1.1 kardel * agc pcm_input_device {igain,line,line1,...}
108 1.1 kardel * monitor pcm_monitor_device {ogain,...}
109 1.1 kardel *
110 1.1 kardel * The device names for the "agc" and "monitor" keywords
111 1.1 kardel * can be found by running either the "mixer" program or the
112 1.1 kardel * util/audio-pcm program.
113 1.1 kardel *
114 1.1 kardel * Great hunks of this subroutine were swiped from refclock_oncore.c
115 1.1 kardel */
116 1.1 kardel static void
117 1.1 kardel audio_config_read(
118 1.1 kardel int unit,
119 1.1 kardel char **c_dev, /* Control device */
120 1.1 kardel char **i_dev /* input device */
121 1.1 kardel )
122 1.1 kardel {
123 1.1 kardel FILE *fd;
124 1.1 kardel char device[20], line[100], ab[100];
125 1.1 kardel
126 1.1 kardel sprintf(device, "%s%d", INIT_FILE, unit);
127 1.1 kardel if ((fd = fopen(device, "r")) == NULL) {
128 1.1 kardel printf("audio_config_read: <%s> NO\n", device);
129 1.1 kardel sprintf(device, "%s.%d", INIT_FILE, unit);
130 1.1 kardel if ((fd = fopen(device, "r")) == NULL) {
131 1.1 kardel printf("audio_config_read: <%s> NO\n", device);
132 1.1 kardel sprintf(device, "%s.%d", INIT_FILE, unit);
133 1.1 kardel if ((fd = fopen(device, "r")) == NULL) {
134 1.1 kardel printf("audio_config_read: <%s> NO\n", device);
135 1.1 kardel return;
136 1.1 kardel }
137 1.1 kardel }
138 1.1 kardel }
139 1.1 kardel printf("audio_config_read: reading <%s>\n", device);
140 1.1 kardel while (fgets(line, sizeof line, fd)) {
141 1.1 kardel char *cp, *cc, *ca;
142 1.1 kardel int i;
143 1.1 kardel
144 1.1 kardel /* Remove comments */
145 1.1 kardel if ((cp = strchr(line, '#')))
146 1.1 kardel *cp = '\0';
147 1.1 kardel
148 1.1 kardel /* Remove any trailing spaces */
149 1.1 kardel for (i = strlen(line);
150 1.1 kardel i > 0 && isascii((int)line[i - 1]) && isspace((int)line[i - 1]);
151 1.1 kardel )
152 1.1 kardel line[--i] = '\0';
153 1.1 kardel
154 1.1 kardel /* Remove leading space */
155 1.1 kardel for (cc = line; *cc && isascii((int)*cc) && isspace((int)*cc); cc++)
156 1.1 kardel continue;
157 1.1 kardel
158 1.1 kardel /* Stop if nothing left */
159 1.1 kardel if (!*cc)
160 1.1 kardel continue;
161 1.1 kardel
162 1.1 kardel /* Uppercase the command and find the arg */
163 1.1 kardel for (ca = cc; *ca; ca++) {
164 1.1 kardel if (isascii((int)*ca)) {
165 1.1 kardel if (islower((int)*ca)) {
166 1.1 kardel *ca = toupper(*ca);
167 1.1 kardel } else if (isspace((int)*ca) || (*ca == '='))
168 1.1 kardel break;
169 1.1 kardel }
170 1.1 kardel }
171 1.1 kardel
172 1.1 kardel /* Remove space (and possible =) leading the arg */
173 1.1 kardel for (; *ca && isascii((int)*ca) && (isspace((int)*ca) || (*ca == '=')); ca++)
174 1.1 kardel continue;
175 1.1 kardel
176 1.1 kardel if (!strncmp(cc, "IDEV", (size_t) 4)) {
177 1.1 kardel sscanf(ca, "%s", ab);
178 1.1 kardel strcpy(cf_i_dev, ab);
179 1.1 kardel printf("idev <%s>\n", ab);
180 1.1 kardel } else if (!strncmp(cc, "CDEV", (size_t) 4)) {
181 1.1 kardel sscanf(ca, "%s", ab);
182 1.1 kardel strcpy(cf_c_dev, ab);
183 1.1 kardel printf("cdev <%s>\n", ab);
184 1.1 kardel } else if (!strncmp(cc, "AGC", (size_t) 3)) {
185 1.1 kardel sscanf(ca, "%s", ab);
186 1.1 kardel strcpy(cf_agc, ab);
187 1.1 kardel printf("agc <%s> %d\n", ab, i);
188 1.1 kardel } else if (!strncmp(cc, "MONITOR", (size_t) 7)) {
189 1.1 kardel sscanf(ca, "%s", ab);
190 1.1 kardel strcpy(cf_monitor, ab);
191 1.1 kardel printf("monitor <%s> %d\n", ab, mixer_name(ab, -1));
192 1.1 kardel }
193 1.1 kardel }
194 1.1 kardel fclose(fd);
195 1.1 kardel return;
196 1.1 kardel }
197 1.1 kardel #endif /* PCM_STYLE_SOUND */
198 1.1 kardel
199 1.1 kardel /*
200 1.1 kardel * audio_init - open and initialize audio device
201 1.1 kardel *
202 1.1 kardel * This code works with SunOS 4.x, Solaris 2.x, and PCM; however, it is
203 1.1 kardel * believed generic and applicable to other systems with a minor twid
204 1.1 kardel * or two. All it does is open the device, set the buffer size (Solaris
205 1.1 kardel * only), preset the gain and set the input port. It assumes that the
206 1.1 kardel * codec sample rate (8000 Hz), precision (8 bits), number of channels
207 1.1 kardel * (1) and encoding (ITU-T G.711 mu-law companded) have been set by
208 1.1 kardel * default.
209 1.1 kardel */
210 1.1 kardel int
211 1.1 kardel audio_init(
212 1.1 kardel char *dname, /* device name */
213 1.1 kardel int bufsiz, /* buffer size */
214 1.1 kardel int unit /* device unit (0-3) */
215 1.1 kardel )
216 1.1 kardel {
217 1.1 kardel #ifdef PCM_STYLE_SOUND
218 1.1 kardel # define ACTL_DEV "/dev/mixer%d"
219 1.1 kardel char actl_dev[30];
220 1.1 kardel # ifdef HAVE_STRUCT_SND_SIZE
221 1.1 kardel struct snd_size s_size;
222 1.1 kardel # endif
223 1.1 kardel # ifdef AIOGFMT
224 1.1 kardel snd_chan_param s_c_p;
225 1.1 kardel # endif
226 1.1 kardel #endif
227 1.1 kardel int fd;
228 1.1 kardel int rval;
229 1.1 kardel char *actl =
230 1.1 kardel #ifdef PCM_STYLE_SOUND
231 1.1 kardel actl_dev
232 1.1 kardel #else
233 1.1 kardel "/dev/audioctl"
234 1.1 kardel #endif
235 1.1 kardel ;
236 1.1 kardel
237 1.1 kardel #ifdef PCM_STYLE_SOUND
238 1.1 kardel (void)sprintf(actl_dev, ACTL_DEV, unit);
239 1.1 kardel
240 1.1 kardel audio_config_read(unit, &actl, &dname);
241 1.1 kardel /* If we have values for cf_c_dev or cf_i_dev, use them. */
242 1.1 kardel if (*cf_c_dev)
243 1.1 kardel actl = cf_c_dev;
244 1.1 kardel if (*cf_i_dev)
245 1.1 kardel dname = cf_i_dev;
246 1.1 kardel #endif
247 1.1 kardel
248 1.1 kardel /*
249 1.1 kardel * Open audio device
250 1.1 kardel */
251 1.1 kardel fd = open(dname, O_RDWR | O_NONBLOCK, 0777);
252 1.1 kardel if (fd < 0) {
253 1.1 kardel msyslog(LOG_ERR, "audio_init: %s %m\n", dname);
254 1.1 kardel return (fd);
255 1.1 kardel }
256 1.1 kardel
257 1.1 kardel /*
258 1.1 kardel * Open audio control device.
259 1.1 kardel */
260 1.1 kardel ctl_fd = open(actl, O_RDWR);
261 1.1 kardel if (ctl_fd < 0) {
262 1.1 kardel msyslog(LOG_ERR, "audio_init: invalid control device <%s>\n",
263 1.1 kardel actl);
264 1.1 kardel close(fd);
265 1.1 kardel return(ctl_fd);
266 1.1 kardel }
267 1.1 kardel
268 1.1 kardel /*
269 1.1 kardel * Set audio device parameters.
270 1.1 kardel */
271 1.1 kardel #ifdef PCM_STYLE_SOUND
272 1.1 kardel printf("audio_init: <%s> bufsiz %d\n", dname, bufsiz);
273 1.1 kardel rval = fd;
274 1.1 kardel
275 1.1 kardel # ifdef HAVE_STRUCT_SND_SIZE
276 1.1 kardel if (ioctl(fd, AIOGSIZE, &s_size) == -1)
277 1.1 kardel printf("audio_init: AIOGSIZE: %s\n", strerror(errno));
278 1.1 kardel else
279 1.1 kardel printf("audio_init: orig: play_size %d, rec_size %d\n",
280 1.1 kardel s_size.play_size, s_size.rec_size);
281 1.1 kardel
282 1.1 kardel s_size.play_size = s_size.rec_size = bufsiz;
283 1.1 kardel printf("audio_init: want: play_size %d, rec_size %d\n",
284 1.1 kardel s_size.play_size, s_size.rec_size);
285 1.1 kardel
286 1.1 kardel if (ioctl(fd, AIOSSIZE, &s_size) == -1)
287 1.1 kardel printf("audio_init: AIOSSIZE: %s\n", strerror(errno));
288 1.1 kardel else
289 1.1 kardel printf("audio_init: set: play_size %d, rec_size %d\n",
290 1.1 kardel s_size.play_size, s_size.rec_size);
291 1.1 kardel # endif /* HAVE_STRUCT_SND_SIZE */
292 1.1 kardel
293 1.1 kardel # ifdef SNDCTL_DSP_SETFRAGMENT
294 1.1 kardel {
295 1.1 kardel int tmp = (16 << 16) + 6; /* 16 fragments, each 2^6 bytes */
296 1.1 kardel if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
297 1.1 kardel printf("audio_init: SNDCTL_DSP_SETFRAGMENT: %s\n",
298 1.1 kardel strerror(errno));
299 1.1 kardel }
300 1.1 kardel # endif /* SNDCTL_DSP_SETFRAGMENT */
301 1.1 kardel
302 1.1 kardel # ifdef AIOGFMT
303 1.1 kardel if (ioctl(fd, AIOGFMT, &s_c_p) == -1)
304 1.1 kardel printf("audio_init: AIOGFMT: %s\n", strerror(errno));
305 1.1 kardel else
306 1.1 kardel printf("audio_init: play_rate %lu, rec_rate %lu, play_format %#lx, rec_format %#lx\n",
307 1.1 kardel s_c_p.play_rate, s_c_p.rec_rate, s_c_p.play_format, s_c_p.rec_format);
308 1.1 kardel # endif
309 1.1 kardel
310 1.1 kardel /* Grab the device and record masks */
311 1.1 kardel
312 1.1 kardel if (ioctl(ctl_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
313 1.1 kardel printf("SOUND_MIXER_READ_DEVMASK: %s\n", strerror(errno));
314 1.1 kardel if (ioctl(ctl_fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
315 1.1 kardel printf("SOUND_MIXER_READ_RECMASK: %s\n", strerror(errno));
316 1.1 kardel
317 1.1 kardel /* validate and set any specified config file stuff */
318 1.1 kardel if (*cf_agc) {
319 1.1 kardel int i;
320 1.1 kardel
321 1.1 kardel i = mixer_name(cf_agc, devmask);
322 1.1 kardel if (i >= 0)
323 1.1 kardel agc = MIXER_WRITE(i);
324 1.1 kardel else
325 1.1 kardel printf("input %s not in recmask %#x\n",
326 1.1 kardel cf_agc, recmask);
327 1.1 kardel }
328 1.1 kardel
329 1.1 kardel if (*cf_monitor) {
330 1.1 kardel int i;
331 1.1 kardel
332 1.1 kardel /* devmask */
333 1.1 kardel i = mixer_name(cf_monitor, devmask);
334 1.1 kardel if (i >= 0)
335 1.1 kardel monitor = MIXER_WRITE(i);
336 1.1 kardel else
337 1.1 kardel printf("monitor %s not in devmask %#x\n",
338 1.1 kardel cf_monitor, devmask);
339 1.1 kardel }
340 1.1 kardel
341 1.1 kardel #else /* not PCM_STYLE_SOUND */
342 1.1 kardel AUDIO_INITINFO(&info);
343 1.1 kardel info.play.gain = AUDIO_MAX_GAIN;
344 1.1 kardel info.play.port = AUDIO_SPEAKER;
345 1.1 kardel # ifdef HAVE_SYS_AUDIOIO_H
346 1.1 kardel info.record.buffer_size = bufsiz;
347 1.1 kardel # endif /* HAVE_SYS_AUDIOIO_H */
348 1.1 kardel rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, (char *)&info);
349 1.1 kardel if (rval < 0) {
350 1.1 kardel msyslog(LOG_ERR, "audio: invalid control device parameters\n");
351 1.1 kardel close(ctl_fd);
352 1.1 kardel close(fd);
353 1.1 kardel return(rval);
354 1.1 kardel }
355 1.1 kardel rval = fd;
356 1.1 kardel #endif /* not PCM_STYLE_SOUND */
357 1.1 kardel return (rval);
358 1.1 kardel }
359 1.1 kardel
360 1.1 kardel
361 1.1 kardel /*
362 1.1 kardel * audio_gain - adjust codec gains and port
363 1.1 kardel */
364 1.1 kardel int
365 1.1 kardel audio_gain(
366 1.1 kardel int gain, /* volume level (gain) 0-255 */
367 1.1 kardel int mongain, /* input to output mix (monitor gain) 0-255 */
368 1.1 kardel int port /* selected I/O port: 1 mic/2 line in */
369 1.1 kardel )
370 1.1 kardel {
371 1.1 kardel int rval;
372 1.1 kardel static int o_mongain = -1;
373 1.1 kardel static int o_port = -1;
374 1.1 kardel
375 1.1 kardel #ifdef PCM_STYLE_SOUND
376 1.1 kardel int l, r;
377 1.1 kardel
378 1.1 kardel rval = 0;
379 1.1 kardel
380 1.1 kardel r = l = 100 * gain / 255; /* Normalize to 0-100 */
381 1.1 kardel # ifdef DEBUG
382 1.1 kardel if (debug > 1)
383 1.1 kardel printf("audio_gain: gain %d/%d\n", gain, l);
384 1.1 kardel # endif
385 1.1 kardel #if 0 /* not a good idea to do this; connector wiring dependency */
386 1.1 kardel /* figure out what channel(s) to use. just nuke right for now. */
387 1.1 kardel r = 0 ; /* setting to zero nicely mutes the channel */
388 1.1 kardel #endif
389 1.1 kardel l |= r << 8;
390 1.1 kardel if ( cf_agc )
391 1.1 kardel rval = ioctl(ctl_fd, agc, &l);
392 1.1 kardel else
393 1.1 kardel if (port == 2) {
394 1.1 kardel rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_LINE, &l);
395 1.1 kardel } else {
396 1.1 kardel rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_MIC, &l);
397 1.1 kardel }
398 1.1 kardel if (rval == -1) {
399 1.1 kardel printf("audio_gain: agc write: %s\n", strerror(errno));
400 1.1 kardel return (rval);
401 1.1 kardel }
402 1.1 kardel
403 1.1 kardel if (o_mongain != mongain) {
404 1.1 kardel r = l = 100 * mongain / 255; /* Normalize to 0-100 */
405 1.1 kardel # ifdef DEBUG
406 1.1 kardel if (debug > 1)
407 1.1 kardel printf("audio_gain: mongain %d/%d\n", mongain, l);
408 1.1 kardel # endif
409 1.1 kardel l |= r << 8;
410 1.1 kardel if ( cf_monitor )
411 1.1 kardel rval = ioctl(ctl_fd, monitor, &l );
412 1.1 kardel else
413 1.1 kardel rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_VOLUME, &l);
414 1.1 kardel if (rval == -1) {
415 1.1 kardel printf("audio_gain: mongain write: %s\n",
416 1.1 kardel strerror(errno));
417 1.1 kardel return (rval);
418 1.1 kardel }
419 1.1 kardel o_mongain = mongain;
420 1.1 kardel }
421 1.1 kardel
422 1.1 kardel if (o_port != port) {
423 1.1 kardel # ifdef DEBUG
424 1.1 kardel if (debug > 1)
425 1.1 kardel printf("audio_gain: port %d\n", port);
426 1.1 kardel # endif
427 1.1 kardel l = (1 << ((port == 2) ? SOUND_MIXER_LINE : SOUND_MIXER_MIC));
428 1.1 kardel rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_RECSRC, &l);
429 1.1 kardel if (rval == -1) {
430 1.1 kardel printf("SOUND_MIXER_WRITE_RECSRC: %s\n",
431 1.1 kardel strerror(errno));
432 1.1 kardel return (rval);
433 1.1 kardel }
434 1.1 kardel # ifdef DEBUG
435 1.1 kardel if (debug > 1) {
436 1.1 kardel if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &l) == -1)
437 1.1 kardel printf("SOUND_MIXER_WRITE_RECSRC: %s\n",
438 1.1 kardel strerror(errno));
439 1.1 kardel else
440 1.1 kardel printf("audio_gain: recsrc is %d\n", l);
441 1.1 kardel }
442 1.1 kardel # endif
443 1.1 kardel o_port = port;
444 1.1 kardel }
445 1.1 kardel #else /* not PCM_STYLE_SOUND */
446 1.1 kardel ioctl(ctl_fd, (int)AUDIO_GETINFO, (char *)&info);
447 1.1 kardel info.record.encoding = AUDIO_ENCODING_ULAW;
448 1.1 kardel info.record.error = 0;
449 1.1 kardel info.record.gain = gain;
450 1.1 kardel if (o_mongain != mongain)
451 1.1 kardel o_mongain = info.monitor_gain = mongain;
452 1.1 kardel if (o_port != port)
453 1.1 kardel o_port = info.record.port = port;
454 1.1 kardel rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, (char *)&info);
455 1.1 kardel if (rval < 0) {
456 1.1 kardel msyslog(LOG_ERR, "audio_gain: %m");
457 1.1 kardel return (rval);
458 1.1 kardel }
459 1.1 kardel rval = info.record.error;
460 1.1 kardel #endif /* not PCM_STYLE_SOUND */
461 1.1 kardel return (rval);
462 1.1 kardel }
463 1.1 kardel
464 1.1 kardel
465 1.1 kardel /*
466 1.1 kardel * audio_show - display audio parameters
467 1.1 kardel *
468 1.1 kardel * This code doesn't really do anything, except satisfy curiousity and
469 1.1 kardel * verify the ioctl's work.
470 1.1 kardel */
471 1.1 kardel void
472 1.1 kardel audio_show(void)
473 1.1 kardel {
474 1.1 kardel #ifdef PCM_STYLE_SOUND
475 1.1 kardel int recsrc = 0;
476 1.1 kardel
477 1.1 kardel printf("audio_show: ctl_fd %d\n", ctl_fd);
478 1.1 kardel if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
479 1.1 kardel printf("SOUND_MIXER_READ_RECSRC: %s\n", strerror(errno));
480 1.1 kardel
481 1.1 kardel #else /* not PCM_STYLE_SOUND */
482 1.1 kardel # ifdef HAVE_SYS_AUDIOIO_H
483 1.1 kardel ioctl(ctl_fd, (int)AUDIO_GETDEV, &device);
484 1.1 kardel printf("audio: name %s, version %s, config %s\n",
485 1.1 kardel device.name, device.version, device.config);
486 1.1 kardel # endif /* HAVE_SYS_AUDIOIO_H */
487 1.1 kardel ioctl(ctl_fd, (int)AUDIO_GETINFO, (char *)&info);
488 1.1 kardel printf(
489 1.1 kardel "audio: rate %d, chan %d, prec %d, code %d, gain %d, mon %d, port %d\n",
490 1.1 kardel info.record.sample_rate, info.record.channels,
491 1.1 kardel info.record.precision, info.record.encoding,
492 1.1 kardel info.record.gain, info.monitor_gain, info.record.port);
493 1.1 kardel printf(
494 1.1 kardel "audio: samples %d, eof %d, pause %d, error %d, waiting %d, balance %d\n",
495 1.1 kardel info.record.samples, info.record.eof,
496 1.1 kardel info.record.pause, info.record.error,
497 1.1 kardel info.record.waiting, info.record.balance);
498 1.1 kardel #endif /* not PCM_STYLE_SOUND */
499 1.1 kardel }
500 1.1 kardel #else
501 1.1 kardel int audio_bs;
502 1.1 kardel #endif /* HAVE_{SYS_AUDIOIO,SUN_AUDIOIO,MACHINE_SOUNDCARD,SYS_SOUNDCARD}_H */
503