libsndfile source files.
[Faustine.git] / interpretor / libsndfile-1.0.25 / src / caf.c
1 /*
2 ** Copyright (C) 2005-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 #include "sfconfig.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <math.h>
26 #include <inttypes.h>
27
28 #include "sndfile.h"
29 #include "sfendian.h"
30 #include "common.h"
31 #include "chanmap.h"
32
33 /*------------------------------------------------------------------------------
34 ** Macros to handle big/little endian issues.
35 */
36
37 #define aac_MARKER MAKE_MARKER ('a', 'a', 'c', ' ')
38 #define alac_MARKER MAKE_MARKER ('a', 'l', 'a', 'c')
39 #define alaw_MARKER MAKE_MARKER ('a', 'l', 'a', 'w')
40 #define caff_MARKER MAKE_MARKER ('c', 'a', 'f', 'f')
41 #define chan_MARKER MAKE_MARKER ('c', 'h', 'a', 'n')
42 #define data_MARKER MAKE_MARKER ('d', 'a', 't', 'a')
43 #define desc_MARKER MAKE_MARKER ('d', 'e', 's', 'c')
44 #define edct_MARKER MAKE_MARKER ('e', 'd', 'c', 't')
45 #define free_MARKER MAKE_MARKER ('f', 'r', 'e', 'e')
46 #define ima4_MARKER MAKE_MARKER ('i', 'm', 'a', '4')
47 #define info_MARKER MAKE_MARKER ('i', 'n', 'f', 'o')
48 #define inst_MARKER MAKE_MARKER ('i', 'n', 's', 't')
49 #define kuki_MARKER MAKE_MARKER ('k', 'u', 'k', 'i')
50 #define lpcm_MARKER MAKE_MARKER ('l', 'p', 'c', 'm')
51 #define mark_MARKER MAKE_MARKER ('m', 'a', 'r', 'k')
52 #define midi_MARKER MAKE_MARKER ('m', 'i', 'd', 'i')
53 #define mp1_MARKER MAKE_MARKER ('.', 'm', 'p', '1')
54 #define mp2_MARKER MAKE_MARKER ('.', 'm', 'p', '2')
55 #define mp3_MARKER MAKE_MARKER ('.', 'm', 'p', '3')
56 #define ovvw_MARKER MAKE_MARKER ('o', 'v', 'v', 'w')
57 #define pakt_MARKER MAKE_MARKER ('p', 'a', 'k', 't')
58 #define peak_MARKER MAKE_MARKER ('p', 'e', 'a', 'k')
59 #define regn_MARKER MAKE_MARKER ('r', 'e', 'g', 'n')
60 #define strg_MARKER MAKE_MARKER ('s', 't', 'r', 'g')
61 #define umid_MARKER MAKE_MARKER ('u', 'm', 'i', 'd')
62 #define uuid_MARKER MAKE_MARKER ('u', 'u', 'i', 'd')
63 #define ulaw_MARKER MAKE_MARKER ('u', 'l', 'a', 'w')
64 #define MAC3_MARKER MAKE_MARKER ('M', 'A', 'C', '3')
65 #define MAC6_MARKER MAKE_MARKER ('M', 'A', 'C', '6')
66
67 #define CAF_PEAK_CHUNK_SIZE(ch) ((int) (sizeof (int) + ch * (sizeof (float) + 8)))
68
69 #define SFE_CAF_NOT_CAF 666
70 #define SFE_CAF_NO_DESC 667
71 #define SFE_CAF_BAD_PEAK 668
72
73 /*------------------------------------------------------------------------------
74 ** Typedefs.
75 */
76
77 typedef struct
78 { unsigned char srate [8] ;
79 unsigned int fmt_id ;
80 unsigned int fmt_flags ;
81 unsigned int pkt_bytes ;
82 unsigned int pkt_frames ;
83 unsigned int channels_per_frame ;
84 unsigned int bits_per_chan ;
85 } DESC_CHUNK ;
86
87 typedef struct
88 { int chanmap_tag ;
89 } CAF_PRIVATE ;
90
91 /*------------------------------------------------------------------------------
92 ** Private static functions.
93 */
94
95 static int caf_close (SF_PRIVATE *psf) ;
96 static int caf_read_header (SF_PRIVATE *psf) ;
97 static int caf_write_header (SF_PRIVATE *psf, int calc_length) ;
98 static int caf_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
99 static int caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size) ;
100
101 /*------------------------------------------------------------------------------
102 ** Public function.
103 */
104
105 int
106 caf_open (SF_PRIVATE *psf)
107 { int subformat, format, error = 0 ;
108
109 if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
110 { if ((error = caf_read_header (psf)))
111 return error ;
112 } ;
113
114 subformat = SF_CODEC (psf->sf.format) ;
115
116 if ((psf->container_data = calloc (1, sizeof (CAF_PRIVATE))) == NULL)
117 return SFE_MALLOC_FAILED ;
118
119 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
120 { if (psf->is_pipe)
121 return SFE_NO_PIPE_WRITE ;
122
123 format = SF_CONTAINER (psf->sf.format) ;
124 if (format != SF_FORMAT_CAF)
125 return SFE_BAD_OPEN_FORMAT ;
126
127 psf->blockwidth = psf->bytewidth * psf->sf.channels ;
128
129 if (psf->file.mode != SFM_RDWR || psf->filelength < 44)
130 { psf->filelength = 0 ;
131 psf->datalength = 0 ;
132 psf->dataoffset = 0 ;
133 psf->sf.frames = 0 ;
134 } ;
135
136 psf->str_flags = SF_STR_ALLOW_START ;
137
138 /*
139 ** By default, add the peak chunk to floating point files. Default behaviour
140 ** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
141 */
142 if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
143 { if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
144 return SFE_MALLOC_FAILED ;
145 psf->peak_info->peak_loc = SF_PEAK_START ;
146 } ;
147
148 if ((error = caf_write_header (psf, SF_FALSE)) != 0)
149 return error ;
150
151 psf->write_header = caf_write_header ;
152 } ;
153
154 psf->container_close = caf_close ;
155 psf->command = caf_command ;
156
157 switch (subformat)
158 { case SF_FORMAT_PCM_S8 :
159 case SF_FORMAT_PCM_16 :
160 case SF_FORMAT_PCM_24 :
161 case SF_FORMAT_PCM_32 :
162 error = pcm_init (psf) ;
163 break ;
164
165 case SF_FORMAT_ULAW :
166 error = ulaw_init (psf) ;
167 break ;
168
169 case SF_FORMAT_ALAW :
170 error = alaw_init (psf) ;
171 break ;
172
173 /* Lite remove start */
174 case SF_FORMAT_FLOAT :
175 error = float32_init (psf) ;
176 break ;
177
178 case SF_FORMAT_DOUBLE :
179 error = double64_init (psf) ;
180 break ;
181 /* Lite remove end */
182
183 default :
184 return SFE_UNSUPPORTED_ENCODING ;
185 } ;
186
187 return error ;
188 } /* caf_open */
189
190 static int
191 caf_close (SF_PRIVATE *psf)
192 {
193 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
194 caf_write_header (psf, SF_TRUE) ;
195
196 return 0 ;
197 } /* caf_close */
198
199 static int
200 caf_command (SF_PRIVATE * psf, int command, void * UNUSED (data), int UNUSED (datasize))
201 { CAF_PRIVATE *pcaf ;
202
203 if ((pcaf = psf->container_data) == NULL)
204 return SFE_INTERNAL ;
205
206 switch (command)
207 { case SFC_SET_CHANNEL_MAP_INFO :
208 pcaf->chanmap_tag = aiff_caf_find_channel_layout_tag (psf->channel_map, psf->sf.channels) ;
209 return (pcaf->chanmap_tag != 0) ;
210
211 default :
212 break ;
213 } ;
214
215 return 0 ;
216 } /* caf_command */
217
218 /*------------------------------------------------------------------------------
219 */
220
221 static int
222 decode_desc_chunk (SF_PRIVATE *psf, const DESC_CHUNK *desc)
223 { int format ;
224
225 psf->sf.channels = desc->channels_per_frame ;
226
227 format = SF_FORMAT_CAF | (psf->endian == SF_ENDIAN_LITTLE ? SF_ENDIAN_LITTLE : 0) ;
228
229 if (desc->fmt_id == lpcm_MARKER && desc->fmt_flags & 1)
230 { /* Floating point data. */
231 if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
232 { psf->bytewidth = 4 ;
233 return format | SF_FORMAT_FLOAT ;
234 } ;
235 if (desc->bits_per_chan == 64 && desc->pkt_bytes == 8 * desc->channels_per_frame)
236 { psf->bytewidth = 8 ;
237 return format | SF_FORMAT_DOUBLE ;
238 } ;
239 } ;
240
241 if ((desc->fmt_flags & 1) != 0)
242 { psf_log_printf (psf, "**** Ooops, 'desc' chunk suggests float data, but other info invalid.\n") ;
243 return 0 ;
244 } ;
245
246 if (desc->fmt_id == lpcm_MARKER)
247 { /* Integer data. */
248 if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
249 { psf->bytewidth = 4 ;
250 return format | SF_FORMAT_PCM_32 ;
251 } ;
252 if (desc->bits_per_chan == 24 && desc->pkt_bytes == 3 * desc->channels_per_frame)
253 { psf->bytewidth = 3 ;
254 return format | SF_FORMAT_PCM_24 ;
255 } ;
256 if (desc->bits_per_chan == 16 && desc->pkt_bytes == 2 * desc->channels_per_frame)
257 { psf->bytewidth = 2 ;
258 return format | SF_FORMAT_PCM_16 ;
259 } ;
260 if (desc->bits_per_chan == 8 && desc->pkt_bytes == 1 * desc->channels_per_frame)
261 { psf->bytewidth = 1 ;
262 return format | SF_FORMAT_PCM_S8 ;
263 } ;
264 } ;
265
266 if (desc->fmt_id == alaw_MARKER && desc->bits_per_chan == 8)
267 { psf->bytewidth = 1 ;
268 return format | SF_FORMAT_ALAW ;
269 } ;
270
271 if (desc->fmt_id == ulaw_MARKER && desc->bits_per_chan == 8)
272 { psf->bytewidth = 1 ;
273 return format | SF_FORMAT_ULAW ;
274 } ;
275
276 return 0 ;
277 } /* decode_desc_chunk */
278
279 static int
280 caf_read_header (SF_PRIVATE *psf)
281 { DESC_CHUNK desc ;
282 sf_count_t chunk_size ;
283 double srate ;
284 short version, flags ;
285 int marker, k, have_data = 0, error ;
286
287 memset (&desc, 0, sizeof (desc)) ;
288
289 /* Set position to start of file to begin reading header. */
290 psf_binheader_readf (psf, "pmE2E2", 0, &marker, &version, &flags) ;
291 psf_log_printf (psf, "%M\n Version : %d\n Flags : %x\n", marker, version, flags) ;
292 if (marker != caff_MARKER)
293 return SFE_CAF_NOT_CAF ;
294
295 psf_binheader_readf (psf, "mE8b", &marker, &chunk_size, psf->u.ucbuf, 8) ;
296 srate = double64_be_read (psf->u.ucbuf) ;
297 snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), "%5.3f", srate) ;
298 psf_log_printf (psf, "%M : %D\n Sample rate : %s\n", marker, chunk_size, psf->u.cbuf) ;
299 if (marker != desc_MARKER)
300 return SFE_CAF_NO_DESC ;
301
302 if (chunk_size < SIGNED_SIZEOF (DESC_CHUNK))
303 { psf_log_printf (psf, "**** Chunk size too small. Should be > 32 bytes.\n") ;
304 return SFE_MALFORMED_FILE ;
305 } ;
306
307 psf->sf.samplerate = lrint (srate) ;
308
309 psf_binheader_readf (psf, "mE44444", &desc.fmt_id, &desc.fmt_flags, &desc.pkt_bytes, &desc.pkt_frames,
310 &desc.channels_per_frame, &desc.bits_per_chan) ;
311 psf_log_printf (psf, " Format id : %M\n Format flags : %x\n Bytes / packet : %u\n"
312 " Frames / packet : %u\n Channels / frame : %u\n Bits / channel : %u\n",
313 desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
314
315 if (desc.channels_per_frame > SF_MAX_CHANNELS)
316 { psf_log_printf (psf, "**** Bad channels per frame value %u.\n", desc.channels_per_frame) ;
317 return SFE_MALFORMED_FILE ;
318 } ;
319
320 if (chunk_size > SIGNED_SIZEOF (DESC_CHUNK))
321 psf_binheader_readf (psf, "j", (int) (chunk_size - sizeof (DESC_CHUNK))) ;
322
323 psf->sf.channels = desc.channels_per_frame ;
324
325 while (have_data == 0 && psf_ftell (psf) < psf->filelength - SIGNED_SIZEOF (marker))
326 { psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ;
327
328 switch (marker)
329 { case peak_MARKER :
330 psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
331 if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels))
332 { psf_binheader_readf (psf, "j", (int) chunk_size) ;
333 psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
334 return SFE_CAF_BAD_PEAK ;
335 } ;
336
337 if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
338 return SFE_MALLOC_FAILED ;
339
340 /* read in rest of PEAK chunk. */
341 psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ;
342 psf_log_printf (psf, " edit count : %d\n", psf->peak_info->edit_number) ;
343
344 psf_log_printf (psf, " Ch Position Value\n") ;
345 for (k = 0 ; k < psf->sf.channels ; k++)
346 { sf_count_t position ;
347 float value ;
348
349 psf_binheader_readf (psf, "Ef8", &value, &position) ;
350 psf->peak_info->peaks [k].value = value ;
351 psf->peak_info->peaks [k].position = position ;
352
353 snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), " %2d %-12" PRId64 " %g\n", k, position, value) ;
354 psf_log_printf (psf, psf->u.cbuf) ;
355 } ;
356
357 psf->peak_info->peak_loc = SF_PEAK_START ;
358 break ;
359
360 case chan_MARKER :
361 if (chunk_size < 12)
362 { psf_log_printf (psf, "%M : %D (should be >= 12)\n", marker, chunk_size) ;
363 psf_binheader_readf (psf, "j", (int) chunk_size) ;
364 break ;
365 }
366
367 psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
368
369 if ((error = caf_read_chanmap (psf, chunk_size)))
370 return error ;
371 break ;
372
373 case free_MARKER :
374 psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
375 psf_binheader_readf (psf, "j", (int) chunk_size) ;
376 break ;
377
378 case data_MARKER :
379 if (psf->filelength > 0 && chunk_size + psf->headindex != psf->filelength)
380 psf_log_printf (psf, "%M : %D (should be %D)\n", marker, chunk_size, chunk_size + 4) ;
381 else
382 psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
383 psf_binheader_readf (psf, "E4", &k) ;
384 psf_log_printf (psf, " edit : %u\n", k) ;
385 have_data = 1 ;
386 break ;
387
388 default :
389 psf_log_printf (psf, " %M : %D (skipped)\n", marker, chunk_size) ;
390 psf_binheader_readf (psf, "j", (int) chunk_size) ;
391 break ;
392 } ;
393 } ;
394
395 if (have_data == 0)
396 { psf_log_printf (psf, "**** Error, could not find 'data' chunk.\n") ;
397 return SFE_MALFORMED_FILE ;
398 } ;
399
400 psf_log_printf (psf, "End\n") ;
401
402 psf->dataoffset = psf_ftell (psf) ;
403 psf->datalength = psf->filelength - psf->dataoffset ;
404 psf->endian = (desc.fmt_flags & 2) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
405
406 if ((psf->sf.format = decode_desc_chunk (psf, &desc)) == 0)
407 return SFE_UNSUPPORTED_ENCODING ;
408
409 if (psf->bytewidth > 0)
410 psf->sf.frames = psf->datalength / psf->bytewidth ;
411
412 return 0 ;
413 } /* caf_read_header */
414
415 /*------------------------------------------------------------------------------
416 */
417
418 static int
419 caf_write_header (SF_PRIVATE *psf, int calc_length)
420 { CAF_PRIVATE *pcaf ;
421 DESC_CHUNK desc ;
422 sf_count_t current, free_len ;
423 int subformat ;
424
425 if ((pcaf = psf->container_data) == NULL)
426 return SFE_INTERNAL ;
427
428 memset (&desc, 0, sizeof (desc)) ;
429
430 current = psf_ftell (psf) ;
431
432 if (calc_length)
433 { psf->filelength = psf_get_filelen (psf) ;
434
435 psf->datalength = psf->filelength - psf->dataoffset ;
436
437 if (psf->dataend)
438 psf->datalength -= psf->filelength - psf->dataend ;
439
440 if (psf->bytewidth > 0)
441 psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
442 } ;
443
444 /* Reset the current header length to zero. */
445 psf->header [0] = 0 ;
446 psf->headindex = 0 ;
447 psf_fseek (psf, 0, SEEK_SET) ;
448
449 /* 'caff' marker, version and flags. */
450 psf_binheader_writef (psf, "Em22", caff_MARKER, 1, 0) ;
451
452 /* 'desc' marker and chunk size. */
453 psf_binheader_writef (psf, "Em8", desc_MARKER, (sf_count_t) (sizeof (DESC_CHUNK))) ;
454
455 double64_be_write (1.0 * psf->sf.samplerate, psf->u.ucbuf) ;
456 psf_binheader_writef (psf, "b", psf->u.ucbuf, make_size_t (8)) ;
457
458 subformat = SF_CODEC (psf->sf.format) ;
459
460 psf->endian = SF_ENDIAN (psf->sf.format) ;
461
462 if (CPU_IS_BIG_ENDIAN && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU))
463 psf->endian = SF_ENDIAN_BIG ;
464 else if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_LITTLE || psf->endian == SF_ENDIAN_CPU))
465 psf->endian = SF_ENDIAN_LITTLE ;
466
467 if (psf->endian == SF_ENDIAN_LITTLE)
468 desc.fmt_flags = 2 ;
469 else
470 psf->endian = SF_ENDIAN_BIG ;
471
472 /* initial section (same for all, it appears) */
473 switch (subformat)
474 { case SF_FORMAT_PCM_S8 :
475 desc.fmt_id = lpcm_MARKER ;
476 psf->bytewidth = 1 ;
477 desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
478 desc.pkt_frames = 1 ;
479 desc.channels_per_frame = psf->sf.channels ;
480 desc.bits_per_chan = 8 ;
481 break ;
482
483 case SF_FORMAT_PCM_16 :
484 desc.fmt_id = lpcm_MARKER ;
485 psf->bytewidth = 2 ;
486 desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
487 desc.pkt_frames = 1 ;
488 desc.channels_per_frame = psf->sf.channels ;
489 desc.bits_per_chan = 16 ;
490 break ;
491
492 case SF_FORMAT_PCM_24 :
493 psf->bytewidth = 3 ;
494 desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
495 desc.pkt_frames = 1 ;
496 desc.channels_per_frame = psf->sf.channels ;
497 desc.bits_per_chan = 24 ;
498 desc.fmt_id = lpcm_MARKER ;
499 break ;
500
501 case SF_FORMAT_PCM_32 :
502 desc.fmt_id = lpcm_MARKER ;
503 psf->bytewidth = 4 ;
504 desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
505 desc.pkt_frames = 1 ;
506 desc.channels_per_frame = psf->sf.channels ;
507 desc.bits_per_chan = 32 ;
508 break ;
509
510 case SF_FORMAT_FLOAT :
511 desc.fmt_id = lpcm_MARKER ;
512 desc.fmt_flags |= 1 ;
513 psf->bytewidth = 4 ;
514 desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
515 desc.pkt_frames = 1 ;
516 desc.channels_per_frame = psf->sf.channels ;
517 desc.bits_per_chan = 32 ;
518 break ;
519
520 case SF_FORMAT_DOUBLE :
521 desc.fmt_id = lpcm_MARKER ;
522 desc.fmt_flags |= 1 ;
523 psf->bytewidth = 8 ;
524 desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
525 desc.pkt_frames = 1 ;
526 desc.channels_per_frame = psf->sf.channels ;
527 desc.bits_per_chan = 64 ;
528 break ;
529
530 case SF_FORMAT_ALAW :
531 desc.fmt_id = alaw_MARKER ;
532 psf->bytewidth = 1 ;
533 desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
534 desc.pkt_frames = 1 ;
535 desc.channels_per_frame = psf->sf.channels ;
536 desc.bits_per_chan = 8 ;
537 break ;
538
539 case SF_FORMAT_ULAW :
540 desc.fmt_id = ulaw_MARKER ;
541 psf->bytewidth = 1 ;
542 desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
543 desc.pkt_frames = 1 ;
544 desc.channels_per_frame = psf->sf.channels ;
545 desc.bits_per_chan = 8 ;
546 break ;
547
548 default :
549 return SFE_UNIMPLEMENTED ;
550 } ;
551
552 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) ;
553
554 #if 0
555 if (psf->str_flags & SF_STR_LOCATE_START)
556 caf_write_strings (psf, SF_STR_LOCATE_START) ;
557 #endif
558
559 if (psf->peak_info != NULL)
560 { int k ;
561 psf_binheader_writef (psf, "Em84", peak_MARKER, (sf_count_t) CAF_PEAK_CHUNK_SIZE (psf->sf.channels), psf->peak_info->edit_number) ;
562 for (k = 0 ; k < psf->sf.channels ; k++)
563 psf_binheader_writef (psf, "Ef8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
564 } ;
565
566 if (psf->channel_map && pcaf->chanmap_tag)
567 psf_binheader_writef (psf, "Em8444", chan_MARKER, (sf_count_t) 12, pcaf->chanmap_tag, 0, 0) ;
568
569 /* Add free chunk so that the actual audio data starts at a multiple 0x1000. */
570 free_len = 0x1000 - psf->headindex - 16 - 12 ;
571 while (free_len < 0)
572 free_len += 0x1000 ;
573 psf_binheader_writef (psf, "Em8z", free_MARKER, free_len, (int) free_len) ;
574
575 psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength + 4, 0) ;
576
577 psf_fwrite (psf->header, psf->headindex, 1, psf) ;
578 if (psf->error)
579 return psf->error ;
580
581 psf->dataoffset = psf->headindex ;
582 if (current < psf->dataoffset)
583 psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
584 else if (current > 0)
585 psf_fseek (psf, current, SEEK_SET) ;
586
587 return psf->error ;
588 } /* caf_write_header */
589
590 static int
591 caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size)
592 { const AIFF_CAF_CHANNEL_MAP * map_info ;
593 unsigned channel_bitmap, channel_decriptions, bytesread ;
594 int layout_tag ;
595
596 bytesread = psf_binheader_readf (psf, "E444", &layout_tag, &channel_bitmap, &channel_decriptions) ;
597
598 map_info = aiff_caf_of_channel_layout_tag (layout_tag) ;
599
600 psf_log_printf (psf, " Tag : %x\n", layout_tag) ;
601 if (map_info)
602 psf_log_printf (psf, " Layout : %s\n", map_info->name) ;
603
604 if (bytesread < chunk_size)
605 psf_binheader_readf (psf, "j", chunk_size - bytesread) ;
606
607 if (map_info->channel_map != NULL)
608 { size_t chanmap_size = psf->sf.channels * sizeof (psf->channel_map [0]) ;
609
610 free (psf->channel_map) ;
611
612 if ((psf->channel_map = malloc (chanmap_size)) == NULL)
613 return SFE_MALLOC_FAILED ;
614
615 memcpy (psf->channel_map, map_info->channel_map, chanmap_size) ;
616 } ;
617
618 return 0 ;
619 } /* caf_read_chanmap */
620