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