• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // container-voc.c - a parser/builder for a container of Creative Voice 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 //  - http://sox.sourceforge.net/
17 
18 #define VOC_MAGIC		"Creative Voice File\x1a"
19 #define VOC_VERSION_1_10	0x010a
20 #define VOC_VERSION_1_20	0x0114
21 
22 enum block_type {
23 	BLOCK_TYPE_TERMINATOR		= 0x00,
24 	BLOCK_TYPE_V110_DATA		= 0x01,
25 	BLOCK_TYPE_CONTINUOUS_DATA	= 0x02,
26 	BLOCK_TYPE_SILENCE		= 0x03,
27 	BLOCK_TYPE_MARKER		= 0x04,
28 	BLOCK_TYPE_STRING		= 0x05,
29 	BLOCK_TYPE_REPEAT_START		= 0x06,
30 	BLOCK_TYPE_REPEAT_END		= 0x07,
31 	BLOCK_TYPE_EXTENDED_V110_FORMAT	= 0x08,
32 	BLOCK_TYPE_V120_DATA		= 0x09,
33 };
34 
35 enum code_id {
36 	// Version 1.10.
37 	CODE_ID_GENERIC_MBLA_U8			= 0x00,
38 	CODE_ID_CREATIVE_ADPCM_8BIT_TO_4BIT_LE	= 0x01,
39 	CODE_ID_CREATIVE_ADPCM_8BIT_TO_3BIT_LE	= 0x02,
40 	CODE_ID_CREATIVE_ADPCM_8BIT_TO_2BIT_LE	= 0x03,
41 	// Version 1.20.
42 	CODE_ID_GENERIC_MBLA_S16_LE		= 0x04,
43 	CODE_ID_CCIT_A_LAW_LE			= 0x06,
44 	CODE_ID_CCIT_MU_LAW_LE			= 0x07,
45 	CODE_ID_CREATIVE_ADPCM_16BIT_TO_4BIT_LE	= 0x2000,
46 };
47 
48 struct format_map {
49 	unsigned int minimal_version;
50 	enum code_id code_id;
51 	snd_pcm_format_t format;
52 };
53 
54 static const struct format_map format_maps[] = {
55 	{VOC_VERSION_1_10, CODE_ID_GENERIC_MBLA_U8,	SND_PCM_FORMAT_U8},
56 	{VOC_VERSION_1_20, CODE_ID_GENERIC_MBLA_S16_LE,	SND_PCM_FORMAT_S16_LE},
57 	{VOC_VERSION_1_20, CODE_ID_CCIT_A_LAW_LE,	SND_PCM_FORMAT_A_LAW},
58 	{VOC_VERSION_1_20, CODE_ID_CCIT_MU_LAW_LE,	SND_PCM_FORMAT_MU_LAW},
59 	// The other formats are not supported by ALSA.
60 };
61 
62 struct container_header {
63 	uint8_t magic[20];
64 	uint16_t hdr_size;
65 	uint16_t version;
66 	uint16_t version_compr;
67 };
68 
69 // A format for data blocks except for terminator type.
70 struct block_header {
71 	uint8_t type;
72 	uint8_t size[3];
73 
74 	uint8_t data[0];
75 };
76 
77 // Data block for terminator type has an exceptional format.
78 struct block_terminator {
79 	uint8_t type;
80 };
81 
82 struct time_const {
83 	unsigned int frames_per_second;
84 	uint16_t code;
85 };
86 
87 static const struct time_const v110_time_consts[] = {
88 	{5512, 74},
89 	{8000, 130},
90 	{11025, 165},
91 	{16000, 193},
92 	{22050, 210},
93 	{32000, 224},
94 	{44100, 233},
95 	{48000, 235},
96 	{64000, 240},
97 	// Time constant for the upper sampling rate is not identical.
98 };
99 
100 static const struct time_const ex_v110_time_consts[] = {
101 	{5512, 19092},
102 	{8000, 33536},
103 	{11025, 42317},
104 	{16000, 49536},
105 	{22050, 53927},
106 	{32000, 57536},
107 	{44100, 59732},
108 	{48000, 60203},
109 	{64000, 61536},
110 	{88200, 62634},
111 	{96000, 62870},
112 	{176400, 64085},
113 	{192000, 64203},
114 	// This support up to 192.0 kHz. The rest is for cases with 2ch.
115 	{352800, 64811},
116 	{384000, 64870},
117 };
118 
119 // v1.10 format:
120 // - monaural.
121 // - frames_per_second = 1,000,000 / (256 - time_const)
122 struct block_v110_data {
123 	uint8_t type;
124 	uint8_t size[3];	// Equals to (2 + the size of frames).
125 
126 	uint8_t time_const;
127 	uint8_t code_id;
128 	uint8_t frames[0];	// Aligned to little-endian.
129 };
130 
131 struct block_continuous_data {
132 	uint8_t type;
133 	uint8_t size[3];	// Equals to the size of frames.
134 
135 	uint8_t frames[0];	// Aligned to little-endian.
136 };
137 
138 // v1.10 format:
139 // - monaural.
140 // - frames_per_second = 1,000,000 / (256 - time_const).
141 struct block_silence {
142 	uint8_t type;
143 	uint8_t size[3];	// Equals to 3.
144 
145 	uint16_t frame_count;
146 	uint8_t time_const;
147 };
148 
149 struct block_marker {
150 	uint8_t type;
151 	uint8_t size[3];	// Equals to 2.
152 
153 	uint16_t mark;
154 };
155 
156 struct block_string {
157 	uint8_t type;
158 	uint8_t size[3];	// Equals to the length of string with 0x00.
159 
160 	uint8_t chars[0];
161 };
162 
163 struct block_repeat_start {
164 	uint8_t type;
165 	uint8_t size[3];	// Equals to 2.
166 
167 	uint16_t count;
168 };
169 
170 struct block_repeat_end {
171 	uint8_t type;
172 	uint8_t size[3];	// Equals to 0.
173 };
174 
175 // Extended v1.10 format:
176 // - manaural/stereo.
177 // - frames_per_second =
178 //		256,000,000 / (samples_per_frame * (65536 - time_const)).
179 // - Appear just before v110_data block.
180 struct block_extended_v110_format {
181 	uint8_t type;
182 	uint8_t size[3];	// Equals to 4.
183 
184 	uint16_t time_const;
185 	uint8_t code_id;
186 	uint8_t ch_mode;	// 0 is monaural, 1 is stereo.
187 };
188 
189 // v1.20 format:
190 // - monaural/stereo.
191 // - 8/16 bits_per_sample.
192 // - time_const is not used.
193 // - code_id is extended.
194 struct block_v120_format {
195 	uint8_t type;
196 	uint8_t size[3];	// Equals to (12 + ).
197 
198 	uint32_t frames_per_second;
199 	uint8_t bits_per_sample;
200 	uint8_t samples_per_frame;
201 	uint16_t code_id;
202 	uint8_t reserved[4];
203 
204 	uint8_t frames[0];	// Aligned to little-endian.
205 };
206 
207 // Aligned to little endian order but 24 bits field.
parse_block_data_size(uint8_t fields[3])208 static uint32_t parse_block_data_size(uint8_t fields[3])
209 {
210 	return (fields[2] << 16) | (fields[1] << 8) | fields[0];
211 }
212 
build_block_data_size(uint8_t fields[3],unsigned int size)213 static void build_block_data_size(uint8_t fields[3], unsigned int size)
214 {
215 	fields[0] = (size & 0x0000ff);
216 	fields[1] = (size & 0x00ff00) >> 8;
217 	fields[2] = (size & 0xff0000) >> 16;
218 }
219 
build_time_constant(unsigned int frames_per_second,unsigned int samples_per_frame,uint16_t * code,bool extended)220 static int build_time_constant(unsigned int frames_per_second,
221 			       unsigned int samples_per_frame, uint16_t *code,
222 			       bool extended)
223 {
224 	int i;
225 
226 	// 16 bits are available for this purpose.
227 	if (extended) {
228 		if (samples_per_frame > 2)
229 			return -EINVAL;
230 		frames_per_second *= samples_per_frame;
231 
232 		for (i = 0; i < ARRAY_SIZE(ex_v110_time_consts); ++i) {
233 			if (ex_v110_time_consts[i].frames_per_second ==
234 					frames_per_second)
235 				break;
236 		}
237 		if (i < ARRAY_SIZE(ex_v110_time_consts) &&
238 		    frames_per_second <= 192000) {
239 			*code = ex_v110_time_consts[i].code;
240 		} else {
241 			*code = 65536 - 256000000 / frames_per_second;
242 		}
243 	} else {
244 		if (samples_per_frame != 1)
245 			return -EINVAL;
246 
247 		for (i = 0; i < ARRAY_SIZE(v110_time_consts); ++i) {
248 			if (v110_time_consts[i].frames_per_second ==
249 					frames_per_second)
250 			break;
251 		}
252 		// Should be within 8 bit.
253 		if (i < ARRAY_SIZE(v110_time_consts))
254 			*code = (uint8_t)v110_time_consts[i].code;
255 		else
256 			*code = 256 - 1000000 / frames_per_second;
257 	}
258 
259 	return 0;
260 }
261 
parse_time_constant(uint16_t code,unsigned int samples_per_frame,unsigned int * frames_per_second,bool extended)262 static unsigned int parse_time_constant(uint16_t code,
263 					unsigned int samples_per_frame,
264 					unsigned int *frames_per_second,
265 					bool extended)
266 {
267 	int i;
268 
269 	if (extended) {
270 		if (samples_per_frame > 2)
271 			return -EINVAL;
272 
273 		for (i = 0; i < ARRAY_SIZE(ex_v110_time_consts); ++i) {
274 			if (ex_v110_time_consts[i].code == code ||
275 			    ex_v110_time_consts[i].code - 1 == code)
276 				break;
277 		}
278 		if (i < ARRAY_SIZE(ex_v110_time_consts)) {
279 			*frames_per_second =
280 				ex_v110_time_consts[i].frames_per_second /
281 				samples_per_frame;
282 		} else {
283 			*frames_per_second = 256000000 / samples_per_frame /
284 					     (65536 - code);
285 		}
286 	} else {
287 		if (samples_per_frame != 1)
288 			return -EINVAL;
289 
290 		for (i = 0; i < ARRAY_SIZE(v110_time_consts); ++i) {
291 			if (v110_time_consts[i].code == code ||
292 			    v110_time_consts[i].code - 1 == code)
293 				break;
294 		}
295 		if (i < ARRAY_SIZE(v110_time_consts)) {
296 			*frames_per_second =
297 					v110_time_consts[i].frames_per_second;
298 		} else {
299 			*frames_per_second = 1000000 / (256 - code);
300 		}
301 	}
302 
303 	return 0;
304 }
305 
306 struct parser_state {
307 	unsigned int version;
308 	bool extended;
309 
310 	unsigned int frames_per_second;
311 	unsigned int samples_per_frame;
312 	unsigned int bytes_per_sample;
313 	enum code_id code_id;
314 	uint32_t byte_count;
315 };
316 
parse_container_header(struct parser_state * state,struct container_header * header)317 static int parse_container_header(struct parser_state *state,
318 				  struct container_header *header)
319 {
320 	uint16_t hdr_size;
321 	uint16_t version;
322 	uint16_t version_compr;
323 
324 	hdr_size = le16toh(header->hdr_size);
325 	version = le16toh(header->version);
326 	version_compr = le16toh(header->version_compr);
327 
328 	if (memcmp(header->magic, VOC_MAGIC, sizeof(header->magic)))
329 		return -EIO;
330 
331 	if (hdr_size != sizeof(*header))
332 		return -EIO;
333 
334 	if (version_compr != 0x1234 + ~version)
335 		return -EIO;
336 
337 	if (version != VOC_VERSION_1_10 && version != VOC_VERSION_1_20)
338 		return -EIO;
339 
340 	state->version = version;
341 
342 	return 0;
343 }
344 
check_code_id(uint8_t code_id,unsigned int version)345 static bool check_code_id(uint8_t code_id, unsigned int version)
346 {
347 	int i;
348 
349 	for (i = 0; i < ARRAY_SIZE(format_maps); ++i) {
350 		if (code_id != format_maps[i].code_id)
351 			continue;
352 		if (version >= format_maps[i].minimal_version)
353 			return true;
354 	}
355 
356 	return false;
357 }
358 
parse_v120_format_block(struct parser_state * state,struct block_v120_format * block)359 static int parse_v120_format_block(struct parser_state *state,
360 				   struct block_v120_format *block)
361 {
362 	state->frames_per_second = le32toh(block->frames_per_second);
363 	state->bytes_per_sample = block->bits_per_sample / 8;
364 	state->samples_per_frame = block->samples_per_frame;
365 	state->code_id = le16toh(block->code_id);
366 	state->byte_count = parse_block_data_size(block->size) - 12;
367 
368 	if (!check_code_id(state->code_id, VOC_VERSION_1_20))
369 		return -EIO;
370 
371 	return 0;
372 }
373 
parse_extended_v110_format(struct parser_state * state,struct block_extended_v110_format * block)374 static int parse_extended_v110_format(struct parser_state *state,
375 				      struct block_extended_v110_format *block)
376 {
377 	unsigned int time_const;
378 	unsigned int frames_per_second;
379 	int err;
380 
381 	state->code_id = block->code_id;
382 	if (!check_code_id(state->code_id, VOC_VERSION_1_10))
383 		return -EIO;
384 
385 	if (block->ch_mode == 0)
386 		state->samples_per_frame = 1;
387 	else if (block->ch_mode == 1)
388 		state->samples_per_frame = 2;
389 	else
390 		return -EIO;
391 
392 	time_const = le16toh(block->time_const);
393 	err = parse_time_constant(time_const, state->samples_per_frame,
394 				  &frames_per_second, true);
395 	if (err < 0)
396 		return err;
397 	state->frames_per_second = frames_per_second;
398 
399 	state->extended = true;
400 
401 	return 0;
402 }
403 
parse_v110_data(struct parser_state * state,struct block_v110_data * block)404 static int parse_v110_data(struct parser_state *state,
405 			   struct block_v110_data *block)
406 {
407 	unsigned int time_const;
408 	unsigned int frames_per_second;
409 	int err;
410 
411 	if (!state->extended) {
412 		state->code_id = block->code_id;
413 		if (!check_code_id(state->code_id, VOC_VERSION_1_10))
414 			return -EIO;
415 
416 		time_const = block->time_const;
417 		err = parse_time_constant(time_const, 1, &frames_per_second,
418 					  false);
419 		if (err < 0)
420 			return err;
421 		state->frames_per_second = frames_per_second;
422 		state->samples_per_frame = 1;
423 	}
424 
425 	state->bytes_per_sample = 1;
426 	state->byte_count = parse_block_data_size(block->size) - 2;
427 
428 	return 0;
429 }
430 
detect_container_version(struct container_context * cntr)431 static int detect_container_version(struct container_context *cntr)
432 {
433 	struct parser_state *state = cntr->private_data;
434 	struct container_header header = {0};
435 	int err;
436 
437 	// 4 bytes were alread read to detect container type.
438 	memcpy(&header.magic, cntr->magic, sizeof(cntr->magic));
439 	err = container_recursive_read(cntr,
440 				       (char *)&header + sizeof(cntr->magic),
441 				       sizeof(header) - sizeof(cntr->magic));
442 	if (err < 0)
443 		return err;
444 	if (cntr->eof)
445 		return 0;
446 
447 	return parse_container_header(state, &header);
448 }
449 
allocate_for_block_cache(struct container_context * cntr,struct block_header * header,void ** buf)450 static int allocate_for_block_cache(struct container_context *cntr,
451 				    struct block_header *header, void **buf)
452 {
453 	uint32_t block_size;
454 	char *cache;
455 	int err;
456 
457 	if (header->type == BLOCK_TYPE_V110_DATA)
458 		block_size = sizeof(struct block_v110_data);
459 	else if (header->type == BLOCK_TYPE_CONTINUOUS_DATA)
460 		block_size = sizeof(struct block_continuous_data);
461 	else if (header->type == BLOCK_TYPE_EXTENDED_V110_FORMAT)
462 		block_size = sizeof(struct block_extended_v110_format);
463 	else if (header->type == BLOCK_TYPE_V120_DATA)
464 		block_size = sizeof(struct block_v120_format);
465 	else
466 		block_size = parse_block_data_size(header->size);
467 
468 	cache = malloc(block_size);
469 	if (cache == NULL)
470 		return -ENOMEM;
471 	memset(cache, 0, block_size);
472 
473 	memcpy(cache, header, sizeof(*header));
474 	err = container_recursive_read(cntr, cache + sizeof(*header),
475 				       block_size - sizeof(*header));
476 	if (err < 0) {
477 		free(cache);
478 		return err;
479 	}
480 	if (cntr->eof) {
481 		free(cache);
482 		return 0;
483 	}
484 
485 	*buf = cache;
486 
487 	return 0;
488 }
489 
cache_data_block(struct container_context * cntr,struct block_header * header,void ** buf)490 static int cache_data_block(struct container_context *cntr,
491 			    struct block_header *header, void **buf)
492 {
493 	int err;
494 
495 	// Check type of this block.
496 	err = container_recursive_read(cntr, &header->type,
497 				       sizeof(header->type));
498 	if (err < 0)
499 		return err;
500 	if (cntr->eof)
501 		return 0;
502 
503 	if (header->type > BLOCK_TYPE_V120_DATA)
504 		return -EIO;
505 	if (header->type == BLOCK_TYPE_TERMINATOR)
506 		return 0;
507 
508 	// Check size of this block. If the block includes a batch of data,
509 	err = container_recursive_read(cntr, &header->size,
510 				       sizeof(header->size));
511 	if (err < 0)
512 		return err;
513 	if (cntr->eof)
514 		return 0;
515 
516 	return allocate_for_block_cache(cntr, header, buf);
517 }
518 
detect_format_block(struct container_context * cntr)519 static int detect_format_block(struct container_context *cntr)
520 {
521 	struct parser_state *state = cntr->private_data;
522 	struct block_header header;
523 	void *buf;
524 	int err;
525 
526 again:
527 	buf = NULL;
528 	err = cache_data_block(cntr, &header, &buf);
529 	if (err < 0)
530 		return err;
531 	if (buf) {
532 		if (header.type == BLOCK_TYPE_EXTENDED_V110_FORMAT) {
533 			err = parse_extended_v110_format(state, buf);
534 		} else if (header.type == BLOCK_TYPE_V120_DATA) {
535 			err = parse_v120_format_block(state, buf);
536 		} else if (header.type == BLOCK_TYPE_V110_DATA) {
537 			err = parse_v110_data(state, buf);
538 		} else {
539 			free(buf);
540 			goto again;
541 		}
542 
543 		free(buf);
544 
545 		if (err < 0)
546 			return err;
547 	}
548 
549 	// Expect to detect block_v110_data.
550 	if (header.type == BLOCK_TYPE_EXTENDED_V110_FORMAT)
551 		goto again;
552 
553 	return 0;
554 }
555 
voc_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)556 static int voc_parser_pre_process(struct container_context *cntr,
557 				  snd_pcm_format_t *format,
558 				  unsigned int *samples_per_frame,
559 				  unsigned int *frames_per_second,
560 				  uint64_t *byte_count)
561 {
562 	struct parser_state *state = cntr->private_data;
563 	int i;
564 	int err;
565 
566 	err = detect_container_version(cntr);
567 	if (err < 0)
568 		return err;
569 
570 	err = detect_format_block(cntr);
571 	if (err < 0)
572 		return err;
573 
574 	for (i = 0; i < ARRAY_SIZE(format_maps); ++i) {
575 		if (format_maps[i].code_id == state->code_id)
576 			break;
577 	}
578 	if (i == ARRAY_SIZE(format_maps))
579 		return -EINVAL;
580 
581 	*format = format_maps[i].format;
582 	*samples_per_frame = state->samples_per_frame;
583 	*frames_per_second = state->frames_per_second;
584 
585 	// This program handles PCM frames in this data block only.
586 	*byte_count = state->byte_count;
587 
588 	return 0;
589 }
590 
591 struct builder_state {
592 	unsigned int version;
593 	bool extended;
594 	enum code_id code_id;
595 
596 	unsigned int samples_per_frame;
597 	unsigned int bytes_per_sample;
598 };
599 
write_container_header(struct container_context * cntr,struct container_header * header)600 static int write_container_header(struct container_context *cntr,
601 				  struct container_header *header)
602 {
603 	struct builder_state *state = cntr->private_data;
604 
605 	// Process container header.
606 	memcpy(header->magic, VOC_MAGIC, sizeof(header->magic));
607 	header->hdr_size = htole16(sizeof(*header));
608 	header->version = htole16(state->version);
609 	header->version_compr = htole16(0x1234 + ~state->version);
610 
611 	return container_recursive_write(cntr, header, sizeof(*header));
612 }
613 
write_v120_format_block(struct container_context * cntr,struct block_v120_format * block,unsigned int frames_per_second,uint64_t byte_count)614 static int write_v120_format_block(struct container_context *cntr,
615 				   struct block_v120_format *block,
616 				   unsigned int frames_per_second,
617 				   uint64_t byte_count)
618 {
619 	struct builder_state *state = cntr->private_data;
620 
621 	block->type = BLOCK_TYPE_V120_DATA;
622 	build_block_data_size(block->size, 12 + byte_count);
623 
624 	block->frames_per_second = htole32(frames_per_second);
625 	block->bits_per_sample = state->bytes_per_sample * 8;
626 	block->samples_per_frame = state->samples_per_frame;
627 	block->code_id = htole16(state->code_id);
628 
629 	return container_recursive_write(cntr, block, sizeof(*block));
630 }
631 
write_extended_v110_format_block(struct container_context * cntr,unsigned int frames_per_second,struct block_extended_v110_format * block)632 static int write_extended_v110_format_block(struct container_context *cntr,
633 				unsigned int frames_per_second,
634 				struct block_extended_v110_format *block)
635 {
636 	struct builder_state *state = cntr->private_data;
637 	uint16_t time_const;
638 	int err;
639 
640 	block->type = BLOCK_TYPE_EXTENDED_V110_FORMAT;
641 	build_block_data_size(block->size, 4);
642 
643 	// 16 bits are available for this purpose.
644 	err = build_time_constant(frames_per_second, state->samples_per_frame,
645 				  &time_const, true);
646 	if (err < 0)
647 		return err;
648 	block->time_const = htole16(time_const);
649 	block->code_id = htole16(state->code_id);
650 
651 	if (state->samples_per_frame == 1)
652 		block->ch_mode = 0;
653 	else
654 		block->ch_mode = 1;
655 
656 	return container_recursive_write(cntr, block, sizeof(*block));
657 }
658 
write_v110_format_block(struct container_context * cntr,struct block_v110_data * block,unsigned int frames_per_second,uint64_t byte_count)659 static int write_v110_format_block(struct container_context *cntr,
660 				   struct block_v110_data *block,
661 				   unsigned int frames_per_second,
662 				   uint64_t byte_count)
663 {
664 	struct builder_state *state = cntr->private_data;
665 	uint16_t time_const;
666 	int err;
667 
668 	block->type = BLOCK_TYPE_V110_DATA;
669 	build_block_data_size(block->size, 2 + byte_count);
670 
671 	// These fields were obsoleted by extension.
672 	err = build_time_constant(frames_per_second, 1, &time_const, false);
673 	if (err < 0)
674 		return err;
675 	block->time_const = (uint8_t)time_const;
676 	block->code_id = state->code_id;
677 	return container_recursive_write(cntr, block, sizeof(*block));
678 }
679 
write_data_blocks(struct container_context * cntr,unsigned int frames_per_second,uint64_t byte_count)680 static int write_data_blocks(struct container_context *cntr,
681 			     unsigned int frames_per_second,
682 			     uint64_t byte_count)
683 {
684 	union {
685 		struct container_header header;
686 		struct block_v110_data v110_data;
687 		struct block_extended_v110_format extended_v110_format;
688 		struct block_v120_format v120_format;
689 	} buf = {0};
690 	struct builder_state *state = cntr->private_data;
691 	int err;
692 
693 	err = write_container_header(cntr, &buf.header);
694 	if (err < 0)
695 		return err;
696 
697 	if (state->version == VOC_VERSION_1_20) {
698 		err = write_v120_format_block(cntr, &buf.v120_format,
699 					      frames_per_second, byte_count);
700 	} else {
701 		if (state->extended) {
702 			err = write_extended_v110_format_block(cntr,
703 					frames_per_second,
704 					&buf.extended_v110_format);
705 			if (err < 0)
706 				return err;
707 		}
708 		err = write_v110_format_block(cntr, &buf.v110_data,
709 					      frames_per_second, byte_count);
710 	}
711 
712 	return err;
713 }
714 
voc_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)715 static int voc_builder_pre_process(struct container_context *cntr,
716 				   snd_pcm_format_t *format,
717 				   unsigned int *samples_per_frame,
718 				   unsigned int *frames_per_second,
719 				   uint64_t *byte_count)
720 {
721 	struct builder_state *state = cntr->private_data;
722 	int i;
723 
724 	// Validate parameters.
725 	for (i = 0; i < ARRAY_SIZE(format_maps); ++i) {
726 		if (format_maps[i].format == *format)
727 			break;
728 	}
729 	if (i == ARRAY_SIZE(format_maps))
730 		return -EINVAL;
731 	state->code_id = format_maps[i].code_id;
732 
733 	// Decide container version.
734 	if (*samples_per_frame > 2)
735 		state->version = VOC_VERSION_1_20;
736 	else
737 		state->version = format_maps[i].minimal_version;
738 	if (state->version == VOC_VERSION_1_10) {
739 		if (*samples_per_frame == 2) {
740 			for (i = 0;
741 			     i < ARRAY_SIZE(ex_v110_time_consts); ++i) {
742 				if (ex_v110_time_consts[i].frames_per_second ==
743 						*frames_per_second)
744 					break;
745 			}
746 			if (i == ARRAY_SIZE(ex_v110_time_consts))
747 				state->version = VOC_VERSION_1_20;
748 			else
749 				state->extended = true;
750 		} else {
751 			for (i = 0; i < ARRAY_SIZE(v110_time_consts); ++i) {
752 				if (v110_time_consts[i].frames_per_second ==
753 							*frames_per_second)
754 					break;
755 			}
756 			if (i == ARRAY_SIZE(v110_time_consts))
757 				state->version = VOC_VERSION_1_20;
758 		}
759 	}
760 
761 	state->bytes_per_sample = snd_pcm_format_physical_width(*format) / 8;
762 	state->samples_per_frame = *samples_per_frame;
763 
764 	return write_data_blocks(cntr, *frames_per_second, *byte_count);
765 }
766 
write_block_terminator(struct container_context * cntr)767 static int write_block_terminator(struct container_context *cntr)
768 {
769 	struct block_terminator block = {0};
770 
771 	block.type = BLOCK_TYPE_TERMINATOR;
772 	return container_recursive_write(cntr, &block, sizeof(block));
773 }
774 
write_data_size(struct container_context * cntr,uint64_t byte_count)775 static int write_data_size(struct container_context *cntr, uint64_t byte_count)
776 {
777 	struct builder_state *state = cntr->private_data;
778 	off64_t offset;
779 	uint8_t size_field[3];
780 	int err;
781 
782 	offset = sizeof(struct container_header) + sizeof(uint8_t);
783 	if (state->version == VOC_VERSION_1_10 && state->extended)
784 		offset += sizeof(struct block_extended_v110_format);
785 	err = container_seek_offset(cntr, offset);
786 	if (err < 0)
787 		return err;
788 
789 	if (state->version == VOC_VERSION_1_10)
790 		offset = 2;
791 	else
792 		offset = 12;
793 
794 	if (byte_count > cntr->max_size - offset)
795 		byte_count = cntr->max_size;
796 	else
797 		byte_count += offset;
798 	build_block_data_size(size_field, byte_count);
799 
800 	return container_recursive_write(cntr, &size_field, sizeof(size_field));
801 }
802 
voc_builder_post_process(struct container_context * cntr,uint64_t handled_byte_count)803 static int voc_builder_post_process(struct container_context *cntr,
804 				    uint64_t handled_byte_count)
805 {
806 	int err;
807 
808 	err = write_block_terminator(cntr);
809 	if (err < 0)
810 		return err;
811 
812 	return write_data_size(cntr, handled_byte_count);
813 }
814 
815 const struct container_parser container_parser_voc = {
816 	.format = CONTAINER_FORMAT_VOC,
817 	.magic = VOC_MAGIC,
818 	.max_size = 0xffffff -	// = UINT24_MAX.
819 		    sizeof(struct block_terminator),
820 	.ops = {
821 		.pre_process	= voc_parser_pre_process,
822 	},
823 	.private_size = sizeof(struct parser_state),
824 };
825 
826 const struct container_builder container_builder_voc = {
827 	.format = CONTAINER_FORMAT_VOC,
828 	.max_size = 0xffffff -	// = UINT24_MAX.
829 		    sizeof(struct block_terminator),
830 	.ops = {
831 		.pre_process	= voc_builder_pre_process,
832 		.post_process	= voc_builder_post_process,
833 	},
834 	.private_size = sizeof(struct builder_state),
835 };
836