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/
32enum 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
42struct format_map {
43	enum wave_format wformat;
44	snd_pcm_format_t format;
45};
46
47static 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
76struct riff_chunk {
77	uint8_t id[4];
78	uint32_t size;
79
80	uint8_t data[0];
81};
82
83struct riff_chunk_data {
84	uint8_t id[4];
85
86	uint8_t subchunks[0];
87};
88
89struct riff_subchunk {
90	uint8_t id[4];
91	uint32_t size;
92
93	uint8_t data[0];
94};
95
96struct 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
109struct wave_data_subchunk {
110	uint8_t id[4];
111	uint32_t size;
112
113	uint8_t frames[0];
114};
115
116struct 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
128static 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
147static 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
185static 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
215static 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
226static 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
327static 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
343static 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	unsigned 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 ((int)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
389struct 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
398static 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
414static 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
425static 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
460static 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
467static 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
510static 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	unsigned 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
538static 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
550const 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
563const 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