blob: d13b03311b6794cac170ea46bc117e7adca6fab0 [file] [log] [blame]
Alexandre Lision7c6f4a62013-09-05 13:27:01 -04001/*
2** Copyright (C) 2001-2011 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 { unsigned size ;
203 short count ;
204
205 block_type = 0 ;
206 offset += psf_binheader_readf (psf, "1", &block_type) ;
207
208 switch (block_type)
209 { case VOC_ASCII :
210 offset += psf_binheader_readf (psf, "e3", &size) ;
211
212 psf_log_printf (psf, " ASCII : %d\n", size) ;
213
214 if (size < sizeof (psf->header) - 1)
215 { offset += psf_binheader_readf (psf, "b", psf->header, size) ;
216 psf->header [size] = 0 ;
217 psf_log_printf (psf, " text : %s\n", psf->header) ;
218 continue ;
219 }
220
221 offset += psf_binheader_readf (psf, "j", size) ;
222 continue ;
223
224 case VOC_REPEAT :
225 offset += psf_binheader_readf (psf, "e32", &size, &count) ;
226 psf_log_printf (psf, " Repeat : %d\n", count) ;
227 continue ;
228
229 case VOC_SOUND_DATA :
230 case VOC_EXTENDED :
231 case VOC_EXTENDED_II :
232 break ;
233
234 default : psf_log_printf (psf, "*** Weird block marker (%d)\n", block_type) ;
235 } ;
236
237 break ;
238 } ;
239
240 if (block_type == VOC_SOUND_DATA)
241 { unsigned char compression ;
242 int size ;
243
244 offset += psf_binheader_readf (psf, "e311", &size, &rate_byte, &compression) ;
245
246 psf->sf.samplerate = 1000000 / (256 - (rate_byte & 0xFF)) ;
247
248 psf_log_printf (psf, " Sound Data : %d\n sr : %d => %dHz\n comp : %d\n",
249 size, rate_byte, psf->sf.samplerate, compression) ;
250
251 if (offset + size - 1 > psf->filelength)
252 { psf_log_printf (psf, "Seems to be a truncated file.\n") ;
253 psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ;
254 return SFE_VOC_BAD_SECTIONS ;
255 }
256 else if (psf->filelength - offset - size > 4)
257 { psf_log_printf (psf, "Seems to be a multi-segment file (#1).\n") ;
258 psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ;
259 return SFE_VOC_BAD_SECTIONS ;
260 } ;
261
262 psf->dataoffset = offset ;
263 psf->dataend = psf->filelength - 1 ;
264
265 psf->sf.channels = 1 ;
266 psf->bytewidth = 1 ;
267
268 psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;
269
270 return 0 ;
271 } ;
272
273 if (block_type == VOC_EXTENDED)
274 { unsigned char pack, stereo, compression ;
275 unsigned short rate_short ;
276 int size ;
277
278 offset += psf_binheader_readf (psf, "e3211", &size, &rate_short, &pack, &stereo) ;
279
280 psf_log_printf (psf, " Extended : %d\n", size) ;
281 if (size == 4)
282 psf_log_printf (psf, " size : 4\n") ;
283 else
284 psf_log_printf (psf, " size : %d (should be 4)\n", size) ;
285
286 psf_log_printf (psf, " pack : %d\n"
287 " stereo : %s\n", pack, (stereo ? "yes" : "no")) ;
288
289 if (stereo)
290 { psf->sf.channels = 2 ;
291 psf->sf.samplerate = 128000000 / (65536 - rate_short) ;
292 }
293 else
294 { psf->sf.channels = 1 ;
295 psf->sf.samplerate = 256000000 / (65536 - rate_short) ;
296 } ;
297
298 psf_log_printf (psf, " sr : %d => %dHz\n", (rate_short & 0xFFFF), psf->sf.samplerate) ;
299
300 offset += psf_binheader_readf (psf, "1", &block_type) ;
301
302 if (block_type != VOC_SOUND_DATA)
303 { psf_log_printf (psf, "*** Expecting VOC_SOUND_DATA section.\n") ;
304 return SFE_VOC_BAD_FORMAT ;
305 } ;
306
307 offset += psf_binheader_readf (psf, "e311", &size, &rate_byte, &compression) ;
308
309 psf_log_printf (psf, " Sound Data : %d\n"
310 " sr : %d\n"
311 " comp : %d\n", size, rate_byte, compression) ;
312
313
314 if (offset + size - 1 > psf->filelength)
315 { psf_log_printf (psf, "Seems to be a truncated file.\n") ;
316 psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ;
317 return SFE_VOC_BAD_SECTIONS ;
318 }
319 else if (offset + size - 1 < psf->filelength)
320 { psf_log_printf (psf, "Seems to be a multi-segment file (#2).\n") ;
321 psf_log_printf (psf, "offset: %d size: %d sum: %d filelength: %D\n", offset, size, offset + size, psf->filelength) ;
322 return SFE_VOC_BAD_SECTIONS ;
323 } ;
324
325 psf->dataoffset = offset ;
326 psf->dataend = psf->filelength - 1 ;
327
328 psf->bytewidth = 1 ;
329
330 psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;
331
332 return 0 ;
333 }
334
335 if (block_type == VOC_EXTENDED_II)
336 { unsigned char bitwidth, channels ;
337 int size, fourbytes ;
338
339 offset += psf_binheader_readf (psf, "e341124", &size, &psf->sf.samplerate,
340 &bitwidth, &channels, &encoding, &fourbytes) ;
341
342 if (size * 2 == psf->filelength - 39)
343 { int temp_size = psf->filelength - 31 ;
344
345 psf_log_printf (psf, " Extended II : %d (SoX bug: should be %d)\n", size, temp_size) ;
346 size = temp_size ;
347 }
348 else
349 psf_log_printf (psf, " Extended II : %d\n", size) ;
350
351 psf_log_printf (psf, " sample rate : %d\n"
352 " bit width : %d\n"
353 " channels : %d\n", psf->sf.samplerate, bitwidth, channels) ;
354
355 if (bitwidth == 16 && encoding == 0)
356 { encoding = 4 ;
357 psf_log_printf (psf, " encoding : 0 (SoX bug: should be 4 for 16 bit signed PCM)\n") ;
358 }
359 else
360 psf_log_printf (psf, " encoding : %d => %s\n", encoding, voc_encoding2str (encoding)) ;
361
362
363 psf_log_printf (psf, " fourbytes : %X\n", fourbytes) ;
364
365 psf->sf.channels = channels ;
366
367 psf->dataoffset = offset ;
368 psf->dataend = psf->filelength - 1 ;
369
370 if (size + 31 == psf->filelength + 1)
371 { /* Hack for reading files produced using
372 ** sf_command (SFC_UPDATE_HEADER_NOW).
373 */
374 psf_log_printf (psf, "Missing zero byte at end of file.\n") ;
375 size = psf->filelength - 30 ;
376 psf->dataend = 0 ;
377 }
378 else if (size + 31 > psf->filelength)
379 { psf_log_printf (psf, "Seems to be a truncated file.\n") ;
380 size = psf->filelength - 31 ;
381 }
382 else if (size + 31 < psf->filelength)
383 psf_log_printf (psf, "Seems to be a multi-segment file (#3).\n") ;
384
385 switch (encoding)
386 { case 0 :
387 psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;
388 psf->bytewidth = 1 ;
389 break ;
390
391 case 4 :
392 psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_16 ;
393 psf->bytewidth = 2 ;
394 break ;
395
396 case 6 :
397 psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_ALAW ;
398 psf->bytewidth = 1 ;
399 break ;
400
401 case 7 :
402 psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_ULAW ;
403 psf->bytewidth = 1 ;
404 break ;
405
406 default : /* Unknown */
407 return SFE_UNKNOWN_FORMAT ;
408 break ;
409 } ;
410
411 } ;
412
413 return 0 ;
414} /* voc_read_header */
415
416/*====================================================================================
417*/
418
419static int
420voc_write_header (SF_PRIVATE *psf, int calc_length)
421{ sf_count_t current ;
422 int rate_const, subformat ;
423
424 current = psf_ftell (psf) ;
425
426 if (calc_length)
427 { psf->filelength = psf_get_filelen (psf) ;
428
429 psf->datalength = psf->filelength - psf->dataoffset ;
430 if (psf->dataend)
431 psf->datalength -= psf->filelength - psf->dataend ;
432
433 psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
434 } ;
435
436 subformat = SF_CODEC (psf->sf.format) ;
437 /* Reset the current header length to zero. */
438 psf->header [0] = 0 ;
439 psf->headindex = 0 ;
440 psf_fseek (psf, 0, SEEK_SET) ;
441
442 /* VOC marker and 0x1A byte. */
443 psf_binheader_writef (psf, "eb1", "Creative Voice File", make_size_t (19), 0x1A) ;
444
445 /* Data offset, version and other. */
446 psf_binheader_writef (psf, "e222", 26, 0x0114, 0x111F) ;
447
448 /* Use same logic as SOX.
449 ** If the file is mono 8 bit data, use VOC_SOUND_DATA.
450 ** If the file is mono 16 bit data, use VOC_EXTENED.
451 ** Otherwise use VOC_EXTENED_2.
452 */
453
454 if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 1)
455 { /* samplerate = 1000000 / (256 - rate_const) ; */
456 rate_const = 256 - 1000000 / psf->sf.samplerate ;
457
458 /* First type marker, length, rate_const and compression */
459 psf_binheader_writef (psf, "e1311", VOC_SOUND_DATA, (int) (psf->datalength + 1), rate_const, 0) ;
460 }
461 else if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 2)
462 { /* sample_rate = 128000000 / (65536 - rate_short) ; */
463 rate_const = 65536 - 128000000 / psf->sf.samplerate ;
464
465 /* First write the VOC_EXTENDED section
466 ** marker, length, rate_const and compression
467 */
468 psf_binheader_writef (psf, "e13211", VOC_EXTENDED, 4, rate_const, 0, 1) ;
469
470 /* samplerate = 1000000 / (256 - rate_const) ; */
471 rate_const = 256 - 1000000 / psf->sf.samplerate ;
472
473 /* Now write the VOC_SOUND_DATA section
474 ** marker, length, rate_const and compression
475 */
476 psf_binheader_writef (psf, "e1311", VOC_SOUND_DATA, (int) (psf->datalength + 1), rate_const, 0) ;
477 }
478 else
479 { int length ;
480
481 if (psf->sf.channels < 1 || psf->sf.channels > 2)
482 return SFE_CHANNEL_COUNT ;
483
484 switch (subformat)
485 { case SF_FORMAT_PCM_U8 :
486 psf->bytewidth = 1 ;
487 length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
488 /* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */
489 psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 16, psf->sf.channels, 4, 0) ;
490 break ;
491
492 case SF_FORMAT_PCM_16 :
493 psf->bytewidth = 2 ;
494 length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
495 /* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */
496 psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 16, psf->sf.channels, 4, 0) ;
497 break ;
498
499 case SF_FORMAT_ALAW :
500 psf->bytewidth = 1 ;
501 length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
502 psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 8, psf->sf.channels, 6, 0) ;
503 break ;
504
505 case SF_FORMAT_ULAW :
506 psf->bytewidth = 1 ;
507 length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
508 psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 8, psf->sf.channels, 7, 0) ;
509 break ;
510
511 default : return SFE_UNIMPLEMENTED ;
512 } ;
513 } ;
514
515 psf_fwrite (psf->header, psf->headindex, 1, psf) ;
516
517 if (psf->error)
518 return psf->error ;
519
520 psf->dataoffset = psf->headindex ;
521
522 if (current > 0)
523 psf_fseek (psf, current, SEEK_SET) ;
524
525 return psf->error ;
526} /* voc_write_header */
527
528static int
529voc_close (SF_PRIVATE *psf)
530{
531 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
532 { /* Now we know for certain the length of the file we can re-write
533 ** correct values for the FORM, 8SVX and BODY chunks.
534 */
535 unsigned char byte = VOC_TERMINATOR ;
536
537
538 psf_fseek (psf, 0, SEEK_END) ;
539
540 /* Write terminator */
541 psf_fwrite (&byte, 1, 1, psf) ;
542
543 voc_write_header (psf, SF_TRUE) ;
544 } ;
545
546 return 0 ;
547} /* voc_close */
548
549static const char*
550voc_encoding2str (int encoding)
551{
552 switch (encoding)
553 { case 0 : return "8 bit unsigned PCM" ;
554 case 4 : return "16 bit signed PCM" ;
555 case 6 : return "A-law" ;
556 case 7 : return "u-law" ;
557 default : break ;
558 }
559 return "*** Unknown ***" ;
560} /* voc_encoding2str */
561
562/*====================================================================================
563*/
564
565#if 0
566static int
567voc_multi_init (SF_PRIVATE *psf, VOC_DATA *pvoc)
568{
569 psf->sf.frames = 0 ;
570
571 if (pvoc->bitwidth == 8)
572 { psf->read_short = voc_multi_read_uc2s ;
573 psf->read_int = voc_multi_read_uc2i ;
574 psf->read_float = voc_multi_read_uc2f ;
575 psf->read_double = voc_multi_read_uc2d ;
576 return 0 ;
577 } ;
578
579 if (pvoc->bitwidth == 16)
580 { psf->read_short = voc_multi_read_les2s ;
581 psf->read_int = voc_multi_read_les2i ;
582 psf->read_float = voc_multi_read_les2f ;
583 psf->read_double = voc_multi_read_les2d ;
584 return 0 ;
585 } ;
586
587 psf_log_printf (psf, "Error : bitwith != 8 && bitwidth != 16.\n") ;
588
589 return SFE_UNIMPLEMENTED ;
590} /* voc_multi_read_int */
591
592/*------------------------------------------------------------------------------------
593*/
594
595static int
596voc_multi_read_uc2s (SF_PRIVATE *psf, short *ptr, int len)
597{
598
599 return 0 ;
600} /* voc_multi_read_uc2s */
601
602static int
603voc_multi_read_les2s (SF_PRIVATE *psf, short *ptr, int len)
604{
605
606 return 0 ;
607} /* voc_multi_read_les2s */
608
609
610static int
611voc_multi_read_uc2i (SF_PRIVATE *psf, int *ptr, int len)
612{
613
614 return 0 ;
615} /* voc_multi_read_uc2i */
616
617static int
618voc_multi_read_les2i (SF_PRIVATE *psf, int *ptr, int len)
619{
620
621 return 0 ;
622} /* voc_multi_read_les2i */
623
624
625static int
626voc_multi_read_uc2f (SF_PRIVATE *psf, float *ptr, int len)
627{
628
629 return 0 ;
630} /* voc_multi_read_uc2f */
631
632static int
633voc_multi_read_les2f (SF_PRIVATE *psf, float *ptr, int len)
634{
635
636 return 0 ;
637} /* voc_multi_read_les2f */
638
639
640static int
641voc_multi_read_uc2d (SF_PRIVATE *psf, double *ptr, int len)
642{
643
644 return 0 ;
645} /* voc_multi_read_uc2d */
646
647static int
648voc_multi_read_les2d (SF_PRIVATE *psf, double *ptr, int len)
649{
650
651 return 0 ;
652} /* voc_multi_read_les2d */
653
654#endif
655
656/*------------------------------------------------------------------------------------
657
658Creative Voice (VOC) file format
659--------------------------------
660
661~From: galt@dsd.es.com
662
663(byte numbers are hex!)
664
665 HEADER (bytes 00-19)
666 Series of DATA BLOCKS (bytes 1A+) [Must end w/ Terminator Block]
667
668- ---------------------------------------------------------------
669
670HEADER:
671=======
672 byte # Description
673 ------ ------------------------------------------
674 00-12 "Creative Voice File"
675 13 1A (eof to abort printing of file)
676 14-15 Offset of first datablock in .voc file (std 1A 00
677 in Intel Notation)
678 16-17 Version number (minor,major) (VOC-HDR puts 0A 01)
679 18-19 1's Comp of Ver. # + 1234h (VOC-HDR puts 29 11)
680
681- ---------------------------------------------------------------
682
683DATA BLOCK:
684===========
685
686 Data Block: TYPE(1-byte), SIZE(3-bytes), INFO(0+ bytes)
687 NOTE: Terminator Block is an exception -- it has only the TYPE byte.
688
689 TYPE Description Size (3-byte int) Info
690 ---- ----------- ----------------- -----------------------
691 00 Terminator (NONE) (NONE)
692 01 Sound data 2+length of data *
693 02 Sound continue length of data Voice Data
694 03 Silence 3 **
695 04 Marker 2 Marker# (2 bytes)
696 05 ASCII length of string null terminated string
697 06 Repeat 2 Count# (2 bytes)
698 07 End repeat 0 (NONE)
699 08 Extended 4 ***
700
701 *Sound Info Format:
702 ---------------------
703 00 Sample Rate
704 01 Compression Type
705 02+ Voice Data
706
707 **Silence Info Format:
708 ----------------------------
709 00-01 Length of silence - 1
710 02 Sample Rate
711
712
713 ***Extended Info Format:
714 ---------------------
715 00-01 Time Constant: Mono: 65536 - (256000000/sample_rate)
716 Stereo: 65536 - (25600000/(2*sample_rate))
717 02 Pack
718 03 Mode: 0 = mono
719 1 = stereo
720
721
722 Marker# -- Driver keeps the most recent marker in a status byte
723 Count# -- Number of repetitions + 1
724 Count# may be 1 to FFFE for 0 - FFFD repetitions
725 or FFFF for endless repetitions
726 Sample Rate -- SR byte = 256-(1000000/sample_rate)
727 Length of silence -- in units of sampling cycle
728 Compression Type -- of voice data
729 8-bits = 0
730 4-bits = 1
731 2.6-bits = 2
732 2-bits = 3
733 Multi DAC = 3+(# of channels) [interesting--
734 this isn't in the developer's manual]
735
736
737---------------------------------------------------------------------------------
738Addendum submitted by Votis Kokavessis:
739
740After some experimenting with .VOC files I found out that there is a Data Block
741Type 9, which is not covered in the VOC.TXT file. Here is what I was able to discover
742about this block type:
743
744
745TYPE: 09
746SIZE: 12 + length of data
747INFO: 12 (twelve) bytes
748
749INFO STRUCTURE:
750
751Bytes 0-1: (Word) Sample Rate (e.g. 44100)
752Bytes 2-3: zero (could be that bytes 0-3 are a DWord for Sample Rate)
753Byte 4: Sample Size in bits (e.g. 16)
754Byte 5: Number of channels (e.g. 1 for mono, 2 for stereo)
755Byte 6: Unknown (equal to 4 in all files I examined)
756Bytes 7-11: zero
757
758
759-------------------------------------------------------------------------------------*/
760
761/*=====================================================================================
762**=====================================================================================
763**=====================================================================================
764**=====================================================================================
765*/
766
767/*------------------------------------------------------------------------
768The following is taken from the Audio File Formats FAQ dated 2-Jan-1995
769and submitted by Guido van Rossum <guido@cwi.nl>.
770--------------------------------------------------------------------------
771Creative Voice (VOC) file format
772--------------------------------
773
774From: galt@dsd.es.com
775
776(byte numbers are hex!)
777
778 HEADER (bytes 00-19)
779 Series of DATA BLOCKS (bytes 1A+) [Must end w/ Terminator Block]
780
781- ---------------------------------------------------------------
782
783HEADER:
784-------
785 byte # Description
786 ------ ------------------------------------------
787 00-12 "Creative Voice File"
788 13 1A (eof to abort printing of file)
789 14-15 Offset of first datablock in .voc file (std 1A 00
790 in Intel Notation)
791 16-17 Version number (minor,major) (VOC-HDR puts 0A 01)
792 18-19 2's Comp of Ver. # + 1234h (VOC-HDR puts 29 11)
793
794- ---------------------------------------------------------------
795
796DATA BLOCK:
797-----------
798
799 Data Block: TYPE(1-byte), SIZE(3-bytes), INFO(0+ bytes)
800 NOTE: Terminator Block is an exception -- it has only the TYPE byte.
801
802 TYPE Description Size (3-byte int) Info
803 ---- ----------- ----------------- -----------------------
804 00 Terminator (NONE) (NONE)
805 01 Sound data 2+length of data *
806 02 Sound continue length of data Voice Data
807 03 Silence 3 **
808 04 Marker 2 Marker# (2 bytes)
809 05 ASCII length of string null terminated string
810 06 Repeat 2 Count# (2 bytes)
811 07 End repeat 0 (NONE)
812 08 Extended 4 ***
813
814 *Sound Info Format: **Silence Info Format:
815 --------------------- ----------------------------
816 00 Sample Rate 00-01 Length of silence - 1
817 01 Compression Type 02 Sample Rate
818 02+ Voice Data
819
820 ***Extended Info Format:
821 ---------------------
822 00-01 Time Constant: Mono: 65536 - (256000000/sample_rate)
823 Stereo: 65536 - (25600000/(2*sample_rate))
824 02 Pack
825 03 Mode: 0 = mono
826 1 = stereo
827
828
829 Marker# -- Driver keeps the most recent marker in a status byte
830 Count# -- Number of repetitions + 1
831 Count# may be 1 to FFFE for 0 - FFFD repetitions
832 or FFFF for endless repetitions
833 Sample Rate -- SR byte = 256-(1000000/sample_rate)
834 Length of silence -- in units of sampling cycle
835 Compression Type -- of voice data
836 8-bits = 0
837 4-bits = 1
838 2.6-bits = 2
839 2-bits = 3
840 Multi DAC = 3+(# of channels) [interesting--
841 this isn't in the developer's manual]
842
843Detailed description of new data blocks (VOC files version 1.20 and above):
844
845 (Source is fax from Barry Boone at Creative Labs, 405/742-6622)
846
847BLOCK 8 - digitized sound attribute extension, must preceed block 1.
848 Used to define stereo, 8 bit audio
849 BYTE bBlockID; // = 8
850 BYTE nBlockLen[3]; // 3 byte length
851 WORD wTimeConstant; // time constant = same as block 1
852 BYTE bPackMethod; // same as in block 1
853 BYTE bVoiceMode; // 0-mono, 1-stereo
854
855 Data is stored left, right
856
857BLOCK 9 - data block that supersedes blocks 1 and 8.
858 Used for stereo, 16 bit.
859
860 BYTE bBlockID; // = 9
861 BYTE nBlockLen[3]; // length 12 plus length of sound
862 DWORD dwSamplesPerSec; // samples per second, not time const.
863 BYTE bBitsPerSample; // e.g., 8 or 16
864 BYTE bChannels; // 1 for mono, 2 for stereo
865 WORD wFormat; // see below
866 BYTE reserved[4]; // pad to make block w/o data
867 // have a size of 16 bytes
868
869 Valid values of wFormat are:
870
871 0x0000 8-bit unsigned PCM
872 0x0001 Creative 8-bit to 4-bit ADPCM
873 0x0002 Creative 8-bit to 3-bit ADPCM
874 0x0003 Creative 8-bit to 2-bit ADPCM
875 0x0004 16-bit signed PCM
876 0x0006 CCITT a-Law
877 0x0007 CCITT u-Law
878 0x02000 Creative 16-bit to 4-bit ADPCM
879
880 Data is stored left, right
881
882------------------------------------------------------------------------*/