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 */ 58310419Sdelphijint audiomonitor = 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 70290000Sglebiusstatic void audio_config_read (int, const char **, const char **); 71290000Sglebiusstatic int mixer_name (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, 117290000Sglebius const char **c_dev, /* Control device */ 118290000Sglebius const char **i_dev /* input device */ 119132451Sroberto ) 120132451Sroberto{ 121132451Sroberto FILE *fd; 122132451Sroberto char device[20], line[100], ab[100]; 123132451Sroberto 124290000Sglebius snprintf(device, sizeof(device), "%s%d", INIT_FILE, unit); 125132451Sroberto if ((fd = fopen(device, "r")) == NULL) { 126132451Sroberto printf("audio_config_read: <%s> NO\n", device); 127290000Sglebius snprintf(device, sizeof(device), "%s.%d", INIT_FILE, 128290000Sglebius unit); 129132451Sroberto if ((fd = fopen(device, "r")) == NULL) { 130132451Sroberto printf("audio_config_read: <%s> NO\n", device); 131290000Sglebius snprintf(device, sizeof(device), "%s", 132290000Sglebius INIT_FILE); 133132451Sroberto if ((fd = fopen(device, "r")) == NULL) { 134290000Sglebius printf("audio_config_read: <%s> NO\n", 135290000Sglebius device); 136132451Sroberto return; 137132451Sroberto } 138132451Sroberto } 139132451Sroberto } 140132451Sroberto printf("audio_config_read: reading <%s>\n", device); 141132451Sroberto while (fgets(line, sizeof line, fd)) { 142132451Sroberto char *cp, *cc, *ca; 143132451Sroberto int i; 144132451Sroberto 145132451Sroberto /* Remove comments */ 146132451Sroberto if ((cp = strchr(line, '#'))) 147132451Sroberto *cp = '\0'; 148132451Sroberto 149132451Sroberto /* Remove any trailing spaces */ 150132451Sroberto for (i = strlen(line); 151290000Sglebius i > 0 && isascii((unsigned char)line[i - 1]) && isspace((unsigned char)line[i - 1]); 152132451Sroberto ) 153132451Sroberto line[--i] = '\0'; 154132451Sroberto 155132451Sroberto /* Remove leading space */ 156290000Sglebius for (cc = line; *cc && isascii((unsigned char)*cc) && isspace((unsigned char)*cc); cc++) 157132451Sroberto continue; 158132451Sroberto 159132451Sroberto /* Stop if nothing left */ 160132451Sroberto if (!*cc) 161132451Sroberto continue; 162132451Sroberto 163132451Sroberto /* Uppercase the command and find the arg */ 164132451Sroberto for (ca = cc; *ca; ca++) { 165290000Sglebius if (isascii((unsigned char)*ca)) { 166290000Sglebius if (islower((unsigned char)*ca)) { 167290000Sglebius *ca = toupper((unsigned char)*ca); 168290000Sglebius } else if (isspace((unsigned char)*ca) || (*ca == '=')) 169132451Sroberto break; 170132451Sroberto } 171132451Sroberto } 172132451Sroberto 173132451Sroberto /* Remove space (and possible =) leading the arg */ 174290000Sglebius for (; *ca && isascii((unsigned char)*ca) && (isspace((unsigned char)*ca) || (*ca == '=')); ca++) 175132451Sroberto continue; 176132451Sroberto 177290000Sglebius if (!strncmp(cc, "IDEV", 4) && 178290000Sglebius 1 == sscanf(ca, "%99s", ab)) { 179290000Sglebius strlcpy(cf_i_dev, ab, sizeof(cf_i_dev)); 180132451Sroberto printf("idev <%s>\n", ab); 181290000Sglebius } else if (!strncmp(cc, "CDEV", 4) && 182290000Sglebius 1 == sscanf(ca, "%99s", ab)) { 183290000Sglebius strlcpy(cf_c_dev, ab, sizeof(cf_c_dev)); 184132451Sroberto printf("cdev <%s>\n", ab); 185290000Sglebius } else if (!strncmp(cc, "AGC", 3) && 186290000Sglebius 1 == sscanf(ca, "%99s", ab)) { 187290000Sglebius strlcpy(cf_agc, ab, sizeof(cf_agc)); 188132451Sroberto printf("agc <%s> %d\n", ab, i); 189290000Sglebius } else if (!strncmp(cc, "MONITOR", 7) && 190290000Sglebius 1 == sscanf(ca, "%99s", ab)) { 191290000Sglebius strlcpy(cf_monitor, ab, sizeof(cf_monitor)); 192132451Sroberto printf("monitor <%s> %d\n", ab, mixer_name(ab, -1)); 193132451Sroberto } 194132451Sroberto } 195132451Sroberto fclose(fd); 196132451Sroberto return; 197132451Sroberto} 198132451Sroberto#endif /* PCM_STYLE_SOUND */ 199132451Sroberto 200132451Sroberto/* 20156746Sroberto * audio_init - open and initialize audio device 20256746Sroberto * 203132451Sroberto * This code works with SunOS 4.x, Solaris 2.x, and PCM; however, it is 20456746Sroberto * believed generic and applicable to other systems with a minor twid 20556746Sroberto * or two. All it does is open the device, set the buffer size (Solaris 20656746Sroberto * only), preset the gain and set the input port. It assumes that the 20756746Sroberto * codec sample rate (8000 Hz), precision (8 bits), number of channels 20856746Sroberto * (1) and encoding (ITU-T G.711 mu-law companded) have been set by 20956746Sroberto * default. 21056746Sroberto */ 21156746Srobertoint 21282498Srobertoaudio_init( 213290000Sglebius const char *dname, /* device name */ 214132451Sroberto int bufsiz, /* buffer size */ 215132451Sroberto int unit /* device unit (0-3) */ 21682498Sroberto ) 21756746Sroberto{ 218132451Sroberto#ifdef PCM_STYLE_SOUND 219132451Sroberto# define ACTL_DEV "/dev/mixer%d" 220132451Sroberto char actl_dev[30]; 221132451Sroberto# ifdef HAVE_STRUCT_SND_SIZE 222132451Sroberto struct snd_size s_size; 223132451Sroberto# endif 224132451Sroberto# ifdef AIOGFMT 225132451Sroberto snd_chan_param s_c_p; 226132451Sroberto# endif 227132451Sroberto#endif 22856746Sroberto int fd; 22956746Sroberto int rval; 230290000Sglebius const char *actl = 231132451Sroberto#ifdef PCM_STYLE_SOUND 232132451Sroberto actl_dev 233132451Sroberto#else 234132451Sroberto "/dev/audioctl" 235132451Sroberto#endif 236132451Sroberto ; 23756746Sroberto 238132451Sroberto#ifdef PCM_STYLE_SOUND 239290000Sglebius snprintf(actl_dev, sizeof(actl_dev), ACTL_DEV, unit); 240132451Sroberto 241132451Sroberto audio_config_read(unit, &actl, &dname); 242132451Sroberto /* If we have values for cf_c_dev or cf_i_dev, use them. */ 243132451Sroberto if (*cf_c_dev) 244182007Sroberto actl = cf_c_dev; 245132451Sroberto if (*cf_i_dev) 246182007Sroberto dname = cf_i_dev; 247132451Sroberto#endif 248132451Sroberto 24956746Sroberto /* 250290000Sglebius * Open audio device 25156746Sroberto */ 25282498Sroberto fd = open(dname, O_RDWR | O_NONBLOCK, 0777); 253290000Sglebius if (fd < 0) { 254290000Sglebius msyslog(LOG_ERR, "audio_init: %s %m", dname); 25556746Sroberto return (fd); 256290000Sglebius } 25756746Sroberto 25856746Sroberto /* 25982498Sroberto * Open audio control device. 26056746Sroberto */ 261132451Sroberto ctl_fd = open(actl, O_RDWR); 26256746Sroberto if (ctl_fd < 0) { 263290000Sglebius msyslog(LOG_ERR, "audio_init: invalid control device <%s>", 264290000Sglebius actl); 26556746Sroberto close(fd); 26656746Sroberto return(ctl_fd); 26756746Sroberto } 26856746Sroberto 26956746Sroberto /* 27056746Sroberto * Set audio device parameters. 27156746Sroberto */ 272132451Sroberto#ifdef PCM_STYLE_SOUND 273132451Sroberto printf("audio_init: <%s> bufsiz %d\n", dname, bufsiz); 274132451Sroberto rval = fd; 275132451Sroberto 276132451Sroberto# ifdef HAVE_STRUCT_SND_SIZE 277132451Sroberto if (ioctl(fd, AIOGSIZE, &s_size) == -1) 278132451Sroberto printf("audio_init: AIOGSIZE: %s\n", strerror(errno)); 279132451Sroberto else 280132451Sroberto printf("audio_init: orig: play_size %d, rec_size %d\n", 281132451Sroberto s_size.play_size, s_size.rec_size); 282132451Sroberto 283132451Sroberto s_size.play_size = s_size.rec_size = bufsiz; 284132451Sroberto printf("audio_init: want: play_size %d, rec_size %d\n", 285132451Sroberto s_size.play_size, s_size.rec_size); 286132451Sroberto 287132451Sroberto if (ioctl(fd, AIOSSIZE, &s_size) == -1) 288132451Sroberto printf("audio_init: AIOSSIZE: %s\n", strerror(errno)); 289132451Sroberto else 290132451Sroberto printf("audio_init: set: play_size %d, rec_size %d\n", 291132451Sroberto s_size.play_size, s_size.rec_size); 292132451Sroberto# endif /* HAVE_STRUCT_SND_SIZE */ 293132451Sroberto 294182007Sroberto# ifdef SNDCTL_DSP_SETFRAGMENT 295182007Sroberto { 296182007Sroberto int tmp = (16 << 16) + 6; /* 16 fragments, each 2^6 bytes */ 297182007Sroberto if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1) 298182007Sroberto printf("audio_init: SNDCTL_DSP_SETFRAGMENT: %s\n", 299182007Sroberto strerror(errno)); 300182007Sroberto } 301182007Sroberto# endif /* SNDCTL_DSP_SETFRAGMENT */ 302182007Sroberto 303132451Sroberto# ifdef AIOGFMT 304132451Sroberto if (ioctl(fd, AIOGFMT, &s_c_p) == -1) 305132451Sroberto printf("audio_init: AIOGFMT: %s\n", strerror(errno)); 306132451Sroberto else 307132451Sroberto printf("audio_init: play_rate %lu, rec_rate %lu, play_format %#lx, rec_format %#lx\n", 308132451Sroberto s_c_p.play_rate, s_c_p.rec_rate, s_c_p.play_format, s_c_p.rec_format); 309132451Sroberto# endif 310132451Sroberto 311132451Sroberto /* Grab the device and record masks */ 312132451Sroberto 313132451Sroberto if (ioctl(ctl_fd, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) 314132451Sroberto printf("SOUND_MIXER_READ_DEVMASK: %s\n", strerror(errno)); 315132451Sroberto if (ioctl(ctl_fd, SOUND_MIXER_READ_RECMASK, &recmask) == -1) 316132451Sroberto printf("SOUND_MIXER_READ_RECMASK: %s\n", strerror(errno)); 317132451Sroberto 318132451Sroberto /* validate and set any specified config file stuff */ 319290000Sglebius if (cf_agc[0] != '\0') { 320132451Sroberto int i; 321132451Sroberto 322290000Sglebius /* recmask */ 323290000Sglebius i = mixer_name(cf_agc, recmask); 324132451Sroberto if (i >= 0) 325132451Sroberto agc = MIXER_WRITE(i); 326132451Sroberto else 327132451Sroberto printf("input %s not in recmask %#x\n", 328132451Sroberto cf_agc, recmask); 329132451Sroberto } 330132451Sroberto 331290000Sglebius if (cf_monitor[0] != '\0') { 332132451Sroberto int i; 333132451Sroberto 334132451Sroberto /* devmask */ 335132451Sroberto i = mixer_name(cf_monitor, devmask); 336132451Sroberto if (i >= 0) 337310419Sdelphij audiomonitor = MIXER_WRITE(i); 338132451Sroberto else 339132451Sroberto printf("monitor %s not in devmask %#x\n", 340132451Sroberto cf_monitor, devmask); 341132451Sroberto } 342132451Sroberto 343132451Sroberto#else /* not PCM_STYLE_SOUND */ 344132451Sroberto AUDIO_INITINFO(&info); 345132451Sroberto info.play.gain = AUDIO_MAX_GAIN; 346132451Sroberto info.play.port = AUDIO_SPEAKER; 347132451Sroberto# ifdef HAVE_SYS_AUDIOIO_H 348132451Sroberto info.record.buffer_size = bufsiz; 349132451Sroberto# endif /* HAVE_SYS_AUDIOIO_H */ 350132451Sroberto rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, (char *)&info); 35156746Sroberto if (rval < 0) { 352290000Sglebius msyslog(LOG_ERR, "audio: invalid control device parameters"); 35356746Sroberto close(ctl_fd); 35456746Sroberto close(fd); 35556746Sroberto return(rval); 35656746Sroberto } 357132451Sroberto rval = fd; 358132451Sroberto#endif /* not PCM_STYLE_SOUND */ 359132451Sroberto return (rval); 36056746Sroberto} 36156746Sroberto 36256746Sroberto 36356746Sroberto/* 364132451Sroberto * audio_gain - adjust codec gains and port 36556746Sroberto */ 36656746Srobertoint 36756746Srobertoaudio_gain( 368132451Sroberto int gain, /* volume level (gain) 0-255 */ 369132451Sroberto int mongain, /* input to output mix (monitor gain) 0-255 */ 370132451Sroberto int port /* selected I/O port: 1 mic/2 line in */ 37156746Sroberto ) 37256746Sroberto{ 37356746Sroberto int rval; 374132451Sroberto static int o_mongain = -1; 375132451Sroberto static int o_port = -1; 37656746Sroberto 377132451Sroberto#ifdef PCM_STYLE_SOUND 378132451Sroberto int l, r; 379132451Sroberto 380290000Sglebius# ifdef GCC 381290000Sglebius rval = 0; /* GCC thinks rval is used uninitialized */ 382290000Sglebius# endif 383132451Sroberto 384132451Sroberto r = l = 100 * gain / 255; /* Normalize to 0-100 */ 385132451Sroberto# ifdef DEBUG 386132451Sroberto if (debug > 1) 387132451Sroberto printf("audio_gain: gain %d/%d\n", gain, l); 388132451Sroberto# endif 389290000Sglebius#if 0 /* not a good idea to do this; connector wiring dependency */ 390132451Sroberto /* figure out what channel(s) to use. just nuke right for now. */ 391132451Sroberto r = 0 ; /* setting to zero nicely mutes the channel */ 392290000Sglebius#endif 393132451Sroberto l |= r << 8; 394290000Sglebius if (cf_agc[0] != '\0') 395290000Sglebius rval = ioctl(ctl_fd, agc, &l); 396290000Sglebius else 397290000Sglebius rval = ioctl(ctl_fd 398290000Sglebius , (2 == port) 399290000Sglebius ? SOUND_MIXER_WRITE_LINE 400290000Sglebius : SOUND_MIXER_WRITE_MIC 401290000Sglebius , &l); 402290000Sglebius if (-1 == rval) { 403132451Sroberto printf("audio_gain: agc write: %s\n", strerror(errno)); 404290000Sglebius return rval; 405132451Sroberto } 406132451Sroberto 407132451Sroberto if (o_mongain != mongain) { 408132451Sroberto r = l = 100 * mongain / 255; /* Normalize to 0-100 */ 409132451Sroberto# ifdef DEBUG 410132451Sroberto if (debug > 1) 411132451Sroberto printf("audio_gain: mongain %d/%d\n", mongain, l); 412132451Sroberto# endif 413132451Sroberto l |= r << 8; 414290000Sglebius if (cf_monitor[0] != '\0') 415310419Sdelphij rval = ioctl(ctl_fd, audiomonitor, &l ); 416290000Sglebius else 417290000Sglebius rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_VOLUME, 418290000Sglebius &l); 419290000Sglebius if (-1 == rval) { 420132451Sroberto printf("audio_gain: mongain write: %s\n", 421132451Sroberto strerror(errno)); 422132451Sroberto return (rval); 423132451Sroberto } 424132451Sroberto o_mongain = mongain; 425132451Sroberto } 426132451Sroberto 427132451Sroberto if (o_port != port) { 428132451Sroberto# ifdef DEBUG 429132451Sroberto if (debug > 1) 430132451Sroberto printf("audio_gain: port %d\n", port); 431132451Sroberto# endif 432132451Sroberto l = (1 << ((port == 2) ? SOUND_MIXER_LINE : SOUND_MIXER_MIC)); 433132451Sroberto rval = ioctl(ctl_fd, SOUND_MIXER_WRITE_RECSRC, &l); 434132451Sroberto if (rval == -1) { 435132451Sroberto printf("SOUND_MIXER_WRITE_RECSRC: %s\n", 436132451Sroberto strerror(errno)); 437132451Sroberto return (rval); 438132451Sroberto } 439132451Sroberto# ifdef DEBUG 440132451Sroberto if (debug > 1) { 441132451Sroberto if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &l) == -1) 442132451Sroberto printf("SOUND_MIXER_WRITE_RECSRC: %s\n", 443132451Sroberto strerror(errno)); 444132451Sroberto else 445132451Sroberto printf("audio_gain: recsrc is %d\n", l); 446132451Sroberto } 447132451Sroberto# endif 448132451Sroberto o_port = port; 449132451Sroberto } 450132451Sroberto#else /* not PCM_STYLE_SOUND */ 451132451Sroberto ioctl(ctl_fd, (int)AUDIO_GETINFO, (char *)&info); 452132451Sroberto info.record.encoding = AUDIO_ENCODING_ULAW; 453132451Sroberto info.record.error = 0; 45456746Sroberto info.record.gain = gain; 455132451Sroberto if (o_mongain != mongain) 456132451Sroberto o_mongain = info.monitor_gain = mongain; 457132451Sroberto if (o_port != port) 458132451Sroberto o_port = info.record.port = port; 459132451Sroberto rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, (char *)&info); 46056746Sroberto if (rval < 0) { 46182498Sroberto msyslog(LOG_ERR, "audio_gain: %m"); 46256746Sroberto return (rval); 46356746Sroberto } 464132451Sroberto rval = info.record.error; 465132451Sroberto#endif /* not PCM_STYLE_SOUND */ 466132451Sroberto return (rval); 46756746Sroberto} 46856746Sroberto 46956746Sroberto 47056746Sroberto/* 47156746Sroberto * audio_show - display audio parameters 47256746Sroberto * 47356746Sroberto * This code doesn't really do anything, except satisfy curiousity and 47456746Sroberto * verify the ioctl's work. 47556746Sroberto */ 47656746Srobertovoid 47756746Srobertoaudio_show(void) 47856746Sroberto{ 479132451Sroberto#ifdef PCM_STYLE_SOUND 480132451Sroberto int recsrc = 0; 481132451Sroberto 482132451Sroberto printf("audio_show: ctl_fd %d\n", ctl_fd); 483132451Sroberto if (ioctl(ctl_fd, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) 484132451Sroberto printf("SOUND_MIXER_READ_RECSRC: %s\n", strerror(errno)); 485132451Sroberto 486132451Sroberto#else /* not PCM_STYLE_SOUND */ 487132451Sroberto# ifdef HAVE_SYS_AUDIOIO_H 48856746Sroberto ioctl(ctl_fd, (int)AUDIO_GETDEV, &device); 48956746Sroberto printf("audio: name %s, version %s, config %s\n", 49056746Sroberto device.name, device.version, device.config); 491132451Sroberto# endif /* HAVE_SYS_AUDIOIO_H */ 492132451Sroberto ioctl(ctl_fd, (int)AUDIO_GETINFO, (char *)&info); 49356746Sroberto printf( 494132451Sroberto "audio: rate %d, chan %d, prec %d, code %d, gain %d, mon %d, port %d\n", 49556746Sroberto info.record.sample_rate, info.record.channels, 49682498Sroberto info.record.precision, info.record.encoding, 497132451Sroberto info.record.gain, info.monitor_gain, info.record.port); 49856746Sroberto printf( 49956746Sroberto "audio: samples %d, eof %d, pause %d, error %d, waiting %d, balance %d\n", 50056746Sroberto info.record.samples, info.record.eof, 50156746Sroberto info.record.pause, info.record.error, 50256746Sroberto info.record.waiting, info.record.balance); 503132451Sroberto#endif /* not PCM_STYLE_SOUND */ 50456746Sroberto} 50582498Sroberto#else 50682498Srobertoint audio_bs; 507132451Sroberto#endif /* HAVE_{SYS_AUDIOIO,SUN_AUDIOIO,MACHINE_SOUNDCARD,SYS_SOUNDCARD}_H */ 508