156746Sroberto/* 256746Sroberto * audio.c - audio interface for reference clock audio drivers 356746Sroberto */ 456746Sroberto#ifdef HAVE_CONFIG_H 5132451Sroberto# include <config.h> 656746Sroberto#endif 756746Sroberto 8132451Sroberto#if defined(HAVE_SYS_AUDIOIO_H) || defined(HAVE_SUN_AUDIOIO_H) || \ 9132451Sroberto defined(HAVE_SYS_SOUNDCARD_H) || defined(HAVE_MACHINE_SOUNDCARD_H) 1082498Sroberto 1156746Sroberto#include "audio.h" 1282498Sroberto#include "ntp_stdlib.h" 1382498Sroberto#include "ntp_syslog.h" 1482498Sroberto#ifdef HAVE_UNISTD_H 1582498Sroberto# include <unistd.h> 1682498Sroberto#endif 1756746Sroberto#include <stdio.h> 1882498Sroberto#include "ntp_string.h" 1956746Sroberto 2056746Sroberto#ifdef HAVE_SYS_AUDIOIO_H 21132451Sroberto# include <sys/audioio.h> 2256746Sroberto#endif /* HAVE_SYS_AUDIOIO_H */ 2382498Sroberto 2456746Sroberto#ifdef HAVE_SUN_AUDIOIO_H 25132451Sroberto# include <sys/ioccom.h> 26132451Sroberto# include <sun/audioio.h> 2756746Sroberto#endif /* HAVE_SUN_AUDIOIO_H */ 2882498Sroberto 2956746Sroberto#ifdef HAVE_SYS_IOCTL_H 30132451Sroberto# include <sys/ioctl.h> 3156746Sroberto#endif /* HAVE_SYS_IOCTL_H */ 3256746Sroberto 3356746Sroberto#include <fcntl.h> 3456746Sroberto 35132451Sroberto#ifdef HAVE_MACHINE_SOUNDCARD_H 36132451Sroberto# include <machine/soundcard.h> 37132451Sroberto# define PCM_STYLE_SOUND 38132451Sroberto#else 39132451Sroberto# ifdef HAVE_SYS_SOUNDCARD_H 40132451Sroberto# include <sys/soundcard.h> 41132451Sroberto# define PCM_STYLE_SOUND 42132451Sroberto# endif 43132451Sroberto#endif 44132451Sroberto 45132451Sroberto#ifdef PCM_STYLE_SOUND 46132451Sroberto# include <ctype.h> 47132451Sroberto#endif 48132451Sroberto 4956746Sroberto/* 5056746Sroberto * Global variables 5156746Sroberto */ 5256746Sroberto#ifdef HAVE_SYS_AUDIOIO_H 5356746Srobertostatic struct audio_device device; /* audio device ident */ 5482498Sroberto#endif /* HAVE_SYS_AUDIOIO_H */ 55132451Sroberto#ifdef PCM_STYLE_SOUND 56132451Sroberto# define INIT_FILE "/etc/ntp.audio" 57132451Srobertoint agc = SOUND_MIXER_WRITE_RECLEV; /* or IGAIN or LINE */ 58132451Srobertoint monitor = SOUND_MIXER_WRITE_VOLUME; /* or OGAIN */ 59132451Srobertoint devmask = 0; 60132451Srobertoint recmask = 0; 61132451Srobertochar cf_c_dev[100], cf_i_dev[100], cf_agc[100], cf_monitor[100]; 62132451Sroberto 63132451Srobertoconst char *m_names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; 64132451Sroberto#else /* not PCM_STYLE_SOUND */ 6556746Srobertostatic struct audio_info info; /* audio device info */ 66132451Sroberto#endif /* not PCM_STYLE_SOUND */ 6756746Srobertostatic int ctl_fd; /* audio control file descriptor */ 6856746Sroberto 69132451Sroberto#ifdef PCM_STYLE_SOUND 70132451Srobertostatic void audio_config_read P((int, char **, char **)); 71132451Srobertostatic int mixer_name P((const char *, int)); 7256746Sroberto 73132451Sroberto 74132451Srobertoint 75132451Srobertomixer_name( 76132451Sroberto const char *m_name, 77132451Sroberto int m_mask 78132451Sroberto ) 79132451Sroberto{ 80132451Sroberto int i; 81132451Sroberto 82132451Sroberto for (i = 0; i < SOUND_MIXER_NRDEVICES; ++i) 83132451Sroberto if (((1 << i) & m_mask) 84132451Sroberto && !strcmp(m_names[i], m_name)) 85132451Sroberto break; 86132451Sroberto 87132451Sroberto return (SOUND_MIXER_NRDEVICES == i) 88132451Sroberto ? -1 89132451Sroberto : i 90132451Sroberto ; 91132451Sroberto} 92132451Sroberto 93132451Sroberto 9456746Sroberto/* 95132451Sroberto * Check: 96132451Sroberto * 97132451Sroberto * /etc/ntp.audio# where # is the unit number 98132451Sroberto * /etc/ntp.audio.# where # is the unit number 99132451Sroberto * /etc/ntp.audio 100132451Sroberto * 101132451Sroberto * for contents of the form: 102132451Sroberto * 103132451Sroberto * idev /dev/input_device 104132451Sroberto * cdev /dev/control_device 105132451Sroberto * agc pcm_input_device {igain,line,line1,...} 106132451Sroberto * monitor pcm_monitor_device {ogain,...} 107132451Sroberto * 108132451Sroberto * The device names for the "agc" and "monitor" keywords 109132451Sroberto * can be found by running either the "mixer" program or the 110132451Sroberto * util/audio-pcm program. 111132451Sroberto * 112132451Sroberto * Great hunks of this subroutine were swiped from refclock_oncore.c 113132451Sroberto */ 114132451Srobertostatic void 115132451Srobertoaudio_config_read( 116132451Sroberto int unit, 117132451Sroberto char **c_dev, /* Control device */ 118132451Sroberto char **i_dev /* input device */ 119132451Sroberto ) 120132451Sroberto{ 121132451Sroberto FILE *fd; 122132451Sroberto char device[20], line[100], ab[100]; 123132451Sroberto 124132451Sroberto sprintf(device, "%s%d", INIT_FILE, unit); 125132451Sroberto if ((fd = fopen(device, "r")) == NULL) { 126132451Sroberto printf("audio_config_read: <%s> NO\n", device); 127132451Sroberto sprintf(device, "%s.%d", INIT_FILE, unit); 128132451Sroberto if ((fd = fopen(device, "r")) == NULL) { 129132451Sroberto printf("audio_config_read: <%s> NO\n", device); 130132451Sroberto sprintf(device, "%s.%d", INIT_FILE, unit); 131132451Sroberto if ((fd = fopen(device, "r")) == NULL) { 132132451Sroberto printf("audio_config_read: <%s> NO\n", device); 133132451Sroberto return; 134132451Sroberto } 135132451Sroberto } 136132451Sroberto } 137132451Sroberto printf("audio_config_read: reading <%s>\n", device); 138132451Sroberto while (fgets(line, sizeof line, fd)) { 139132451Sroberto char *cp, *cc, *ca; 140132451Sroberto int i; 141132451Sroberto 142132451Sroberto /* Remove comments */ 143132451Sroberto if ((cp = strchr(line, '#'))) 144132451Sroberto *cp = '\0'; 145132451Sroberto 146132451Sroberto /* Remove any trailing spaces */ 147132451Sroberto for (i = strlen(line); 148132451Sroberto i > 0 && isascii((int)line[i - 1]) && isspace((int)line[i - 1]); 149132451Sroberto ) 150132451Sroberto line[--i] = '\0'; 151132451Sroberto 152132451Sroberto /* Remove leading space */ 153132451Sroberto for (cc = line; *cc && isascii((int)*cc) && isspace((int)*cc); cc++) 154132451Sroberto continue; 155132451Sroberto 156132451Sroberto /* Stop if nothing left */ 157132451Sroberto if (!*cc) 158132451Sroberto continue; 159132451Sroberto 160132451Sroberto /* Uppercase the command and find the arg */ 161132451Sroberto for (ca = cc; *ca; ca++) { 162132451Sroberto if (isascii((int)*ca)) { 163132451Sroberto if (islower((int)*ca)) { 164132451Sroberto *ca = toupper(*ca); 165132451Sroberto } else if (isspace((int)*ca) || (*ca == '=')) 166132451Sroberto break; 167132451Sroberto } 168132451Sroberto } 169132451Sroberto 170132451Sroberto /* Remove space (and possible =) leading the arg */ 171132451Sroberto for (; *ca && isascii((int)*ca) && (isspace((int)*ca) || (*ca == '=')); ca++) 172132451Sroberto continue; 173132451Sroberto 174132451Sroberto if (!strncmp(cc, "IDEV", (size_t) 4)) { 175132451Sroberto sscanf(ca, "%s", ab); 176132451Sroberto strcpy(cf_i_dev, ab); 177132451Sroberto printf("idev <%s>\n", ab); 178132451Sroberto } else if (!strncmp(cc, "CDEV", (size_t) 4)) { 179132451Sroberto sscanf(ca, "%s", ab); 180132451Sroberto strcpy(cf_c_dev, ab); 181132451Sroberto printf("cdev <%s>\n", ab); 182132451Sroberto } else if (!strncmp(cc, "AGC", (size_t) 3)) { 183132451Sroberto sscanf(ca, "%s", ab); 184132451Sroberto strcpy(cf_agc, ab); 185132451Sroberto printf("agc <%s> %d\n", ab, i); 186132451Sroberto } else if (!strncmp(cc, "MONITOR", (size_t) 7)) { 187132451Sroberto sscanf(ca, "%s", ab); 188132451Sroberto strcpy(cf_monitor, ab); 189132451Sroberto printf("monitor <%s> %d\n", ab, mixer_name(ab, -1)); 190132451Sroberto } 191132451Sroberto } 192132451Sroberto fclose(fd); 193132451Sroberto return; 194132451Sroberto} 195132451Sroberto#endif /* PCM_STYLE_SOUND */ 196132451Sroberto 197132451Sroberto/* 19856746Sroberto * audio_init - open and initialize audio device 19956746Sroberto * 200132451Sroberto * This code works with SunOS 4.x, Solaris 2.x, and PCM; however, it is 20156746Sroberto * believed generic and applicable to other systems with a minor twid 20256746Sroberto * or two. All it does is open the device, set the buffer size (Solaris 20356746Sroberto * only), preset the gain and set the input port. It assumes that the 20456746Sroberto * codec sample rate (8000 Hz), precision (8 bits), number of channels 20556746Sroberto * (1) and encoding (ITU-T G.711 mu-law companded) have been set by 20656746Sroberto * default. 20756746Sroberto */ 20856746Srobertoint 20982498Srobertoaudio_init( 210132451Sroberto char *dname, /* device name */ 211132451Sroberto int bufsiz, /* buffer size */ 212132451Sroberto int unit /* device unit (0-3) */ 21382498Sroberto ) 21456746Sroberto{ 215132451Sroberto#ifdef PCM_STYLE_SOUND 216132451Sroberto# define ACTL_DEV "/dev/mixer%d" 217132451Sroberto char actl_dev[30]; 218132451Sroberto# ifdef HAVE_STRUCT_SND_SIZE 219132451Sroberto struct snd_size s_size; 220132451Sroberto# endif 221132451Sroberto# ifdef AIOGFMT 222132451Sroberto snd_chan_param s_c_p; 223132451Sroberto# endif 224132451Sroberto#endif 22556746Sroberto int fd; 22656746Sroberto int rval; 227132451Sroberto char *actl = 228132451Sroberto#ifdef PCM_STYLE_SOUND 229132451Sroberto actl_dev 230132451Sroberto#else 231132451Sroberto "/dev/audioctl" 232132451Sroberto#endif 233132451Sroberto ; 23456746Sroberto 235132451Sroberto#ifdef PCM_STYLE_SOUND 236132451Sroberto (void)sprintf(actl_dev, ACTL_DEV, unit); 237132451Sroberto 238132451Sroberto audio_config_read(unit, &actl, &dname); 239132451Sroberto /* If we have values for cf_c_dev or cf_i_dev, use them. */ 240132451Sroberto if (*cf_c_dev) 241182007Sroberto actl = cf_c_dev; 242132451Sroberto if (*cf_i_dev) 243182007Sroberto dname = cf_i_dev; 244132451Sroberto#endif 245132451Sroberto 24656746Sroberto /* 24782498Sroberto * Open audio device. Do not complain if not there. 24856746Sroberto */ 24982498Sroberto fd = open(dname, O_RDWR | O_NONBLOCK, 0777); 25082498Sroberto if (fd < 0) 25156746Sroberto return (fd); 25256746Sroberto 25356746Sroberto /* 25482498Sroberto * Open audio control device. 25556746Sroberto */ 256132451Sroberto ctl_fd = open(actl, O_RDWR); 25756746Sroberto if (ctl_fd < 0) { 258132451Sroberto msyslog(LOG_ERR, "audio_init: invalid control device <%s>\n", actl); 25956746Sroberto close(fd); 26056746Sroberto return(ctl_fd); 26156746Sroberto } 26256746Sroberto 26356746Sroberto /* 26456746Sroberto * Set audio device parameters. 26556746Sroberto */ 266132451Sroberto#ifdef PCM_STYLE_SOUND 267132451Sroberto printf("audio_init: <%s> bufsiz %d\n", dname, bufsiz); 268132451Sroberto rval = fd; 269132451Sroberto 270132451Sroberto# ifdef HAVE_STRUCT_SND_SIZE 271132451Sroberto if (ioctl(fd, AIOGSIZE, &s_size) == -1) 272132451Sroberto printf("audio_init: AIOGSIZE: %s\n", strerror(errno)); 273132451Sroberto else 274132451Sroberto printf("audio_init: orig: play_size %d, rec_size %d\n", 275132451Sroberto s_size.play_size, s_size.rec_size); 276132451Sroberto 277132451Sroberto s_size.play_size = s_size.rec_size = bufsiz; 278132451Sroberto printf("audio_init: want: play_size %d, rec_size %d\n", 279132451Sroberto s_size.play_size, s_size.rec_size); 280132451Sroberto 281132451Sroberto if (ioctl(fd, AIOSSIZE, &s_size) == -1) 282132451Sroberto printf("audio_init: AIOSSIZE: %s\n", strerror(errno)); 283132451Sroberto else 284132451Sroberto printf("audio_init: set: play_size %d, rec_size %d\n", 285132451Sroberto s_size.play_size, s_size.rec_size); 286132451Sroberto# endif /* HAVE_STRUCT_SND_SIZE */ 287132451Sroberto 288182007Sroberto# ifdef SNDCTL_DSP_SETFRAGMENT 289182007Sroberto { 290182007Sroberto int tmp = (16 << 16) + 6; /* 16 fragments, each 2^6 bytes */ 291182007Sroberto if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1) 292182007Sroberto printf("audio_init: SNDCTL_DSP_SETFRAGMENT: %s\n", 293182007Sroberto strerror(errno)); 294182007Sroberto } 295182007Sroberto# endif /* SNDCTL_DSP_SETFRAGMENT */ 296182007Sroberto 297132451Sroberto# ifdef AIOGFMT 298132451Sroberto if (ioctl(fd, AIOGFMT, &s_c_p) == -1) 299132451Sroberto printf("audio_init: AIOGFMT: %s\n", strerror(errno)); 300132451Sroberto else 301132451Sroberto printf("audio_init: play_rate %lu, rec_rate %lu, play_format %#lx, rec_format %#lx\n", 302132451Sroberto s_c_p.play_rate, s_c_p.rec_rate, s_c_p.play_format, s_c_p.rec_format); 303132451Sroberto# endif 304132451Sroberto 305132451Sroberto /* Grab the device and record masks */ 306132451Sroberto 307132451Sroberto if (ioctl(ctl_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) 308132451Sroberto printf("SOUND_MIXER_READ_DEVMASK: %s\n", strerror(errno)); 309132451Sroberto if (ioctl(ctl_fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) 310132451Sroberto printf("SOUND_MIXER_READ_RECMASK: %s\n", strerror(errno)); 311132451Sroberto 312132451Sroberto /* validate and set any specified config file stuff */ 313132451Sroberto if (*cf_agc) { 314132451Sroberto int i; 315132451Sroberto 316182007Sroberto i = mixer_name(cf_agc, devmask); 317132451Sroberto if (i >= 0) 318132451Sroberto agc = MIXER_WRITE(i); 319132451Sroberto else 320132451Sroberto printf("input %s not in recmask %#x\n", 321132451Sroberto cf_agc, recmask); 322132451Sroberto } 323132451Sroberto 324132451Sroberto if (*cf_monitor) { 325132451Sroberto int i; 326132451Sroberto 327132451Sroberto /* devmask */ 328132451Sroberto i = mixer_name(cf_monitor, devmask); 329132451Sroberto if (i >= 0) 330132451Sroberto monitor = MIXER_WRITE(i); 331132451Sroberto else 332132451Sroberto printf("monitor %s not in devmask %#x\n", 333132451Sroberto cf_monitor, devmask); 334132451Sroberto } 335132451Sroberto 336132451Sroberto#else /* not PCM_STYLE_SOUND */ 337132451Sroberto AUDIO_INITINFO(&info); 338132451Sroberto info.play.gain = AUDIO_MAX_GAIN; 339132451Sroberto info.play.port = AUDIO_SPEAKER; 340132451Sroberto# ifdef HAVE_SYS_AUDIOIO_H 341132451Sroberto info.record.buffer_size = bufsiz; 342132451Sroberto# endif /* HAVE_SYS_AUDIOIO_H */ 343132451Sroberto rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, (char *)&info); 34456746Sroberto if (rval < 0) { 34582498Sroberto msyslog(LOG_ERR, "audio: invalid control device parameters\n"); 34656746Sroberto close(ctl_fd); 34756746Sroberto close(fd); 34856746Sroberto return(rval); 34956746Sroberto } 350132451Sroberto rval = fd; 351132451Sroberto#endif /* not PCM_STYLE_SOUND */ 352132451Sroberto return (rval); 35356746Sroberto} 35456746Sroberto 35556746Sroberto 35656746Sroberto/* 357132451Sroberto * audio_gain - adjust codec gains and port 35856746Sroberto */ 35956746Srobertoint 36056746Srobertoaudio_gain( 361132451Sroberto int gain, /* volume level (gain) 0-255 */ 362132451Sroberto int mongain, /* input to output mix (monitor gain) 0-255 */ 363132451Sroberto int port /* selected I/O port: 1 mic/2 line in */ 36456746Sroberto ) 36556746Sroberto{ 36656746Sroberto int rval; 367132451Sroberto static int o_mongain = -1; 368132451Sroberto static int o_port = -1; 36956746Sroberto 370132451Sroberto#ifdef PCM_STYLE_SOUND 371132451Sroberto int l, r; 372132451Sroberto 373132451Sroberto rval = 0; 374132451Sroberto 375132451Sroberto r = l = 100 * gain / 255; /* Normalize to 0-100 */ 376132451Sroberto# ifdef DEBUG 377132451Sroberto if (debug > 1) 378132451Sroberto printf("audio_gain: gain %d/%d\n", gain, l); 379132451Sroberto# endif 380132451Sroberto /* figure out what channel(s) to use. just nuke right for now. */ 381132451Sroberto r = 0 ; /* setting to zero nicely mutes the channel */ 382132451Sroberto 383132451Sroberto l |= r << 8; 384182007Sroberto if ( cf_agc ) 385182007Sroberto rval = ioctl(ctl_fd, agc, &l); 386182007Sroberto else 387182007Sroberto if (port == 2) { 388182007Sroberto rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_LINE, &l); 389182007Sroberto } else { 390182007Sroberto rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_MIC, &l); 391182007Sroberto } 392132451Sroberto if (rval == -1) { 393132451Sroberto printf("audio_gain: agc write: %s\n", strerror(errno)); 394132451Sroberto return (rval); 395132451Sroberto } 396132451Sroberto 397132451Sroberto if (o_mongain != mongain) { 398132451Sroberto r = l = 100 * mongain / 255; /* Normalize to 0-100 */ 399132451Sroberto# ifdef DEBUG 400132451Sroberto if (debug > 1) 401132451Sroberto printf("audio_gain: mongain %d/%d\n", mongain, l); 402132451Sroberto# endif 403132451Sroberto l |= r << 8; 404182007Sroberto if ( cf_monitor ) 405182007Sroberto rval = ioctl(ctl_fd, monitor, &l ); 406182007Sroberto else 407182007Sroberto rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_VOLUME, &l); 408132451Sroberto if (rval == -1) { 409132451Sroberto printf("audio_gain: mongain write: %s\n", 410132451Sroberto strerror(errno)); 411132451Sroberto return (rval); 412132451Sroberto } 413132451Sroberto o_mongain = mongain; 414132451Sroberto } 415132451Sroberto 416132451Sroberto if (o_port != port) { 417132451Sroberto# ifdef DEBUG 418132451Sroberto if (debug > 1) 419132451Sroberto printf("audio_gain: port %d\n", port); 420132451Sroberto# endif 421132451Sroberto l = (1 << ((port == 2) ? SOUND_MIXER_LINE : SOUND_MIXER_MIC)); 422132451Sroberto rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_RECSRC, &l); 423132451Sroberto if (rval == -1) { 424132451Sroberto printf("SOUND_MIXER_WRITE_RECSRC: %s\n", 425132451Sroberto strerror(errno)); 426132451Sroberto return (rval); 427132451Sroberto } 428132451Sroberto# ifdef DEBUG 429132451Sroberto if (debug > 1) { 430132451Sroberto if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &l) == -1) 431132451Sroberto printf("SOUND_MIXER_WRITE_RECSRC: %s\n", 432132451Sroberto strerror(errno)); 433132451Sroberto else 434132451Sroberto printf("audio_gain: recsrc is %d\n", l); 435132451Sroberto } 436132451Sroberto# endif 437132451Sroberto o_port = port; 438132451Sroberto } 439132451Sroberto#else /* not PCM_STYLE_SOUND */ 440132451Sroberto ioctl(ctl_fd, (int)AUDIO_GETINFO, (char *)&info); 441132451Sroberto info.record.encoding = AUDIO_ENCODING_ULAW; 442132451Sroberto info.record.error = 0; 44356746Sroberto info.record.gain = gain; 444132451Sroberto if (o_mongain != mongain) 445132451Sroberto o_mongain = info.monitor_gain = mongain; 446132451Sroberto if (o_port != port) 447132451Sroberto o_port = info.record.port = port; 448132451Sroberto rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, (char *)&info); 44956746Sroberto if (rval < 0) { 45082498Sroberto msyslog(LOG_ERR, "audio_gain: %m"); 45156746Sroberto return (rval); 45256746Sroberto } 453132451Sroberto rval = info.record.error; 454132451Sroberto#endif /* not PCM_STYLE_SOUND */ 455132451Sroberto return (rval); 45656746Sroberto} 45756746Sroberto 45856746Sroberto 45956746Sroberto/* 46056746Sroberto * audio_show - display audio parameters 46156746Sroberto * 46256746Sroberto * This code doesn't really do anything, except satisfy curiousity and 46356746Sroberto * verify the ioctl's work. 46456746Sroberto */ 46556746Srobertovoid 46656746Srobertoaudio_show(void) 46756746Sroberto{ 468132451Sroberto#ifdef PCM_STYLE_SOUND 469132451Sroberto int recsrc = 0; 470132451Sroberto 471132451Sroberto printf("audio_show: ctl_fd %d\n", ctl_fd); 472132451Sroberto if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) 473132451Sroberto printf("SOUND_MIXER_READ_RECSRC: %s\n", strerror(errno)); 474132451Sroberto 475132451Sroberto#else /* not PCM_STYLE_SOUND */ 476132451Sroberto# ifdef HAVE_SYS_AUDIOIO_H 47756746Sroberto ioctl(ctl_fd, (int)AUDIO_GETDEV, &device); 47856746Sroberto printf("audio: name %s, version %s, config %s\n", 47956746Sroberto device.name, device.version, device.config); 480132451Sroberto# endif /* HAVE_SYS_AUDIOIO_H */ 481132451Sroberto ioctl(ctl_fd, (int)AUDIO_GETINFO, (char *)&info); 48256746Sroberto printf( 483132451Sroberto "audio: rate %d, chan %d, prec %d, code %d, gain %d, mon %d, port %d\n", 48456746Sroberto info.record.sample_rate, info.record.channels, 48582498Sroberto info.record.precision, info.record.encoding, 486132451Sroberto info.record.gain, info.monitor_gain, info.record.port); 48756746Sroberto printf( 48856746Sroberto "audio: samples %d, eof %d, pause %d, error %d, waiting %d, balance %d\n", 48956746Sroberto info.record.samples, info.record.eof, 49056746Sroberto info.record.pause, info.record.error, 49156746Sroberto info.record.waiting, info.record.balance); 492132451Sroberto#endif /* not PCM_STYLE_SOUND */ 49356746Sroberto} 49482498Sroberto#else 49582498Srobertoint audio_bs; 496132451Sroberto#endif /* HAVE_{SYS_AUDIOIO,SUN_AUDIOIO,MACHINE_SOUNDCARD,SYS_SOUNDCARD}_H */ 497