summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2010-05-25 06:27:42 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2010-05-25 06:27:42 +0000
commit558a7195aec0c708ea3d4d9ff27b3b1592ffa15f (patch)
tree5e9a8e088b0a18720c1182b4df22a82a3c26c936 /usr.bin
parent733e3ed41203ad6e79097dbeda973d198d1cead4 (diff)
enable support for ``extended'' .wav files since certain programs
use this format instead of the non-extended one (ex. audio/libao) spotted/suggested by naddy
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/aucat/headers.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/usr.bin/aucat/headers.c b/usr.bin/aucat/headers.c
index b9d0a6efe57..e6d7e0f1a9f 100644
--- a/usr.bin/aucat/headers.c
+++ b/usr.bin/aucat/headers.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: headers.c,v 1.14 2010/05/02 11:54:26 ratchov Exp $ */
+/* $OpenBSD: headers.c,v 1.15 2010/05/25 06:27:41 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -33,6 +33,7 @@
#define WAV_ENC_PCM 1
#define WAV_ENC_ALAW 6
#define WAV_ENC_ULAW 7
+#define WAV_ENC_EXT 0xfffe
struct wavriff {
char magic[4];
@@ -52,28 +53,59 @@ struct wavfmt {
uint32_t byterate;
uint16_t blkalign;
uint16_t bits;
+#define WAV_FMT_SIZE 16
+#define WAV_FMT_SIZE2 (16 + 2)
+#define WAV_FMT_EXT_SIZE (16 + 24)
+ uint16_t extsize;
+ uint16_t valbits;
+ uint32_t chanmask;
+ uint16_t extfmt;
+ char guid[14];
} __packed;
char wav_id_riff[4] = { 'R', 'I', 'F', 'F' };
char wav_id_wave[4] = { 'W', 'A', 'V', 'E' };
char wav_id_data[4] = { 'd', 'a', 't', 'a' };
char wav_id_fmt[4] = { 'f', 'm', 't', ' ' };
+char wav_guid[14] = {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x80, 0x00,
+ 0x00, 0xAA, 0x00, 0x38,
+ 0x9B, 0x71
+};
int
wav_readfmt(int fd, unsigned csize, struct aparams *par, short **map)
{
struct wavfmt fmt;
- unsigned nch, cmax, rate, bits, enc;
+ unsigned nch, cmax, rate, bits, bps, enc;
- if (csize < sizeof(fmt)) {
- warnx("bogus format chunk");
+ if (csize < WAV_FMT_SIZE) {
+ warnx("%u: bugus format chunk size", csize);
return 0;
}
- if (read(fd, &fmt, sizeof(fmt)) != sizeof(fmt)) {
+ if (csize > WAV_FMT_EXT_SIZE)
+ csize = WAV_FMT_EXT_SIZE;
+ if (read(fd, &fmt, csize) != csize) {
warn("riff_read: chunk");
return 0;
}
enc = letoh16(fmt.fmt);
+ bits = letoh16(fmt.bits);
+ if (enc == WAV_ENC_EXT) {
+ if (csize != WAV_FMT_EXT_SIZE) {
+ warnx("missing extended format chunk in .wav file");
+ return 0;
+ }
+ if (memcmp(fmt.guid, wav_guid, sizeof(wav_guid)) != 0) {
+ warnx("unknown format (GUID) in .wav file");
+ return 0;
+ }
+ bps = (bits + 7) / 8;
+ bits = letoh16(fmt.valbits);
+ enc = letoh16(fmt.extfmt);
+ } else
+ bps = (bits + 7) / 8;
switch (enc) {
case WAV_ENC_PCM:
*map = NULL;
@@ -102,13 +134,16 @@ wav_readfmt(int fd, unsigned csize, struct aparams *par, short **map)
warnx("%u: bad sample rate", rate);
return 0;
}
- bits = letoh16(fmt.bits);
if (bits == 0 || bits > 32) {
warnx("%u: bad number of bits", bits);
return 0;
}
+ if (bits > bps * 8) {
+ warnx("%u: bits larger than bytes-per-sample", bps);
+ return 0;
+ }
if (enc == WAV_ENC_PCM) {
- par->bps = (bits + 7) / 8;
+ par->bps = bps;
par->bits = bits;
par->le = 1;
par->sig = (bits <= 8) ? 0 : 1; /* ask microsoft why... */
@@ -233,7 +268,7 @@ wav_writehdr(int fd, struct aparams *par, off_t *startpos, off_t datasz)
hdr.fmt.rate = htole32(par->rate);
hdr.fmt.byterate = htole32(par->rate * par->bps * nch);
hdr.fmt.bits = htole16(par->bits);
- hdr.fmt.blkalign = 0;
+ hdr.fmt.blkalign = par->bps * nch;
memcpy(hdr.data_hdr.id, wav_id_data, 4);
hdr.data_hdr.size = htole32(datasz);