Tue Jun 23 06:53:37 2009 UTC ()
Pull up following revision(s) (requested by mrg in ticket #825):
	usr.bin/audio/common/libaudio.h: revision 1.16
	usr.bin/audio/common/wav.c: revision 1.9
- - add extended WAVE header support
- - attempt to play a bunch more WAV files


(snj)
diff -r1.15 -r1.15.4.1 src/usr.bin/audio/common/libaudio.h
diff -r1.8 -r1.8.4.1 src/usr.bin/audio/common/wav.c

cvs diff -r1.15 -r1.15.4.1 src/usr.bin/audio/common/libaudio.h (switch to unified diff)

--- src/usr.bin/audio/common/libaudio.h 2008/05/29 14:51:27 1.15
+++ src/usr.bin/audio/common/libaudio.h 2009/06/23 06:53:36 1.15.4.1
@@ -1,195 +1,215 @@ @@ -1,195 +1,215 @@
1/* $NetBSD: libaudio.h,v 1.15 2008/05/29 14:51:27 mrg Exp $ */ 1/* $NetBSD: libaudio.h,v 1.15.4.1 2009/06/23 06:53:36 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999 Matthew R. Green 4 * Copyright (c) 1999, 2009 Matthew R. Green
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 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 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * audio formats 30 * audio formats
31 */ 31 */
32#define AUDIO_FORMAT_DEFAULT -1 32#define AUDIO_FORMAT_DEFAULT -1
33#define AUDIO_FORMAT_NONE 1 33#define AUDIO_FORMAT_NONE 1
34#define AUDIO_FORMAT_SUN 2 34#define AUDIO_FORMAT_SUN 2
35#define AUDIO_FORMAT_WAV 3 35#define AUDIO_FORMAT_WAV 3
36 36
37int audio_format_from_str (char *); 37int audio_format_from_str (char *);
38 38
39/* 39/*
40 * We copy the Sun/NeXT on-disk audio header format and document what 40 * We copy the Sun/NeXT on-disk audio header format and document what
41 * we know of it here. 41 * we know of it here.
42 * 42 *
43 * The header size appears to be an offset to where the data really 43 * The header size appears to be an offset to where the data really
44 * begins, rather than defining the real length of the audio header. 44 * begins, rather than defining the real length of the audio header.
45 * The Sun/NeXT audio format seems to only use 24 bytes of data (with 45 * The Sun/NeXT audio format seems to only use 24 bytes of data (with
46 * an additional 8 bytes of nuls written, padding it to 32 bytes). 46 * an additional 8 bytes of nuls written, padding it to 32 bytes).
47 * 47 *
48 * If the size of the audio data is unknown (eg, reading from a pipe) 48 * If the size of the audio data is unknown (eg, reading from a pipe)
49 * the Sun demo audio tools place AUDIO_UNKNOWN_SIZE in the 49 * the Sun demo audio tools place AUDIO_UNKNOWN_SIZE in the
50 * `data_size' member. 50 * `data_size' member.
51 * 51 *
52 * For stereo data, the channels appear to be interleaved with the 52 * For stereo data, the channels appear to be interleaved with the
53 * left channel first. For more channels, who knows? 53 * left channel first. For more channels, who knows?
54 */ 54 */
55 55
56/* 56/*
57 * This is the Sun/NeXT audio file magic value. Note that it 57 * This is the Sun/NeXT audio file magic value. Note that it
58 * is also `.snd' in ASCII. 58 * is also `.snd' in ASCII.
59 */ 59 */
60#define AUDIO_FILE_MAGIC ((u_int32_t)0x2e736e64) 60#define AUDIO_FILE_MAGIC ((u_int32_t)0x2e736e64)
61#define AUDIO_UNKNOWN_SIZE ((unsigned)(~0)) 61#define AUDIO_UNKNOWN_SIZE ((unsigned)(~0))
62 62
63typedef struct { 63typedef struct {
64 u_int32_t magic; 64 u_int32_t magic;
65 u_int32_t hdr_size; /* header size; in bytes */ 65 u_int32_t hdr_size; /* header size; in bytes */
66 u_int32_t data_size; /* optional; in bytes */ 66 u_int32_t data_size; /* optional; in bytes */
67 u_int32_t encoding; /* see below */ 67 u_int32_t encoding; /* see below */
68 u_int32_t sample_rate; /* per second */ 68 u_int32_t sample_rate; /* per second */
69 u_int32_t channels; /* number of interleaved channels */ 69 u_int32_t channels; /* number of interleaved channels */
70} sun_audioheader; 70} sun_audioheader;
71 71
72#define Audio_filehdr sun_audioheader /* SunOS compat(?) */ 72#define Audio_filehdr sun_audioheader /* SunOS compat(?) */
73 73
74/* 74/*
75 * these are the types of "encoding" for above. taken from the 75 * these are the types of "encoding" for above. taken from the
76 * SunOS <multimedia/audio_filehdr.h>. 76 * SunOS <multimedia/audio_filehdr.h>.
77 */ 77 */
78#define AUDIO_FILE_ENCODING_MULAW_8 1 78#define AUDIO_FILE_ENCODING_MULAW_8 1
79#define AUDIO_FILE_ENCODING_LINEAR_8 2 79#define AUDIO_FILE_ENCODING_LINEAR_8 2
80#define AUDIO_FILE_ENCODING_LINEAR_16 3 80#define AUDIO_FILE_ENCODING_LINEAR_16 3
81#define AUDIO_FILE_ENCODING_LINEAR_24 4 81#define AUDIO_FILE_ENCODING_LINEAR_24 4
82#define AUDIO_FILE_ENCODING_LINEAR_32 5 82#define AUDIO_FILE_ENCODING_LINEAR_32 5
83#define AUDIO_FILE_ENCODING_FLOAT 6 83#define AUDIO_FILE_ENCODING_FLOAT 6
84#define AUDIO_FILE_ENCODING_DOUBLE 7 84#define AUDIO_FILE_ENCODING_DOUBLE 7
85#define AUDIO_FILE_ENCODING_ADPCM_G721 23 85#define AUDIO_FILE_ENCODING_ADPCM_G721 23
86#define AUDIO_FILE_ENCODING_ADPCM_G722 24 86#define AUDIO_FILE_ENCODING_ADPCM_G722 24
87#define AUDIO_FILE_ENCODING_ADPCM_G723_3 25 87#define AUDIO_FILE_ENCODING_ADPCM_G723_3 25
88#define AUDIO_FILE_ENCODING_ADPCM_G723_5 26 88#define AUDIO_FILE_ENCODING_ADPCM_G723_5 26
89#define AUDIO_FILE_ENCODING_ALAW_8 27 89#define AUDIO_FILE_ENCODING_ALAW_8 27
90 90
91const char *audio_enc_from_val (int); 91const char *audio_enc_from_val (int);
92int audio_enc_to_val (const char *); 92int audio_enc_to_val (const char *);
93 93
94int audio_sun_to_encoding (int, u_int *, u_int *); 94int audio_sun_to_encoding (int, u_int *, u_int *);
95int audio_encoding_to_sun (int, int, int *); 95int audio_encoding_to_sun (int, int, int *);
96 96
97/* 97/*
98 * M$ WAV files, info gleamed from sox sources 98 * M$ WAV files, info gleamed from sox sources
99 */ 99 */
100 100
101/* 101/*
102 * This is the WAV audio file magic value. Note that it 102 * This is the WAV audio file magic value. Note that it
103 * is also `RIFF' and `WAVE' in ASCII. 103 * is also `RIFF' and `WAVE' in ASCII.
104 */ 104 */
105#define WAVAUDIO_FILE_MAGIC_RIFF ((u_int32_t)0x52494646) 105#define WAVAUDIO_FILE_MAGIC_RIFF ((u_int32_t)0x52494646)
106#define WAVAUDIO_FILE_MAGIC_WAVE ((u_int32_t)0x57415645) 106#define WAVAUDIO_FILE_MAGIC_WAVE ((u_int32_t)0x57415645)
107#define WAVAUDIO_FILE_MAGIC_FMT ((u_int32_t)0x666d7420) 107#define WAVAUDIO_FILE_MAGIC_FMT ((u_int32_t)0x666d7420)
108#define WAVAUDIO_FILE_MAGIC_DATA ((u_int32_t)0x64617461) 108#define WAVAUDIO_FILE_MAGIC_DATA ((u_int32_t)0x64617461)
109 109
110/* purloined from public Microsoft RIFF docs via sox */ 110/* purloined from public Microsoft RIFF docs via sox or mplayer */
111#define WAVE_FORMAT_UNKNOWN (0x0000) 111#define WAVE_FORMAT_UNKNOWN (0x0000)
112#define WAVE_FORMAT_PCM (0x0001) 112#define WAVE_FORMAT_PCM (0x0001)
113#define WAVE_FORMAT_ADPCM (0x0002) 113#define WAVE_FORMAT_ADPCM (0x0002)
114#define WAVE_FORMAT_ALAW (0x0006) 114#define WAVE_FORMAT_ALAW (0x0006)
115#define WAVE_FORMAT_MULAW (0x0007) 115#define WAVE_FORMAT_MULAW (0x0007)
116#define WAVE_FORMAT_OKI_ADPCM (0x0010) 116#define WAVE_FORMAT_OKI_ADPCM (0x0010)
 117#define WAVE_FORMAT_IMA_ADPCM (0x0011)
117#define WAVE_FORMAT_DIGISTD (0x0015) 118#define WAVE_FORMAT_DIGISTD (0x0015)
118#define WAVE_FORMAT_DIGIFIX (0x0016) 119#define WAVE_FORMAT_DIGIFIX (0x0016)
 120#define WAVE_FORMAT_DOLBY_AC2 (0x0030)
 121#define WAVE_FORMAT_GSM610 (0x0031)
 122#define WAVE_FORMAT_ROCKWELL_ADPCM (0x003b)
 123#define WAVE_FORMAT_ROCKWELL_DIGITALK (0x003c)
 124#define WAVE_FORMAT_G721_ADPCM (0x0040)
 125#define WAVE_FORMAT_G728_CELP (0x0041)
 126#define WAVE_FORMAT_MPEG (0x0050)
 127#define WAVE_FORMAT_MPEGLAYER3 (0x0055)
 128#define WAVE_FORMAT_G726_ADPCM (0x0064)
 129#define WAVE_FORMAT_G722_ADPCM (0x0065)
119#define IBM_FORMAT_MULAW (0x0101) 130#define IBM_FORMAT_MULAW (0x0101)
120#define IBM_FORMAT_ALAW (0x0102) 131#define IBM_FORMAT_ALAW (0x0102)
121#define IBM_FORMAT_ADPCM (0x0103) 132#define IBM_FORMAT_ADPCM (0x0103)
 133#define WAVE_FORMAT_EXTENSIBLE (0xfffe)
122 134
123const char *wav_enc_from_val (int); 135const char *wav_enc_from_val (int);
124 136
125typedef struct { 137typedef struct {
126 char name[4]; 138 char name[4];
127 u_int32_t len; 139 u_int32_t len;
128} wav_audioheaderpart; 140} wav_audioheaderpart;
129 141
130typedef struct { 142typedef struct {
131 u_int16_t tag; 143 u_int16_t tag;
132 u_int16_t channels; 144 u_int16_t channels;
133 u_int32_t sample_rate; 145 u_int32_t sample_rate;
134 u_int32_t avg_bps; 146 u_int32_t avg_bps;
135 u_int16_t alignment; 147 u_int16_t alignment;
136 u_int16_t bits_per_sample; 148 u_int16_t bits_per_sample;
137} __packed wav_audioheaderfmt; 149} __packed wav_audioheaderfmt;
138 150
 151typedef struct {
 152 u_int16_t len;
 153 u_int16_t valid_bits;
 154 u_int32_t speaker_pos_mask;
 155 u_int16_t sub_tag;
 156 u_int8_t dummy[14];
 157} __packed wav_audiohdrextensible;
 158
139/* returns size of header, or -ve for failure */ 159/* returns size of header, or -ve for failure */
140ssize_t audio_wav_parse_hdr (void *, size_t, u_int *, u_int *, u_int *, u_int *, size_t *); 160ssize_t audio_wav_parse_hdr (void *, size_t, u_int *, u_int *, u_int *, u_int *, size_t *);
141 161
142/* 162/*
143 * audio routine error codes 163 * audio routine error codes
144 */ 164 */
145#define AUDIO_ENOENT -1 /* no such audio format */ 165#define AUDIO_ENOENT -1 /* no such audio format */
146#define AUDIO_ESHORTHDR -2 /* short header */ 166#define AUDIO_ESHORTHDR -2 /* short header */
147#define AUDIO_EWAVUNSUPP -3 /* WAV: unsupported file */ 167#define AUDIO_EWAVUNSUPP -3 /* WAV: unsupported file */
148#define AUDIO_EWAVBADPCM -4 /* WAV: bad PCM bps */ 168#define AUDIO_EWAVBADPCM -4 /* WAV: bad PCM bps */
149#define AUDIO_EWAVNODATA -5 /* WAV: missing data */ 169#define AUDIO_EWAVNODATA -5 /* WAV: missing data */
150#define AUDIO_EINTERNAL -6 /* internal error */ 170#define AUDIO_EINTERNAL -6 /* internal error */
151 171
152#define AUDIO_MAXERRNO 5 172#define AUDIO_MAXERRNO 5
153 173
154/* and something to get a string associated with this error */ 174/* and something to get a string associated with this error */
155const char *audio_errstring (int); 175const char *audio_errstring (int);
156 176
157/* 177/*
158 * generic routines? 178 * generic routines?
159 */ 179 */
160void decode_int (const char *, int *); 180void decode_int (const char *, int *);
161void decode_time (const char *, struct timeval *); 181void decode_time (const char *, struct timeval *);
162void decode_encoding (const char *, int *); 182void decode_encoding (const char *, int *);
163 183
164/* 184/*
165 * get/put 16/32 bits of big/little endian data 185 * get/put 16/32 bits of big/little endian data
166 */ 186 */
167#include <sys/types.h> 187#include <sys/types.h>
168#include <machine/endian.h> 188#include <machine/endian.h>
169#include <machine/bswap.h> 189#include <machine/bswap.h>
170 190
171#if BYTE_ORDER == BIG_ENDIAN 191#if BYTE_ORDER == BIG_ENDIAN
172 192
173#define getle16(v) bswap16(v) 193#define getle16(v) bswap16(v)
174#define getle32(v) bswap32(v) 194#define getle32(v) bswap32(v)
175#define getbe16(v) (v) 195#define getbe16(v) (v)
176#define getbe32(v) (v) 196#define getbe32(v) (v)
177 197
178#define putle16(x,v) (x) = bswap16(v) 198#define putle16(x,v) (x) = bswap16(v)
179#define putle32(x,v) (x) = bswap32(v) 199#define putle32(x,v) (x) = bswap32(v)
180#define putbe16(x,v) (x) = (v) 200#define putbe16(x,v) (x) = (v)
181#define putbe32(x,v) (x) = (v) 201#define putbe32(x,v) (x) = (v)
182 202
183#else 203#else
184 204
185#define getle16(v) (v) 205#define getle16(v) (v)
186#define getle32(v) (v) 206#define getle32(v) (v)
187#define getbe16(v) bswap16(v) 207#define getbe16(v) bswap16(v)
188#define getbe32(v) bswap32(v) 208#define getbe32(v) bswap32(v)
189 209
190#define putle16(x,v) (x) = (v) 210#define putle16(x,v) (x) = (v)
191#define putle32(x,v) (x) = (v) 211#define putle32(x,v) (x) = (v)
192#define putbe16(x,v) (x) = bswap16(v) 212#define putbe16(x,v) (x) = bswap16(v)
193#define putbe32(x,v) (x) = bswap32(v) 213#define putbe32(x,v) (x) = bswap32(v)
194 214
195#endif 215#endif

cvs diff -r1.8 -r1.8.4.1 src/usr.bin/audio/common/wav.c (switch to unified diff)

--- src/usr.bin/audio/common/wav.c 2008/05/29 14:51:27 1.8
+++ src/usr.bin/audio/common/wav.c 2009/06/23 06:53:36 1.8.4.1
@@ -1,198 +1,219 @@ @@ -1,198 +1,219 @@
1/* $NetBSD: wav.c,v 1.8 2008/05/29 14:51:27 mrg Exp $ */ 1/* $NetBSD: wav.c,v 1.8.4.1 2009/06/23 06:53:36 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2002 Matthew R. Green 4 * Copyright (c) 2002, 2009 Matthew R. Green
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 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 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * WAV support for the audio tools; thanks go to the sox utility for 30 * WAV support for the audio tools; thanks go to the sox utility for
31 * clearing up issues with WAV files. 31 * clearing up issues with WAV files.
32 */ 32 */
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34 34
35#ifndef lint 35#ifndef lint
36__RCSID("$NetBSD: wav.c,v 1.8 2008/05/29 14:51:27 mrg Exp $"); 36__RCSID("$NetBSD: wav.c,v 1.8.4.1 2009/06/23 06:53:36 snj Exp $");
37#endif 37#endif
38 38
39 39
40#include <sys/types.h> 40#include <sys/types.h>
41#include <sys/audioio.h> 41#include <sys/audioio.h>
42#include <sys/ioctl.h> 42#include <sys/ioctl.h>
43#include <sys/time.h> 43#include <sys/time.h>
44 44
45#include <ctype.h> 45#include <ctype.h>
46#include <err.h> 46#include <err.h>
47#include <stdio.h> 47#include <stdio.h>
48#include <stdlib.h> 48#include <stdlib.h>
49#include <string.h> 49#include <string.h>
 50#include <stdint.h>
50 51
51#include "libaudio.h" 52#include "libaudio.h"
52 53
53struct { 54struct {
54 int wenc; 55 int wenc;
55 const char *wname; 56 const char *wname;
56} wavencs[] = { 57} wavencs[] = {
57 { WAVE_FORMAT_UNKNOWN, "Microsoft Official Unknown" }, 58 { WAVE_FORMAT_UNKNOWN, "Microsoft Official Unknown" },
58 { WAVE_FORMAT_PCM, "Microsoft PCM" }, 59 { WAVE_FORMAT_PCM, "Microsoft PCM" },
59 { WAVE_FORMAT_ADPCM, "Microsoft ADPCM" }, 60 { WAVE_FORMAT_ADPCM, "Microsoft ADPCM" },
60 { WAVE_FORMAT_ALAW, "Microsoft A-law" }, 61 { WAVE_FORMAT_ALAW, "Microsoft A-law" },
61 { WAVE_FORMAT_MULAW, "Microsoft mu-law" }, 62 { WAVE_FORMAT_MULAW, "Microsoft mu-law" },
62 { WAVE_FORMAT_OKI_ADPCM,"OKI ADPCM" }, 63 { WAVE_FORMAT_OKI_ADPCM,"OKI ADPCM" },
63 { WAVE_FORMAT_DIGISTD, "Digistd format" }, 64 { WAVE_FORMAT_DIGISTD, "Digistd format" },
64 { WAVE_FORMAT_DIGIFIX, "Digifix format" }, 65 { WAVE_FORMAT_DIGIFIX, "Digifix format" },
65 { -1, "?Unknown?" }, 66 { -1, "?Unknown?" },
66}; 67};
67 68
68const char * 69const char *
69wav_enc_from_val(int encoding) 70wav_enc_from_val(int encoding)
70{ 71{
71 int i; 72 int i;
72 73
73 for (i = 0; wavencs[i].wenc != -1; i++) 74 for (i = 0; wavencs[i].wenc != -1; i++)
74 if (wavencs[i].wenc == encoding) 75 if (wavencs[i].wenc == encoding)
75 break; 76 break;
76 return (wavencs[i].wname); 77 return (wavencs[i].wname);
77} 78}
78 79
 80extern int verbose;
 81
79/* 82/*
80 * sample header is: 83 * sample header is:
81 * 84 *
82 * RIFF\^@^C^@WAVEfmt ^P^@^@^@^A^@^B^@D<AC>^@^@^P<B1>^B^@^D^@^P^@data^@^@^C^@^@^@^@^@^@^@^@^@^@ 85 * RIFF\^@^C^@WAVEfmt ^P^@^@^@^A^@^B^@D<AC>^@^@^P<B1>^B^@^D^@^P^@data^@^@^C^@^@^@^@^@^@^@^@^@^@
83 * 86 *
84 */ 87 */
85/* 88/*
86 * WAV format helpers 89 * WAV format helpers
87 */ 90 */
88/* 91/*
89 * find a .wav header, etc. returns header length on success 92 * find a .wav header, etc. returns header length on success
90 */ 93 */
91ssize_t 94ssize_t
92audio_wav_parse_hdr(hdr, sz, enc, prec, sample, channels, datasize) 95audio_wav_parse_hdr(hdr, sz, enc, prec, sample, channels, datasize)
93 void *hdr; 96 void *hdr;
94 size_t sz; 97 size_t sz;
95 u_int *enc; 98 u_int *enc;
96 u_int *prec; 99 u_int *prec;
97 u_int *sample; 100 u_int *sample;
98 u_int *channels; 101 u_int *channels;
99 size_t *datasize; 102 size_t *datasize;
100{ 103{
101 char *where = hdr, *owhere; 104 char *where = hdr, *owhere;
102 wav_audioheaderpart part; 105 wav_audioheaderpart part;
103 wav_audioheaderfmt fmt; 106 wav_audioheaderfmt fmt;
 107 wav_audiohdrextensible ext;
104 char *end = (((char *)hdr) + sz); 108 char *end = (((char *)hdr) + sz);
105 u_int newenc, newprec; 109 u_int newenc, newprec;
 110 u_int16_t fmttag;
106 static const char 111 static const char
107 strfmt[4] = "fmt ", 112 strfmt[4] = "fmt ",
108 strRIFF[4] = "RIFF", 113 strRIFF[4] = "RIFF",
109 strWAVE[4] = "WAVE", 114 strWAVE[4] = "WAVE",
110 strdata[4] = "data"; 115 strdata[4] = "data";
111  116
112 if (sz < 32) 117 if (sz < 32)
113 return (AUDIO_ENOENT); 118 return (AUDIO_ENOENT);
114 119
115 if (strncmp(where, strRIFF, sizeof strRIFF)) 120 if (strncmp(where, strRIFF, sizeof strRIFF))
116 return (AUDIO_ENOENT); 121 return (AUDIO_ENOENT);
117 where += 8; 122 where += 8;
118 if (strncmp(where, strWAVE, sizeof strWAVE)) 123 if (strncmp(where, strWAVE, sizeof strWAVE))
119 return (AUDIO_ENOENT); 124 return (AUDIO_ENOENT);
120 where += 4; 125 where += 4;
121 126
122 do { 127 do {
123 memcpy(&part, where, sizeof part); 128 memcpy(&part, where, sizeof part);
124 owhere = where; 129 owhere = where;
125 where += getle32(part.len) + 8; 130 where += getle32(part.len) + 8;
126 } while (where < end && strncmp(part.name, strfmt, sizeof strfmt)); 131 } while (where < end && strncmp(part.name, strfmt, sizeof strfmt));
127 132
128 /* too short ? */ 133 /* too short ? */
129 if (where + sizeof fmt > end) 134 if (where + sizeof fmt > end)
130 return (AUDIO_ESHORTHDR); 135 return (AUDIO_ESHORTHDR);
131 136
132 memcpy(&fmt, (owhere + 8), sizeof fmt); 137 memcpy(&fmt, (owhere + 8), sizeof fmt);
133 138
134 switch (getle16(fmt.tag)) { 139 fmttag = getle16(fmt.tag);
 140 if (verbose)
 141 printf("WAVE format tag: %x\n", fmttag);
 142
 143 if (fmttag == WAVE_FORMAT_EXTENSIBLE) {
 144 if ((uintptr_t)(where - owhere) < sizeof(fmt) + sizeof(ext))
 145 return (AUDIO_ESHORTHDR);
 146 memcpy(&ext, owhere + sizeof fmt, sizeof ext);
 147 if (getle16(ext.len) < sizeof(ext) - sizeof(ext.len))
 148 return (AUDIO_ESHORTHDR);
 149 fmttag = ext.sub_tag;
 150 if (verbose)
 151 printf("WAVE extensible sub tag: %x\n", fmttag);
 152 }
 153
 154 switch (fmttag) {
135 case WAVE_FORMAT_UNKNOWN: 155 case WAVE_FORMAT_UNKNOWN:
136 case WAVE_FORMAT_ADPCM: 
137 case WAVE_FORMAT_OKI_ADPCM: 
138 case WAVE_FORMAT_DIGISTD: 
139 case WAVE_FORMAT_DIGIFIX: 
140 case IBM_FORMAT_MULAW: 156 case IBM_FORMAT_MULAW:
141 case IBM_FORMAT_ALAW: 157 case IBM_FORMAT_ALAW:
142 case IBM_FORMAT_ADPCM: 158 case IBM_FORMAT_ADPCM:
143 default: 159 default:
144 return (AUDIO_EWAVUNSUPP); 160 return (AUDIO_EWAVUNSUPP);
145 161
146 case WAVE_FORMAT_PCM: 162 case WAVE_FORMAT_PCM:
 163 case WAVE_FORMAT_ADPCM:
 164 case WAVE_FORMAT_OKI_ADPCM:
 165 case WAVE_FORMAT_IMA_ADPCM:
 166 case WAVE_FORMAT_DIGIFIX:
 167 case WAVE_FORMAT_DIGISTD:
147 switch (getle16(fmt.bits_per_sample)) { 168 switch (getle16(fmt.bits_per_sample)) {
148 case 8: 169 case 8:
149 newprec = 8; 170 newprec = 8;
150 break; 171 break;
151 case 16: 172 case 16:
152 newprec = 16; 173 newprec = 16;
153 break; 174 break;
154 case 24: 175 case 24:
155 newprec = 24; 176 newprec = 24;
156 break; 177 break;
157 case 32: 178 case 32:
158 newprec = 32; 179 newprec = 32;
159 break; 180 break;
160 default: 181 default:
161 return (AUDIO_EWAVBADPCM); 182 return (AUDIO_EWAVBADPCM);
162 } 183 }
163 if (newprec == 8) 184 if (newprec == 8)
164 newenc = AUDIO_ENCODING_ULINEAR_LE; 185 newenc = AUDIO_ENCODING_ULINEAR_LE;
165 else 186 else
166 newenc = AUDIO_ENCODING_SLINEAR_LE; 187 newenc = AUDIO_ENCODING_SLINEAR_LE;
167 break; 188 break;
168 case WAVE_FORMAT_ALAW: 189 case WAVE_FORMAT_ALAW:
169 newenc = AUDIO_ENCODING_ALAW; 190 newenc = AUDIO_ENCODING_ALAW;
170 newprec = 8; 191 newprec = 8;
171 break; 192 break;
172 case WAVE_FORMAT_MULAW: 193 case WAVE_FORMAT_MULAW:
173 newenc = AUDIO_ENCODING_ULAW; 194 newenc = AUDIO_ENCODING_ULAW;
174 newprec = 8; 195 newprec = 8;
175 break; 196 break;
176 } 197 }
177 198
178 do { 199 do {
179 memcpy(&part, where, sizeof part); 200 memcpy(&part, where, sizeof part);
180 owhere = where; 201 owhere = where;
181 where += (getle32(part.len) + 8); 202 where += (getle32(part.len) + 8);
182 } while (where < end && strncmp(part.name, strdata, sizeof strdata)); 203 } while (where < end && strncmp(part.name, strdata, sizeof strdata));
183 204
184 if ((where - getle32(part.len)) <= end) { 205 if ((where - getle32(part.len)) <= end) {
185 if (channels) 206 if (channels)
186 *channels = (u_int)getle16(fmt.channels); 207 *channels = (u_int)getle16(fmt.channels);
187 if (sample) 208 if (sample)
188 *sample = getle32(fmt.sample_rate); 209 *sample = getle32(fmt.sample_rate);
189 if (enc) 210 if (enc)
190 *enc = newenc; 211 *enc = newenc;
191 if (prec) 212 if (prec)
192 *prec = newprec; 213 *prec = newprec;
193 if (datasize) 214 if (datasize)
194 *datasize = (size_t)getle32(part.len); 215 *datasize = (size_t)getle32(part.len);
195 return (owhere - (char *)hdr + 8); 216 return (owhere - (char *)hdr + 8);
196 } 217 }
197 return (AUDIO_EWAVNODATA); 218 return (AUDIO_EWAVNODATA);
198} 219}