Пример #1
0
static int
mat4_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t	current ;
	int			encoding ;
	double		samplerate ;

	current = psf_ftell (psf->filedes) ;

	if (calc_length)
	{	psf_fseek (psf->filedes, 0, SEEK_END) ;
		psf->filelength = psf_ftell (psf->filedes) ;
		psf_fseek (psf->filedes, 0, SEEK_SET) ;

		psf->datalength = psf->filelength - psf->dataoffset ;
		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	encoding = mat4_format_to_encoding (psf->sf.format & SF_FORMAT_SUBMASK, psf->endian) ;

	if (encoding == -1)
		return SFE_BAD_OPEN_FORMAT ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;
	psf_fseek (psf->filedes, 0, SEEK_SET) ;

	/* Need sample rate as a double for writing to the header. */
	samplerate = psf->sf.samplerate ;

	if (psf->endian == SF_ENDIAN_BIG)
	{	psf_binheader_writef (psf, "Em444", MAT4_BE_DOUBLE, 1, 1, 0) ;
		psf_binheader_writef (psf, "E4bd", 11, "samplerate", 11, samplerate) ;
		psf_binheader_writef (psf, "tEm484", encoding, psf->sf.channels, psf->sf.frames, 0) ;
		psf_binheader_writef (psf, "E4b", 9, "wavedata", 9) ;
		}
	else if  (psf->endian == SF_ENDIAN_LITTLE)
	{	psf_binheader_writef (psf, "em444", MAT4_LE_DOUBLE, 1, 1, 0) ;
		psf_binheader_writef (psf, "e4bd", 11, "samplerate", 11, samplerate) ;
		psf_binheader_writef (psf, "tem484", encoding, psf->sf.channels, psf->sf.frames, 0) ;
		psf_binheader_writef (psf, "e4b", 9, "wavedata", 9) ;
		}
	else
		return SFE_BAD_OPEN_FORMAT ;

	/* Header construction complete so write it out. */
	psf_fwrite (psf->header, psf->headindex, 1, psf->filedes) ;

	psf->dataoffset = psf->headindex ;

	if (current > 0)
		psf_fseek (psf->filedes, current, SEEK_SET) ;

	return 0 ;
} /* mat4_write_header */
Пример #2
0
static int	
voc_close	(SF_PRIVATE  *psf)
{	
	if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
	{	/*  Now we know for certain the length of the file we can re-write 
		**	correct values for the FORM, 8SVX and BODY chunks.
		*/
		unsigned byte = VOC_TERMINATOR ;
		
		
		psf_fseek (psf, 0, SEEK_END) ;
		
		/* Write terminator */
		psf_fwrite (&byte, 1, 1, psf) ;
		
		psf->filelength = psf_ftell (psf) ;
		psf_fseek (psf, 0, SEEK_SET) ;
		
		psf->datalength = psf->filelength - psf->dataoffset ;
 		psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		
		voc_write_header (psf, SF_FALSE) ;
		} ;

	return 0 ;
} /* voc_close */
Пример #3
0
static int
pvf_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
{	sf_count_t	current ;

	if (psf->pipeoffset > 0)
		return 0 ;

	current = psf_ftell (psf) ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;

	if (psf->is_pipe == SF_FALSE)
		psf_fseek (psf, 0, SEEK_SET) ;

	snprintf ((char*) psf->header, sizeof (psf->header), "PVF1\n%d %d %d\n",
		psf->sf.channels, psf->sf.samplerate, psf->bytewidth * 8) ;

	psf->headindex = strlen ((char*) psf->header) ;

	/* Header construction complete so write it out. */
	psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	if (psf->error)
		return psf->error ;

	psf->dataoffset = psf->headindex ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* pvf_write_header */
Пример #4
0
static int
mat4_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t	current ;
	int			encoding ;
	double		samplerate ;

	current = psf_ftell (psf) ;

	if (calc_length)
	{	psf->filelength = psf_get_filelen (psf) ;

		psf->datalength = psf->filelength - psf->dataoffset ;
		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	encoding = mat4_format_to_encoding (SF_CODEC (psf->sf.format), psf->endian) ;

	if (encoding == -1)
		return SFE_BAD_OPEN_FORMAT ;

	/* Reset the current header length to zero. */
	psf->header.ptr [0] = 0 ;
	psf->header.indx = 0 ;
	psf_fseek (psf, 0, SEEK_SET) ;

	/* Need sample rate as a double for writing to the header. */
	samplerate = psf->sf.samplerate ;

	if (psf->endian == SF_ENDIAN_BIG)
	{	psf_binheader_writef (psf, "Em444", BHWm (MAT4_BE_DOUBLE), BHW4 (1), BHW4 (1), BHW4 (0)) ;
		psf_binheader_writef (psf, "E4bd", BHW4 (11), BHWv ("samplerate"), BHWz (11), BHWd (samplerate)) ;
		psf_binheader_writef (psf, "tEm484", BHWm (encoding), BHW4 (psf->sf.channels), BHW8 (psf->sf.frames), BHW4 (0)) ;
		psf_binheader_writef (psf, "E4b", BHW4 (9), BHWv ("wavedata"), BHWz (9)) ;
		}
	else if (psf->endian == SF_ENDIAN_LITTLE)
	{	psf_binheader_writef (psf, "em444", BHWm (MAT4_LE_DOUBLE), BHW4 (1), BHW4 (1), BHW4 (0)) ;
		psf_binheader_writef (psf, "e4bd", BHW4 (11), BHWv ("samplerate"), BHWz (11), BHWd (samplerate)) ;
		psf_binheader_writef (psf, "tem484", BHWm (encoding), BHW4 (psf->sf.channels), BHW8 (psf->sf.frames), BHW4 (0)) ;
		psf_binheader_writef (psf, "e4b", BHW4 (9), BHWv ("wavedata"), BHWz (9)) ;
		}
	else
		return SFE_BAD_OPEN_FORMAT ;

	/* Header construction complete so write it out. */
	psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;

	if (psf->error)
		return psf->error ;

	psf->dataoffset = psf->header.indx ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* mat4_write_header */
Пример #5
0
static int
avr_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t	current ;
	int			sign, datalength ;

	if (psf->pipeoffset > 0)
		return 0 ;

	current = psf_ftell (psf) ;

	if (calc_length)
	{	psf->filelength = psf_get_filelen (psf) ;

		psf->datalength = psf->filelength - psf->dataoffset ;
		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;

	/*
	** Only attempt to seek if we are not writng to a pipe. If we are
	** writing to a pipe we shouldn't be here anyway.
	*/
	if (psf->is_pipe == SF_FALSE)
		psf_fseek (psf, 0, SEEK_SET) ;

	datalength = (int) (psf->datalength & 0x7FFFFFFF) ;

	psf_binheader_writef (psf, "Emz22", TWOBIT_MARKER, (size_t) 8,
			psf->sf.channels == 2 ? 0xFFFF : 0, psf->bytewidth * 8) ;

	sign = ((psf->sf.format & SF_FORMAT_SUBMASK) == SF_FORMAT_PCM_U8) ? 0 : 0xFFFF ;

	psf_binheader_writef (psf, "E222", sign, 0, 0xFFFF) ;
	psf_binheader_writef (psf, "E4444", psf->sf.samplerate, psf->sf.frames, 0, 0) ;

	psf_binheader_writef (psf, "E222zz", 0, 0, 0, (size_t) 20, (size_t) 64) ;

	/* Header construction complete so write it out. */
	psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	if (psf->error)
		return psf->error ;

	psf->dataoffset = psf->headindex ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* avr_write_header */
Пример #6
0
static int
pvf_read_header (SF_PRIVATE *psf)
{	char	buffer [32] ;
	int		marker, channels, samplerate, bitwidth ;

	psf_binheader_readf (psf, "pmj", 0, &marker, 1) ;
	psf_log_printf (psf, "%M\n", marker) ;

	if (marker != PVF1_MARKER)
		return SFE_PVF_NO_PVF1 ;

	/* Grab characters up until a newline which is replaced by an EOS. */
	psf_binheader_readf (psf, "G", buffer, sizeof (buffer)) ;

	if (sscanf (buffer, "%d %d %d", &channels, &samplerate, &bitwidth) != 3)
		return SFE_PVF_BAD_HEADER ;

	psf_log_printf (psf, " Channels    : %d\n Sample rate : %d\n Bit width   : %d\n",
				channels, samplerate, bitwidth) ;

	psf->sf.channels = channels ;
	psf->sf.samplerate = samplerate ;

	switch (bitwidth)
	{	case 8 :
				psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_S8 ;
				psf->bytewidth = 1 ;
				break ;

		case 16 :
				psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_16 ;
				psf->bytewidth = 2 ;
				break ;
		case 32 :
				psf->sf.format = SF_FORMAT_PVF | SF_FORMAT_PCM_32 ;
				psf->bytewidth = 4 ;
				break ;

		default :
				return SFE_PVF_BAD_BITWIDTH ;
		} ;

	psf->dataoffset = psf_ftell (psf) ;
	psf_log_printf (psf, " Data Offset : %D\n", psf->dataoffset) ;

	psf->endian = SF_ENDIAN_BIG ;

	psf->datalength = psf->filelength - psf->dataoffset ;
	psf->blockwidth = psf->sf.channels * psf->bytewidth ;

	if (! psf->sf.frames && psf->blockwidth)
		psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;

	return 0 ;
} /* pvf_read_header */
Пример #7
0
static int
ircam_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
{	int			encoding ;
	float		samplerate ;
	sf_count_t	current ;

	if (psf->pipeoffset > 0)
		return 0 ;

	current = psf_ftell (psf) ;

	/* This also sets psf->endian. */
	encoding = get_encoding (SF_CODEC (psf->sf.format)) ;

	if (encoding == 0)
		return SFE_BAD_OPEN_FORMAT ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;

	if (psf->is_pipe == SF_FALSE)
		psf_fseek (psf, 0, SEEK_SET) ;

	samplerate = psf->sf.samplerate ;

	switch (psf->endian)
	{	case SF_ENDIAN_BIG :
			psf_binheader_writef (psf, "Emf", IRCAM_02B_MARKER, samplerate) ;
			psf_binheader_writef (psf, "E44", psf->sf.channels, encoding) ;
			break ;

		case SF_ENDIAN_LITTLE :
			psf_binheader_writef (psf, "emf", IRCAM_03L_MARKER, samplerate) ;
			psf_binheader_writef (psf, "e44", psf->sf.channels, encoding) ;
			break ;

		default :
			return SFE_BAD_OPEN_FORMAT ;
	} ;

	psf_binheader_writef (psf, "z", (size_t) (IRCAM_DATA_OFFSET - psf->headindex)) ;

	/* Header construction complete so write it out. */
	psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	if (psf->error)
		return psf->error ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* ircam_write_header */
Пример #8
0
static void
test_tell_or_die	(SF_PRIVATE *psf, sf_count_t expected_position, int linenum)
{
	sf_count_t retval ;

	retval = psf_ftell (psf) ;

	if (retval != expected_position)
	{	printf ("\n\nLine %d: psf_ftell() failed. Position reported as %" PRId64 " (should be %" PRId64 ").\n\n",
			linenum, retval, expected_position) ;
		exit (1) ;
		} ;
}
Пример #9
0
static int	
w64_close	(SF_PRIVATE  *psf)
{	
	if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
	{	/*  Now we know for certain the length of the file we can
		 *  re-write correct values for the riff and data chunks.
		 */

		psf_fseek (psf->filedes, 0, SEEK_END) ;
		psf->dataend = psf_ftell (psf->filedes) ;

		psf_fseek (psf->filedes, 0, SEEK_END) ;
		psf->filelength = psf_ftell (psf->filedes) ;
		psf_fseek (psf->filedes, 0, SEEK_SET) ;
		
		psf->datalength = psf->filelength - psf->dataoffset - (psf->filelength - psf->dataend) ;
 		psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;

		w64_write_header (psf, SF_FALSE) ;
		} ;

	return 0 ;
} /* w64_close */
Пример #10
0
int
ogg_open (SF_PRIVATE *psf)
{   OGG_PRIVATE* odata = calloc (1, sizeof (OGG_PRIVATE)) ;
    sf_count_t pos = psf_ftell (psf) ;
    int	error = 0 ;

    psf->container_data = odata ;
    psf->container_close = ogg_close ;

    if (psf->file.mode == SFM_RDWR)
        return SFE_BAD_MODE_RW ;

    if (psf->file.mode == SFM_READ)
        if ((error = ogg_stream_classify (psf, odata)) != 0)
            return error ;

    /* Reset everything to an initial state. */
    ogg_sync_clear (&odata->osync) ;
    ogg_stream_clear (&odata->ostream) ;
    psf_fseek (psf, pos, SEEK_SET) ;

    switch (psf->sf.format)
    {
    case SF_FORMAT_OGG | SF_FORMAT_VORBIS :
        return ogg_vorbis_open (psf) ;

    case SF_FORMAT_OGGFLAC :
        free (psf->container_data) ;
        psf->container_data = NULL ;
        psf->container_close = NULL ;
        return flac_open (psf) ;

#if ENABLE_EXPERIMENTAL_CODE
    case SF_FORMAT_OGG | SF_FORMAT_SPEEX :
        return ogg_speex_open (psf) ;

    case SF_FORMAT_OGG | SF_FORMAT_PCM_16 :
    case SF_FORMAT_OGG | SF_FORMAT_PCM_24 :
        return ogg_pcm_open (psf) ;
#endif

    default :
        break ;
    } ;

    psf_log_printf (psf, "%s : mode should be SFM_READ or SFM_WRITE.\n", __func__) ;
    return SFE_INTERNAL ;
} /* ogg_open */
Пример #11
0
static int
ircam_write_header (SF_PRIVATE *psf, int calc_length)
{	int			encoding ;
	float		samplerate ;
	sf_count_t	current ;

	current = psf_ftell (psf) ;

	calc_length = calc_length ;

	/* This also sets psf->endian. */
	encoding = get_encoding (psf->sf.format & SF_FORMAT_SUBMASK) ;
	
	if (! encoding)
		return SFE_BAD_OPEN_FORMAT ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;
	psf_fseek (psf, 0, SEEK_SET) ;
	
	samplerate = psf->sf.samplerate ;

	if (psf->endian == SF_ENDIAN_BIG)
	{	psf_binheader_writef (psf, "Emf", IRCAM_02B_MARKER, samplerate) ;
		psf_binheader_writef (psf, "E44", psf->sf.channels, encoding) ;
		}
	else if  (psf->endian == SF_ENDIAN_LITTLE)
	{	psf_binheader_writef (psf, "emf", IRCAM_03L_MARKER, samplerate) ;
		psf_binheader_writef (psf, "e44", psf->sf.channels, encoding) ;
		}
	else
		return SFE_BAD_OPEN_FORMAT ;

	psf_binheader_writef (psf, "z", IRCAM_DATA_OFFSET - psf->headindex) ;
	
	/* Header construction complete so write it out. */
	psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	if (psf->error)
		return psf->error ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;
		
	return psf->error ;
} /* ircam_write_header */ 
Пример #12
0
static void
test_read_or_die (SF_PRIVATE *psf, void *data, sf_count_t bytes, sf_count_t items, sf_count_t new_position, int linenum)
{	sf_count_t	retval ;

	retval = psf_fread (data, bytes, items, psf) ;
	if (retval != items)
	{	printf ("\n\nLine %d: psf_write() returned %ld (should be %ld)\n\n", linenum, (long) retval, (long) items) ;
		exit (1) ;
		} ;

	if ((retval = psf_ftell (psf)) != new_position)
	{	printf ("\n\nLine %d: file length after write is not correct. (%ld should be %ld)\n\n", linenum, (long) retval, (long) new_position) ;
		exit (1) ;
		} ;

	return ;
} /* test_write_or_die */
Пример #13
0
static int
wve_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t	current ;
	unsigned datalen ;

	current = psf_ftell (psf) ;

	if (calc_length)
	{	psf->filelength = psf_get_filelen (psf) ;

		psf->datalength = psf->filelength - psf->dataoffset ;
		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;
	psf_fseek (psf, 0, SEEK_SET) ;

	/* Write header. */
	datalen = psf->datalength ;
	psf_binheader_writef (psf, "Emmmm", ALAW_MARKER, SOUN_MARKER, DFIL_MARKER, ESSN_MARKER) ;
	psf_binheader_writef (psf, "E2422222", PSION_VERSION, datalen, 0, 0, 0, 0, 0) ;
	psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	if (psf->sf.channels != 1)
		return SFE_CHANNEL_COUNT ;

	if (psf->error)
		return psf->error ;

	psf->dataoffset = psf->headindex ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* wve_write_header */
Пример #14
0
static int
caf_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info)
{	int indx ;
	sf_count_t pos ;

	if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0)
		return SFE_UNKNOWN_CHUNK ;

	if (chunk_info->data == NULL)
		return SFE_BAD_CHUNK_DATA_PTR ;

	chunk_info->id_size = psf->rchunks.chunks [indx].id_size ;
	memcpy (chunk_info->id, psf->rchunks.chunks [indx].id, sizeof (chunk_info->id) / sizeof (*chunk_info->id)) ;

	pos = psf_ftell (psf) ;
	psf_fseek (psf, psf->rchunks.chunks [indx].offset, SEEK_SET) ;
	psf_fread (chunk_info->data, SF_MIN (chunk_info->datalen, psf->rchunks.chunks [indx].len), 1, psf) ;
	psf_fseek (psf, pos, SEEK_SET) ;

	return SFE_NO_ERROR ;
} /* caf_get_chunk_data */
Пример #15
0
static int	
nist_close	(SF_PRIVATE  *psf)
{
	if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
	{	/*  Now we know for certain the length of the file we can
		**  re-write correct values for the datasize header element.
		*/

		psf_fseek (psf->filedes, 0, SEEK_END) ;
		psf->filelength = psf_ftell (psf->filedes) ;

		psf->dataoffset = NIST_HEADER_LENGTH ;
		psf->datalength = psf->filelength - psf->dataoffset ;

		psf->sf.frames = psf->datalength / psf->blockwidth ;

		nist_write_header (psf, SF_FALSE) ;
		} ;

	return 0 ;
} /* nist_close */
Пример #16
0
static int
htk_write_header (SF_PRIVATE *psf, int calc_length)
{   sf_count_t	current ;
    int			sample_count, sample_period ;

    current = psf_ftell (psf) ;

    if (calc_length)
        psf->filelength = psf_get_filelen (psf) ;

    /* Reset the current header length to zero. */
    psf->header.ptr [0] = 0 ;
    psf->header.indx = 0 ;
    psf_fseek (psf, 0, SEEK_SET) ;

    if (psf->filelength > 12)
        sample_count = (psf->filelength - 12) / 2 ;
    else
        sample_count = 0 ;

    sample_period = 10000000 / psf->sf.samplerate ;

    psf_binheader_writef (psf, "E444", sample_count, sample_period, 0x20000) ;

    /* Header construction complete so write it out. */
    psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;

    if (psf->error)
        return psf->error ;

    psf->dataoffset = psf->header.indx ;

    if (current > 0)
        psf_fseek (psf, current, SEEK_SET) ;

    return psf->error ;
} /* htk_write_header */
Пример #17
0
static int
mat4_close	(SF_PRIVATE  *psf)
{
	if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
	{	/*  Now we know for certain the length of the file we can
		 *  re-write correct values for the datasize header element.
		 */

		psf_fseek (psf->filedes, 0, SEEK_END) ;
		psf->filelength = psf_ftell (psf->filedes) ;

		psf->datalength = psf->filelength - psf->dataoffset ;
		psf_fseek (psf->filedes, 0, SEEK_SET) ;

		psf->sf.frames = psf->datalength / psf->blockwidth ;
		mat4_write_header (psf, SF_FALSE) ;
		} ;

	if (psf->fdata)
		free (psf->fdata) ;
	psf->fdata = NULL ;

	return 0 ;
} /* mat4_close */
Пример #18
0
static int
caf_write_header (SF_PRIVATE *psf, int calc_length)
{	BUF_UNION	ubuf ;
	CAF_PRIVATE	*pcaf ;
	DESC_CHUNK desc ;
	sf_count_t current, free_len ;
	uint32_t uk ;
	int subformat, append_free_block = SF_TRUE ;

	if ((pcaf = psf->container_data) == NULL)
		return SFE_INTERNAL ;

	memset (&desc, 0, sizeof (desc)) ;

	current = psf_ftell (psf) ;

	if (calc_length)
	{	psf->filelength = psf_get_filelen (psf) ;

		psf->datalength = psf->filelength - psf->dataoffset ;

		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		if (psf->bytewidth > 0)
			psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;
	psf_fseek (psf, 0, SEEK_SET) ;

	/* 'caff' marker, version and flags. */
	psf_binheader_writef (psf, "Em22", caff_MARKER, 1, 0) ;

	/* 'desc' marker and chunk size. */
	psf_binheader_writef (psf, "Em8", desc_MARKER, (sf_count_t) (sizeof (DESC_CHUNK))) ;

 	double64_be_write (1.0 * psf->sf.samplerate, ubuf.ucbuf) ;
	psf_binheader_writef (psf, "b", ubuf.ucbuf, make_size_t (8)) ;

	subformat = SF_CODEC (psf->sf.format) ;

	psf->endian = SF_ENDIAN (psf->sf.format) ;

	if (CPU_IS_BIG_ENDIAN && (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU))
		psf->endian = SF_ENDIAN_BIG ;
	else if (CPU_IS_LITTLE_ENDIAN && (psf->endian == SF_ENDIAN_LITTLE || psf->endian == SF_ENDIAN_CPU))
		psf->endian = SF_ENDIAN_LITTLE ;

	if (psf->endian == SF_ENDIAN_LITTLE)
		desc.fmt_flags = 2 ;
	else
		psf->endian = SF_ENDIAN_BIG ;

	/* initial section (same for all, it appears) */
	switch (subformat)
	{	case SF_FORMAT_PCM_S8 :
			desc.fmt_id = lpcm_MARKER ;
			psf->bytewidth = 1 ;
			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
			desc.frames_per_packet = 1 ;
			desc.channels_per_frame = psf->sf.channels ;
			desc.bits_per_chan = 8 ;
			break ;

		case SF_FORMAT_PCM_16 :
			desc.fmt_id = lpcm_MARKER ;
			psf->bytewidth = 2 ;
			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
			desc.frames_per_packet = 1 ;
			desc.channels_per_frame = psf->sf.channels ;
			desc.bits_per_chan = 16 ;
			break ;

		case SF_FORMAT_PCM_24 :
			psf->bytewidth = 3 ;
			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
			desc.frames_per_packet = 1 ;
			desc.channels_per_frame = psf->sf.channels ;
			desc.bits_per_chan = 24 ;
			desc.fmt_id = lpcm_MARKER ;
			break ;

		case SF_FORMAT_PCM_32 :
			desc.fmt_id = lpcm_MARKER ;
			psf->bytewidth = 4 ;
			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
			desc.frames_per_packet = 1 ;
			desc.channels_per_frame = psf->sf.channels ;
			desc.bits_per_chan = 32 ;
			break ;

		case SF_FORMAT_FLOAT :
			desc.fmt_id = lpcm_MARKER ;
			desc.fmt_flags |= 1 ;
			psf->bytewidth = 4 ;
			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
			desc.frames_per_packet = 1 ;
			desc.channels_per_frame = psf->sf.channels ;
			desc.bits_per_chan = 32 ;
			break ;

		case SF_FORMAT_DOUBLE :
			desc.fmt_id = lpcm_MARKER ;
			desc.fmt_flags |= 1 ;
			psf->bytewidth = 8 ;
			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
			desc.frames_per_packet = 1 ;
			desc.channels_per_frame = psf->sf.channels ;
			desc.bits_per_chan = 64 ;
			break ;

		case SF_FORMAT_ALAW :
			desc.fmt_id = alaw_MARKER ;
			psf->bytewidth = 1 ;
			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
			desc.frames_per_packet = 1 ;
			desc.channels_per_frame = psf->sf.channels ;
			desc.bits_per_chan = 8 ;
			break ;

		case SF_FORMAT_ULAW :
			desc.fmt_id = ulaw_MARKER ;
			psf->bytewidth = 1 ;
			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
			desc.frames_per_packet = 1 ;
			desc.channels_per_frame = psf->sf.channels ;
			desc.bits_per_chan = 8 ;
			break ;

		case SF_FORMAT_ALAC_16 :
		case SF_FORMAT_ALAC_20 :
		case SF_FORMAT_ALAC_24 :
		case SF_FORMAT_ALAC_32 :
			desc.fmt_id = alac_MARKER ;
			desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
			desc.channels_per_frame = psf->sf.channels ;
			alac_get_desc_chunk_items (subformat, &desc.fmt_flags, &desc.frames_per_packet) ;
			append_free_block = SF_FALSE ;
			break ;

		default :
			return SFE_UNIMPLEMENTED ;
		} ;

	psf_binheader_writef (psf, "mE44444", desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.frames_per_packet, desc.channels_per_frame, desc.bits_per_chan) ;

	caf_write_strings (psf, SF_STR_LOCATE_START) ;

	if (psf->peak_info != NULL)
	{	int k ;
		psf_binheader_writef (psf, "Em84", peak_MARKER, (sf_count_t) CAF_PEAK_CHUNK_SIZE (psf->sf.channels), psf->peak_info->edit_number) ;
		for (k = 0 ; k < psf->sf.channels ; k++)
			psf_binheader_writef (psf, "Ef8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
		} ;

	if (psf->channel_map && pcaf->chanmap_tag)
		psf_binheader_writef (psf, "Em8444", chan_MARKER, (sf_count_t) 12, pcaf->chanmap_tag, 0, 0) ;

	/* Write custom headers. */
	for (uk = 0 ; uk < psf->wchunks.used ; uk++)
		psf_binheader_writef (psf, "m44b", (int) psf->wchunks.chunks [uk].mark32, 0, psf->wchunks.chunks [uk].len, psf->wchunks.chunks [uk].data, make_size_t (psf->wchunks.chunks [uk].len)) ;

	if (append_free_block)
	{	/* Add free chunk so that the actual audio data starts at a multiple 0x1000. */
		free_len = 0x1000 - psf->headindex - 16 - 12 ;
		while (free_len < 0)
			free_len += 0x1000 ;
		psf_binheader_writef (psf, "Em8z", free_MARKER, free_len, (int) free_len) ;
		} ;

	psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength + 4, 0) ;

	psf_fwrite (psf->header, psf->headindex, 1, psf) ;
	if (psf->error)
		return psf->error ;

	psf->dataoffset = psf->headindex ;
	if (current < psf->dataoffset)
		psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
	else if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* caf_write_header */
Пример #19
0
static int
avr_read_header (SF_PRIVATE *psf)
{	AVR_HEADER	hdr ;

	memset (&hdr, 0, sizeof (hdr)) ;

	psf_binheader_readf (psf, "pmb", 0, &hdr.marker, &hdr.name, sizeof (hdr.name)) ;
	psf_log_printf (psf, "%M\n", hdr.marker) ;

	if (hdr.marker != TWOBIT_MARKER)
		return SFE_AVR_X ;

	psf_log_printf (psf, "  Name        : %s\n", hdr.name) ;

	psf_binheader_readf (psf, "E22222", &hdr.mono, &hdr.rez, &hdr.sign, &hdr.loop, &hdr.midi) ;

	psf->sf.channels = (hdr.mono & 1) + 1 ;

	psf_log_printf (psf, "  Channels    : %d\n  Bit width   : %d\n  Signed      : %s\n",
			(hdr.mono & 1) + 1, hdr.rez, hdr.sign ? "yes" : "no") ;

	switch ((hdr.rez << 16) + (hdr.sign & 1))
	{	case ((8 << 16) + 0) :
			psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_U8 ;
			psf->bytewidth = 1 ;
			break ;

		case ((8 << 16) + 1) :
			psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_S8 ;
			psf->bytewidth = 1 ;
			break ;

		case ((16 << 16) + 1) :
			psf->sf.format = SF_FORMAT_AVR | SF_FORMAT_PCM_16 ;
			psf->bytewidth = 2 ;
			break ;

		default :
			psf_log_printf (psf, "Error : bad rez/sign combination.\n") ;
			return SFE_AVR_X ;
		} ;

	psf_binheader_readf (psf, "E4444", &hdr.srate, &hdr.frames, &hdr.lbeg, &hdr.lend) ;

	psf->sf.frames = hdr.frames ;
	psf->sf.samplerate = hdr.srate ;

	psf_log_printf (psf, "  Frames      : %D\n", psf->sf.frames) ;
	psf_log_printf (psf, "  Sample rate : %d\n", psf->sf.samplerate) ;

	psf_binheader_readf (psf, "E222", &hdr.res1, &hdr.res2, &hdr.res3) ;
	psf_binheader_readf (psf, "bb", hdr.ext, sizeof (hdr.ext), hdr.user, sizeof (hdr.user)) ;

	psf_log_printf (psf, "  Ext         : %s\n  User        : %s\n", hdr.ext, hdr.user) ;

	psf->endian = SF_ENDIAN_BIG ;

 	psf->dataoffset = AVR_HDR_SIZE ;
	psf->datalength = hdr.frames * (hdr.rez / 8) ;

	if (psf->fileoffset > 0)
		psf->filelength = AVR_HDR_SIZE + psf->datalength ;

	if (psf_ftell (psf) != psf->dataoffset)
		psf_binheader_readf (psf, "j", psf->dataoffset - psf_ftell (psf)) ;

	psf->blockwidth = psf->sf.channels * psf->bytewidth ;

	if (psf->sf.frames == 0 && psf->blockwidth)
		psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;

	return 0 ;
} /* avr_read_header */
Пример #20
0
static int
w64_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t 	fmt_size, current ;
	size_t		fmt_pad = 0 ;
	int 		subformat, add_fact_chunk = SF_FALSE ;

	current = psf_ftell (psf) ;

	if (calc_length)
	{	psf->filelength = psf_get_filelen (psf) ;

		psf->datalength = psf->filelength - psf->dataoffset ;
		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		if (psf->bytewidth)
			psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;
	psf_fseek (psf, 0, SEEK_SET) ;

	/* riff marker, length, wave and 'fmt ' markers. */
	psf_binheader_writef (psf, "eh8hh", riff_MARKER16, psf->filelength, wave_MARKER16, fmt_MARKER16) ;

	subformat = SF_CODEC (psf->sf.format) ;

	switch (subformat)
	{	case	SF_FORMAT_PCM_U8 :
		case	SF_FORMAT_PCM_16 :
		case	SF_FORMAT_PCM_24 :
		case	SF_FORMAT_PCM_32 :
					fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ;
					fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
					fmt_size += fmt_pad ;

					/* fmt : format, channels, samplerate */
					psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_PCM, psf->sf.channels, psf->sf.samplerate) ;
					/*  fmt : bytespersec */
					psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
					/*  fmt : blockalign, bitwidth */
					psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;
					break ;

		case SF_FORMAT_FLOAT :
		case SF_FORMAT_DOUBLE :
					fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ;
					fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
					fmt_size += fmt_pad ;

					/* fmt : format, channels, samplerate */
					psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_IEEE_FLOAT, psf->sf.channels, psf->sf.samplerate) ;
					/*  fmt : bytespersec */
					psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
					/*  fmt : blockalign, bitwidth */
					psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;

					add_fact_chunk = SF_TRUE ;
					break ;

		case SF_FORMAT_ULAW :
					fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ;
					fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
					fmt_size += fmt_pad ;

					/* fmt : format, channels, samplerate */
					psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_MULAW, psf->sf.channels, psf->sf.samplerate) ;
					/*  fmt : bytespersec */
					psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
					/*  fmt : blockalign, bitwidth */
					psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, 8) ;

					add_fact_chunk = SF_TRUE ;
					break ;

		case SF_FORMAT_ALAW :
					fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 ;
					fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
					fmt_size += fmt_pad ;

					/* fmt : format, channels, samplerate */
					psf_binheader_writef (psf, "e8224", fmt_size, WAVE_FORMAT_ALAW, psf->sf.channels, psf->sf.samplerate) ;
					/*  fmt : bytespersec */
					psf_binheader_writef (psf, "e4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
					/*  fmt : blockalign, bitwidth */
					psf_binheader_writef (psf, "e22", psf->bytewidth * psf->sf.channels, 8) ;

					add_fact_chunk = SF_TRUE ;
					break ;

		/* Lite remove start */
		case SF_FORMAT_IMA_ADPCM :
					{	int		blockalign, framesperblock, bytespersec ;

						blockalign		= wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
						framesperblock	= 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
						bytespersec		= (psf->sf.samplerate * blockalign) / framesperblock ;

						/* fmt chunk. */
						fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
						fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
						fmt_size += fmt_pad ;

						/* fmt : size, WAV format type, channels. */
						psf_binheader_writef (psf, "e822", fmt_size, WAVE_FORMAT_IMA_ADPCM, psf->sf.channels) ;

						/* fmt : samplerate, bytespersec. */
						psf_binheader_writef (psf, "e44", psf->sf.samplerate, bytespersec) ;

						/* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
						psf_binheader_writef (psf, "e2222", blockalign, 4, 2, framesperblock) ;
						} ;

					add_fact_chunk = SF_TRUE ;
					break ;

		case SF_FORMAT_MS_ADPCM :
					{	int blockalign, framesperblock, bytespersec, extrabytes ;

						blockalign		= wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
						framesperblock	= 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ;
						bytespersec		= (psf->sf.samplerate * blockalign) / framesperblock ;

						/* fmt chunk. */
						extrabytes	= 2 + 2 + MSADPCM_ADAPT_COEFF_COUNT * (2 + 2) ;
						fmt_size	= 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + extrabytes ;
						fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
						fmt_size += fmt_pad ;

						/* fmt : size, W64 format type, channels. */
						psf_binheader_writef (psf, "e822", fmt_size, WAVE_FORMAT_MS_ADPCM, psf->sf.channels) ;

						/* fmt : samplerate, bytespersec. */
						psf_binheader_writef (psf, "e44", psf->sf.samplerate, bytespersec) ;

						/* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
						psf_binheader_writef (psf, "e22222", blockalign, 4, extrabytes, framesperblock, 7) ;

						msadpcm_write_adapt_coeffs (psf) ;
						} ;

					add_fact_chunk = SF_TRUE ;
					break ;
		/* Lite remove end */

		case SF_FORMAT_GSM610 :
					{	int bytespersec ;

						bytespersec = (psf->sf.samplerate * WAV_W64_GSM610_BLOCKSIZE) / WAV_W64_GSM610_SAMPLES ;

						/* fmt chunk. */
						fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
						fmt_pad = (size_t) (8 - (fmt_size & 0x7)) ;
						fmt_size += fmt_pad ;

						/* fmt : size, WAV format type, channels. */
						psf_binheader_writef (psf, "e822", fmt_size, WAVE_FORMAT_GSM610, psf->sf.channels) ;

						/* fmt : samplerate, bytespersec. */
						psf_binheader_writef (psf, "e44", psf->sf.samplerate, bytespersec) ;

						/* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
						psf_binheader_writef (psf, "e2222", WAV_W64_GSM610_BLOCKSIZE, 0, 2, WAV_W64_GSM610_SAMPLES) ;
						} ;

					add_fact_chunk = SF_TRUE ;
					break ;

		default : 	return SFE_UNIMPLEMENTED ;
		} ;

	/* Pad to 8 bytes with zeros. */
	if (fmt_pad > 0)
		psf_binheader_writef (psf, "z", fmt_pad) ;

	if (add_fact_chunk)
		psf_binheader_writef (psf, "eh88", fact_MARKER16, (sf_count_t) (16 + 8 + 8), psf->sf.frames) ;

	psf_binheader_writef (psf, "eh8", data_MARKER16, psf->datalength + 24) ;
	psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	if (psf->error)
		return psf->error ;

	psf->dataoffset = psf->headindex ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* w64_write_header */
Пример #21
0
static int
voc_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t	current ;
	int			rate_const, subformat ;

	current = psf_ftell (psf) ;

	if (calc_length)
	{	psf->filelength = psf_get_filelen (psf) ;

		psf->datalength = psf->filelength - psf->dataoffset ;
		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	subformat = SF_CODEC (psf->sf.format) ;
	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;
	psf_fseek (psf, 0, SEEK_SET) ;

	/* VOC marker and 0x1A byte. */
	psf_binheader_writef (psf, "eb1", "Creative Voice File", make_size_t (19), 0x1A) ;

	/* Data offset, version and other. */
	psf_binheader_writef (psf, "e222", 26, 0x0114, 0x111F) ;

	/*	Use same logic as SOX.
	**	If the file is mono 8 bit data, use VOC_SOUND_DATA.
	**	If the file is mono 16 bit data, use VOC_EXTENED.
	**	Otherwise use VOC_EXTENED_2.
	*/

	if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 1)
	{	/* samplerate = 1000000 / (256 - rate_const) ; */
		rate_const = 256 - 1000000 / psf->sf.samplerate ;

		/* First type marker, length, rate_const and compression */
		psf_binheader_writef (psf, "e1311", VOC_SOUND_DATA, (int) (psf->datalength + 1), rate_const, 0) ;
		}
	else if (subformat == SF_FORMAT_PCM_U8 && psf->sf.channels == 2)
	{	/* sample_rate = 128000000 / (65536 - rate_short) ; */
		rate_const = 65536 - 128000000 / psf->sf.samplerate ;

		/* First write the VOC_EXTENDED section
		** 		marker, length, rate_const and compression
		*/
		psf_binheader_writef (psf, "e13211", VOC_EXTENDED, 4, rate_const, 0, 1) ;

		/* samplerate = 1000000 / (256 - rate_const) ; */
		rate_const = 256 - 1000000 / psf->sf.samplerate ;

		/*	Now write the VOC_SOUND_DATA section
		** 		marker, length, rate_const and compression
		*/
		psf_binheader_writef (psf, "e1311", VOC_SOUND_DATA, (int) (psf->datalength + 1), rate_const, 0) ;
		}
	else
	{	int length ;

		if (psf->sf.channels < 1 || psf->sf.channels > 2)
			return SFE_CHANNEL_COUNT ;

		switch (subformat)
		{	case SF_FORMAT_PCM_U8 :
					psf->bytewidth = 1 ;
					length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
					/* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */
					psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 16, psf->sf.channels, 4, 0) ;
					break ;

			case SF_FORMAT_PCM_16 :
					psf->bytewidth = 2 ;
					length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
					/* Marker, length, sample rate, bitwidth, stereo flag, encoding and fourt zero bytes. */
					psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 16, psf->sf.channels, 4, 0) ;
					break ;

			case SF_FORMAT_ALAW :
					psf->bytewidth = 1 ;
					length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
					psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 8, psf->sf.channels, 6, 0) ;
					break ;

			case SF_FORMAT_ULAW :
					psf->bytewidth = 1 ;
					length = psf->sf.frames * psf->sf.channels * psf->bytewidth + 12 ;
					psf_binheader_writef (psf, "e1341124", VOC_EXTENDED_II, length, psf->sf.samplerate, 8, psf->sf.channels, 7, 0) ;
					break ;

			default : return SFE_UNIMPLEMENTED ;
			} ;
		} ;

	psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	if (psf->error)
		return psf->error ;

	psf->dataoffset = psf->headindex ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* voc_write_header */
Пример #22
0
static int
nist_write_header (SF_PRIVATE  *psf, int calc_length)
{	char		*end_str ;
	long		samples ;
	sf_count_t	current ;

	current = psf_ftell (psf->filedes) ;

	/* Prevent compiler warning. */
	calc_length = calc_length ;

	if (psf->endian == SF_ENDIAN_BIG)
		end_str = "10" ;
	else if (psf->endian == SF_ENDIAN_LITTLE)
		end_str = "01" ;
	else
		end_str = "error" ;

	/* Clear the whole header. */
	memset (psf->header, 0, sizeof (psf->header)) ;
	psf->headindex = 0 ;
		
	psf_fseek (psf->filedes, 0, SEEK_SET) ;

	psf_asciiheader_printf (psf, "NIST_1A\n   1024\n") ;
	psf_asciiheader_printf (psf, "channel_count -i %d\n", psf->sf.channels) ;
	psf_asciiheader_printf (psf, "sample_rate -i %d\n", psf->sf.samplerate) ;

	switch (psf->sf.format & SF_FORMAT_SUBMASK)
	{	case SF_FORMAT_PCM_S8 :
				psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n") ;
				psf_asciiheader_printf (psf, "sample_n_bytes -i 1\n"
											"sample_sig_bits -i 8\n") ;
				break ;

		case SF_FORMAT_PCM_16 :
		case SF_FORMAT_PCM_24 :
		case SF_FORMAT_PCM_32 :
				psf_asciiheader_printf (psf, "sample_n_bytes -i %d\n", psf->bytewidth) ;
				psf_asciiheader_printf (psf, "sample_sig_bits -i %d\n", psf->bytewidth * 8) ;
				psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n"
								"sample_byte_format -s%d %s\n", psf->bytewidth, end_str) ;
				break ;
	
		case SF_FORMAT_ALAW :
				psf_asciiheader_printf (psf, "sample_coding -s4 alaw\n") ;
				psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ;
				break ;
	
		case SF_FORMAT_ULAW :
				psf_asciiheader_printf (psf, "sample_coding -s4 ulaw\n") ;
				psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ;
				break ;
				
		default : return SFE_UNIMPLEMENTED ;
		} ;
	
	psf->dataoffset = NIST_HEADER_LENGTH ;
	
	/* Fix this */
	samples = psf->sf.frames ;
	psf_asciiheader_printf (psf, "sample_count -i %ld\n", samples) ;
	psf_asciiheader_printf (psf, "end_head\n") ;

	/* Zero fill to dataoffset. */
	psf_binheader_writef (psf, "z", NIST_HEADER_LENGTH - psf->headindex) ;

	psf_fwrite (psf->header, psf->headindex, 1, psf->filedes) ;

	if (current > 0)
		psf_fseek (psf->filedes, current, SEEK_SET) ;
		
	return 0 ;		
} /* nist_write_header */
Пример #23
0
static int
w64_read_header	(SF_PRIVATE *psf, int *blockalign, int *framesperblock)
{	WAV_PRIVATE *wpriv ;
	WAV_FMT 	*wav_fmt ;
	int			dword = 0, marker, format = 0 ;
	sf_count_t	chunk_size, bytesread = 0 ;
	int			parsestage = 0, error, done = 0 ;

	if ((wpriv = psf->container_data) == NULL)
		return SFE_INTERNAL ;
	wav_fmt = &wpriv->wav_fmt ;

	/* Set position to start of file to begin reading header. */
	psf_binheader_readf (psf, "p", 0) ;

	while (! done)
	{	/* Each new chunk must start on an 8 byte boundary, so jump if needed. */
		if (psf->headindex & 0x7)
			psf_binheader_readf (psf, "j", 8 - (psf->headindex & 0x7)) ;

		/* Generate hash of 16 byte marker. */
		marker = chunk_size = 0 ;
		bytesread = psf_binheader_readf (psf, "eh8", &marker, &chunk_size) ;
		if (bytesread == 0)
			break ;
		switch (marker)
		{	case riff_HASH16 :
					if (parsestage)
						return SFE_W64_NO_RIFF ;

					if (psf->filelength != chunk_size)
						psf_log_printf (psf, "riff : %D (should be %D)\n", chunk_size, psf->filelength) ;
					else
						psf_log_printf (psf, "riff : %D\n", chunk_size) ;

					parsestage |= HAVE_riff ;

					bytesread += psf_binheader_readf (psf, "h", &marker) ;
					if (marker == wave_HASH16)
					{ 	if ((parsestage & HAVE_riff) != HAVE_riff)
							return SFE_W64_NO_WAVE ;
						psf_log_printf (psf, "wave\n") ;
						parsestage |= HAVE_wave ;
					} ;
					chunk_size = 0 ;
					break ;

			case ACID_HASH16:
					psf_log_printf (psf, "Looks like an ACID file. Exiting.\n") ;
					return SFE_UNIMPLEMENTED ;

			case fmt_HASH16 :
					if ((parsestage & (HAVE_riff | HAVE_wave)) != (HAVE_riff | HAVE_wave))
						return SFE_WAV_NO_FMT ;

					psf_log_printf (psf, " fmt : %D\n", chunk_size) ;

					/* size of 16 byte marker and 8 byte chunk_size value. */
					chunk_size -= 24 ;

					if ((error = wav_w64_read_fmt_chunk (psf, (int) chunk_size)))
						return error ;

					if (chunk_size % 8)
						psf_binheader_readf (psf, "j", 8 - (chunk_size % 8)) ;

					format		= wav_fmt->format ;
					parsestage |= HAVE_fmt ;
					chunk_size = 0 ;
					break ;

			case fact_HASH16:
					{	sf_count_t frames ;

						psf_binheader_readf (psf, "e8", &frames) ;
						psf_log_printf (psf, "   fact : %D\n     frames : %D\n",
										chunk_size, frames) ;
						} ;
					chunk_size = 0 ;
					break ;


			case data_HASH16 :
					if ((parsestage & (HAVE_riff | HAVE_wave | HAVE_fmt)) != (HAVE_riff | HAVE_wave | HAVE_fmt))
						return SFE_W64_NO_DATA ;

					psf->dataoffset = psf_ftell (psf) ;
					psf->datalength = SF_MIN (chunk_size - 24, psf->filelength - psf->dataoffset) ;

					if (chunk_size % 8)
						chunk_size += 8 - (chunk_size % 8) ;

					psf_log_printf (psf, "data : %D\n", chunk_size) ;

					parsestage |= HAVE_data ;

					if (! psf->sf.seekable)
						break ;

					/* Seek past data and continue reading header. */
					psf_fseek (psf, chunk_size, SEEK_CUR) ;
					chunk_size = 0 ;
					break ;

			case levl_HASH16 :
					psf_log_printf (psf, "levl : %D\n", chunk_size) ;
					chunk_size -= 24 ;
					break ;

			case list_HASH16 :
					psf_log_printf (psf, "list : %D\n", chunk_size) ;
					chunk_size -= 24 ;
					break ;

			case junk_HASH16 :
					psf_log_printf (psf, "junk : %D\n", chunk_size) ;
					chunk_size -= 24 ;
					break ;

			case bext_MARKER :
					psf_log_printf (psf, "bext : %D\n", chunk_size) ;
					chunk_size -= 24 ;
					break ;

			case MARKER_HASH16 :
					psf_log_printf (psf, "marker : %D\n", chunk_size) ;
					chunk_size -= 24 ;
					break ;

			case SUMLIST_HASH16 :
					psf_log_printf (psf, "summary list : %D\n", chunk_size) ;
					chunk_size -= 24 ;
					break ;

			default :
					psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D with length %D. Exiting parser.\n", marker, psf_ftell (psf) - 8, chunk_size) ;
					done = SF_TRUE ;
					break ;
			} ;	/* switch (dword) */

		if (chunk_size >= psf->filelength)
		{	psf_log_printf (psf, "*** Chunk size %u > file length %D. Exiting parser.\n", chunk_size, psf->filelength) ;
			break ;
			} ;

		if (psf->sf.seekable == 0 && (parsestage & HAVE_data))
			break ;

		if (psf_ftell (psf) >= (psf->filelength - (2 * SIGNED_SIZEOF (dword))))
			break ;

		if (chunk_size > 0 && chunk_size < 0xffff0000)
		{	dword = chunk_size ;
			psf_binheader_readf (psf, "j", dword - 24) ;
			} ;
		} ; /* while (1) */

	if (psf->dataoffset <= 0)
		return SFE_W64_NO_DATA ;

	if (psf->sf.channels < 1)
		return SFE_CHANNEL_COUNT_ZERO ;

	if (psf->sf.channels >= SF_MAX_CHANNELS)
		return SFE_CHANNEL_COUNT ;

	psf->endian = SF_ENDIAN_LITTLE ;		/* All W64 files are little endian. */

	if (psf_ftell (psf) != psf->dataoffset)
		psf_fseek (psf, psf->dataoffset, SEEK_SET) ;

	if (psf->blockwidth)
	{	if (psf->filelength - psf->dataoffset < psf->datalength)
			psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
		else
			psf->sf.frames = psf->datalength / psf->blockwidth ;
		} ;

	switch (format)
	{	case WAVE_FORMAT_PCM :
		case WAVE_FORMAT_EXTENSIBLE :
					/* extensible might be FLOAT, MULAW, etc as well! */
					psf->sf.format = SF_FORMAT_W64 | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
					break ;

		case WAVE_FORMAT_MULAW :
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ULAW) ;
					break ;

		case WAVE_FORMAT_ALAW :
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ALAW) ;
					break ;

		case WAVE_FORMAT_MS_ADPCM :
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM) ;
					*blockalign = wav_fmt->msadpcm.blockalign ;
					*framesperblock = wav_fmt->msadpcm.samplesperblock ;
					break ;

		case WAVE_FORMAT_IMA_ADPCM :
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM) ;
					*blockalign = wav_fmt->ima.blockalign ;
					*framesperblock = wav_fmt->ima.samplesperblock ;
					break ;

		case WAVE_FORMAT_GSM610 :
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_GSM610) ;
					break ;

		case WAVE_FORMAT_IEEE_FLOAT :
					psf->sf.format = SF_FORMAT_W64 ;
					psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ;
					break ;

		default : return SFE_UNIMPLEMENTED ;
		} ;

	return 0 ;
} /* w64_read_header */
Пример #24
0
static int
au_read_header (SF_PRIVATE *psf)
{	AU_FMT	au_fmt ;
	int		marker, dword ;

	memset (&au_fmt, 0, sizeof (au_fmt)) ;
	psf_binheader_readf (psf, "pm", 0, &marker) ;
	psf_log_printf (psf, "%M\n", marker) ;

	if (marker == DOTSND_MARKER)
	{	psf->endian = SF_ENDIAN_BIG ;

		psf_binheader_readf (psf, "E44444", &(au_fmt.dataoffset), &(au_fmt.datasize),
					&(au_fmt.encoding), &(au_fmt.samplerate), &(au_fmt.channels)) ;
		}
	else if (marker == DNSDOT_MARKER)
	{	psf->endian = SF_ENDIAN_LITTLE ;
		psf_binheader_readf (psf, "e44444", &(au_fmt.dataoffset), &(au_fmt.datasize),
					&(au_fmt.encoding), &(au_fmt.samplerate), &(au_fmt.channels)) ;
		}
	else
		return SFE_AU_NO_DOTSND ;

	psf_log_printf (psf, "  Data Offset : %d\n", au_fmt.dataoffset) ;

	if (psf->fileoffset > 0 && au_fmt.datasize == -1)
	{	psf_log_printf (psf, "  Data Size   : -1\n") ;
		return SFE_AU_EMBED_BAD_LEN ;
		} ;

	if (psf->fileoffset > 0)
	{	psf->filelength = au_fmt.dataoffset + au_fmt.datasize ;
		psf_log_printf (psf, "  Data Size   : %d\n", au_fmt.datasize) ;
		}
	else if (au_fmt.datasize == -1 || au_fmt.dataoffset + au_fmt.datasize == psf->filelength)
		psf_log_printf (psf, "  Data Size   : %d\n", au_fmt.datasize) ;
	else if (au_fmt.dataoffset + au_fmt.datasize < psf->filelength)
	{	psf->filelength = au_fmt.dataoffset + au_fmt.datasize ;
		psf_log_printf (psf, "  Data Size   : %d\n", au_fmt.datasize) ;
		}
	else
	{	dword = psf->filelength - au_fmt.dataoffset ;
		psf_log_printf (psf, "  Data Size   : %d (should be %d)\n", au_fmt.datasize, dword) ;
		au_fmt.datasize = dword ;
		} ;

 	psf->dataoffset = au_fmt.dataoffset ;
	psf->datalength = psf->filelength - psf->dataoffset ;

	if (psf_ftell (psf) < psf->dataoffset)
		psf_binheader_readf (psf, "j", psf->dataoffset - psf_ftell (psf)) ;

	psf->sf.samplerate	= au_fmt.samplerate ;
	psf->sf.channels 	= au_fmt.channels ;

	/* Only fill in type major. */
	if (psf->endian == SF_ENDIAN_BIG)
		psf->sf.format = SF_FORMAT_AU ;
	else if (psf->endian == SF_ENDIAN_LITTLE)
		psf->sf.format = SF_ENDIAN_LITTLE | SF_FORMAT_AU ;

	psf_log_printf (psf, "  Encoding    : %d => ", au_fmt.encoding) ;

	psf->sf.format = SF_ENDIAN (psf->sf.format) ;

	switch (au_fmt.encoding)
	{	case AU_ENCODING_ULAW_8 :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_ULAW ;
				psf->bytewidth = 1 ;	/* Before decoding */
				psf_log_printf (psf, "8-bit ISDN u-law\n") ;
				break ;

		case AU_ENCODING_PCM_8 :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_S8 ;
				psf->bytewidth = 1 ;
				psf_log_printf (psf, "8-bit linear PCM\n") ;
				break ;

		case AU_ENCODING_PCM_16 :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_16 ;
				psf->bytewidth = 2 ;
				psf_log_printf (psf, "16-bit linear PCM\n") ;
				break ;

		case AU_ENCODING_PCM_24 :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_24 ;
				psf->bytewidth = 3 ;
				psf_log_printf (psf, "24-bit linear PCM\n") ;
				break ;

		case AU_ENCODING_PCM_32 :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_PCM_32 ;
				psf->bytewidth = 4 ;
				psf_log_printf (psf, "32-bit linear PCM\n") ;
				break ;

		case AU_ENCODING_FLOAT :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_FLOAT ;
				psf->bytewidth = 4 ;
				psf_log_printf (psf, "32-bit float\n") ;
				break ;

		case AU_ENCODING_DOUBLE :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_DOUBLE ;
				psf->bytewidth = 8 ;
				psf_log_printf (psf, "64-bit double precision float\n") ;
				break ;

		case AU_ENCODING_ALAW_8 :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_ALAW ;
				psf->bytewidth = 1 ;	/* Before decoding */
				psf_log_printf (psf, "8-bit ISDN A-law\n") ;
				break ;

		case AU_ENCODING_ADPCM_G721_32 :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G721_32 ;
				psf->bytewidth = 0 ;
				psf_log_printf (psf, "G721 32kbs ADPCM\n") ;
				break ;

		case AU_ENCODING_ADPCM_G723_24 :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G723_24 ;
				psf->bytewidth = 0 ;
				psf_log_printf (psf, "G723 24kbs ADPCM\n") ;
				break ;

		case AU_ENCODING_ADPCM_G723_40 :
				psf->sf.format |= SF_FORMAT_AU | SF_FORMAT_G723_40 ;
				psf->bytewidth = 0 ;
				psf_log_printf (psf, "G723 40kbs ADPCM\n") ;
				break ;

		case AU_ENCODING_ADPCM_G722 :
				psf_log_printf (psf, "G722 64 kbs ADPCM (unsupported)\n") ;
				break ;

		case AU_ENCODING_NEXT :
				psf_log_printf (psf, "Weird NeXT encoding format (unsupported)\n") ;
				break ;

		default :
				psf_log_printf (psf, "Unknown!!\n") ;
				break ;
		} ;

	psf_log_printf (psf, "  Sample Rate : %d\n", au_fmt.samplerate) ;
	if (au_fmt.channels < 1)
	{	psf_log_printf (psf, "  Channels    : %d  **** should be >= 1\n", au_fmt.channels) ;
		return SFE_CHANNEL_COUNT_ZERO ;
		}
	else if (au_fmt.channels > SF_MAX_CHANNELS)
	{	psf_log_printf (psf, "  Channels    : %d  **** should be <= %d\n", au_fmt.channels, SF_MAX_CHANNELS) ;
		return SFE_CHANNEL_COUNT ;
		} ;

	psf_log_printf (psf, "  Channels    : %d\n", au_fmt.channels) ;

	psf->blockwidth = psf->sf.channels * psf->bytewidth ;

	if (! psf->sf.frames && psf->blockwidth)
		psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;

	return 0 ;
} /* au_read_header */
Пример #25
0
static int
w64_read_header	(SF_PRIVATE *psf, int *blockalign, int *framesperblock)
{	WAV_FMT wav_fmt ;
	int		dword = 0, marker, format = 0 ;
	sf_count_t	chunk_size, bytesread = 0 ;
	int		parsestage = 0, error, done = 0 ;
	
	/* Set position to start of file to begin reading header. */
	psf_binheader_readf (psf, "p", 0) ;	
		
	while (! done)
	{	/* Read the 4 byte marker and jump 12 bytes. */
		bytesread += psf_binheader_readf (psf, "h", &marker) ;
		chunk_size = 0 ;
		
		switch (marker)
		{	case riff_HASH16 :
					if (parsestage)
						return SFE_W64_NO_RIFF ;

					bytesread += psf_binheader_readf (psf, "e8", &chunk_size) ;
					
					if (psf->filelength  < chunk_size)
						psf_log_printf (psf, "riff : %d (should be %d)\n", chunk_size, psf->filelength) ;
					else
						psf_log_printf (psf, "riff : %d\n", chunk_size) ;

					parsestage |= HAVE_riff ;
					break ;
					
			case ACID_HASH16:
					psf_log_printf (psf, "Looks like an ACID file. Exiting.\n") ;
					return SFE_UNIMPLEMENTED ;

			case wave_HASH16 :
					if ((parsestage & HAVE_riff) != HAVE_riff)
						return SFE_W64_NO_WAVE ;
					psf_log_printf (psf, "wave\n") ;
					parsestage |= HAVE_wave ;
					break ;

			case fmt_HASH16 :
					if ((parsestage & (HAVE_riff | HAVE_wave)) != (HAVE_riff | HAVE_wave))
						return SFE_W64_NO_FMT ;
						
					bytesread += psf_binheader_readf (psf, "e8", &chunk_size) ;
					psf_log_printf (psf, " fmt : %d (0x%X)\n", chunk_size, chunk_size) ;
						
					/* size of 16 byte marker and 8 byte chunk_size value. */
					chunk_size -= 24 ;

					if ((error = wav_w64_read_fmt_chunk (psf, &wav_fmt, (int) chunk_size)))
						return error ;
						
					if (chunk_size % 8)
						psf_binheader_readf (psf, "j", 8 - (chunk_size % 8)) ;
						
					format     = wav_fmt.format ;
					parsestage |= HAVE_fmt ;
					break ;

			case fact_HASH16:
					{	sf_count_t frames ;
					
						psf_binheader_readf (psf, "e88", &chunk_size, &frames) ;
						psf_log_printf (psf, "   fact : 0x%X\n"
											 "     frames : %d\n", 
										chunk_size, frames) ;
						} ;
					break ;

					
			case data_HASH16 :
					if ((parsestage & (HAVE_riff | HAVE_wave | HAVE_fmt)) != (HAVE_riff | HAVE_wave | HAVE_fmt))
						return SFE_W64_NO_DATA ;
					
					psf_binheader_readf (psf, "e8", &chunk_size) ;

					psf->dataoffset = psf_ftell (psf->filedes) ;
					
					psf->datalength = chunk_size - 24 ;

					if (chunk_size % 8)
						chunk_size += 8 - (chunk_size % 8) ;

					psf_log_printf (psf, "data : %d (0x%X)\n", chunk_size, psf->datalength) ;

					parsestage |= HAVE_data ;

					if (! psf->sf.seekable)
						break ;
					
					/* Seek past data and continue reading header. */
					psf_fseek (psf->filedes, chunk_size, SEEK_CUR) ;
					break ;

			default : 
					if (psf_ftell (psf->filedes) & 0x0F)
					{	psf_log_printf (psf, "  Unknown chunk marker at position %d. Resynching.\n", dword - 4) ;
						psf_binheader_readf (psf, "j", -3) ;
						break ;
						} ;
					psf_log_printf (psf, "*** Unknown chunk marker : %X. Exiting parser.\n", marker) ;
					done = SF_TRUE ;
					break ;
			} ;	/* switch (dword) */

		if (! psf->sf.seekable && (parsestage & HAVE_data))
			break ;

		if (psf_ferror (psf->filedes))
		{	psf_log_printf (psf, "*** Error on file handle. ***\n", marker) ;
			psf_fclearerr (psf->filedes) ;
			break ;
			} ;

		if (psf_ftell (psf->filedes) >= (int) (psf->filelength - (2 * sizeof (dword))))
			break ;

		if (psf->logindex >= sizeof (psf->logbuffer) - 2)
			return SFE_LOG_OVERRUN ;
		} ; /* while (1) */
		
	if (! psf->dataoffset)
		return SFE_W64_NO_DATA ;

	psf->endian = SF_ENDIAN_LITTLE ;		/* All WAV files are little endian. */
	
	psf_fseek (psf->filedes, psf->dataoffset, SEEK_SET) ;
	
	psf->close = w64_close ;

	if (psf->blockwidth)
	{	if (psf->filelength - psf->dataoffset < psf->datalength)
			psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
		else
			psf->sf.frames = psf->datalength / psf->blockwidth ;
		} ;

	switch (format)
	{	case WAVE_FORMAT_PCM :
		case WAVE_FORMAT_EXTENSIBLE :
					psf->sf.format = SF_FORMAT_W64 | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
					break ;
					
		case WAVE_FORMAT_MULAW :
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ULAW) ;
					break ;
	
		case WAVE_FORMAT_ALAW :
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_ALAW) ;
					break ;
		
		case WAVE_FORMAT_MS_ADPCM : 
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM) ;
					*blockalign = wav_fmt.msadpcm.blockalign ;
					*framesperblock = wav_fmt.msadpcm.samplesperblock ;
					break ;

		case WAVE_FORMAT_IMA_ADPCM :
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM) ;
					*blockalign = wav_fmt.ima.blockalign ;
					*framesperblock = wav_fmt.ima.samplesperblock ;
					break ;
		
		case WAVE_FORMAT_GSM610 :
					psf->sf.format = (SF_FORMAT_W64 | SF_FORMAT_GSM610) ;
					break ;
		
		case WAVE_FORMAT_IEEE_FLOAT :
					psf->sf.format  = SF_FORMAT_W64 ;
					psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ;
					break ;
		
		default : return SFE_UNIMPLEMENTED ;
		} ;

	return 0 ;
} /* w64_read_header */
Пример #26
0
static int
au_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t	current ;
	int			encoding, datalength ;

	if (psf->pipeoffset > 0)
		return 0 ;

	current = psf_ftell (psf) ;

	if (calc_length)
	{	psf->filelength = psf_get_filelen (psf) ;

		psf->datalength = psf->filelength - psf->dataoffset ;
		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;
		} ;

	encoding = au_format_to_encoding (SF_CODEC (psf->sf.format)) ;
	if (! encoding)
		return (psf->error = SFE_BAD_OPEN_FORMAT) ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;

	/*
	** Only attempt to seek if we are not writng to a pipe. If we are
	** writing to a pipe we shouldn't be here anyway.
	*/
	if (psf->is_pipe == SF_FALSE)
		psf_fseek (psf, 0, SEEK_SET) ;

	/*
	**	AU format files allow a datalength value of -1 if the datalength
	**	is not know at the time the header is written.
	**	Also use this value of -1 if the datalength > 2 gigabytes.
	*/
	if (psf->datalength	< 0 || psf->datalength > 0x7FFFFFFF)
		datalength = -1 ;
	else
		datalength = (int) (psf->datalength & 0x7FFFFFFF) ;

	if (psf->endian == SF_ENDIAN_BIG)
	{	psf_binheader_writef (psf, "Em4", DOTSND_MARKER, AU_DATA_OFFSET) ;
		psf_binheader_writef (psf, "E4444", datalength, encoding, psf->sf.samplerate, psf->sf.channels) ;
		}
	else if (psf->endian == SF_ENDIAN_LITTLE)
	{	psf_binheader_writef (psf, "em4", DNSDOT_MARKER, AU_DATA_OFFSET) ;
		psf_binheader_writef (psf, "e4444", datalength, encoding, psf->sf.samplerate, psf->sf.channels) ;
		}
	else
		return (psf->error = SFE_BAD_OPEN_FORMAT) ;

	/* Header construction complete so write it out. */
	psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	if (psf->error)
		return psf->error ;

	psf->dataoffset = psf->headindex ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* au_write_header */
