1 /* $NetBSD: audio.c,v 1.18 2004/10/30 16:57:27 dsl Exp $ */
4 * Copyright (c) 1999 Matthew R. Green
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * XXX this is slightly icky in places...
32 #include <sys/cdefs.h>
35 __RCSID("$NetBSD: audio.c,v 1.18 2004/10/30 16:57:27 dsl Exp $");
39 #include <sys/types.h>
40 #include <sys/audioio.h>
41 #include <sys/ioctl.h>
52 /* what format am i? */
58 { "sunau", AUDIO_FORMAT_SUN
},
59 { "au", AUDIO_FORMAT_SUN
},
60 { "sun", AUDIO_FORMAT_SUN
},
61 { "wav", AUDIO_FORMAT_WAV
},
62 { "wave", AUDIO_FORMAT_WAV
},
63 { "riff", AUDIO_FORMAT_WAV
},
64 { "no", AUDIO_FORMAT_NONE
},
65 { "none", AUDIO_FORMAT_NONE
},
70 audio_format_from_str(str
)
75 for (i
= 0; formats
[i
].fname
; i
++)
76 if (strcasecmp(formats
[i
].fname
, str
) == 0)
78 return (formats
[i
].fno
);
83 /* back and forth between encodings */
88 { AudioEmulaw
, AUDIO_ENCODING_ULAW
},
89 { "ulaw", AUDIO_ENCODING_ULAW
},
90 { AudioEalaw
, AUDIO_ENCODING_ALAW
},
91 { AudioEslinear
, AUDIO_ENCODING_SLINEAR
},
92 { "linear", AUDIO_ENCODING_SLINEAR
},
93 { AudioEulinear
, AUDIO_ENCODING_ULINEAR
},
94 { AudioEadpcm
, AUDIO_ENCODING_ADPCM
},
95 { "ADPCM", AUDIO_ENCODING_ADPCM
},
96 { AudioEslinear_le
, AUDIO_ENCODING_SLINEAR_LE
},
97 { "linear_le", AUDIO_ENCODING_SLINEAR_LE
},
98 { AudioEulinear_le
, AUDIO_ENCODING_ULINEAR_LE
},
99 { AudioEslinear_be
, AUDIO_ENCODING_SLINEAR_BE
},
100 { "linear_be", AUDIO_ENCODING_SLINEAR_BE
},
101 { AudioEulinear_be
, AUDIO_ENCODING_ULINEAR_BE
},
102 { AudioEmpeg_l1_stream
, AUDIO_ENCODING_MPEG_L1_STREAM
},
103 { AudioEmpeg_l1_packets
,AUDIO_ENCODING_MPEG_L1_PACKETS
},
104 { AudioEmpeg_l1_system
, AUDIO_ENCODING_MPEG_L1_SYSTEM
},
105 { AudioEmpeg_l2_stream
, AUDIO_ENCODING_MPEG_L2_STREAM
},
106 { AudioEmpeg_l2_packets
,AUDIO_ENCODING_MPEG_L2_PACKETS
},
107 { AudioEmpeg_l2_system
, AUDIO_ENCODING_MPEG_L2_SYSTEM
},
113 audio_enc_from_val(val
)
118 for (i
= 0; encs
[i
].ename
; i
++)
119 if (encs
[i
].eno
== val
)
121 return (encs
[i
].ename
);
125 audio_enc_to_val(enc
)
130 for (i
= 0; encs
[i
].ename
; i
++)
131 if (strcmp(encs
[i
].ename
, enc
) == 0)
134 return (encs
[i
].eno
);
136 return (AUDIO_ENOENT
);
140 decode_int(arg
, intp
)
147 ret
= (int)strtoul(arg
, &ep
, 10);
153 errx(1, "argument `%s' not a valid integer", arg
);
157 decode_time(arg
, tvp
)
161 char *s
, *colon
, *dot
;
162 char *copy
= strdup(arg
);
166 err(1, "could not allocate a copy of %s", arg
);
168 tvp
->tv_sec
= tvp
->tv_usec
= 0;
171 /* handle [hh:]mm:ss.dd */
172 if ((colon
= strchr(s
, ':')) != NULL
) {
174 decode_int(s
, &first
);
175 tvp
->tv_sec
= first
* 60; /* minutes */
178 if ((colon
= strchr(s
, ':')) != NULL
) {
180 decode_int(s
, &first
);
181 tvp
->tv_sec
+= first
; /* minutes and hours */
186 if ((dot
= strchr(s
, '.')) != NULL
) {
187 int i
, base
= 100000;
191 for (i
= 0; i
< 6; i
++, base
/= 10) {
194 if (!isdigit((unsigned char)dot
[i
]))
195 errx(1, "argument `%s' is not a value time specification", arg
);
196 tvp
->tv_usec
+= base
* (dot
[i
] - '0');
199 decode_int(s
, &first
);
200 tvp
->tv_sec
+= first
;
206 * decode a string into an encoding value.
209 decode_encoding(arg
, encp
)
217 for (i
= 0; encs
[i
].ename
; i
++)
218 if (strncmp(encs
[i
].ename
, arg
, len
) == 0) {
222 errx(1, "unknown encoding `%s'", arg
);
225 const char *const audio_errlist
[] = {
226 "error zero", /* nothing? */
227 "no audio entry", /* AUDIO_ENOENT */
228 "short header", /* AUDIO_ESHORTHDR */
229 "unsupported WAV format", /* AUDIO_EWAVUNSUPP */
230 "bad (unsupported) WAV PCM format", /* AUDIO_EWAVBADPCM */
231 "no WAV audio data", /* AUDIO_EWAVNODATA */
232 "internal error", /* AUDIO_EINTERNAL */
236 audio_errstring(errval
)
241 if (errval
< 1 || errval
> AUDIO_MAXERRNO
)
242 return "Invalid error";
243 return audio_errlist
[errval
];