diff --git a/usr.bin/audio/common/libaudio.h b/usr.bin/audio/common/libaudio.h index 0b7366dea13e..43d7a47644e0 100644 --- a/usr.bin/audio/common/libaudio.h +++ b/usr.bin/audio/common/libaudio.h @@ -1,7 +1,7 @@ -/* $NetBSD: libaudio.h,v 1.15 2008/05/29 14:51:27 mrg Exp $ */ +/* $NetBSD: libaudio.h,v 1.16 2009/06/18 02:37:27 mrg Exp $ */ /* - * Copyright (c) 1999 Matthew R. Green + * Copyright (c) 1999, 2009 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -107,18 +107,30 @@ int audio_encoding_to_sun (int, int, int *); #define WAVAUDIO_FILE_MAGIC_FMT ((u_int32_t)0x666d7420) #define WAVAUDIO_FILE_MAGIC_DATA ((u_int32_t)0x64617461) -/* purloined from public Microsoft RIFF docs via sox */ +/* purloined from public Microsoft RIFF docs via sox or mplayer */ #define WAVE_FORMAT_UNKNOWN (0x0000) #define WAVE_FORMAT_PCM (0x0001) #define WAVE_FORMAT_ADPCM (0x0002) #define WAVE_FORMAT_ALAW (0x0006) #define WAVE_FORMAT_MULAW (0x0007) #define WAVE_FORMAT_OKI_ADPCM (0x0010) +#define WAVE_FORMAT_IMA_ADPCM (0x0011) #define WAVE_FORMAT_DIGISTD (0x0015) #define WAVE_FORMAT_DIGIFIX (0x0016) +#define WAVE_FORMAT_DOLBY_AC2 (0x0030) +#define WAVE_FORMAT_GSM610 (0x0031) +#define WAVE_FORMAT_ROCKWELL_ADPCM (0x003b) +#define WAVE_FORMAT_ROCKWELL_DIGITALK (0x003c) +#define WAVE_FORMAT_G721_ADPCM (0x0040) +#define WAVE_FORMAT_G728_CELP (0x0041) +#define WAVE_FORMAT_MPEG (0x0050) +#define WAVE_FORMAT_MPEGLAYER3 (0x0055) +#define WAVE_FORMAT_G726_ADPCM (0x0064) +#define WAVE_FORMAT_G722_ADPCM (0x0065) #define IBM_FORMAT_MULAW (0x0101) #define IBM_FORMAT_ALAW (0x0102) #define IBM_FORMAT_ADPCM (0x0103) +#define WAVE_FORMAT_EXTENSIBLE (0xfffe) const char *wav_enc_from_val (int); @@ -136,6 +148,14 @@ typedef struct { u_int16_t bits_per_sample; } __packed wav_audioheaderfmt; +typedef struct { + u_int16_t len; + u_int16_t valid_bits; + u_int32_t speaker_pos_mask; + u_int16_t sub_tag; + u_int8_t dummy[14]; +} __packed wav_audiohdrextensible; + /* returns size of header, or -ve for failure */ ssize_t audio_wav_parse_hdr (void *, size_t, u_int *, u_int *, u_int *, u_int *, size_t *); diff --git a/usr.bin/audio/common/wav.c b/usr.bin/audio/common/wav.c index 4a1b696a75fa..e00dda2f214e 100644 --- a/usr.bin/audio/common/wav.c +++ b/usr.bin/audio/common/wav.c @@ -1,7 +1,7 @@ -/* $NetBSD: wav.c,v 1.8 2008/05/29 14:51:27 mrg Exp $ */ +/* $NetBSD: wav.c,v 1.9 2009/06/18 02:37:27 mrg Exp $ */ /* - * Copyright (c) 2002 Matthew R. Green + * Copyright (c) 2002, 2009 Matthew R. Green * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ #include #ifndef lint -__RCSID("$NetBSD: wav.c,v 1.8 2008/05/29 14:51:27 mrg Exp $"); +__RCSID("$NetBSD: wav.c,v 1.9 2009/06/18 02:37:27 mrg Exp $"); #endif @@ -47,6 +47,7 @@ __RCSID("$NetBSD: wav.c,v 1.8 2008/05/29 14:51:27 mrg Exp $"); #include #include #include +#include #include "libaudio.h" @@ -76,6 +77,8 @@ wav_enc_from_val(int encoding) return (wavencs[i].wname); } +extern int verbose; + /* * sample header is: * @@ -101,8 +104,10 @@ audio_wav_parse_hdr(hdr, sz, enc, prec, sample, channels, datasize) char *where = hdr, *owhere; wav_audioheaderpart part; wav_audioheaderfmt fmt; + wav_audiohdrextensible ext; char *end = (((char *)hdr) + sz); u_int newenc, newprec; + u_int16_t fmttag; static const char strfmt[4] = "fmt ", strRIFF[4] = "RIFF", @@ -131,12 +136,23 @@ audio_wav_parse_hdr(hdr, sz, enc, prec, sample, channels, datasize) memcpy(&fmt, (owhere + 8), sizeof fmt); - switch (getle16(fmt.tag)) { + fmttag = getle16(fmt.tag); + if (verbose) + printf("WAVE format tag: %x\n", fmttag); + + if (fmttag == WAVE_FORMAT_EXTENSIBLE) { + if ((uintptr_t)(where - owhere) < sizeof(fmt) + sizeof(ext)) + return (AUDIO_ESHORTHDR); + memcpy(&ext, owhere + sizeof fmt, sizeof ext); + if (getle16(ext.len) < sizeof(ext) - sizeof(ext.len)) + return (AUDIO_ESHORTHDR); + fmttag = ext.sub_tag; + if (verbose) + printf("WAVE extensible sub tag: %x\n", fmttag); + } + + switch (fmttag) { case WAVE_FORMAT_UNKNOWN: - case WAVE_FORMAT_ADPCM: - case WAVE_FORMAT_OKI_ADPCM: - case WAVE_FORMAT_DIGISTD: - case WAVE_FORMAT_DIGIFIX: case IBM_FORMAT_MULAW: case IBM_FORMAT_ALAW: case IBM_FORMAT_ADPCM: @@ -144,6 +160,11 @@ audio_wav_parse_hdr(hdr, sz, enc, prec, sample, channels, datasize) return (AUDIO_EWAVUNSUPP); case WAVE_FORMAT_PCM: + case WAVE_FORMAT_ADPCM: + case WAVE_FORMAT_OKI_ADPCM: + case WAVE_FORMAT_IMA_ADPCM: + case WAVE_FORMAT_DIGIFIX: + case WAVE_FORMAT_DIGISTD: switch (getle16(fmt.bits_per_sample)) { case 8: newprec = 8;