xref: /third_party/libsnd/src/voc.c (revision b815c7f3)
1/*
2** Copyright (C) 2001-2018 Erik de Castro Lopo <erikd@mega-nerd.com>
3**
4** This program is free software; you can redistribute it and/or modify
5** it under the terms of the GNU Lesser General Public License as published by
6** the Free Software Foundation; either version 2.1 of the License, or
7** (at your option) any later version.
8**
9** This program is distributed in the hope that it will be useful,
10** but WITHOUT ANY WARRANTY; without even the implied warranty of
11** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12** GNU Lesser General Public License for more details.
13**
14** You should have received a copy of the GNU Lesser General Public License
15** along with this program; if not, write to the Free Software
16** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*/
18
19/*	RANT:
20**	The VOC file format is the most brain damaged format I have yet had to deal
21**	with. No one programmer could have bee stupid enough to put this together.
22**	Instead it looks like a series of manic, dyslexic assembly language programmers
23**	hacked it to fit their needs.
24**	Utterly woeful.
25*/
26
27#include "sfconfig.h"
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32
33#include "sndfile.h"
34#include "sfendian.h"
35#include "common.h"
36
37
38/*------------------------------------------------------------------------------
39 * Typedefs for file chunks.
40*/
41
42#define	VOC_MAX_SECTIONS	200
43
44enum
45{	VOC_TERMINATOR		= 0,
46	VOC_SOUND_DATA		= 1,
47	VOC_SOUND_CONTINUE	= 2,
48	VOC_SILENCE			= 3,
49	VOC_MARKER			= 4,
50	VOC_ASCII			= 5,
51	VOC_REPEAT			= 6,
52	VOC_END_REPEAT		= 7,
53	VOC_EXTENDED		= 8,
54	VOC_EXTENDED_II		= 9
55} ;
56
57typedef struct
58{	int 	samples ;
59	int		offset ;	/* Offset of zero => silence. */
60} SND_DATA_BLOCKS ;
61
62typedef struct
63{	unsigned int 	sections, section_types ;
64	int				samplerate, channels, bitwidth ;
65	SND_DATA_BLOCKS	blocks [VOC_MAX_SECTIONS] ;
66} VOC_DATA ;
67
68/*------------------------------------------------------------------------------
69 * Private static functions.
70*/
71
72static	int	voc_close	(SF_PRIVATE *psf) ;
73static	int voc_write_header (SF_PRIVATE *psf, int calc_length) ;
74static	int voc_read_header	(SF_PRIVATE *psf) ;
75
76static const char* voc_encoding2str (int encoding) ;
77
78#if 0
79
80/*	These functions would be required for files with more than one VOC_SOUND_DATA
81**	segment. Not sure whether to bother implementing this.
82*/
83
84static int	voc_multi_init (SF_PRIVATE *psf, VOC_DATA *pvoc) ;
85
86static int	voc_multi_read_uc2s		(SF_PRIVATE *psf, short *ptr, int len) ;
87static int	voc_multi_read_les2s	(SF_PRIVATE *psf, short *ptr, int len) ;
88
89static int	voc_multi_read_uc2i		(SF_PRIVATE *psf, int *ptr, int len) ;
90static int	voc_multi_read_les2i	(SF_PRIVATE *psf, int *ptr, int len) ;
91
92static int	voc_multi_read_uc2f		(SF_PRIVATE *psf, float *ptr, int len) ;
93static int	voc_multi_read_les2f	(SF_PRIVATE *psf, float *ptr, int len) ;
94
95static int	voc_multi_read_uc2d		(SF_PRIVATE *psf, double *ptr, int len) ;
96static int	voc_multi_read_les2d	(SF_PRIVATE *psf, double *ptr, int len) ;
97#endif
98
99/*------------------------------------------------------------------------------
100** Public function.
101*/
102
103int
104voc_open	(SF_PRIVATE *psf)
105{	int subformat, error = 0 ;
106
107	if (psf->is_pipe)
108		return SFE_VOC_NO_PIPE ;
109
110	if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
111	{	if ((error = voc_read_header (psf)))
112			return error ;
113		} ;
114
115	subformat = SF_CODEC (psf->sf.format) ;
116
117	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
118	{	if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_VOC)
119			return	SFE_BAD_OPEN_FORMAT ;
120
121		psf->endian = SF_ENDIAN_LITTLE ;
122
123		if ((error = voc_write_header (psf, SF_FALSE)))
124			return error ;
125
126		psf->write_header = voc_write_header ;
127		} ;
128
129	psf->blockwidth = psf->bytewidth * psf->sf.channels ;
130
131	psf->container_close = voc_close ;
132
133	switch (subformat)
134	{	case SF_FORMAT_PCM_U8 :
135		case SF_FORMAT_PCM_16 :
136				error = pcm_init (psf) ;
137				break ;
138
139		case SF_FORMAT_ALAW :
140				error = alaw_init (psf) ;
141				break ;
142
143		case SF_FORMAT_ULAW :
144				error = ulaw_init (psf) ;
145				break ;
146
147		default : return SFE_UNIMPLEMENTED ;
148		} ;
149
150	return error ;
151} /* voc_open */
152
153/*------------------------------------------------------------------------------
154*/
155
156static int
157voc_read_header	(SF_PRIVATE *psf)
158{	VOC_DATA	*pvoc ;
159	char	creative [20] ;
160	unsigned char block_type, rate_byte ;
161	short	version, checksum, encoding, dataoffset ;
162	int		offset ;
163
164	/* Set position to start of file to begin reading header. */
165	offset = psf_binheader_readf (psf, "pb", 0, creative, SIGNED_SIZEOF (creative)) ;
166
167	if (creative [sizeof (creative) - 1] != 0x1A)
168		return SFE_VOC_NO_CREATIVE ;
169
170	/* Terminate the string. */
171	creative [sizeof (creative) - 1] = 0 ;
172
173	if (strcmp ("Creative Voice File", creative))
174		return SFE_VOC_NO_CREATIVE ;
175
176	psf_log_printf (psf, "%s\n", creative) ;
177
178	offset += psf_binheader_readf (psf, "e222", &dataoffset, &version, &checksum) ;
179
180	psf->dataoffset = dataoffset ;
181
182	psf_log_printf (psf, 	"dataoffset : %d\n"
183							"version    : 0x%X\n"
184							"checksum   : 0x%X\n", psf->dataoffset, version, checksum) ;
185
186	if (version != 0x010A && version != 0x0114)
187		return SFE_VOC_BAD_VERSION ;
188
189	if (! (psf->codec_data = malloc (sizeof (VOC_DATA))))
190		return SFE_MALLOC_FAILED ;
191
192	pvoc = (VOC_DATA*) psf->codec_data ;
193
194	memset (pvoc, 0, sizeof (VOC_DATA)) ;
195
196	/* Set the default encoding now. */
197	psf->sf.format = SF_FORMAT_VOC ; /* Major format */
198	encoding = SF_FORMAT_PCM_U8 ; /* Minor format */
199	psf->endian = SF_ENDIAN_LITTLE ;
200
201	while (1)
202	{	char header [256] ;
203		unsigned size ;
204		short count ;
205
206		block_type = 0 ;
207		offset += psf_binheader_readf (psf, "1", &block_type) ;
208
209		switch (block_type)
210		{	case VOC_ASCII :
211					offset += psf_binheader_readf (psf, "e3", &size) ;
212
213					psf_log_printf (psf, " ASCII : %d\n", size) ;
214
215					if (size < sizeof (header) - 1)
216					{	offset += psf_binheader_readf (psf, "b", header, size) ;
217						header [size] = 0 ;
218						psf_log_printf (psf, "  text : %s\n", header) ;
219						continue ;
220						}
221
222					offset += psf_binheader_readf (psf, "j", size) ;
223					continue ;
224
225			case VOC_REPEAT :
226					offset += psf_binheader_readf (psf, "e32", &size, &count) ;
227					psf_log_printf (psf, " Repeat : %d\n", count) ;
228					continue ;
229
230			case VOC_SOUND_DATA :
231			case VOC_EXTENDED :
232			case VOC_EXTENDED_II :
233					break ;
234
235			default : psf_log_printf (psf, "*** Weird block marker (%d)\n", block_type) ;
236			} ;
237
238		break ;
239		} ;
240
241	if (block_type == VOC_SOUND_DATA)
242	{	unsigned char compression ;
243		int 	size ;
244
245		offset += psf_binheader_readf (psf, "e311", &size, &rate_byte, &compression) ;
246
247		psf->sf.samplerate = 1000000 / (256 - (rate_byte & 0xFF)) ;
248
249		psf_log_printf (psf, " Sound Data : %d\n  sr   : %d => %dHz\n  comp : %d\n",
250								size, rate_byte, psf->sf.samplerate, compression) ;
251
252		if (offset + size - 1 > psf->filelength)
253		{	psf_log_printf (psf, "Seems to be a truncated file.\n") ;
254			psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
255			return SFE_VOC_BAD_SECTIONS ;
256			}
257		else if (psf->filelength - offset - size > 4)
258		{	psf_log_printf (psf, "Seems to be a multi-segment file (#1).\n") ;
259			psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
260			return SFE_VOC_BAD_SECTIONS ;
261			} ;
262
263		psf->dataoffset = offset ;
264		psf->dataend	= psf->filelength - 1 ;
265
266		psf->sf.channels = 1 ;
267		psf->bytewidth = 1 ;
268
269		psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;
270
271		return 0 ;
272		} ;
273
274	if (block_type == VOC_EXTENDED)
275	{	unsigned char pack, stereo, compression ;
276		unsigned short rate_short ;
277		int		size ;
278
279		offset += psf_binheader_readf (psf, "e3211", &size, &rate_short, &pack, &stereo) ;
280
281		psf_log_printf (psf, " Extended : %d\n", size) ;
282		if (size == 4)
283			psf_log_printf (psf, "  size   : 4\n") ;
284		else
285			psf_log_printf (psf, "  size   : %d (should be 4)\n", size) ;
286
287		psf_log_printf (psf,	"  pack   : %d\n"
288								"  stereo : %s\n", pack, (stereo ? "yes" : "no")) ;
289
290		if (stereo)
291		{	psf->sf.channels = 2 ;
292			psf->sf.samplerate = 128000000 / (65536 - rate_short) ;
293			}
294		else
295		{	psf->sf.channels = 1 ;
296			psf->sf.samplerate = 256000000 / (65536 - rate_short) ;
297			} ;
298
299		psf_log_printf (psf, "  sr     : %d => %dHz\n", (rate_short & 0xFFFF), psf->sf.samplerate) ;
300
301		offset += psf_binheader_readf (psf, "1", &block_type) ;
302
303		if (block_type != VOC_SOUND_DATA)
304		{	psf_log_printf (psf, "*** Expecting VOC_SOUND_DATA section.\n") ;
305			return SFE_VOC_BAD_FORMAT ;
306			} ;
307
308		offset += psf_binheader_readf (psf, "e311", &size, &rate_byte, &compression) ;
309
310		psf_log_printf (psf,	" Sound Data : %d\n"
311								"  sr     : %d\n"
312								"  comp   : %d\n", size, rate_byte, compression) ;
313
314
315		if (offset + size - 1 > psf->filelength)
316		{	psf_log_printf (psf, "Seems to be a truncated file.\n") ;
317			psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
318			return SFE_VOC_BAD_SECTIONS ;
319			}
320		else if (offset + size - 1 < psf->filelength)
321		{	psf_log_printf (psf, "Seems to be a multi-segment file (#2).\n") ;
322			psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
323			return SFE_VOC_BAD_SECTIONS ;
324			} ;
325
326		psf->dataoffset = offset ;
327		psf->dataend = psf->filelength - 1 ;
328
329		psf->bytewidth = 1 ;
330
331		psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;
332
333		return 0 ;
334		}
335
336	if (block_type == VOC_EXTENDED_II)
337	{	unsigned char bitwidth, channels ;
338		int size, fourbytes ;
339
340		offset += psf_binheader_readf (psf, "e341124", &size, &psf->sf.samplerate,
341								&bitwidth, &channels, &encoding, &fourbytes) ;
342
343		if (size * 2 == psf->filelength - 39)
344		{	int temp_size = psf->filelength - 31 ;
345
346			psf_log_printf (psf, " Extended II : %d (SoX bug: should be %d)\n", size, temp_size) ;
347			size = temp_size ;
348			}
349		else
350			psf_log_printf (psf, " Extended II : %d\n", size) ;
351
352		psf_log_printf (psf,	"  sample rate : %d\n"
353								"  bit width   : %d\n"
354								"  channels    : %d\n", psf->sf.samplerate, bitwidth, channels) ;
355
356		if (bitwidth == 16 && encoding == 0)
357		{	encoding = 4 ;
358			psf_log_printf (psf, "  encoding    : 0 (SoX bug: should be 4 for 16 bit signed PCM)\n") ;
359			}
360		else
361			psf_log_printf (psf, "  encoding    : %d => %s\n", encoding, voc_encoding2str (encoding)) ;
362
363
364		psf_log_printf (psf, "  fourbytes   : %X\n", fourbytes) ;
365
366		psf->sf.channels = channels ;
367
368		psf->dataoffset = offset ;
369		psf->dataend	= psf->filelength - 1 ;
370
371		if (size + 31 == psf->filelength + 1)
372		{	/* Hack for reading files produced using
373			** sf_command (SFC_UPDATE_HEADER_NOW).
374			*/
375			psf_log_printf (psf, "Missing zero byte at end of file.\n") ;
376			size = psf->filelength - 30 ;
377			psf->dataend = 0 ;
378			}
379		else if (size + 31 > psf->filelength)
380		{	psf_log_printf (psf, "Seems to be a truncated file.\n") ;
381			size = psf->filelength - 31 ;
382			}
383		else if (size + 31 < psf->filelength)
384			psf_log_printf (psf, "Seems to be a multi-segment file (#3).\n") ;
385
386		switch (encoding)
387		{	case 0 :
388					psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;
389					psf->bytewidth = 1 ;
390					break ;
391
392			case 4 :
393					psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_16 ;
394					psf->bytewidth = 2 ;
395					break ;
396
397			case 6 :
398					psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_ALAW ;
399					psf->bytewidth = 1 ;
400					break ;
401
402			case 7 :
403					psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_ULAW ;
404					psf->bytewidth = 1 ;
405					break ;
406
407			default : /* Unknown */
408					return SFE_VOC_BAD_FORMAT ;
409					break ;
410			} ;
411
412		} ;
413
414	return 0 ;
415} /* voc_read_header */
416
417/*====================================================================================
418*/
419
420static int
421voc_write_header (SF_PRIVATE *psf, int calc_length)
422{	sf_count_t	current ;
423	int			rate_const, subformat ;
424
425	current = psf_ftell (psf) ;
426
427	if (calc_length)
428	{	psf->filelength = psf_get_filelen (psf) ;
429
430		psf->datalength = psf->filelength - psf->dataoffset ;
431		if (psf->dataend)
432			psf->datalength -= psf->filelength - psf->dataend ;
433
434		psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
435		} ;
436
437	subformat = SF_CODEC (psf->sf.format) ;
438	/* Reset the current header length to zero. */
439	psf->header.ptr [0] = 0 ;
440	psf->header.indx = 0 ;
441	psf_fseek (psf, 0, SEEK_SET) ;
442
443	/* VOC marker and 0x1A byte. */
444	psf_binheader_writef (psf, "eb1", BHWv ("Creative Voice File"), BHWz (19), BHW1 (0x1A)) ;
445
446	/* Data offset, version and other. */
447	psf_binheader_writef (psf, "e222", BHW2 (26), BHW2 (0x0114), BHW2 (0x111F)) ;
448
449	/*	Use same logic as SOX.
450	**	If the file is mono 8 bit data, use VOC_SOUND_DATA.
451	**	If the file is mono 16 bit data, use VOC_EXTENED.
452	**	Otherwise use VOC_EXTENED_2.
453	*/
454
455	if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 1)
456	{	/* samplerate = 1000000 / (256 - rate_const) ; */
457		rate_const = 256 - 1000000 / psf->sf.samplerate ;
458
459		/* First type marker, length, rate_const and compression */
460		psf_binheader_writef (psf, "e1311", BHW1 (VOC_SOUND_DATA), BHW3 ((int) (psf->datalength + 1)), BHW1 (rate_const), BHW1 (0)) ;
461		}
462	else if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 2)
463	{	/* sample_rate = 128000000 / (65536 - rate_short) ; */
464		rate_const = 65536 - 128000000 / psf->sf.samplerate ;
465
466		/* First write the VOC_EXTENDED section
467		** 		marker, length, rate_const and compression
468		*/
469		psf_binheader_writef (psf, "e13211", BHW1 (VOC_EXTENDED), BHW3 (4), BHW2 (rate_const), BHW1 (0), BHW1 (1)) ;
470
471		/* samplerate = 1000000 / (256 - rate_const) ; */
472		rate_const = 256 - 1000000 / psf->sf.samplerate ;
473
474		/*	Now write the VOC_SOUND_DATA section
475		** 		marker, length, rate_const and compression
476		*/
477		psf_binheader_writef (psf, "e1311", BHW1 (VOC_SOUND_DATA), BHW3 ((int) (psf->datalength + 1)), BHW1 (rate_const), BHW1 (0)) ;
478		}
479	else
480	{	int length ;
481
482		if (psf->sf.channels < 1 || psf->sf.channels > 2)
483			return SFE_CHANNEL_COUNT ;
484
485		switch (subformat)
486		{	case SF_FORMAT_PCM_U8 :
487					psf->bytewidth = 1 ;
488					length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
489					/* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */
490					psf_binheader_writef (psf, "e1341124", BHW1 (VOC_EXTENDED_II), BHW3 (length), BHW4 (psf->sf.samplerate), BHW1 (16), BHW1 (psf->sf.channels), BHW2 (4), BHW4 (0)) ;
491					break ;
492
493			case SF_FORMAT_PCM_16 :
494					psf->bytewidth = 2 ;
495					length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
496					/* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */
497					psf_binheader_writef (psf, "e1341124", BHW1 (VOC_EXTENDED_II), BHW3 (length), BHW4 (psf->sf.samplerate), BHW1 (16), BHW1 (psf->sf.channels), BHW2 (4), BHW4 (0)) ;
498					break ;
499
500			case SF_FORMAT_ALAW :
501					psf->bytewidth = 1 ;
502					length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
503					psf_binheader_writef (psf, "e1341124", BHW1 (VOC_EXTENDED_II), BHW3 (length), BHW4 (psf->sf.samplerate), BHW1 (8), BHW1 (psf->sf.channels), BHW2 (6), BHW4 (0)) ;
504					break ;
505
506			case SF_FORMAT_ULAW :
507					psf->bytewidth = 1 ;
508					length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
509					psf_binheader_writef (psf, "e1341124", BHW1 (VOC_EXTENDED_II), BHW3 (length), BHW4 (psf->sf.samplerate), BHW1 (8), BHW1 (psf->sf.channels), BHW2 (7), BHW4 (0)) ;
510					break ;
511
512			default : return SFE_UNIMPLEMENTED ;
513			} ;
514		} ;
515
516	psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;
517
518	if (psf->error)
519		return psf->error ;
520
521	psf->dataoffset = psf->header.indx ;
522
523	if (current > 0)
524		psf_fseek (psf, current, SEEK_SET) ;
525
526	return psf->error ;
527} /* voc_write_header */
528
529static int
530voc_close	(SF_PRIVATE *psf)
531{
532	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
533	{	/*  Now we know for certain the length of the file we can re-write
534		**	correct values for the FORM, 8SVX and BODY chunks.
535		*/
536		unsigned char byte = VOC_TERMINATOR ;
537
538
539		psf_fseek (psf, 0, SEEK_END) ;
540
541		/* Write terminator */
542		psf_fwrite (&byte, 1, 1, psf) ;
543
544		voc_write_header (psf, SF_TRUE) ;
545		} ;
546
547	return 0 ;
548} /* voc_close */
549
550static const 	char*
551voc_encoding2str (int encoding)
552{
553	switch (encoding)
554	{	case 0 :	return "8 bit unsigned PCM" ;
555		case 4 :	return "16 bit signed PCM" ;
556		case 6 :	return "A-law" ;
557		case 7 :	return "u-law" ;
558		default :	break ;
559		}
560	return "*** Unknown ***" ;
561} /* voc_encoding2str */
562
563/*====================================================================================
564*/
565
566#if 0
567static int
568voc_multi_init (SF_PRIVATE *psf, VOC_DATA *pvoc)
569{
570	psf->sf.frames = 0 ;
571
572	if (pvoc->bitwidth == 8)
573	{	psf->read_short		= voc_multi_read_uc2s ;
574		psf->read_int		= voc_multi_read_uc2i ;
575		psf->read_float		= voc_multi_read_uc2f ;
576		psf->read_double	= voc_multi_read_uc2d ;
577		return 0 ;
578		} ;
579
580	if (pvoc->bitwidth == 16)
581	{	psf->read_short		= voc_multi_read_les2s ;
582		psf->read_int		= voc_multi_read_les2i ;
583		psf->read_float		= voc_multi_read_les2f ;
584		psf->read_double	= voc_multi_read_les2d ;
585		return 0 ;
586		} ;
587
588	psf_log_printf (psf, "Error : bitwith != 8 && bitwidth != 16.\n") ;
589
590	return SFE_UNIMPLEMENTED ;
591} /* voc_multi_read_int */
592
593/*------------------------------------------------------------------------------------
594*/
595
596static int
597voc_multi_read_uc2s (SF_PRIVATE *psf, short *ptr, int len)
598{
599
600	return 0 ;
601} /* voc_multi_read_uc2s */
602
603static int
604voc_multi_read_les2s (SF_PRIVATE *psf, short *ptr, int len)
605{
606
607	return 0 ;
608} /* voc_multi_read_les2s */
609
610
611static int
612voc_multi_read_uc2i (SF_PRIVATE *psf, int *ptr, int len)
613{
614
615	return 0 ;
616} /* voc_multi_read_uc2i */
617
618static int
619voc_multi_read_les2i (SF_PRIVATE *psf, int *ptr, int len)
620{
621
622	return 0 ;
623} /* voc_multi_read_les2i */
624
625
626static int
627voc_multi_read_uc2f (SF_PRIVATE *psf, float *ptr, int len)
628{
629
630	return 0 ;
631} /* voc_multi_read_uc2f */
632
633static int
634voc_multi_read_les2f (SF_PRIVATE *psf, float *ptr, int len)
635{
636
637	return 0 ;
638} /* voc_multi_read_les2f */
639
640
641static int
642voc_multi_read_uc2d (SF_PRIVATE *psf, double *ptr, int len)
643{
644
645	return 0 ;
646} /* voc_multi_read_uc2d */
647
648static int
649voc_multi_read_les2d (SF_PRIVATE *psf, double *ptr, int len)
650{
651
652	return 0 ;
653} /* voc_multi_read_les2d */
654
655#endif
656
657/*------------------------------------------------------------------------------------
658
659Creative Voice (VOC) file format
660--------------------------------
661
662~From: galt@dsd.es.com
663
664(byte numbers are hex!)
665
666    HEADER (bytes 00-19)
667    Series of DATA BLOCKS (bytes 1A+) [Must end w/ Terminator Block]
668
669- ---------------------------------------------------------------
670
671HEADER:
672=======
673     byte #     Description
674     ------     ------------------------------------------
675     00-12      "Creative Voice File"
676     13         1A (eof to abort printing of file)
677     14-15      Offset of first datablock in .voc file (std 1A 00
678                in Intel Notation)
679     16-17      Version number (minor,major) (VOC-HDR puts 0A 01)
680     18-19      1's Comp of Ver. # + 1234h (VOC-HDR puts 29 11)
681
682- ---------------------------------------------------------------
683
684DATA BLOCK:
685===========
686
687   Data Block:  TYPE(1-byte), SIZE(3-bytes), INFO(0+ bytes)
688   NOTE: Terminator Block is an exception -- it has only the TYPE byte.
689
690      TYPE   Description     Size (3-byte int)   Info
691      ----   -----------     -----------------   -----------------------
692      00     Terminator      (NONE)              (NONE)
693      01     Sound data      2+length of data    *
694      02     Sound continue  length of data      Voice Data
695      03     Silence         3                   **
696      04     Marker          2                   Marker# (2 bytes)
697      05     ASCII           length of string    null terminated string
698      06     Repeat          2                   Count# (2 bytes)
699      07     End repeat      0                   (NONE)
700      08     Extended        4                   ***
701
702      *Sound Info Format:
703       ---------------------
704       00   Sample Rate
705       01   Compression Type
706       02+  Voice Data
707
708      **Silence Info Format:
709      ----------------------------
710      00-01  Length of silence - 1
711      02     Sample Rate
712
713
714    ***Extended Info Format:
715       ---------------------
716       00-01  Time Constant: Mono: 65536 - (256000000/sample_rate)
717                             Stereo: 65536 - (25600000/(2*sample_rate))
718       02     Pack
719       03     Mode: 0 = mono
720                    1 = stereo
721
722
723  Marker#           -- Driver keeps the most recent marker in a status byte
724  Count#            -- Number of repetitions + 1
725                         Count# may be 1 to FFFE for 0 - FFFD repetitions
726                         or FFFF for endless repetitions
727  Sample Rate       -- SR byte = 256-(1000000/sample_rate)
728  Length of silence -- in units of sampling cycle
729  Compression Type  -- of voice data
730                         8-bits    = 0
731                         4-bits    = 1
732                         2.6-bits  = 2
733                         2-bits    = 3
734                         Multi DAC = 3+(# of channels) [interesting--
735                                       this isn't in the developer's manual]
736
737
738---------------------------------------------------------------------------------
739Addendum submitted by Votis Kokavessis:
740
741After some experimenting with .VOC files I found out that there is a Data Block
742Type 9, which is not covered in the VOC.TXT file. Here is what I was able to discover
743about this block type:
744
745
746TYPE: 09
747SIZE: 12 + length of data
748INFO: 12 (twelve) bytes
749
750INFO STRUCTURE:
751
752Bytes 0-1: (Word) Sample Rate (e.g. 44100)
753Bytes 2-3: zero (could be that bytes 0-3 are a DWord for Sample Rate)
754Byte 4: Sample Size in bits (e.g. 16)
755Byte 5: Number of channels (e.g. 1 for mono, 2 for stereo)
756Byte 6: Unknown (equal to 4 in all files I examined)
757Bytes 7-11: zero
758
759
760-------------------------------------------------------------------------------------*/
761
762/*=====================================================================================
763**=====================================================================================
764**=====================================================================================
765**=====================================================================================
766*/
767
768/*------------------------------------------------------------------------
769The following is taken from the Audio File Formats FAQ dated 2-Jan-1995
770and submitted by Guido van Rossum <guido@cwi.nl>.
771--------------------------------------------------------------------------
772Creative Voice (VOC) file format
773--------------------------------
774
775From: galt@dsd.es.com
776
777(byte numbers are hex!)
778
779    HEADER (bytes 00-19)
780    Series of DATA BLOCKS (bytes 1A+) [Must end w/ Terminator Block]
781
782- ---------------------------------------------------------------
783
784HEADER:
785-------
786     byte #     Description
787     ------     ------------------------------------------
788     00-12      "Creative Voice File"
789     13         1A (eof to abort printing of file)
790     14-15      Offset of first datablock in .voc file (std 1A 00
791                in Intel Notation)
792     16-17      Version number (minor,major) (VOC-HDR puts 0A 01)
793     18-19      2's Comp of Ver. # + 1234h (VOC-HDR puts 29 11)
794
795- ---------------------------------------------------------------
796
797DATA BLOCK:
798-----------
799
800   Data Block:  TYPE(1-byte), SIZE(3-bytes), INFO(0+ bytes)
801   NOTE: Terminator Block is an exception -- it has only the TYPE byte.
802
803      TYPE   Description     Size (3-byte int)   Info
804      ----   -----------     -----------------   -----------------------
805      00     Terminator      (NONE)              (NONE)
806      01     Sound data      2+length of data    *
807      02     Sound continue  length of data      Voice Data
808      03     Silence         3                   **
809      04     Marker          2                   Marker# (2 bytes)
810      05     ASCII           length of string    null terminated string
811      06     Repeat          2                   Count# (2 bytes)
812      07     End repeat      0                   (NONE)
813      08     Extended        4                   ***
814
815      *Sound Info Format:       **Silence Info Format:
816       ---------------------      ----------------------------
817       00   Sample Rate           00-01  Length of silence - 1
818       01   Compression Type      02     Sample Rate
819       02+  Voice Data
820
821    ***Extended Info Format:
822       ---------------------
823       00-01  Time Constant: Mono: 65536 - (256000000/sample_rate)
824                             Stereo: 65536 - (25600000/(2*sample_rate))
825       02     Pack
826       03     Mode: 0 = mono
827                    1 = stereo
828
829
830  Marker#           -- Driver keeps the most recent marker in a status byte
831  Count#            -- Number of repetitions + 1
832                         Count# may be 1 to FFFE for 0 - FFFD repetitions
833                         or FFFF for endless repetitions
834  Sample Rate       -- SR byte = 256-(1000000/sample_rate)
835  Length of silence -- in units of sampling cycle
836  Compression Type  -- of voice data
837                         8-bits    = 0
838                         4-bits    = 1
839                         2.6-bits  = 2
840                         2-bits    = 3
841                         Multi DAC = 3+(# of channels) [interesting--
842                                       this isn't in the developer's manual]
843
844Detailed description of new data blocks (VOC files version 1.20 and above):
845
846        (Source is fax from Barry Boone at Creative Labs, 405/742-6622)
847
848BLOCK 8 - digitized sound attribute extension, must preceed block 1.
849          Used to define stereo, 8 bit audio
850        BYTE bBlockID;       // = 8
851        BYTE nBlockLen[3];   // 3 byte length
852        WORD wTimeConstant;  // time constant = same as block 1
853        BYTE bPackMethod;    // same as in block 1
854        BYTE bVoiceMode;     // 0-mono, 1-stereo
855
856        Data is stored left, right
857
858BLOCK 9 - data block that supersedes blocks 1 and 8.
859          Used for stereo, 16 bit.
860
861        BYTE bBlockID;          // = 9
862        BYTE nBlockLen[3];      // length 12 plus length of sound
863        DWORD dwSamplesPerSec;  // samples per second, not time const.
864        BYTE bBitsPerSample;    // e.g., 8 or 16
865        BYTE bChannels;         // 1 for mono, 2 for stereo
866        WORD wFormat;           // see below
867        BYTE reserved[4];       // pad to make block w/o data
868                                // have a size of 16 bytes
869
870        Valid values of wFormat are:
871
872                0x0000  8-bit unsigned PCM
873                0x0001  Creative 8-bit to 4-bit ADPCM
874                0x0002  Creative 8-bit to 3-bit ADPCM
875                0x0003  Creative 8-bit to 2-bit ADPCM
876                0x0004  16-bit signed PCM
877                0x0006  CCITT a-Law
878                0x0007  CCITT u-Law
879                0x02000 Creative 16-bit to 4-bit ADPCM
880
881        Data is stored left, right
882
883------------------------------------------------------------------------*/
884