4 #include "inttypes.h"
\r
11 uint16_t block_align;
\r
12 uint16_t sample_bytes;
\r
15 struct playback_data {
\r
16 uint32_t start, size;
\r
17 uint32_t bytes_left;
\r
20 #define FOURCC(a, b, c, d) \
\r
21 ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
\r
24 ID_RIFF = FOURCC('R', 'I', 'F', 'F'),
\r
25 ID_WAVE = FOURCC('W', 'A', 'V', 'E'),
\r
26 ID_FMT = FOURCC('f', 'm', 't', ' '),
\r
27 ID_DATA = FOURCC('d', 'a', 't', 'a')
\r
30 static void close_wav(struct au_file *au);
\r
31 static void reset_wav(struct au_file *au);
\r
32 static int read_wav(struct au_file *au, void *buf, int size);
\r
33 static int read_uint32(uint32_t *res, FILE *fp);
\r
34 static int read_format(struct format *fmt, int fmtsize, FILE *fp);
\r
37 int au_open_wav(struct au_file *au)
\r
41 struct playback_data *pb;
\r
43 if(read_uint32(&id, au->fp) == -1 || id != ID_RIFF)
\r
45 fseek(au->fp, 4, SEEK_CUR);
\r
46 if(read_uint32(&id, au->fp) == -1 || id != ID_WAVE)
\r
48 if(read_uint32(&id, au->fp) == -1 || id != ID_FMT)
\r
50 if(read_uint32(&len, au->fp) == -1)
\r
52 if(read_format(&fmt, len, au->fp) == -1)
\r
54 if(read_uint32(&id, au->fp) == -1 || id != ID_DATA)
\r
56 if(read_uint32(&len, au->fp) == -1)
\r
59 if(!(pb = malloc(sizeof *pb))) {
\r
60 fprintf(stderr, "failed to allocate wav playback data block\n");
\r
63 pb->start = ftell(au->fp);
\r
64 pb->size = pb->bytes_left = len;
\r
66 au->rate = fmt.rate;
\r
67 au->bits = fmt.sample_bytes * 8;
\r
68 au->chan = fmt.nchan;
\r
71 au->close = close_wav;
\r
72 au->reset = reset_wav;
\r
73 au->read = read_wav;
\r
77 static void close_wav(struct au_file *au)
\r
82 static void reset_wav(struct au_file *au)
\r
84 struct playback_data *pb = au->data;
\r
85 pb->bytes_left = pb->size;
\r
86 fseek(au->fp, pb->start, SEEK_SET);
\r
89 static int read_wav(struct au_file *au, void *buf, int size)
\r
91 struct playback_data *pb = au->data;
\r
94 if(size > pb->bytes_left) {
\r
95 size = pb->bytes_left;
\r
100 if((rd = fread(buf, 1, size, au->fp)) == -1) {
\r
101 pb->bytes_left = 0;
\r
104 pb->bytes_left -= rd;
\r
109 static void swap_uint32(uint32_t *val)
\r
112 *val = (x << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | (x >> 24);
\r
115 static void swap_uint16(uint16_t *val)
\r
118 *val = (x << 8) | (x >> 8);
\r
122 static int read_uint32(uint32_t *res, FILE *fp)
\r
124 if(fread(res, 4, 1, fp) < 1) {
\r
133 static int read_format(struct format *fmt, int fmtsize, FILE *fp)
\r
135 if(fread(fmt, 1, fmtsize, fp) < fmtsize) {
\r
139 swap_uint16(&fmt->fmt);
\r
140 swap_uint16(&fmt->nchan);
\r
141 swap_uint32(&fmt->rate);
\r
142 swap_uint16(&fmt->avgbaud);
\r
143 swap_uint16(&fmt->block_align);
\r