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