2
** Copyright (C) 2005 Erik de Castro Lopo <erikd@mega-nerd.com>
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.
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.
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.
28
#include "float_cast.h"
31
/*------------------------------------------------------------------------------
32
** Macros to handle big/little endian issues.
35
#define aac_MARKER MAKE_MARKER ('a', 'a', 'c', ' ')
36
#define alac_MARKER MAKE_MARKER ('a', 'l', 'a', 'c')
37
#define alaw_MARKER MAKE_MARKER ('a', 'l', 'a', 'w')
38
#define caff_MARKER MAKE_MARKER ('c', 'a', 'f', 'f')
39
#define chan_MARKER MAKE_MARKER ('c', 'h', 'a', 'n')
40
#define data_MARKER MAKE_MARKER ('d', 'a', 't', 'a')
41
#define desc_MARKER MAKE_MARKER ('d', 'e', 's', 'c')
42
#define edct_MARKER MAKE_MARKER ('e', 'd', 'c', 't')
43
#define free_MARKER MAKE_MARKER ('f', 'r', 'e', 'e')
44
#define ima4_MARKER MAKE_MARKER ('i', 'm', 'a', '4')
45
#define info_MARKER MAKE_MARKER ('i', 'n', 'f', 'o')
46
#define inst_MARKER MAKE_MARKER ('i', 'n', 's', 't')
47
#define kuki_MARKER MAKE_MARKER ('k', 'u', 'k', 'i')
48
#define lpcm_MARKER MAKE_MARKER ('l', 'p', 'c', 'm')
49
#define mark_MARKER MAKE_MARKER ('m', 'a', 'r', 'k')
50
#define midi_MARKER MAKE_MARKER ('m', 'i', 'd', 'i')
51
#define mp1_MARKER MAKE_MARKER ('.', 'm', 'p', '1')
52
#define mp2_MARKER MAKE_MARKER ('.', 'm', 'p', '2')
53
#define mp3_MARKER MAKE_MARKER ('.', 'm', 'p', '3')
54
#define ovvw_MARKER MAKE_MARKER ('o', 'v', 'v', 'w')
55
#define pakt_MARKER MAKE_MARKER ('p', 'a', 'k', 't')
56
#define peak_MARKER MAKE_MARKER ('p', 'e', 'a', 'k')
57
#define regn_MARKER MAKE_MARKER ('r', 'e', 'g', 'n')
58
#define strg_MARKER MAKE_MARKER ('s', 't', 'r', 'g')
59
#define umid_MARKER MAKE_MARKER ('u', 'm', 'i', 'd')
60
#define uuid_MARKER MAKE_MARKER ('u', 'u', 'i', 'd')
61
#define ulaw_MARKER MAKE_MARKER ('u', 'l', 'a', 'w')
62
#define MAC3_MARKER MAKE_MARKER ('M', 'A', 'C', '3')
63
#define MAC6_MARKER MAKE_MARKER ('M', 'A', 'C', '6')
65
#define CAF_PEAK_CHUNK_SIZE(ch) (sizeof (int) + ch * (sizeof (float) + 8))
67
#define SFE_CAF_NOT_CAF 666
68
#define SFE_CAF_NO_DESC 667
69
#define SFE_CAF_BAD_PEAK 668
71
/*------------------------------------------------------------------------------
76
{ unsigned char srate [8] ;
78
unsigned int fmt_flags ;
79
unsigned int pkt_bytes ;
80
unsigned int pkt_frames ;
81
unsigned int channels_per_frame ;
82
unsigned int bits_per_chan ;
85
/*------------------------------------------------------------------------------
86
** Private static functions.
89
static int caf_close (SF_PRIVATE *psf) ;
90
static int caf_read_header (SF_PRIVATE *psf) ;
91
static int caf_write_header (SF_PRIVATE *psf, int calc_length) ;
93
/*------------------------------------------------------------------------------
98
caf_open (SF_PRIVATE *psf)
99
{ int subformat, format, error = 0 ;
101
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
102
{ if ((error = caf_read_header (psf)))
106
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
108
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
110
return SFE_NO_PIPE_WRITE ;
112
format = psf->sf.format & SF_FORMAT_TYPEMASK ;
113
if (format != SF_FORMAT_CAF)
114
return SFE_BAD_OPEN_FORMAT ;
116
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
118
if (psf->mode != SFM_RDWR || psf->filelength < 44)
119
{ psf->filelength = 0 ;
120
psf->datalength = 0 ;
121
psf->dataoffset = 0 ;
125
psf->str_flags = SF_STR_ALLOW_START ;
128
** By default, add the peak chunk to floating point files. Default behaviour
129
** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
131
if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
132
{ if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
133
return SFE_MALLOC_FAILED ;
134
psf->peak_info->peak_loc = SF_PEAK_START ;
137
if ((error = caf_write_header (psf, SF_FALSE)) != 0)
140
psf->write_header = caf_write_header ;
143
psf->container_close = caf_close ;
144
/*psf->command = caf_command ;*/
147
{ case SF_FORMAT_PCM_S8 :
148
case SF_FORMAT_PCM_16 :
149
case SF_FORMAT_PCM_24 :
150
case SF_FORMAT_PCM_32 :
151
error = pcm_init (psf) ;
154
case SF_FORMAT_ULAW :
155
error = ulaw_init (psf) ;
158
case SF_FORMAT_ALAW :
159
error = alaw_init (psf) ;
162
/* Lite remove start */
163
case SF_FORMAT_FLOAT :
164
error = float32_init (psf) ;
167
case SF_FORMAT_DOUBLE :
168
error = double64_init (psf) ;
170
/* Lite remove end */
173
return SFE_UNSUPPORTED_ENCODING ;
180
caf_close (SF_PRIVATE *psf)
182
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
183
caf_write_header (psf, SF_TRUE) ;
188
/*------------------------------------------------------------------------------
192
decode_desc_chunk (SF_PRIVATE *psf, const DESC_CHUNK *desc)
195
psf->sf.channels = desc->channels_per_frame ;
197
format = SF_FORMAT_CAF | (psf->endian == SF_ENDIAN_LITTLE ? SF_ENDIAN_LITTLE : 0) ;
199
if (desc->fmt_id == lpcm_MARKER && desc->fmt_flags & 1)
200
{ /* Floating point data. */
201
if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
202
{ psf->bytewidth = 4 ;
203
return format | SF_FORMAT_FLOAT ;
205
if (desc->bits_per_chan == 64 && desc->pkt_bytes == 8 * desc->channels_per_frame)
206
{ psf->bytewidth = 8 ;
207
return format | SF_FORMAT_DOUBLE ;
211
if ((desc->fmt_flags & 1) != 0)
212
{ psf_log_printf (psf, "**** Ooops, 'desc' chunk suggests float data, but other info invalid.\n") ;
216
if (desc->fmt_id == lpcm_MARKER)
217
{ /* Integer data. */
218
if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
219
{ psf->bytewidth = 4 ;
220
return format | SF_FORMAT_PCM_32 ;
222
if (desc->bits_per_chan == 24 && desc->pkt_bytes == 3 * desc->channels_per_frame)
223
{ psf->bytewidth = 3 ;
224
return format | SF_FORMAT_PCM_24 ;
226
if (desc->bits_per_chan == 16 && desc->pkt_bytes == 2 * desc->channels_per_frame)
227
{ psf->bytewidth = 2 ;
228
return format | SF_FORMAT_PCM_16 ;
230
if (desc->bits_per_chan == 8 && desc->pkt_bytes == 1 * desc->channels_per_frame)
231
{ psf->bytewidth = 1 ;
232
return format | SF_FORMAT_PCM_S8 ;
236
if (desc->fmt_id == alaw_MARKER && desc->bits_per_chan == 8)
237
{ psf->bytewidth = 1 ;
238
return format | SF_FORMAT_ALAW ;
241
if (desc->fmt_id == ulaw_MARKER && desc->bits_per_chan == 8)
242
{ psf->bytewidth = 1 ;
243
return format | SF_FORMAT_ULAW ;
247
} /* decode_desc_chunk */
250
caf_read_header (SF_PRIVATE *psf)
252
sf_count_t chunk_size ;
254
short version, flags ;
255
int marker, k, have_data = 0 ;
257
memset (&desc, 0, sizeof (desc)) ;
259
/* Set position to start of file to begin reading header. */
260
psf_binheader_readf (psf, "pmE2E2", 0, &marker, &version, &flags) ;
261
psf_log_printf (psf, "%M\n Version : %d\n Flags : %x\n", marker, version, flags) ;
262
if (marker != caff_MARKER)
263
return SFE_CAF_NOT_CAF ;
265
psf_binheader_readf (psf, "mE8b", &marker, &chunk_size, psf->u.ucbuf, 8) ;
266
srate = double64_be_read (psf->u.ucbuf) ;
267
LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), "%5.3f", srate) ;
268
psf_log_printf (psf, "%M : %D\n Sample rate : %s\n", marker, chunk_size, psf->u.cbuf) ;
269
if (marker != desc_MARKER)
270
return SFE_CAF_NO_DESC ;
272
if (chunk_size < sizeof (DESC_CHUNK))
273
{ psf_log_printf (psf, "**** Chunk size too small. Should be > 32 bytes.\n") ;
274
return SFE_MALFORMED_FILE ;
277
psf->sf.samplerate = lrint (srate) ;
279
psf_binheader_readf (psf, "mE44444", &desc.fmt_id, &desc.fmt_flags, &desc.pkt_bytes, &desc.pkt_frames,
280
&desc.channels_per_frame, &desc.bits_per_chan) ;
281
psf_log_printf (psf, " Format id : %M\n Format flags : %x\n Bytes / packet : %u\n"
282
" Frames / packet : %u\n Channels / frame : %u\n Bits / channel : %u\n",
283
desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
285
if (chunk_size > sizeof (DESC_CHUNK))
286
psf_binheader_readf (psf, "j", (int) (chunk_size - sizeof (DESC_CHUNK))) ;
288
psf->sf.channels = desc.channels_per_frame ;
290
while (have_data == 0 && psf_ftell (psf) < psf->filelength - SIGNED_SIZEOF (marker))
291
{ psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ;
295
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
296
if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels))
297
{ psf_binheader_readf (psf, "j", (int) chunk_size) ;
298
psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
299
return SFE_CAF_BAD_PEAK ;
302
if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
303
return SFE_MALLOC_FAILED ;
305
/* read in rest of PEAK chunk. */
306
psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ;
307
psf_log_printf (psf, " edit count : %d\n", psf->peak_info->edit_number) ;
309
psf_log_printf (psf, " Ch Position Value\n") ;
310
for (k = 0 ; k < psf->sf.channels ; k++)
311
{ sf_count_t position ;
314
psf_binheader_readf (psf, "Ef8", &value, &position) ;
315
psf->peak_info->peaks [k].value = value ;
316
psf->peak_info->peaks [k].position = position ;
318
LSF_SNPRINTF (psf->u.cbuf, sizeof (psf->u.cbuf), " %2d %-12ld %g\n", k, (long) position, value) ;
319
psf_log_printf (psf, psf->u.cbuf) ;
322
psf->peak_info->peak_loc = SF_PEAK_START ;
326
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
327
psf_binheader_readf (psf, "j", (int) chunk_size) ;
331
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
332
psf_binheader_readf (psf, "E4", &k) ;
333
psf_log_printf (psf, " edit : %u\n", k) ;
338
psf_log_printf (psf, " %M : %D (skipped)\n", marker, chunk_size) ;
339
psf_binheader_readf (psf, "j", (int) chunk_size) ;
345
{ psf_log_printf (psf, "**** Error, could not find 'data' chunk.\n") ;
346
return SFE_MALFORMED_FILE ;
349
psf_log_printf (psf, "End\n") ;
351
psf->dataoffset = psf_ftell (psf) ;
352
psf->datalength = psf->filelength - psf->dataoffset ;
353
psf->endian = (desc.fmt_flags & 2) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
355
if ((psf->sf.format = decode_desc_chunk (psf, &desc)) == 0)
356
return SFE_UNSUPPORTED_ENCODING ;
358
if (psf->bytewidth > 0)
359
psf->sf.frames = psf->datalength / psf->bytewidth ;
362
} /* caf_read_header */
364
/*------------------------------------------------------------------------------
368
caf_write_header (SF_PRIVATE *psf, int calc_length)
370
sf_count_t current, free_len ;
373
memset (&desc, 0, sizeof (desc)) ;
375
current = psf_ftell (psf) ;
378
{ psf->filelength = psf_get_filelen (psf) ;
380
psf->datalength = psf->filelength - psf->dataoffset ;
383
psf->datalength -= psf->filelength - psf->dataend ;
385
if (psf->bytewidth > 0)
386
psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
389
/* Reset the current header length to zero. */
390
psf->header [0] = 0 ;
392
psf_fseek (psf, 0, SEEK_SET) ;
394
/* 'caff' marker, version and flags. */
395
psf_binheader_writef (psf, "Em22", caff_MARKER, 1, 0) ;
397
/* 'desc' marker and chunk size. */
398
psf_binheader_writef (psf, "Em8", desc_MARKER, (sf_count_t) (sizeof (DESC_CHUNK))) ;
400
double64_be_write (1.0 * psf->sf.samplerate, psf->u.ucbuf) ;
401
psf_binheader_writef (psf, "b", psf->u.ucbuf, 8) ;
403
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
405
psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;
407
if (CPU_IS_BIG_ENDIAN && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU))
408
psf->endian = SF_ENDIAN_BIG ;
409
else if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_LITTLE || psf->endian == SF_ENDIAN_CPU))
410
psf->endian = SF_ENDIAN_LITTLE ;
412
if (psf->endian == SF_ENDIAN_LITTLE)
415
psf->endian = SF_ENDIAN_BIG ;
417
/* initial section (same for all, it appears) */
419
{ case SF_FORMAT_PCM_S8 :
420
desc.fmt_id = lpcm_MARKER ;
422
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
423
desc.pkt_frames = 1 ;
424
desc.channels_per_frame = psf->sf.channels ;
425
desc.bits_per_chan = 8 ;
428
case SF_FORMAT_PCM_16 :
429
desc.fmt_id = lpcm_MARKER ;
431
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
432
desc.pkt_frames = 1 ;
433
desc.channels_per_frame = psf->sf.channels ;
434
desc.bits_per_chan = 16 ;
437
case SF_FORMAT_PCM_24 :
439
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
440
desc.pkt_frames = 1 ;
441
desc.channels_per_frame = psf->sf.channels ;
442
desc.bits_per_chan = 24 ;
443
desc.fmt_id = lpcm_MARKER ;
446
case SF_FORMAT_PCM_32 :
447
desc.fmt_id = lpcm_MARKER ;
449
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
450
desc.pkt_frames = 1 ;
451
desc.channels_per_frame = psf->sf.channels ;
452
desc.bits_per_chan = 32 ;
455
case SF_FORMAT_FLOAT :
456
desc.fmt_id = lpcm_MARKER ;
457
desc.fmt_flags |= 1 ;
459
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
460
desc.pkt_frames = 1 ;
461
desc.channels_per_frame = psf->sf.channels ;
462
desc.bits_per_chan = 32 ;
465
case SF_FORMAT_DOUBLE :
466
desc.fmt_id = lpcm_MARKER ;
467
desc.fmt_flags |= 1 ;
469
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
470
desc.pkt_frames = 1 ;
471
desc.channels_per_frame = psf->sf.channels ;
472
desc.bits_per_chan = 64 ;
475
case SF_FORMAT_ALAW :
476
desc.fmt_id = alaw_MARKER ;
478
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
479
desc.pkt_frames = 1 ;
480
desc.channels_per_frame = psf->sf.channels ;
481
desc.bits_per_chan = 8 ;
484
case SF_FORMAT_ULAW :
485
desc.fmt_id = ulaw_MARKER ;
487
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
488
desc.pkt_frames = 1 ;
489
desc.channels_per_frame = psf->sf.channels ;
490
desc.bits_per_chan = 8 ;
494
return SFE_UNIMPLEMENTED ;
497
psf_binheader_writef (psf, "mE44444", desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
500
if (psf->str_flags & SF_STR_LOCATE_START)
501
caf_write_strings (psf, SF_STR_LOCATE_START) ;
504
if (psf->peak_info != NULL)
506
psf_binheader_writef (psf, "Em84", peak_MARKER, (sf_count_t) CAF_PEAK_CHUNK_SIZE (psf->sf.channels), psf->peak_info->edit_number) ;
507
for (k = 0 ; k < psf->sf.channels ; k++)
508
psf_binheader_writef (psf, "Ef8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
511
/* Add free chunk so that the actual audio data starts at a multiple 0x1000. */
512
free_len = 0x1000 - psf->headindex - 16 - 12 ;
515
psf_binheader_writef (psf, "Em8z", free_MARKER, free_len, (int) free_len) ;
517
psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength, 0) ;
519
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
523
psf->dataoffset = psf->headindex ;
524
if (current < psf->dataoffset)
525
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
526
else if (current > 0)
527
psf_fseek (psf, current, SEEK_SET) ;
530
} /* caf_write_header */
533
** Do not edit or modify anything in this comment block.
534
** The arch-tag line is a file identity tag for the GNU Arch
535
** revision control system.
537
** arch-tag: 65883e65-bd3c-4618-9241-d3c02fd630bd