audio.c revision 1.4 1 1.4 kardel /* $NetBSD: audio.c,v 1.4 2012/02/01 07:46:22 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.4 kardel snprintf(device, sizeof(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.4 kardel snprintf(device, sizeof(device), "%s.%d", INIT_FILE,
130 1.4 kardel unit);
131 1.1 kardel if ((fd = fopen(device, "r")) == NULL) {
132 1.1 kardel printf("audio_config_read: <%s> NO\n", device);
133 1.4 kardel snprintf(device, sizeof(device), "%s",
134 1.4 kardel INIT_FILE);
135 1.1 kardel if ((fd = fopen(device, "r")) == NULL) {
136 1.4 kardel printf("audio_config_read: <%s> NO\n",
137 1.4 kardel device);
138 1.1 kardel return;
139 1.1 kardel }
140 1.1 kardel }
141 1.1 kardel }
142 1.1 kardel printf("audio_config_read: reading <%s>\n", device);
143 1.1 kardel while (fgets(line, sizeof line, fd)) {
144 1.1 kardel char *cp, *cc, *ca;
145 1.1 kardel int i;
146 1.1 kardel
147 1.1 kardel /* Remove comments */
148 1.1 kardel if ((cp = strchr(line, '#')))
149 1.1 kardel *cp = '\0';
150 1.1 kardel
151 1.1 kardel /* Remove any trailing spaces */
152 1.1 kardel for (i = strlen(line);
153 1.2 christos i > 0 && isascii((unsigned char)line[i - 1]) && isspace((unsigned char)line[i - 1]);
154 1.1 kardel )
155 1.1 kardel line[--i] = '\0';
156 1.1 kardel
157 1.1 kardel /* Remove leading space */
158 1.2 christos for (cc = line; *cc && isascii((unsigned char)*cc) && isspace((unsigned char)*cc); cc++)
159 1.1 kardel continue;
160 1.1 kardel
161 1.1 kardel /* Stop if nothing left */
162 1.1 kardel if (!*cc)
163 1.1 kardel continue;
164 1.1 kardel
165 1.1 kardel /* Uppercase the command and find the arg */
166 1.1 kardel for (ca = cc; *ca; ca++) {
167 1.2 christos if (isascii((unsigned char)*ca)) {
168 1.2 christos if (islower((unsigned char)*ca)) {
169 1.2 christos *ca = toupper((unsigned char)*ca);
170 1.2 christos } else if (isspace((unsigned char)*ca) || (*ca == '='))
171 1.1 kardel break;
172 1.1 kardel }
173 1.1 kardel }
174 1.1 kardel
175 1.1 kardel /* Remove space (and possible =) leading the arg */
176 1.2 christos for (; *ca && isascii((unsigned char)*ca) && (isspace((unsigned char)*ca) || (*ca == '=')); ca++)
177 1.1 kardel continue;
178 1.1 kardel
179 1.4 kardel if (!strncmp(cc, "IDEV", 4) &&
180 1.4 kardel 1 == sscanf(ca, "%99s", ab)) {
181 1.4 kardel strncpy(cf_i_dev, ab, sizeof(cf_i_dev));
182 1.1 kardel printf("idev <%s>\n", ab);
183 1.4 kardel } else if (!strncmp(cc, "CDEV", 4) &&
184 1.4 kardel 1 == sscanf(ca, "%99s", ab)) {
185 1.4 kardel strncpy(cf_c_dev, ab, sizeof(cf_c_dev));
186 1.1 kardel printf("cdev <%s>\n", ab);
187 1.4 kardel } else if (!strncmp(cc, "AGC", 3) &&
188 1.4 kardel 1 == sscanf(ca, "%99s", ab)) {
189 1.4 kardel strncpy(cf_agc, ab, sizeof(cf_agc));
190 1.1 kardel printf("agc <%s> %d\n", ab, i);
191 1.4 kardel } else if (!strncmp(cc, "MONITOR", 7) &&
192 1.4 kardel 1 == sscanf(ca, "%99s", ab)) {
193 1.4 kardel strncpy(cf_monitor, ab, sizeof(cf_monitor));
194 1.1 kardel printf("monitor <%s> %d\n", ab, mixer_name(ab, -1));
195 1.1 kardel }
196 1.1 kardel }
197 1.1 kardel fclose(fd);
198 1.1 kardel return;
199 1.1 kardel }
200 1.1 kardel #endif /* PCM_STYLE_SOUND */
201 1.1 kardel
202 1.1 kardel /*
203 1.1 kardel * audio_init - open and initialize audio device
204 1.1 kardel *
205 1.1 kardel * This code works with SunOS 4.x, Solaris 2.x, and PCM; however, it is
206 1.1 kardel * believed generic and applicable to other systems with a minor twid
207 1.1 kardel * or two. All it does is open the device, set the buffer size (Solaris
208 1.1 kardel * only), preset the gain and set the input port. It assumes that the
209 1.1 kardel * codec sample rate (8000 Hz), precision (8 bits), number of channels
210 1.1 kardel * (1) and encoding (ITU-T G.711 mu-law companded) have been set by
211 1.1 kardel * default.
212 1.1 kardel */
213 1.1 kardel int
214 1.1 kardel audio_init(
215 1.3 christos const char *dname, /* device name */
216 1.1 kardel int bufsiz, /* buffer size */
217 1.1 kardel int unit /* device unit (0-3) */
218 1.1 kardel )
219 1.1 kardel {
220 1.1 kardel #ifdef PCM_STYLE_SOUND
221 1.1 kardel # define ACTL_DEV "/dev/mixer%d"
222 1.1 kardel char actl_dev[30];
223 1.1 kardel # ifdef HAVE_STRUCT_SND_SIZE
224 1.1 kardel struct snd_size s_size;
225 1.1 kardel # endif
226 1.1 kardel # ifdef AIOGFMT
227 1.1 kardel snd_chan_param s_c_p;
228 1.1 kardel # endif
229 1.1 kardel #endif
230 1.1 kardel int fd;
231 1.1 kardel int rval;
232 1.3 christos const char *actl =
233 1.1 kardel #ifdef PCM_STYLE_SOUND
234 1.1 kardel actl_dev
235 1.1 kardel #else
236 1.1 kardel "/dev/audioctl"
237 1.1 kardel #endif
238 1.1 kardel ;
239 1.1 kardel
240 1.1 kardel #ifdef PCM_STYLE_SOUND
241 1.4 kardel snprintf(actl_dev, sizeof(actl_dev), ACTL_DEV, unit);
242 1.1 kardel
243 1.1 kardel audio_config_read(unit, &actl, &dname);
244 1.1 kardel /* If we have values for cf_c_dev or cf_i_dev, use them. */
245 1.1 kardel if (*cf_c_dev)
246 1.1 kardel actl = cf_c_dev;
247 1.1 kardel if (*cf_i_dev)
248 1.1 kardel dname = cf_i_dev;
249 1.1 kardel #endif
250 1.1 kardel
251 1.1 kardel /*
252 1.1 kardel * Open audio device
253 1.1 kardel */
254 1.1 kardel fd = open(dname, O_RDWR | O_NONBLOCK, 0777);
255 1.1 kardel if (fd < 0) {
256 1.1 kardel msyslog(LOG_ERR, "audio_init: %s %m\n", dname);
257 1.1 kardel return (fd);
258 1.1 kardel }
259 1.1 kardel
260 1.1 kardel /*
261 1.1 kardel * Open audio control device.
262 1.1 kardel */
263 1.1 kardel ctl_fd = open(actl, O_RDWR);
264 1.1 kardel if (ctl_fd < 0) {
265 1.1 kardel msyslog(LOG_ERR, "audio_init: invalid control device <%s>\n",
266 1.1 kardel actl);
267 1.1 kardel close(fd);
268 1.1 kardel return(ctl_fd);
269 1.1 kardel }
270 1.1 kardel
271 1.1 kardel /*
272 1.1 kardel * Set audio device parameters.
273 1.1 kardel */
274 1.1 kardel #ifdef PCM_STYLE_SOUND
275 1.1 kardel printf("audio_init: <%s> bufsiz %d\n", dname, bufsiz);
276 1.1 kardel rval = fd;
277 1.1 kardel
278 1.1 kardel # ifdef HAVE_STRUCT_SND_SIZE
279 1.1 kardel if (ioctl(fd, AIOGSIZE, &s_size) == -1)
280 1.1 kardel printf("audio_init: AIOGSIZE: %s\n", strerror(errno));
281 1.1 kardel else
282 1.1 kardel printf("audio_init: orig: play_size %d, rec_size %d\n",
283 1.1 kardel s_size.play_size, s_size.rec_size);
284 1.1 kardel
285 1.1 kardel s_size.play_size = s_size.rec_size = bufsiz;
286 1.1 kardel printf("audio_init: want: play_size %d, rec_size %d\n",
287 1.1 kardel s_size.play_size, s_size.rec_size);
288 1.1 kardel
289 1.1 kardel if (ioctl(fd, AIOSSIZE, &s_size) == -1)
290 1.1 kardel printf("audio_init: AIOSSIZE: %s\n", strerror(errno));
291 1.1 kardel else
292 1.1 kardel printf("audio_init: set: play_size %d, rec_size %d\n",
293 1.1 kardel s_size.play_size, s_size.rec_size);
294 1.1 kardel # endif /* HAVE_STRUCT_SND_SIZE */
295 1.1 kardel
296 1.1 kardel # ifdef SNDCTL_DSP_SETFRAGMENT
297 1.1 kardel {
298 1.1 kardel int tmp = (16 << 16) + 6; /* 16 fragments, each 2^6 bytes */
299 1.1 kardel if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
300 1.1 kardel printf("audio_init: SNDCTL_DSP_SETFRAGMENT: %s\n",
301 1.1 kardel strerror(errno));
302 1.1 kardel }
303 1.1 kardel # endif /* SNDCTL_DSP_SETFRAGMENT */
304 1.1 kardel
305 1.1 kardel # ifdef AIOGFMT
306 1.1 kardel if (ioctl(fd, AIOGFMT, &s_c_p) == -1)
307 1.1 kardel printf("audio_init: AIOGFMT: %s\n", strerror(errno));
308 1.1 kardel else
309 1.1 kardel printf("audio_init: play_rate %lu, rec_rate %lu, play_format %#lx, rec_format %#lx\n",
310 1.1 kardel s_c_p.play_rate, s_c_p.rec_rate, s_c_p.play_format, s_c_p.rec_format);
311 1.1 kardel # endif
312 1.1 kardel
313 1.1 kardel /* Grab the device and record masks */
314 1.1 kardel
315 1.1 kardel if (ioctl(ctl_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
316 1.1 kardel printf("SOUND_MIXER_READ_DEVMASK: %s\n", strerror(errno));
317 1.1 kardel if (ioctl(ctl_fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
318 1.1 kardel printf("SOUND_MIXER_READ_RECMASK: %s\n", strerror(errno));
319 1.1 kardel
320 1.1 kardel /* validate and set any specified config file stuff */
321 1.4 kardel if (cf_agc[0] != '\0') {
322 1.1 kardel int i;
323 1.1 kardel
324 1.1 kardel i = mixer_name(cf_agc, devmask);
325 1.1 kardel if (i >= 0)
326 1.1 kardel agc = MIXER_WRITE(i);
327 1.1 kardel else
328 1.1 kardel printf("input %s not in recmask %#x\n",
329 1.1 kardel cf_agc, recmask);
330 1.1 kardel }
331 1.1 kardel
332 1.4 kardel if (cf_monitor[0] != '\0') {
333 1.1 kardel int i;
334 1.1 kardel
335 1.1 kardel /* devmask */
336 1.1 kardel i = mixer_name(cf_monitor, devmask);
337 1.1 kardel if (i >= 0)
338 1.1 kardel monitor = MIXER_WRITE(i);
339 1.1 kardel else
340 1.1 kardel printf("monitor %s not in devmask %#x\n",
341 1.1 kardel cf_monitor, devmask);
342 1.1 kardel }
343 1.1 kardel
344 1.1 kardel #else /* not PCM_STYLE_SOUND */
345 1.1 kardel AUDIO_INITINFO(&info);
346 1.1 kardel info.play.gain = AUDIO_MAX_GAIN;
347 1.1 kardel info.play.port = AUDIO_SPEAKER;
348 1.1 kardel # ifdef HAVE_SYS_AUDIOIO_H
349 1.1 kardel info.record.buffer_size = bufsiz;
350 1.1 kardel # endif /* HAVE_SYS_AUDIOIO_H */
351 1.1 kardel rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, (char *)&info);
352 1.1 kardel if (rval < 0) {
353 1.1 kardel msyslog(LOG_ERR, "audio: invalid control device parameters\n");
354 1.1 kardel close(ctl_fd);
355 1.1 kardel close(fd);
356 1.1 kardel return(rval);
357 1.1 kardel }
358 1.1 kardel rval = fd;
359 1.1 kardel #endif /* not PCM_STYLE_SOUND */
360 1.1 kardel return (rval);
361 1.1 kardel }
362 1.1 kardel
363 1.1 kardel
364 1.1 kardel /*
365 1.1 kardel * audio_gain - adjust codec gains and port
366 1.1 kardel */
367 1.1 kardel int
368 1.1 kardel audio_gain(
369 1.1 kardel int gain, /* volume level (gain) 0-255 */
370 1.1 kardel int mongain, /* input to output mix (monitor gain) 0-255 */
371 1.1 kardel int port /* selected I/O port: 1 mic/2 line in */
372 1.1 kardel )
373 1.1 kardel {
374 1.1 kardel int rval;
375 1.1 kardel static int o_mongain = -1;
376 1.1 kardel static int o_port = -1;
377 1.1 kardel
378 1.1 kardel #ifdef PCM_STYLE_SOUND
379 1.1 kardel int l, r;
380 1.1 kardel
381 1.1 kardel rval = 0;
382 1.1 kardel
383 1.1 kardel r = l = 100 * gain / 255; /* Normalize to 0-100 */
384 1.1 kardel # ifdef DEBUG
385 1.1 kardel if (debug > 1)
386 1.1 kardel printf("audio_gain: gain %d/%d\n", gain, l);
387 1.1 kardel # endif
388 1.1 kardel #if 0 /* not a good idea to do this; connector wiring dependency */
389 1.1 kardel /* figure out what channel(s) to use. just nuke right for now. */
390 1.1 kardel r = 0 ; /* setting to zero nicely mutes the channel */
391 1.1 kardel #endif
392 1.1 kardel l |= r << 8;
393 1.4 kardel if (cf_agc[0] != '\0')
394 1.4 kardel rval = ioctl(ctl_fd, agc, &l);
395 1.4 kardel else
396 1.4 kardel if (2 == port)
397 1.4 kardel rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_LINE, &l);
398 1.4 kardel else
399 1.4 kardel rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_MIC, &l);
400 1.4 kardel if (-1 == rval) {
401 1.1 kardel printf("audio_gain: agc write: %s\n", strerror(errno));
402 1.4 kardel return rval;
403 1.1 kardel }
404 1.1 kardel
405 1.1 kardel if (o_mongain != mongain) {
406 1.1 kardel r = l = 100 * mongain / 255; /* Normalize to 0-100 */
407 1.1 kardel # ifdef DEBUG
408 1.1 kardel if (debug > 1)
409 1.1 kardel printf("audio_gain: mongain %d/%d\n", mongain, l);
410 1.1 kardel # endif
411 1.1 kardel l |= r << 8;
412 1.4 kardel if (cf_monitor[0] != '\0')
413 1.4 kardel rval = ioctl(ctl_fd, monitor, &l );
414 1.4 kardel else
415 1.4 kardel rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_VOLUME,
416 1.4 kardel &l);
417 1.4 kardel if (-1 == rval) {
418 1.1 kardel printf("audio_gain: mongain write: %s\n",
419 1.1 kardel strerror(errno));
420 1.1 kardel return (rval);
421 1.1 kardel }
422 1.1 kardel o_mongain = mongain;
423 1.1 kardel }
424 1.1 kardel
425 1.1 kardel if (o_port != port) {
426 1.1 kardel # ifdef DEBUG
427 1.1 kardel if (debug > 1)
428 1.1 kardel printf("audio_gain: port %d\n", port);
429 1.1 kardel # endif
430 1.1 kardel l = (1 << ((port == 2) ? SOUND_MIXER_LINE : SOUND_MIXER_MIC));
431 1.1 kardel rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_RECSRC, &l);
432 1.1 kardel if (rval == -1) {
433 1.1 kardel printf("SOUND_MIXER_WRITE_RECSRC: %s\n",
434 1.1 kardel strerror(errno));
435 1.1 kardel return (rval);
436 1.1 kardel }
437 1.1 kardel # ifdef DEBUG
438 1.1 kardel if (debug > 1) {
439 1.1 kardel if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &l) == -1)
440 1.1 kardel printf("SOUND_MIXER_WRITE_RECSRC: %s\n",
441 1.1 kardel strerror(errno));
442 1.1 kardel else
443 1.1 kardel printf("audio_gain: recsrc is %d\n", l);
444 1.1 kardel }
445 1.1 kardel # endif
446 1.1 kardel o_port = port;
447 1.1 kardel }
448 1.1 kardel #else /* not PCM_STYLE_SOUND */
449 1.1 kardel ioctl(ctl_fd, (int)AUDIO_GETINFO, (char *)&info);
450 1.1 kardel info.record.encoding = AUDIO_ENCODING_ULAW;
451 1.1 kardel info.record.error = 0;
452 1.1 kardel info.record.gain = gain;
453 1.1 kardel if (o_mongain != mongain)
454 1.1 kardel o_mongain = info.monitor_gain = mongain;
455 1.1 kardel if (o_port != port)
456 1.1 kardel o_port = info.record.port = port;
457 1.1 kardel rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, (char *)&info);
458 1.1 kardel if (rval < 0) {
459 1.1 kardel msyslog(LOG_ERR, "audio_gain: %m");
460 1.1 kardel return (rval);
461 1.1 kardel }
462 1.1 kardel rval = info.record.error;
463 1.1 kardel #endif /* not PCM_STYLE_SOUND */
464 1.1 kardel return (rval);
465 1.1 kardel }
466 1.1 kardel
467 1.1 kardel
468 1.1 kardel /*
469 1.1 kardel * audio_show - display audio parameters
470 1.1 kardel *
471 1.1 kardel * This code doesn't really do anything, except satisfy curiousity and
472 1.1 kardel * verify the ioctl's work.
473 1.1 kardel */
474 1.1 kardel void
475 1.1 kardel audio_show(void)
476 1.1 kardel {
477 1.1 kardel #ifdef PCM_STYLE_SOUND
478 1.1 kardel int recsrc = 0;
479 1.1 kardel
480 1.1 kardel printf("audio_show: ctl_fd %d\n", ctl_fd);
481 1.1 kardel if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
482 1.1 kardel printf("SOUND_MIXER_READ_RECSRC: %s\n", strerror(errno));
483 1.1 kardel
484 1.1 kardel #else /* not PCM_STYLE_SOUND */
485 1.1 kardel # ifdef HAVE_SYS_AUDIOIO_H
486 1.1 kardel ioctl(ctl_fd, (int)AUDIO_GETDEV, &device);
487 1.1 kardel printf("audio: name %s, version %s, config %s\n",
488 1.1 kardel device.name, device.version, device.config);
489 1.1 kardel # endif /* HAVE_SYS_AUDIOIO_H */
490 1.1 kardel ioctl(ctl_fd, (int)AUDIO_GETINFO, (char *)&info);
491 1.1 kardel printf(
492 1.1 kardel "audio: rate %d, chan %d, prec %d, code %d, gain %d, mon %d, port %d\n",
493 1.1 kardel info.record.sample_rate, info.record.channels,
494 1.1 kardel info.record.precision, info.record.encoding,
495 1.1 kardel info.record.gain, info.monitor_gain, info.record.port);
496 1.1 kardel printf(
497 1.1 kardel "audio: samples %d, eof %d, pause %d, error %d, waiting %d, balance %d\n",
498 1.1 kardel info.record.samples, info.record.eof,
499 1.1 kardel info.record.pause, info.record.error,
500 1.1 kardel info.record.waiting, info.record.balance);
501 1.1 kardel #endif /* not PCM_STYLE_SOUND */
502 1.1 kardel }
503 1.1 kardel #else
504 1.1 kardel int audio_bs;
505 1.1 kardel #endif /* HAVE_{SYS_AUDIOIO,SUN_AUDIOIO,MACHINE_SOUNDCARD,SYS_SOUNDCARD}_H */
506