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 (expand / 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,17 +1,17 @@ @@ -1,17 +1,17 @@
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
@@ -97,55 +97,75 @@ int audio_encoding_to_sun (int, int, int @@ -97,55 +97,75 @@ int audio_encoding_to_sun (int, int, int
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

cvs diff -r1.8 -r1.8.4.1 src/usr.bin/audio/common/wav.c (expand / 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,17 +1,17 @@ @@ -1,17 +1,17 @@
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
@@ -23,40 +23,41 @@ @@ -23,40 +23,41 @@
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" },
@@ -66,53 +67,57 @@ struct { @@ -66,53 +67,57 @@ struct {
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))
@@ -121,39 +126,55 @@ audio_wav_parse_hdr(hdr, sz, enc, prec,  @@ -121,39 +126,55 @@ audio_wav_parse_hdr(hdr, sz, enc, prec,
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;