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