1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // container-riff-wave.c - a parser/builder for a container of RIFF/Wave File.
4 //
5 // Copyright (c) 2018 Takashi Sakamoto <o-takashi@sakamocchi.jp>
6 //
7 // Licensed under the terms of the GNU General Public License, version 2.
8
9 #include "container.h"
10 #include "misc.h"
11
12 // Not portable to all of UNIX platforms.
13 #include <endian.h>
14
15 // References:
16 // - 'Resource Interchange File Format (RIFF)' at msdn.microsoft.com
17 // - 'Multiple channel audio data and WAVE files' at msdn.microsoft.com
18 // - RFC 2361 'WAVE and AVI Codec Registries' at ietf.org
19 // - 'mmreg.h' in Wine project
20 // - 'mmreg.h' in ReactOS project
21
22 #define RIFF_MAGIC "RIF" // A common part.
23
24 #define RIFF_CHUNK_ID_LE "RIFF"
25 #define RIFF_CHUNK_ID_BE "RIFX"
26 #define RIFF_FORM_WAVE "WAVE"
27 #define FMT_SUBCHUNK_ID "fmt "
28 #define DATA_SUBCHUNK_ID "data"
29
30 // See 'WAVE and AVI Codec Registries (Historic Registry)' in 'iana.org'.
31 // https://www.iana.org/assignments/wave-avi-codec-registry/
32 enum wave_format {
33 WAVE_FORMAT_PCM = 0x0001,
34 WAVE_FORMAT_ADPCM = 0x0002,
35 WAVE_FORMAT_IEEE_FLOAT = 0x0003,
36 WAVE_FORMAT_ALAW = 0x0006,
37 WAVE_FORMAT_MULAW = 0x0007,
38 WAVE_FORMAT_G723_ADPCM = 0x0014,
39 // The others are not supported.
40 };
41
42 struct format_map {
43 enum wave_format wformat;
44 snd_pcm_format_t format;
45 };
46
47 static const struct format_map format_maps[] = {
48 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_U8},
49 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S16_LE},
50 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S16_BE},
51 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S24_LE},
52 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S24_BE},
53 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S32_LE},
54 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S32_BE},
55 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S24_3LE},
56 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S24_3BE},
57 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S20_3LE},
58 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S20_3BE},
59 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S18_3LE},
60 {WAVE_FORMAT_PCM, SND_PCM_FORMAT_S18_3BE},
61 {WAVE_FORMAT_IEEE_FLOAT, SND_PCM_FORMAT_FLOAT_LE},
62 {WAVE_FORMAT_IEEE_FLOAT, SND_PCM_FORMAT_FLOAT_BE},
63 {WAVE_FORMAT_IEEE_FLOAT, SND_PCM_FORMAT_FLOAT64_LE},
64 {WAVE_FORMAT_IEEE_FLOAT, SND_PCM_FORMAT_FLOAT64_BE},
65 {WAVE_FORMAT_ALAW, SND_PCM_FORMAT_A_LAW},
66 {WAVE_FORMAT_MULAW, SND_PCM_FORMAT_MU_LAW},
67 // Below sample formats are not currently supported, due to width of
68 // its sample.
69 // - WAVE_FORMAT_ADPCM
70 // - WAVE_FORMAT_G723_ADPCM
71 // - WAVE_FORMAT_G723_ADPCM
72 // - WAVE_FORMAT_G723_ADPCM
73 // - WAVE_FORMAT_G723_ADPCM
74 };
75
76 struct riff_chunk {
77 uint8_t id[4];
78 uint32_t size;
79
80 uint8_t data[0];
81 };
82
83 struct riff_chunk_data {
84 uint8_t id[4];
85
86 uint8_t subchunks[0];
87 };
88
89 struct riff_subchunk {
90 uint8_t id[4];
91 uint32_t size;
92
93 uint8_t data[0];
94 };
95
96 struct wave_fmt_subchunk {
97 uint8_t id[4];
98 uint32_t size;
99
100 uint16_t format;
101 uint16_t samples_per_frame;
102 uint32_t frames_per_second;
103 uint32_t average_bytes_per_second;
104 uint16_t bytes_per_frame;
105 uint16_t bits_per_sample;
106 uint8_t extension[0];
107 };
108
109 struct wave_data_subchunk {
110 uint8_t id[4];
111 uint32_t size;
112
113 uint8_t frames[0];
114 };
115
116 struct parser_state {
117 bool be;
118 enum wave_format format;
119 unsigned int samples_per_frame;
120 unsigned int frames_per_second;
121 unsigned int average_bytes_per_second;
122 unsigned int bytes_per_frame;
123 unsigned int bytes_per_sample;
124 unsigned int avail_bits_in_sample;
125 unsigned int byte_count;
126 };
127
parse_riff_chunk_header(struct parser_state * state,struct riff_chunk * chunk,uint64_t * byte_count)128 static int parse_riff_chunk_header(struct parser_state *state,
129 struct riff_chunk *chunk,
130 uint64_t *byte_count)
131 {
132 if (!memcmp(chunk->id, RIFF_CHUNK_ID_BE, sizeof(chunk->id)))
133 state->be = true;
134 else if (!memcmp(chunk->id, RIFF_CHUNK_ID_LE, sizeof(chunk->id)))
135 state->be = false;
136 else
137 return -EINVAL;
138
139 if (state->be)
140 *byte_count = be32toh(chunk->size);
141 else
142 *byte_count = le32toh(chunk->size);
143
144 return 0;
145 }
146
parse_riff_chunk(struct container_context * cntr,uint64_t * byte_count)147 static int parse_riff_chunk(struct container_context *cntr,
148 uint64_t *byte_count)
149 {
150 struct parser_state *state = cntr->private_data;
151 union {
152 struct riff_chunk chunk;
153 struct riff_chunk_data chunk_data;
154 } buf = {0};
155 int err;
156
157 // Chunk header. 4 bytes were alread read to detect container type.
158 memcpy(buf.chunk.id, cntr->magic, sizeof(cntr->magic));
159 err = container_recursive_read(cntr,
160 (char *)&buf.chunk + sizeof(cntr->magic),
161 sizeof(buf.chunk) - sizeof(cntr->magic));
162 if (err < 0)
163 return err;
164 if (cntr->eof)
165 return 0;
166
167 err = parse_riff_chunk_header(state, &buf.chunk, byte_count);
168 if (err < 0)
169 return err;
170
171 // Chunk data header.
172 err = container_recursive_read(cntr, &buf, sizeof(buf.chunk_data));
173 if (err < 0)
174 return err;
175 if (cntr->eof)
176 return 0;
177
178 if (memcmp(buf.chunk_data.id, RIFF_FORM_WAVE,
179 sizeof(buf.chunk_data.id)))
180 return -EINVAL;
181
182 return 0;
183 }
184
parse_wave_fmt_subchunk(struct parser_state * state,struct wave_fmt_subchunk * subchunk)185 static int parse_wave_fmt_subchunk(struct parser_state *state,
186 struct wave_fmt_subchunk *subchunk)
187 {
188 if (state->be) {
189 state->format = be16toh(subchunk->format);
190 state->samples_per_frame = be16toh(subchunk->samples_per_frame);
191 state->frames_per_second = be32toh(subchunk->frames_per_second);
192 state->average_bytes_per_second =
193 be32toh(subchunk->average_bytes_per_second);
194 state->bytes_per_frame = be16toh(subchunk->bytes_per_frame);
195 state->avail_bits_in_sample =
196 be16toh(subchunk->bits_per_sample);
197 } else {
198 state->format = le16toh(subchunk->format);
199 state->samples_per_frame = le16toh(subchunk->samples_per_frame);
200 state->frames_per_second = le32toh(subchunk->frames_per_second);
201 state->average_bytes_per_second =
202 le32toh(subchunk->average_bytes_per_second);
203 state->bytes_per_frame = le16toh(subchunk->bytes_per_frame);
204 state->avail_bits_in_sample =
205 le16toh(subchunk->bits_per_sample);
206 }
207
208 if (state->average_bytes_per_second !=
209 state->bytes_per_frame * state->frames_per_second)
210 return -EINVAL;
211
212 return 0;
213 }
214
parse_wave_data_subchunk(struct parser_state * state,struct wave_data_subchunk * subchunk)215 static int parse_wave_data_subchunk(struct parser_state *state,
216 struct wave_data_subchunk *subchunk)
217 {
218 if (state->be)
219 state->byte_count = be32toh(subchunk->size);
220 else
221 state->byte_count = le32toh(subchunk->size);
222
223 return 0;
224 }
225
parse_wave_subchunk(struct container_context * cntr)226 static int parse_wave_subchunk(struct container_context *cntr)
227 {
228 union {
229 struct riff_subchunk subchunk;
230 struct wave_fmt_subchunk fmt_subchunk;
231 struct wave_data_subchunk data_subchunk;
232 } buf = {0};
233 enum {
234 SUBCHUNK_TYPE_UNKNOWN = -1,
235 SUBCHUNK_TYPE_FMT,
236 SUBCHUNK_TYPE_DATA,
237 } subchunk_type;
238 struct parser_state *state = cntr->private_data;
239 unsigned int required_size;
240 unsigned int subchunk_data_size;
241 int err;
242
243 while (1) {
244 err = container_recursive_read(cntr, &buf,
245 sizeof(buf.subchunk));
246 if (err < 0)
247 return err;
248 if (cntr->eof)
249 return 0;
250
251 // Calculate the size of subchunk data.
252 if (state->be)
253 subchunk_data_size = be32toh(buf.subchunk.size);
254 else
255 subchunk_data_size = le32toh(buf.subchunk.size);
256
257 // Detect type of subchunk.
258 if (!memcmp(buf.subchunk.id, FMT_SUBCHUNK_ID,
259 sizeof(buf.subchunk.id))) {
260 subchunk_type = SUBCHUNK_TYPE_FMT;
261 } else if (!memcmp(buf.subchunk.id, DATA_SUBCHUNK_ID,
262 sizeof(buf.subchunk.id))) {
263 subchunk_type = SUBCHUNK_TYPE_DATA;
264 } else {
265 subchunk_type = SUBCHUNK_TYPE_UNKNOWN;
266 }
267
268 if (subchunk_type != SUBCHUNK_TYPE_UNKNOWN) {
269 // Parse data of this subchunk.
270 if (subchunk_type == SUBCHUNK_TYPE_FMT) {
271 required_size =
272 sizeof(struct wave_fmt_subchunk) -
273 sizeof(struct riff_chunk);
274 } else {
275 required_size =
276 sizeof(struct wave_data_subchunk)-
277 sizeof(struct riff_chunk);
278 }
279
280 if (subchunk_data_size < required_size)
281 return -EINVAL;
282
283 err = container_recursive_read(cntr, &buf.subchunk.data,
284 required_size);
285 if (err < 0)
286 return err;
287 if (cntr->eof)
288 return 0;
289 subchunk_data_size -= required_size;
290
291 if (subchunk_type == SUBCHUNK_TYPE_FMT) {
292 err = parse_wave_fmt_subchunk(state,
293 &buf.fmt_subchunk);
294 } else if (subchunk_type == SUBCHUNK_TYPE_DATA) {
295 err = parse_wave_data_subchunk(state,
296 &buf.data_subchunk);
297 }
298 if (err < 0)
299 return err;
300
301 // Found frame data.
302 if (subchunk_type == SUBCHUNK_TYPE_DATA)
303 break;
304 }
305
306 // Go to next subchunk.
307 while (subchunk_data_size > 0) {
308 unsigned int consume;
309
310 if (subchunk_data_size > sizeof(buf))
311 consume = sizeof(buf);
312 else
313 consume = subchunk_data_size;
314
315 err = container_recursive_read(cntr, &buf, consume);
316 if (err < 0)
317 return err;
318 if (cntr->eof)
319 return 0;
320 subchunk_data_size -= consume;
321 }
322 }
323
324 return 0;
325 }
326
parse_riff_wave_format(struct container_context * cntr)327 static int parse_riff_wave_format(struct container_context *cntr)
328 {
329 uint64_t byte_count;
330 int err;
331
332 err = parse_riff_chunk(cntr, &byte_count);
333 if (err < 0)
334 return err;
335
336 err = parse_wave_subchunk(cntr);
337 if (err < 0)
338 return err;
339
340 return 0;
341 }
342
wave_parser_pre_process(struct container_context * cntr,snd_pcm_format_t * format,unsigned int * samples_per_frame,unsigned int * frames_per_second,uint64_t * byte_count)343 static int wave_parser_pre_process(struct container_context *cntr,
344 snd_pcm_format_t *format,
345 unsigned int *samples_per_frame,
346 unsigned int *frames_per_second,
347 uint64_t *byte_count)
348 {
349 struct parser_state *state = cntr->private_data;
350 int phys_width;
351 const struct format_map *map;
352 int i;
353 int err;
354
355 err = parse_riff_wave_format(cntr);
356 if (err < 0)
357 return err;
358
359 phys_width = 8 * state->average_bytes_per_second /
360 state->samples_per_frame / state->frames_per_second;
361
362 for (i = 0; i < ARRAY_SIZE(format_maps); ++i) {
363 map = &format_maps[i];
364 if (state->format != map->wformat)
365 continue;
366 if (state->avail_bits_in_sample !=
367 snd_pcm_format_width(map->format))
368 continue;
369 if (phys_width != snd_pcm_format_physical_width(map->format))
370 continue;
371
372 if (state->be && snd_pcm_format_big_endian(map->format) != 1)
373 continue;
374
375 break;
376 }
377 if (i == ARRAY_SIZE(format_maps))
378 return -EINVAL;
379
380 // Set parameters.
381 *format = format_maps[i].format;
382 *samples_per_frame = state->samples_per_frame;
383 *frames_per_second = state->frames_per_second;
384 *byte_count = state->byte_count;
385
386 return 0;
387 }
388
389 struct builder_state {
390 bool be;
391 enum wave_format format;
392 unsigned int avail_bits_in_sample;
393 unsigned int bytes_per_sample;
394 unsigned int samples_per_frame;
395 unsigned int frames_per_second;
396 };
397
build_riff_chunk_header(struct riff_chunk * chunk,uint64_t byte_count,bool be)398 static void build_riff_chunk_header(struct riff_chunk *chunk,
399 uint64_t byte_count, bool be)
400 {
401 uint64_t data_size = sizeof(struct riff_chunk_data) +
402 sizeof(struct wave_fmt_subchunk) +
403 sizeof(struct wave_data_subchunk) + byte_count;
404
405 if (be) {
406 memcpy(chunk->id, RIFF_CHUNK_ID_BE, sizeof(chunk->id));
407 chunk->size = htobe32(data_size);
408 } else {
409 memcpy(chunk->id, RIFF_CHUNK_ID_LE, sizeof(chunk->id));
410 chunk->size = htole32(data_size);
411 }
412 }
413
build_subchunk_header(struct riff_subchunk * subchunk,const char * const form,uint64_t size,bool be)414 static void build_subchunk_header(struct riff_subchunk *subchunk,
415 const char *const form, uint64_t size,
416 bool be)
417 {
418 memcpy(subchunk->id, form, sizeof(subchunk->id));
419 if (be)
420 subchunk->size = htobe32(size);
421 else
422 subchunk->size = htole32(size);
423 }
424
build_wave_format_subchunk(struct wave_fmt_subchunk * subchunk,struct builder_state * state)425 static void build_wave_format_subchunk(struct wave_fmt_subchunk *subchunk,
426 struct builder_state *state)
427 {
428 unsigned int bytes_per_frame =
429 state->bytes_per_sample * state->samples_per_frame;
430 unsigned int average_bytes_per_second = state->bytes_per_sample *
431 state->samples_per_frame * state->frames_per_second;
432 uint64_t size;
433
434 // No extensions.
435 size = sizeof(struct wave_fmt_subchunk) - sizeof(struct riff_subchunk);
436 build_subchunk_header((struct riff_subchunk *)subchunk, FMT_SUBCHUNK_ID,
437 size, state->be);
438
439 if (state->be) {
440 subchunk->format = htobe16(state->format);
441 subchunk->samples_per_frame = htobe16(state->samples_per_frame);
442 subchunk->frames_per_second = htobe32(state->frames_per_second);
443 subchunk->average_bytes_per_second =
444 htobe32(average_bytes_per_second);
445 subchunk->bytes_per_frame = htobe16(bytes_per_frame);
446 subchunk->bits_per_sample =
447 htobe16(state->avail_bits_in_sample);
448 } else {
449 subchunk->format = htole16(state->format);
450 subchunk->samples_per_frame = htole16(state->samples_per_frame);
451 subchunk->frames_per_second = htole32(state->frames_per_second);
452 subchunk->average_bytes_per_second =
453 htole32(average_bytes_per_second);
454 subchunk->bytes_per_frame = htole16(bytes_per_frame);
455 subchunk->bits_per_sample =
456 htole16(state->avail_bits_in_sample);
457 }
458 }
459
build_wave_data_subchunk(struct wave_data_subchunk * subchunk,uint64_t byte_count,bool be)460 static void build_wave_data_subchunk(struct wave_data_subchunk *subchunk,
461 uint64_t byte_count, bool be)
462 {
463 build_subchunk_header((struct riff_subchunk *)subchunk,
464 DATA_SUBCHUNK_ID, byte_count, be);
465 }
466
write_riff_chunk_for_wave(struct container_context * cntr,uint64_t byte_count)467 static int write_riff_chunk_for_wave(struct container_context *cntr,
468 uint64_t byte_count)
469 {
470 struct builder_state *state = cntr->private_data;
471 union {
472 struct riff_chunk chunk;
473 struct riff_chunk_data chunk_data;
474 struct wave_fmt_subchunk fmt_subchunk;
475 struct wave_data_subchunk data_subchunk;
476 } buf = {0};
477 uint64_t total_byte_count;
478 int err;
479
480 // Chunk header.
481 total_byte_count = sizeof(struct riff_chunk_data) +
482 sizeof(struct wave_fmt_subchunk) +
483 sizeof(struct wave_data_subchunk);
484 if (byte_count > cntr->max_size - total_byte_count)
485 total_byte_count = cntr->max_size;
486 else
487 total_byte_count += byte_count;
488 build_riff_chunk_header(&buf.chunk, total_byte_count, state->be);
489 err = container_recursive_write(cntr, &buf, sizeof(buf.chunk));
490 if (err < 0)
491 return err;
492
493 // Chunk data header.
494 memcpy(buf.chunk_data.id, RIFF_FORM_WAVE, sizeof(buf.chunk_data.id));
495 err = container_recursive_write(cntr, &buf, sizeof(buf.chunk_data));
496 if (err < 0)
497 return err;
498
499 // A subchunk in the chunk data for WAVE format.
500 build_wave_format_subchunk(&buf.fmt_subchunk, state);
501 err = container_recursive_write(cntr, &buf, sizeof(buf.fmt_subchunk));
502 if (err < 0)
503 return err;
504
505 // A subchunk in the chunk data for WAVE data.
506 build_wave_data_subchunk(&buf.data_subchunk, byte_count, state->be);
507 return container_recursive_write(cntr, &buf, sizeof(buf.data_subchunk));
508 }
509
wave_builder_pre_process(struct container_context * cntr,snd_pcm_format_t * format,unsigned int * samples_per_frame,unsigned int * frames_per_second,uint64_t * byte_count)510 static int wave_builder_pre_process(struct container_context *cntr,
511 snd_pcm_format_t *format,
512 unsigned int *samples_per_frame,
513 unsigned int *frames_per_second,
514 uint64_t *byte_count)
515 {
516 struct builder_state *state = cntr->private_data;
517 int i;
518
519 // Validate parameters.
520 for (i = 0; i < ARRAY_SIZE(format_maps); ++i) {
521 if (format_maps[i].format == *format)
522 break;
523 }
524 if (i == ARRAY_SIZE(format_maps))
525 return -EINVAL;
526
527 state->format = format_maps[i].wformat;
528 state->avail_bits_in_sample = snd_pcm_format_width(*format);
529 state->bytes_per_sample = snd_pcm_format_physical_width(*format) / 8;
530 state->samples_per_frame = *samples_per_frame;
531 state->frames_per_second = *frames_per_second;
532
533 state->be = (snd_pcm_format_big_endian(*format) == 1);
534
535 return write_riff_chunk_for_wave(cntr, *byte_count);
536 }
537
wave_builder_post_process(struct container_context * cntr,uint64_t handled_byte_count)538 static int wave_builder_post_process(struct container_context *cntr,
539 uint64_t handled_byte_count)
540 {
541 int err;
542
543 err = container_seek_offset(cntr, 0);
544 if (err < 0)
545 return err;
546
547 return write_riff_chunk_for_wave(cntr, handled_byte_count);
548 }
549
550 const struct container_parser container_parser_riff_wave = {
551 .format = CONTAINER_FORMAT_RIFF_WAVE,
552 .magic = RIFF_MAGIC,
553 .max_size = UINT32_MAX -
554 sizeof(struct riff_chunk_data) -
555 sizeof(struct wave_fmt_subchunk) -
556 sizeof(struct wave_data_subchunk),
557 .ops = {
558 .pre_process = wave_parser_pre_process,
559 },
560 .private_size = sizeof(struct parser_state),
561 };
562
563 const struct container_builder container_builder_riff_wave = {
564 .format = CONTAINER_FORMAT_RIFF_WAVE,
565 .max_size = UINT32_MAX -
566 sizeof(struct riff_chunk_data) -
567 sizeof(struct wave_fmt_subchunk) -
568 sizeof(struct wave_data_subchunk),
569 .ops = {
570 .pre_process = wave_builder_pre_process,
571 .post_process = wave_builder_post_process,
572 },
573 .private_size = sizeof(struct builder_state),
574 };
575