Пример #27
0
static int
mat5_write_header (SF_PRIVATE *psf, int calc_length)
{	static const char	*sr_name = "samplerate\0\0\0\0\0\0\0\0\0\0\0" ;
	static const char	*wd_name = "wavedata\0" ;
	sf_count_t	current, datasize ;
	int			encoding ;

	current = psf_ftell (psf) ;

	if (calc_length)
	{	psf_fseek (psf, 0, SEEK_END) ;
		psf->filelength = psf_ftell (psf) ;
		psf_fseek (psf, 0, SEEK_SET) ;

		psf->datalength = psf->filelength - psf->dataoffset ;
		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	switch (psf->sf.format & SF_FORMAT_SUBMASK)
	{	case SF_FORMAT_PCM_U8 :
				encoding = MAT5_TYPE_UCHAR ;
				break ;

		case SF_FORMAT_PCM_16 :
				encoding = MAT5_TYPE_INT16 ;
				break ;

		case SF_FORMAT_PCM_32 :
				encoding = MAT5_TYPE_INT32 ;
				break ;

		case SF_FORMAT_FLOAT :
				encoding = MAT5_TYPE_FLOAT ;
				break ;

		case SF_FORMAT_DOUBLE :
				encoding = MAT5_TYPE_DOUBLE ;
				break ;

		default :
				return SFE_BAD_OPEN_FORMAT ;
		} ;

	/* Reset the current header length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;
	psf_fseek (psf, 0, SEEK_SET) ;

	psf_binheader_writef (psf, "S", "MATLAB 5.0 MAT-file, written by " PACKAGE "-" VERSION ", ") ;
	psf_get_date_str (psf->u.scbuf, sizeof (psf->u.scbuf)) ;
	psf_binheader_writef (psf, "jS", -1, psf->u.scbuf) ;

	memset (psf->u.scbuf, ' ', 124 - psf->headindex) ;
	psf_binheader_writef (psf, "b", psf->u.scbuf, 124 - psf->headindex) ;

	psf->rwf_endian = psf->endian ;

	if (psf->rwf_endian == SF_ENDIAN_BIG)
		psf_binheader_writef (psf, "2b", 0x0100, "MI", 2) ;
	else
		psf_binheader_writef (psf, "2b", 0x0100, "IM", 2) ;

	psf_binheader_writef (psf, "444444", MAT5_TYPE_ARRAY, 64, MAT5_TYPE_UINT32, 8, 6, 0) ;
	psf_binheader_writef (psf, "4444", MAT5_TYPE_INT32, 8, 1, 1) ;
	psf_binheader_writef (psf, "44b", MAT5_TYPE_SCHAR, strlen (sr_name), sr_name, 16) ;

	if (psf->sf.samplerate > 0xFFFF)
		psf_binheader_writef (psf, "44", MAT5_TYPE_COMP_UINT, psf->sf.samplerate) ;
	else
	{	unsigned short samplerate = psf->sf.samplerate ;

		psf_binheader_writef (psf, "422", MAT5_TYPE_COMP_USHORT, samplerate, 0) ;
		} ;

	datasize = psf->sf.frames * psf->sf.channels * psf->bytewidth ;

	psf_binheader_writef (psf, "t484444", MAT5_TYPE_ARRAY, datasize + 64, MAT5_TYPE_UINT32, 8, 6, 0) ;
	psf_binheader_writef (psf, "t4448", MAT5_TYPE_INT32, 8, psf->sf.channels, psf->sf.frames) ;
	psf_binheader_writef (psf, "44b", MAT5_TYPE_SCHAR, strlen (wd_name), wd_name, strlen (wd_name)) ;

	datasize = psf->sf.frames * psf->sf.channels * psf->bytewidth ;
	if (datasize > 0x7FFFFFFF)
		datasize = 0x7FFFFFFF ;

	psf_binheader_writef (psf, "t48", encoding, datasize) ;

	/* Header construction complete so write it out. */
	psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	if (psf->error)
		return psf->error ;

	psf->dataoffset = psf->headindex ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* mat5_write_header */
Пример #28
0
static int
mat4_read_header (SF_PRIVATE *psf)
{	int		marker, rows, cols, imag ;
	unsigned namesize ;
	double	value ;
	const char *marker_str ;
	char	name [64] ;

	psf_binheader_readf (psf, "pm", 0, &marker) ;

	/* MAT4 file must start with a double for the samplerate. */
	if (marker == MAT4_BE_DOUBLE)
	{	psf->endian = psf->rwf_endian = SF_ENDIAN_BIG ;
		marker_str = "big endian double" ;
		}
	else if (marker == MAT4_LE_DOUBLE)
	{	psf->endian = psf->rwf_endian = SF_ENDIAN_LITTLE ;
		marker_str = "little endian double" ;
		}
	else
		return SFE_UNIMPLEMENTED ;

	psf_log_printf (psf, "GNU Octave 2.0 / MATLAB v4.2 format\nMarker : %s\n", marker_str) ;

	psf_binheader_readf (psf, "444", &rows, &cols, &imag) ;

	psf_log_printf (psf, " Rows  : %d\n Cols  : %d\n Imag  : %s\n", rows, cols, imag ? "True" : "False") ;

	psf_binheader_readf (psf, "4", &namesize) ;

	if (namesize >= SIGNED_SIZEOF (name))
		return SFE_MAT4_BAD_NAME ;

	psf_binheader_readf (psf, "b", name, namesize) ;
	name [namesize] = 0 ;

	psf_log_printf (psf, " Name  : %s\n", name) ;

	psf_binheader_readf (psf, "d", &value) ;

	snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), " Value : %f\n", value) ;
	psf_log_printf (psf, psf->u.cbuf) ;

	if ((rows != 1) || (cols != 1))
		return SFE_MAT4_NO_SAMPLERATE ;

	psf->sf.samplerate = (int)lrint(value);   // kengo:

	/* Now write out the audio data. */

	psf_binheader_readf (psf, "m", &marker) ;

	psf_log_printf (psf, "Marker : %s\n", mat4_marker_to_str (marker)) ;

	psf_binheader_readf (psf, "444", &rows, &cols, &imag) ;

	psf_log_printf (psf, " Rows  : %d\n Cols  : %d\n Imag  : %s\n", rows, cols, imag ? "True" : "False") ;

	psf_binheader_readf (psf, "4", &namesize) ;

	if (namesize >= SIGNED_SIZEOF (name))
		return SFE_MAT4_BAD_NAME ;

	psf_binheader_readf (psf, "b", name, namesize) ;
	name [namesize] = 0 ;

	psf_log_printf (psf, " Name  : %s\n", name) ;

	psf->dataoffset = psf_ftell (psf) ;

	if (rows == 0 && cols == 0)
	{	psf_log_printf (psf, "*** Error : zero channel count.\n") ;
		return SFE_CHANNEL_COUNT_ZERO ;
		} ;

	psf->sf.channels	= rows ;
	psf->sf.frames		= cols ;

	psf->sf.format = psf->endian | SF_FORMAT_MAT4 ;
	switch (marker)
	{	case MAT4_BE_DOUBLE :
		case MAT4_LE_DOUBLE :
				psf->sf.format |= SF_FORMAT_DOUBLE ;
				psf->bytewidth = 8 ;
				break ;

		case MAT4_BE_FLOAT :
		case MAT4_LE_FLOAT :
				psf->sf.format |= SF_FORMAT_FLOAT ;
				psf->bytewidth = 4 ;
				break ;

		case MAT4_BE_PCM_32	:
		case MAT4_LE_PCM_32	:
				psf->sf.format |= SF_FORMAT_PCM_32 ;
				psf->bytewidth = 4 ;
				break ;

		case MAT4_BE_PCM_16	:
		case MAT4_LE_PCM_16	:
				psf->sf.format |= SF_FORMAT_PCM_16 ;
				psf->bytewidth = 2 ;
				break ;

		default :
				psf_log_printf (psf, "*** Error : Bad marker %08X\n", marker) ;
				return SFE_UNIMPLEMENTED ;
		} ;

	if ((psf->filelength - psf->dataoffset) < psf->sf.channels * psf->sf.frames * psf->bytewidth)
	{	psf_log_printf (psf, "*** File seems to be truncated. %D <--> %D\n",
				psf->filelength - psf->dataoffset, psf->sf.channels * psf->sf.frames * psf->bytewidth) ;
		}
	else if ((psf->filelength - psf->dataoffset) > psf->sf.channels * psf->sf.frames * psf->bytewidth)
		psf->dataend = psf->dataoffset + rows * cols * psf->bytewidth ;

	psf->datalength = psf->filelength - psf->dataoffset - psf->dataend ;

	psf->sf.sections = 1 ;

	return 0 ;
} /* mat4_read_header */
Пример #29
0
static int
nist_write_header (SF_PRIVATE *psf, int calc_length)
{	const char	*end_str ;
	long		samples ;
	sf_count_t	current ;

	current = psf_ftell (psf) ;

	if (calc_length)
	{	psf->filelength = psf_get_filelen (psf) ;

		psf->datalength = psf->filelength - psf->dataoffset ;

		if (psf->dataend)
			psf->datalength -= psf->filelength - psf->dataend ;

		if (psf->bytewidth > 0)
			psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
		} ;

	if (psf->endian == SF_ENDIAN_BIG)
		end_str = "10" ;
	else if (psf->endian == SF_ENDIAN_LITTLE)
		end_str = "01" ;
	else
		end_str = "error" ;

	/* Clear the whole header. */
	memset (psf->header.ptr, 0, psf->header.len) ;
	psf->header.indx = 0 ;

	psf_fseek (psf, 0, SEEK_SET) ;

	psf_asciiheader_printf (psf, "NIST_1A\n   1024\n") ;
	psf_asciiheader_printf (psf, "channel_count -i %d\n", psf->sf.channels) ;
	psf_asciiheader_printf (psf, "sample_rate -i %d\n", psf->sf.samplerate) ;

	switch (SF_CODEC (psf->sf.format))
	{	case SF_FORMAT_PCM_S8 :
				psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n") ;
				psf_asciiheader_printf (psf, "sample_n_bytes -i 1\n"
											"sample_sig_bits -i 8\n") ;
				break ;

		case SF_FORMAT_PCM_16 :
		case SF_FORMAT_PCM_24 :
		case SF_FORMAT_PCM_32 :
				psf_asciiheader_printf (psf, "sample_n_bytes -i %d\n", psf->bytewidth) ;
				psf_asciiheader_printf (psf, "sample_sig_bits -i %d\n", psf->bytewidth * 8) ;
				psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n"
								"sample_byte_format -s%d %s\n", psf->bytewidth, end_str) ;
				break ;

		case SF_FORMAT_ALAW :
				psf_asciiheader_printf (psf, "sample_coding -s4 alaw\n") ;
				psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ;
				break ;

		case SF_FORMAT_ULAW :
				psf_asciiheader_printf (psf, "sample_coding -s4 ulaw\n") ;
				psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ;
				break ;

		default : return SFE_UNIMPLEMENTED ;
		} ;

	psf->dataoffset = NIST_HEADER_LENGTH ;

	/* Fix this */
	samples = psf->sf.frames ;
	psf_asciiheader_printf (psf, "sample_count -i %ld\n", samples) ;
	psf_asciiheader_printf (psf, "end_head\n") ;

	/* Zero fill to dataoffset. */
	psf_binheader_writef (psf, "z", BHWz ((size_t) (NIST_HEADER_LENGTH - psf->header.indx))) ;

	psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;

	if (psf->error)
		return psf->error ;

	if (current > 0)
		psf_fseek (psf, current, SEEK_SET) ;

	return psf->error ;
} /* nist_write_header */
Пример #30
0
static int
caf_read_header (SF_PRIVATE *psf)
{	CAF_PRIVATE	*pcaf ;
	BUF_UNION	ubuf ;
	DESC_CHUNK desc ;
	sf_count_t chunk_size ;
	double srate ;
	short version, flags ;
	int marker, k, have_data = 0, error ;

	if ((pcaf = psf->container_data) == NULL)
		return SFE_INTERNAL ;

	memset (&desc, 0, sizeof (desc)) ;

	/* Set position to start of file to begin reading header. */
	psf_binheader_readf (psf, "pmE2E2", 0, &marker, &version, &flags) ;
	psf_log_printf (psf, "%M\n  Version : %d\n  Flags   : %x\n", marker, version, flags) ;
	if (marker != caff_MARKER)
		return SFE_CAF_NOT_CAF ;

	psf_binheader_readf (psf, "mE8b", &marker, &chunk_size, ubuf.ucbuf, 8) ;
	srate = double64_be_read (ubuf.ucbuf) ;
	snprintf (ubuf.cbuf, sizeof (ubuf.cbuf), "%5.3f", srate) ;
	psf_log_printf (psf, "%M : %D\n  Sample rate  : %s\n", marker, chunk_size, ubuf.cbuf) ;
	if (marker != desc_MARKER)
		return SFE_CAF_NO_DESC ;

	if (chunk_size < SIGNED_SIZEOF (DESC_CHUNK))
	{	psf_log_printf (psf, "**** Chunk size too small. Should be > 32 bytes.\n") ;
		return SFE_MALFORMED_FILE ;
		} ;

	psf->sf.samplerate = lrint (srate) ;

	psf_binheader_readf (psf, "mE44444", &desc.fmt_id, &desc.fmt_flags, &desc.pkt_bytes, &desc.frames_per_packet,
			&desc.channels_per_frame, &desc.bits_per_chan) ;
	psf_log_printf (psf, "  Format id    : %M\n  Format flags : %x\n  Bytes / packet   : %u\n"
			"  Frames / packet  : %u\n  Channels / frame : %u\n  Bits / channel   : %u\n",
			desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.frames_per_packet, desc.channels_per_frame, desc.bits_per_chan) ;

	if (desc.channels_per_frame > SF_MAX_CHANNELS)
	{	psf_log_printf (psf, "**** Bad channels per frame value %u.\n", desc.channels_per_frame) ;
		return SFE_MALFORMED_FILE ;
		} ;

	if (chunk_size > SIGNED_SIZEOF (DESC_CHUNK))
		psf_binheader_readf (psf, "j", (int) (chunk_size - sizeof (DESC_CHUNK))) ;

	psf->sf.channels = desc.channels_per_frame ;

	while (1)
	{	marker = 0 ;
		chunk_size = 0 ;

		psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ;
		if (marker == 0)
		{	sf_count_t pos = psf_ftell (psf) ;
			psf_log_printf (psf, "Have 0 marker at position %D (0x%x).\n", pos, pos) ;
			break ;
			} ;
		if (chunk_size < 0)
		{	psf_log_printf (psf, "%M : %D *** Should be >= 0 ***\n", marker, chunk_size) ;
			break ;
			} ;

		psf_store_read_chunk_u32 (&psf->rchunks, marker, psf_ftell (psf), chunk_size) ;

		switch (marker)
		{	case peak_MARKER :
				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
				if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels))
				{	psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
					psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
					return SFE_CAF_BAD_PEAK ;
					} ;

				if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
					return SFE_MALLOC_FAILED ;

				/* read in rest of PEAK chunk. */
				psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ;
				psf_log_printf (psf, "  edit count : %d\n", psf->peak_info->edit_number) ;

				psf_log_printf (psf, "     Ch   Position       Value\n") ;
				for (k = 0 ; k < psf->sf.channels ; k++)
				{	sf_count_t position ;
					float value ;

					psf_binheader_readf (psf, "Ef8", &value, &position) ;
					psf->peak_info->peaks [k].value = value ;
					psf->peak_info->peaks [k].position = position ;

					snprintf (ubuf.cbuf, sizeof (ubuf.cbuf), "    %2d   %-12" PRId64 "   %g\n", k, position, value) ;
					psf_log_printf (psf, ubuf.cbuf) ;
					} ;

				psf->peak_info->peak_loc = SF_PEAK_START ;
				break ;

			case chan_MARKER :
				if (chunk_size < 12)
				{	psf_log_printf (psf, "%M : %D (should be >= 12)\n", marker, chunk_size) ;
					psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
					break ;
					}

				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;

				if ((error = caf_read_chanmap (psf, chunk_size)))
					return error ;
				break ;

			case free_MARKER :
				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
				psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
				break ;

			case data_MARKER :
				psf_binheader_readf (psf, "E4", &k) ;
				if (chunk_size == -1)
				{	psf_log_printf (psf, "%M : -1\n") ;
					chunk_size = psf->filelength - psf->headindex ;
					}
				else if (psf->filelength > 0 && chunk_size > psf->filelength - psf->headindex + 10)
				{	psf_log_printf (psf, "%M : %D (should be %D)\n", marker, chunk_size, psf->filelength - psf->headindex - 8) ;
					psf->datalength = psf->filelength - psf->headindex - 8 ;
					}
				else
				{	psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
					/* Subtract the 4 bytes of the 'edit' field above. */
					psf->datalength = chunk_size - 4 ;
					} ;

				psf_log_printf (psf, "  edit : %u\n", k) ;

				psf->dataoffset = psf->headindex ;
				if (psf->datalength + psf->dataoffset < psf->filelength)
					psf->dataend = psf->datalength + psf->dataoffset ;

				psf_binheader_readf (psf, "j", make_size_t (psf->datalength)) ;
				have_data = 1 ;
				break ;

			case kuki_MARKER :
				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
				pcaf->alac.kuki_offset = psf_ftell (psf) - 12 ;
				psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
				break ;

			case pakt_MARKER :
				if (chunk_size < 24)
				{	psf_log_printf (psf, "%M : %D (should be > 24)\n", marker, chunk_size) ;
					return SFE_MALFORMED_FILE ;
					}
				else if (chunk_size > psf->filelength - psf->headindex)
				{	psf_log_printf (psf, "%M : %D (should be < %D)\n", marker, chunk_size, psf->filelength - psf->headindex) ;
					return SFE_MALFORMED_FILE ;
					}
				else
					psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;

				psf_binheader_readf (psf, "E8844", &pcaf->alac.packets, &pcaf->alac.valid_frames,
									&pcaf->alac.priming_frames, &pcaf->alac.remainder_frames) ;

				psf_log_printf (psf,
						"  Packets          : %D\n"
						"  Valid frames     : %D\n"
						"  Priming frames   : %d\n"
						"  Remainder frames : %d\n",
						pcaf->alac.packets, pcaf->alac.valid_frames, pcaf->alac.priming_frames,
						pcaf->alac.remainder_frames
						) ;

				if (pcaf->alac.packets == 0 && pcaf->alac.valid_frames == 0
							&& pcaf->alac.priming_frames == 0 && pcaf->alac.remainder_frames == 0)
					psf_log_printf (psf, "*** 'pakt' chunk header is all zero.\n") ;

				pcaf->alac.pakt_offset = psf_ftell (psf) - 12 ;
				psf_binheader_readf (psf, "j", make_size_t (chunk_size) - 24) ;
				break ;

			case info_MARKER :
				if (chunk_size < 4)
				{	psf_log_printf (psf, "%M : %D (should be > 4)\n", marker, chunk_size) ;
					return SFE_MALFORMED_FILE ;
					}
				else if (chunk_size > psf->filelength - psf->headindex)
				{	psf_log_printf (psf, "%M : %D (should be < %D)\n", marker, chunk_size, psf->filelength - psf->headindex) ;
					return SFE_MALFORMED_FILE ;
					} ;
				psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
				caf_read_strings (psf, chunk_size) ;
				break ;

			default :
				psf_log_printf (psf, "%M : %D (skipped)\n", marker, chunk_size) ;
				psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
				break ;
			} ;

		if (marker != data_MARKER && chunk_size >= 0xffffff00)
			break ;

		if (! psf->sf.seekable && have_data)
			break ;

		if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (chunk_size))
		{	psf_log_printf (psf, "End\n") ;
			break ;
			} ;
		} ;

	if (have_data == 0)
	{	psf_log_printf (psf, "**** Error, could not find 'data' chunk.\n") ;
		return SFE_MALFORMED_FILE ;
		} ;

	psf->endian = (desc.fmt_flags & 2) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;

	psf_fseek (psf, psf->dataoffset, SEEK_SET) ;

	if ((psf->sf.format = decode_desc_chunk (psf, &desc)) == 0)
		return SFE_UNSUPPORTED_ENCODING ;

	if (psf->bytewidth > 0)
		psf->sf.frames = psf->datalength / psf->bytewidth ;

	return 0 ;
} /* caf_read_header */