xref: /freebsd/contrib/ntp/libntp/audio.c (revision 2357939bc239bd5334a169b62313806178dd8f30)
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