~ubuntu-branches/ubuntu/gutsy/audacity/gutsy-backports

« back to all changes in this revision

Viewing changes to lib-src/libsndfile/src/voc.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-18 21:58:19 UTC
  • mfrom: (13.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080218215819-tmbcf1rx238r8gdv
Tags: 1.3.4-1.1ubuntu1~gutsy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

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