add default MSYS filenames for libraries.
[sox/ew.git] / src / sunaudio.c
blobd4cc83c4f02b167c6b69ffd1fceafab9d1635973
1 /* libSoX direct to Sun Audio Driver
3 * Added by Chris Bagwell (cbagwell@sprynet.com) on 2/26/96
4 * Based on oss handler.
6 * Cleaned up changes of format somewhat in sunstartwrite on 03/31/98
8 */
11 * Copyright 1997 Chris Bagwell And Sundry Contributors
12 * This source code is freely redistributable and may be used for
13 * any purpose. This copyright notice must be maintained.
14 * Rick Richardson, Lance Norskog And Sundry Contributors are not
15 * responsible for the consequences of using this software.
18 #include "sox_i.h"
20 #include <sys/ioctl.h>
21 #include <sys/types.h>
22 #ifdef HAVE_SUN_AUDIOIO_H
23 #include <sun/audioio.h>
24 #else
25 #include <sys/audioio.h>
26 #endif
27 #include <errno.h>
28 #if !defined(__NetBSD__) && !defined(__OpenBSD__)
29 #include <stropts.h>
30 #endif
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <string.h>
35 typedef sox_fileinfo_t priv_t;
37 * Do anything required before you start reading samples.
38 * Read file header.
39 * Find out sampling rate,
40 * size and encoding of samples,
41 * mono/stereo/quad.
43 static int sox_sunstartread(sox_format_t * ft)
45 priv_t *file = (priv_t *)ft->priv;
46 size_t samplesize, encoding;
47 audio_info_t audio_if;
48 #ifdef __SVR4
49 audio_device_t audio_dev;
50 #endif
51 char simple_hw=0;
53 lsx_set_signal_defaults(ft);
55 /* Hard-code for now. */
56 file->count = 0;
57 file->pos = 0;
58 file->size = 1024;
59 file->buf = lsx_malloc (file->size);
61 if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN) ft->encoding.encoding = SOX_ENCODING_ULAW;
63 #ifdef __SVR4
64 /* Read in old values, change to what we need and then send back */
65 if (ioctl(fileno(ft->fp), AUDIO_GETDEV, &audio_dev) < 0) {
66 lsx_fail_errno(ft,errno,"Unable to get device information.");
67 return(SOX_EOF);
69 lsx_report("Hardware detected: %s",audio_dev.name);
70 if (strcmp("SUNW,am79c30",audio_dev.name) == 0)
72 simple_hw = 1;
74 #endif
76 /* If simple hardware detected in force data to ulaw. */
77 if (simple_hw)
79 if (ft->encoding.bits_per_sample == 8)
81 if (ft->encoding.encoding != SOX_ENCODING_ULAW &&
82 ft->encoding.encoding != SOX_ENCODING_ALAW)
84 lsx_report("Warning: Detected simple hardware. Forcing output to ULAW");
85 ft->encoding.encoding = SOX_ENCODING_ULAW;
88 else if (ft->encoding.bits_per_sample == 16)
90 lsx_report("Warning: Detected simple hardware. Forcing output to ULAW");
91 ft->encoding.bits_per_sample = 8;
92 ft->encoding.encoding = SOX_ENCODING_ULAW;
96 if (ft->encoding.bits_per_sample == 8) {
97 samplesize = 8;
98 if (ft->encoding.encoding != SOX_ENCODING_ULAW &&
99 ft->encoding.encoding != SOX_ENCODING_ALAW &&
100 ft->encoding.encoding != SOX_ENCODING_SIGN2) {
101 lsx_fail_errno(ft,SOX_EFMT,"Sun audio driver only supports ULAW, ALAW, and signed linear for bytes.");
102 return (SOX_EOF);
104 if ((ft->encoding.encoding == SOX_ENCODING_ULAW ||
105 ft->encoding.encoding == SOX_ENCODING_ALAW) &&
106 ft->signal.channels == 2)
108 lsx_report("Warning: only support mono for ULAW and ALAW data. Forcing to mono.");
109 ft->signal.channels = 1;
112 else if (ft->encoding.bits_per_sample == 16) {
113 samplesize = 16;
114 if (ft->encoding.encoding != SOX_ENCODING_SIGN2) {
115 lsx_fail_errno(ft,SOX_EFMT,"Sun audio driver only supports signed linear for words.");
116 return(SOX_EOF);
119 else {
120 lsx_fail_errno(ft,SOX_EFMT,"Sun audio driver only supports bytes and words");
121 return(SOX_EOF);
124 if (ft->signal.channels == 0) ft->signal.channels = 1;
125 else if (ft->signal.channels > 1) {
126 lsx_report("Warning: some Sun audio devices can not play stereo");
127 lsx_report("at all or sometimes only with signed words. If the");
128 lsx_report("sound seems sluggish then this is probably the case.");
129 lsx_report("Try forcing output to signed words or use the avg");
130 lsx_report("filter to reduce the number of channels.");
131 ft->signal.channels = 2;
134 /* Read in old values, change to what we need and then send back */
135 if (ioctl(fileno(ft->fp), AUDIO_GETINFO, &audio_if) < 0) {
136 lsx_fail_errno(ft,errno,"Unable to initialize /dev/audio");
137 return(SOX_EOF);
139 audio_if.record.precision = samplesize;
140 audio_if.record.channels = ft->signal.channels;
141 audio_if.record.sample_rate = ft->signal.rate;
142 if (ft->encoding.encoding == SOX_ENCODING_ULAW)
143 encoding = AUDIO_ENCODING_ULAW;
144 else if (ft->encoding.encoding == SOX_ENCODING_ALAW)
145 encoding = AUDIO_ENCODING_ALAW;
146 else
147 encoding = AUDIO_ENCODING_LINEAR;
148 audio_if.record.encoding = encoding;
150 ioctl(fileno(ft->fp), AUDIO_SETINFO, &audio_if);
151 if (audio_if.record.precision != samplesize) {
152 lsx_fail_errno(ft,errno,"Unable to initialize sample size for /dev/audio");
153 return(SOX_EOF);
155 if (audio_if.record.channels != ft->signal.channels) {
156 lsx_fail_errno(ft,errno,"Unable to initialize number of channels for /dev/audio");
157 return(SOX_EOF);
159 if (audio_if.record.sample_rate != ft->signal.rate) {
160 lsx_fail_errno(ft,errno,"Unable to initialize rate for /dev/audio");
161 return(SOX_EOF);
163 if (audio_if.record.encoding != encoding) {
164 lsx_fail_errno(ft,errno,"Unable to initialize encoding for /dev/audio");
165 return(SOX_EOF);
167 /* Flush any data in the buffers - its probably in the wrong format */
168 #if defined(__NetBSD__) || defined(__OpenBSD__)
169 ioctl(fileno(ft->fp), AUDIO_FLUSH);
170 #elif defined __GLIBC__
171 ioctl(fileno(ft->fp), (unsigned long int)I_FLUSH, FLUSHR);
172 #else
173 ioctl(fileno(ft->fp), I_FLUSH, FLUSHR);
174 #endif
175 /* Change to non-buffered I/O*/
176 setvbuf(ft->fp, NULL, _IONBF, sizeof(char) * file->size);
178 return (SOX_SUCCESS);
181 static int sox_sunstartwrite(sox_format_t * ft)
183 priv_t *file = (priv_t *)ft->priv;
184 size_t samplesize, encoding;
185 audio_info_t audio_if;
186 #ifdef __SVR4
187 audio_device_t audio_dev;
188 #endif
189 char simple_hw=0;
191 /* Hard-code for now. */
192 file->count = 0;
193 file->pos = 0;
194 file->size = 1024;
195 file->buf = lsx_malloc (file->size);
197 #ifdef __SVR4
198 /* Read in old values, change to what we need and then send back */
199 if (ioctl(fileno(ft->fp), AUDIO_GETDEV, &audio_dev) < 0) {
200 lsx_fail_errno(ft,errno,"Unable to get device information.");
201 return(SOX_EOF);
203 lsx_report("Hardware detected: %s",audio_dev.name);
204 if (strcmp("SUNW,am79c30",audio_dev.name) == 0)
206 simple_hw = 1;
208 #endif
210 if (simple_hw)
212 if (ft->encoding.bits_per_sample == 8)
214 if (ft->encoding.encoding != SOX_ENCODING_ULAW &&
215 ft->encoding.encoding != SOX_ENCODING_ALAW)
217 lsx_report("Warning: Detected simple hardware. Forcing output to ULAW");
218 ft->encoding.encoding = SOX_ENCODING_ULAW;
221 else if (ft->encoding.bits_per_sample == 16)
223 lsx_report("Warning: Detected simple hardware. Forcing output to ULAW");
224 ft->encoding.bits_per_sample = 8;
225 ft->encoding.encoding = SOX_ENCODING_ULAW;
229 if (ft->encoding.bits_per_sample == 8)
231 samplesize = 8;
232 if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
233 ft->encoding.encoding = SOX_ENCODING_ULAW;
234 else if (ft->encoding.encoding != SOX_ENCODING_ULAW &&
235 ft->encoding.encoding != SOX_ENCODING_ALAW &&
236 ft->encoding.encoding != SOX_ENCODING_SIGN2) {
237 lsx_report("Sun Audio driver only supports ULAW, ALAW, and Signed Linear for bytes.");
238 lsx_report("Forcing to ULAW");
239 ft->encoding.encoding = SOX_ENCODING_ULAW;
241 if ((ft->encoding.encoding == SOX_ENCODING_ULAW ||
242 ft->encoding.encoding == SOX_ENCODING_ALAW) &&
243 ft->signal.channels == 2)
245 lsx_report("Warning: only support mono for ULAW and ALAW data. Forcing to mono.");
246 ft->signal.channels = 1;
250 else if (ft->encoding.bits_per_sample == 16) {
251 samplesize = 16;
252 if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
253 ft->encoding.encoding = SOX_ENCODING_SIGN2;
254 else if (ft->encoding.encoding != SOX_ENCODING_SIGN2) {
255 lsx_report("Sun Audio driver only supports Signed Linear for words.");
256 lsx_report("Forcing to Signed Linear");
257 ft->encoding.encoding = SOX_ENCODING_SIGN2;
260 else {
261 lsx_report("Sun Audio driver only supports bytes and words");
262 ft->encoding.bits_per_sample = 16;
263 ft->encoding.encoding = SOX_ENCODING_SIGN2;
264 samplesize = 16;
267 if (ft->signal.channels > 1) ft->signal.channels = 2;
269 /* Read in old values, change to what we need and then send back */
270 if (ioctl(fileno(ft->fp), AUDIO_GETINFO, &audio_if) < 0) {
271 lsx_fail_errno(ft,errno,"Unable to initialize /dev/audio");
272 return(SOX_EOF);
274 audio_if.play.precision = samplesize;
275 audio_if.play.channels = ft->signal.channels;
276 audio_if.play.sample_rate = ft->signal.rate;
277 if (ft->encoding.encoding == SOX_ENCODING_ULAW)
278 encoding = AUDIO_ENCODING_ULAW;
279 else if (ft->encoding.encoding == SOX_ENCODING_ALAW)
280 encoding = AUDIO_ENCODING_ALAW;
281 else
282 encoding = AUDIO_ENCODING_LINEAR;
283 audio_if.play.encoding = encoding;
285 ioctl(fileno(ft->fp), AUDIO_SETINFO, &audio_if);
286 if (audio_if.play.precision != samplesize) {
287 lsx_fail_errno(ft,errno,"Unable to initialize sample size for /dev/audio");
288 return(SOX_EOF);
290 if (audio_if.play.channels != ft->signal.channels) {
291 lsx_fail_errno(ft,errno,"Unable to initialize number of channels for /dev/audio");
292 return(SOX_EOF);
294 if (audio_if.play.sample_rate != ft->signal.rate) {
295 lsx_fail_errno(ft,errno,"Unable to initialize rate for /dev/audio");
296 return(SOX_EOF);
298 if (audio_if.play.encoding != encoding) {
299 lsx_fail_errno(ft,errno,"Unable to initialize encoding for /dev/audio");
300 return(SOX_EOF);
302 /* Change to non-buffered I/O */
303 setvbuf(ft->fp, NULL, _IONBF, sizeof(char) * file->size);
305 return (SOX_SUCCESS);
308 LSX_FORMAT_HANDLER(sunau)
310 static char const * const names[] = {"sunau", NULL};
311 static unsigned const write_encodings[] = {
312 SOX_ENCODING_ULAW, 8, 0,
313 SOX_ENCODING_ALAW, 8, 0,
314 SOX_ENCODING_SIGN2, 8, 16, 0,
316 static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
317 "Sun audio device driver", names, SOX_FILE_DEVICE,
318 sox_sunstartread, lsx_rawread, lsx_rawstopread,
319 sox_sunstartwrite, lsx_rawwrite, lsx_rawstopwrite,
320 NULL, write_encodings, NULL, sizeof(priv_t)
322 return &handler;