PageRenderTime 79ms CodeModel.GetById 17ms app.highlight 57ms RepoModel.GetById 1ms app.codeStats 0ms

/project/jni/sndfile/src/caf.c

https://github.com/aichunyu/FFPlayer
C | 620 lines | 448 code | 126 blank | 46 comment | 139 complexity | f556f79d371147532161030d3f323f9d MD5 | raw file
  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
 77typedef 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
 87typedef struct
 88{	int chanmap_tag ;
 89} CAF_PRIVATE ;
 90
 91/*------------------------------------------------------------------------------
 92** Private static functions.
 93*/
 94
 95static int	caf_close (SF_PRIVATE *psf) ;
 96static int	caf_read_header (SF_PRIVATE *psf) ;
 97static int	caf_write_header (SF_PRIVATE *psf, int calc_length) ;
 98static int	caf_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
 99static int	caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size) ;
100
101/*------------------------------------------------------------------------------
102** Public function.
103*/
104
105int
106caf_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
190static int
191caf_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
199static int
200caf_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
221static int
222decode_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
279static int
280caf_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
418static int
419caf_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
590static int
591caf_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