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 10 #include "audio.h" 11 #include "ntp_stdlib.h" 12 #include "ntp_syslog.h" 13 #ifdef HAVE_UNISTD_H 14 # include <unistd.h> 15 #endif 16 #include <stdio.h> 17 #include "ntp_string.h" 18 19 #ifdef HAVE_SYS_AUDIOIO_H 20 #include <sys/audioio.h> 21 #endif /* HAVE_SYS_AUDIOIO_H */ 22 23 #ifdef HAVE_SUN_AUDIOIO_H 24 #include <sys/ioccom.h> 25 #include <sun/audioio.h> 26 #endif /* HAVE_SUN_AUDIOIO_H */ 27 28 #ifdef HAVE_SYS_IOCTL_H 29 #include <sys/ioctl.h> 30 #endif /* HAVE_SYS_IOCTL_H */ 31 32 #include <fcntl.h> 33 34 /* 35 * Global variables 36 */ 37 #ifdef HAVE_SYS_AUDIOIO_H 38 static struct audio_device device; /* audio device ident */ 39 #endif /* HAVE_SYS_AUDIOIO_H */ 40 static struct audio_info info; /* audio device info */ 41 static int ctl_fd; /* audio control file descriptor */ 42 43 44 /* 45 * audio_init - open and initialize audio device 46 * 47 * This code works with SunOS 4.x and Solaris 2.x; however, it is 48 * believed generic and applicable to other systems with a minor twid 49 * or two. All it does is open the device, set the buffer size (Solaris 50 * only), preset the gain and set the input port. It assumes that the 51 * codec sample rate (8000 Hz), precision (8 bits), number of channels 52 * (1) and encoding (ITU-T G.711 mu-law companded) have been set by 53 * default. 54 */ 55 int 56 audio_init( 57 char *dname /* device name */ 58 ) 59 { 60 int fd; 61 int rval; 62 63 /* 64 * Open audio device. Do not complain if not there. 65 */ 66 fd = open(dname, O_RDWR | O_NONBLOCK, 0777); 67 if (fd < 0) 68 return (fd); 69 70 /* 71 * Open audio control device. 72 */ 73 ctl_fd = open("/dev/audioctl", O_RDWR); 74 if (ctl_fd < 0) { 75 msyslog(LOG_ERR, "audio: invalid control device\n"); 76 close(fd); 77 return(ctl_fd); 78 } 79 80 /* 81 * Set audio device parameters. 82 */ 83 rval = audio_gain((AUDIO_MAX_GAIN - AUDIO_MIN_GAIN) / 2, 84 AUDIO_MICROPHONE); 85 if (rval < 0) { 86 msyslog(LOG_ERR, "audio: invalid control device parameters\n"); 87 close(ctl_fd); 88 close(fd); 89 return(rval); 90 } 91 return (fd); 92 } 93 94 95 /* 96 * audio_gain - adjust codec gain and port 97 */ 98 int 99 audio_gain( 100 int gain, /* gain 0-255 */ 101 int port /* port */ 102 ) 103 { 104 int rval; 105 106 AUDIO_INITINFO(&info); 107 #ifdef HAVE_SYS_AUDIOIO_H 108 info.record.buffer_size = AUDIO_BUFSIZ; 109 #endif /* HAVE_SYS_AUDIOIO_H */ 110 info.record.gain = gain; 111 info.record.port = port; 112 info.record.error = 0; 113 rval = ioctl(ctl_fd, (int)AUDIO_SETINFO, &info); 114 if (rval < 0) { 115 msyslog(LOG_ERR, "audio_gain: %m"); 116 return (rval); 117 } 118 return (info.record.error); 119 } 120 121 122 /* 123 * audio_show - display audio parameters 124 * 125 * This code doesn't really do anything, except satisfy curiousity and 126 * verify the ioctl's work. 127 */ 128 void 129 audio_show(void) 130 { 131 #ifdef HAVE_SYS_AUDIOIO_H 132 ioctl(ctl_fd, (int)AUDIO_GETDEV, &device); 133 printf("audio: name %s, version %s, config %s\n", 134 device.name, device.version, device.config); 135 #endif /* HAVE_SYS_AUDIOIO_H */ 136 ioctl(ctl_fd, (int)AUDIO_GETINFO, &info); 137 printf( 138 "audio: samples %d, channels %d, precision %d, encoding %d, gain %d, port %d\n", 139 info.record.sample_rate, info.record.channels, 140 info.record.precision, info.record.encoding, 141 info.record.gain, info.record.port); 142 printf( 143 "audio: samples %d, eof %d, pause %d, error %d, waiting %d, balance %d\n", 144 info.record.samples, info.record.eof, 145 info.record.pause, info.record.error, 146 info.record.waiting, info.record.balance); 147 } 148 #else 149 int audio_bs; 150 #endif /* HAVE_SYS_AUDIOIO_H HAVE_SUN_AUDIOIO_H */ 151