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