- add extended WAVE header support

- attempt to play a bunch more WAV files
This commit is contained in:
mrg 2009-06-18 02:37:27 +00:00
parent 6709212e45
commit 95c070cab9
2 changed files with 52 additions and 11 deletions

View File

@ -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 *);

View File

@ -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 <sys/cdefs.h>
#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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#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;