Ejemplo n.º 1
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 */
Ejemplo n.º 2
0
/* Win32 */ sf_count_t
psf_get_filelen (SF_PRIVATE *psf)
{
#if 0
	/* 
	** Windoze is SOOOOO F****D!!!!!!!
	** This code should work but doesn't. Why?
	** Code below does work.
	*/
	struct _stati64 statbuf ;

	if (_fstati64 (psf->filedes, &statbuf))
	{	psf_log_syserr (psf, errno) ;
		return (sf_count_t) -1 ;
		} ;

	return statbuf.st_size ;
#else
	sf_count_t  current, len ;
	
	current = psf_fseek (psf, 0, SEEK_CUR) ;
	len = psf_fseek (psf, 0, SEEK_END) ;
	psf_fseek (psf, current, SEEK_SET) ;
	
	return len ;
#endif
} /* psf_get_filelen */
Ejemplo n.º 3
0
static int
caf_write_tailer (SF_PRIVATE *psf)
{
	/* Reset the current header buffer length to zero. */
	psf->header [0] = 0 ;
	psf->headindex = 0 ;

	if (psf->bytewidth > 0 && psf->sf.seekable == SF_TRUE)
	{	psf->datalength = psf->sf.frames * psf->bytewidth * psf->sf.channels ;
		psf->dataend = psf->dataoffset + psf->datalength ;
		} ;

	if (psf->dataend > 0)
		psf_fseek (psf, psf->dataend, SEEK_SET) ;
	else
		psf->dataend = psf_fseek (psf, 0, SEEK_END) ;

	if (psf->dataend & 1)
		psf_binheader_writef (psf, "z", 1) ;

	if (psf->strings.flags & SF_STR_LOCATE_END)
		caf_write_strings (psf, SF_STR_LOCATE_END) ;

	/* Write the tailer. */
	if (psf->headindex > 0)
		psf_fwrite (psf->header, psf->headindex, 1, psf) ;

	return 0 ;
} /* caf_write_tailer */
Ejemplo n.º 4
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 */
Ejemplo n.º 5
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 [0] = 0 ;
	psf->headindex = 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", MAT4_BE_DOUBLE, 1, 1, 0) ;
		psf_binheader_writef (psf, "E4bd", 11, "samplerate", make_size_t (11), samplerate) ;
		psf_binheader_writef (psf, "tEm484", encoding, psf->sf.channels, psf->sf.frames, 0) ;
		psf_binheader_writef (psf, "E4b", 9, "wavedata", make_size_t (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", make_size_t (11), samplerate) ;
		psf_binheader_writef (psf, "tem484", encoding, psf->sf.channels, psf->sf.frames, 0) ;
		psf_binheader_writef (psf, "e4b", 9, "wavedata", make_size_t (9)) ;
		}
	else
		return 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 ;
} /* mat4_write_header */
Ejemplo n.º 6
0
void
wav_w64_analyze (SF_PRIVATE *psf)
{   AUDIO_DETECT ad ;
    int format = 0 ;

    if (psf->is_pipe)
    {   psf_log_printf (psf, "*** Error : Reading from a pipe. Can't analyze data section to figure out real data format.\n\n") ;
        return ;
    } ;

    psf_log_printf (psf, "---------------------------------------------------\n"
                    "Format is known to be broken. Using detection code.\n") ;

    /* Code goes here. */
    ad.endianness = SF_ENDIAN_LITTLE ;
    ad.channels = psf->sf.channels ;

    psf_fseek (psf, 3 * 4 * 50, SEEK_SET) ;

    while (psf_fread (psf->u.ucbuf, 1, 4096, psf) == 4096)
    {   format = audio_detect (psf, &ad, psf->u.ucbuf, 4096) ;
        if (format != 0)
            break ;
    } ;

    /* Seek to start of DATA section. */
    psf_fseek (psf, psf->dataoffset, SEEK_SET) ;

    if (format == 0)
    {   psf_log_printf (psf, "wav_w64_analyze : detection failed.\n") ;
        return ;
    } ;

    switch (format)
    {
    case SF_FORMAT_PCM_32 :
    case SF_FORMAT_FLOAT :
        psf_log_printf (psf, "wav_w64_analyze : found format : 0x%X\n", format) ;
        psf->sf.format = (psf->sf.format & ~SF_FORMAT_SUBMASK) + format ;
        psf->bytewidth = 4 ;
        psf->blockwidth = psf->sf.channels * psf->bytewidth ;
        break ;

    case SF_FORMAT_PCM_24 :
        psf_log_printf (psf, "wav_w64_analyze : found format : 0x%X\n", format) ;
        psf->sf.format = (psf->sf.format & ~SF_FORMAT_SUBMASK) + format ;
        psf->bytewidth = 3 ;
        psf->blockwidth = psf->sf.channels * psf->bytewidth ;
        break ;

    default :
        psf_log_printf (psf, "wav_w64_analyze : unhandled format : 0x%X\n", format) ;
        break ;
    } ;

    return ;
} /* wav_w64_analyze */
Ejemplo n.º 7
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 */
Ejemplo n.º 8
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 */
Ejemplo n.º 9
0
int
au_nh_open	(SF_PRIVATE *psf)
{
	if (psf->mode == SFM_RDWR)
		return SFE_BAD_OPEN_FORMAT ;

	if (psf_fseek (psf, psf->dataoffset, SEEK_SET))
		return SFE_BAD_SEEK ;

	psf_log_printf (psf, "Header-less u-law encoded file.\n") ;
	psf_log_printf (psf, "Setting up for 8kHz, mono, u-law.\n") ;

	psf->sf.format = SF_FORMAT_AU | SF_FORMAT_ULAW ;

 	psf->dataoffset		= 0 ;
	psf->endian			= 0 ;	/* Irrelevant but it must be something. */
	psf->sf.samplerate	= 8000 ;
	psf->sf.channels	= 1 ;
	psf->bytewidth		= 1 ;	/* Before decoding */

	ulaw_init (psf) ;

	psf->close = au_close ;

	psf->blockwidth = 1 ;
	psf->sf.frames = psf->filelength ;
	psf->datalength = psf->filelength - AU_DATA_OFFSET ;

	return 0 ;
} /* au_nh_open */
Ejemplo n.º 10
0
static void
file_seek_with_offset_test (const char *filename)
{	SF_PRIVATE sf_data, *psf ;
	sf_count_t real_end ;
	const size_t fileoffset = 64 ;

	print_test_name ("Testing seek with offset") ;

	/* Open the file created by the previous test for reading. */
	memset (&sf_data, 0, sizeof (sf_data)) ;
	psf = &sf_data ;
	psf->file.mode = SFM_READ ;
	snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
	test_open_or_die (psf, __LINE__) ;

	/* Gather basic info before setting offset. */
	real_end = psf_fseek (psf, 0, SEEK_END) ;
	test_tell_or_die (psf, real_end, __LINE__) ;

	/* Set the fileoffset (usually in a real system this is due to an id3 tag). */
	psf->fileoffset = fileoffset ;

	/* Check tell respects offset. */
	test_tell_or_die (psf, real_end - fileoffset, __LINE__) ;

	/* Check seeking works as expected. */
	test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ;
	test_seek_or_die (psf, 0, SEEK_CUR, 0, __LINE__) ;
	test_seek_or_die (psf, 0, SEEK_CUR, 0, __LINE__) ;
	test_seek_or_die (psf, 0, SEEK_END, real_end - fileoffset, __LINE__) ;

	test_close_or_die (psf, __LINE__) ;

	puts ("ok") ;
} /* file_seek_with_offset_test */
Ejemplo n.º 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 */ 
Ejemplo n.º 12
0
static sf_count_t
vorbis_length (SF_PRIVATE *psf)
{	sf_count_t length ;
	int error ;

	if (psf->sf.seekable == 0)
		return SF_COUNT_MAX ;

	psf_fseek (psf, 0, SEEK_SET) ;
	length = vorbis_length_aux (psf) ;

	psf_fseek (psf, 12, SEEK_SET) ;
	if ((error = vorbis_read_header (psf, 0)) != 0)
		psf->error = error ;

	return length ;
} /* vorbis_length */
Ejemplo n.º 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 */
Ejemplo n.º 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 */
Ejemplo n.º 15
0
static void
test_seek_or_die (SF_PRIVATE *psf, sf_count_t offset, int whence, sf_count_t new_position, int linenum)
{	sf_count_t retval ;

	retval = psf_fseek (psf, offset, whence) ;

	if (retval != new_position)
	{	printf ("\n\nLine %d: psf_fseek() failed. New position is %ld (should be %ld).\n\n",
			linenum, (long) retval, (long) new_position) ;
		exit (1) ;
		} ;

} /* test_seek_or_die */
Ejemplo n.º 16
0
Archivo: w64.c Proyecto: joshlong/libcd
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 */
Ejemplo n.º 17
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 */
Ejemplo n.º 18
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 */
Ejemplo n.º 19
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 */
Ejemplo n.º 20
0
static int
voc_close	(SF_PRIVATE *psf)
{	if (psf->file.mode == SFM_WRITE || psf->file.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 char byte = VOC_TERMINATOR ;


		psf_fseek (psf, 0, SEEK_END) ;

		/* Write terminator */
		psf_fwrite (&byte, 1, 1, psf) ;

		voc_write_header (psf, SF_TRUE) ;
	} ;

	return 0 ;
} /* voc_close */
Ejemplo n.º 21
0
static sf_count_t
ogg_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
{
	OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
	VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;

	if (odata == NULL || vdata == NULL)
		return 0 ;

	if (offset < 0)
	{	psf->error = SFE_BAD_SEEK ;
		return ((sf_count_t) -1) ;
		} ;

	if (psf->file.mode == SFM_READ)
	{	sf_count_t target = offset - vdata->loc ;

		if (target < 0)
		{	/* 12 to allow for OggS bit */
			psf_fseek (psf, 12, SEEK_SET) ;
			ogg_read_header (psf, 0) ; /* Reset state */
			target = offset ;
			} ;

		while (target > 0)
		{	sf_count_t m = target > 4096 ? 4096 : target ;

			/*
			**	Need to multiply by channels here because the seek is done in
			**	terms of frames and the read function is done in terms of
			**	samples.
			*/
			ogg_read_sample (psf, (void *) NULL, m * psf->sf.channels, ogg_rnull) ;

			target -= m ;
			} ;

		return vdata->loc ;
		} ;

	return 0 ;
} /* ogg_seek */
Ejemplo n.º 22
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 */
Ejemplo n.º 23
0
int
txw_open	(SF_PRIVATE *psf)
{	int error ;

	if (psf->file.mode != SFM_READ)
		return SFE_UNIMPLEMENTED ;

	if ((error = txw_read_header (psf)))
			return error ;

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

	psf->read_short		= txw_read_s ;
	psf->read_int		= txw_read_i ;
	psf->read_float		= txw_read_f ;
	psf->read_double	= txw_read_d ;

	psf->seek = txw_seek ;

	return 0 ;
} /* txw_open */
Ejemplo n.º 24
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 */
Ejemplo n.º 25
0
static int
spx_read_header (SF_PRIVATE * psf)
{	static SpeexStereoState STEREO_INIT = SPEEX_STEREO_STATE_INIT ;

	OGG_PRIVATE* odata = psf->container_data ;
	SPX_PRIVATE* spx = psf->codec_data ;

	ogg_int64_t page_granule = 0 ;
	int stream_init = 0 ;
	int	page_nb_packets = 0 ;
	int packet_count = 0 ;
	int enh_enabled = 1 ;
	int force_mode = -1 ;
	char * data ;
	int nb_read ;
	int lookahead ;

printf ("%s %d\n", __func__, __LINE__) ;

	psf_log_printf (psf, "Speex header\n") ;
	odata->eos = 0 ;

	/* Reset ogg stuff which has already been used in src/ogg.c. */
	ogg_stream_reset (&odata->ostream) ;
	ogg_sync_reset (&odata->osync) ;

	/* Seek to start of stream. */
	psf_fseek (psf, 0, SEEK_SET) ;

	/* Initialize. */
	ogg_sync_init (&odata->osync) ;
	speex_bits_init (&spx->bits) ;

	/* Set defaults. */
	psf->sf.channels = -1 ;
	psf->sf.samplerate = 0 ;
	spx->stereo = STEREO_INIT ;

	/* Get a pointer to the ogg buffer and read data into it. */
	data = ogg_sync_buffer (&odata->osync, OGG_SPX_READ_SIZE) ;
	nb_read = psf_fread (data, 1, OGG_SPX_READ_SIZE, psf) ;
	ogg_sync_wrote (&odata->osync, nb_read) ;

	/* Now we chew on Ogg packets. */
	while (ogg_sync_pageout (&odata->osync, &odata->opage) == 1)
	{	if (stream_init == 0)
		{	ogg_stream_init (&odata->ostream, ogg_page_serialno (&odata->opage)) ;
			stream_init = 1 ;
			} ;

		if (ogg_page_serialno (&odata->opage) != odata->ostream.serialno)
		{	/* so all streams are read. */
			ogg_stream_reset_serialno (&odata->ostream, ogg_page_serialno (&odata->opage)) ;
			} ;

		/*Add page to the bitstream*/
		ogg_stream_pagein (&odata->ostream, &odata->opage) ;
		page_granule = ogg_page_granulepos (&odata->opage) ;
		page_nb_packets = ogg_page_packets (&odata->opage) ;

		/*Extract all available packets*/
		while (odata->eos == 0 && ogg_stream_packetout (&odata->ostream, &odata->opacket) == 1)
		{	if (odata->opacket.bytes >= 8 && memcmp (odata->opacket.packet, "Speex   ", 8) == 0)
			{	spx->serialno = odata->ostream.serialno ;
				} ;

			if (spx->serialno == -1 || odata->ostream.serialno != spx->serialno)
				break ;

			if (packet_count == 0)
			{	spx->state = spx_header_read (psf, &odata->opacket, enh_enabled, force_mode) ;
				if (! spx->state)
					break ;

				speex_decoder_ctl (spx->state, SPEEX_GET_LOOKAHEAD, &lookahead) ;
				if (spx->nframes == 0)
					spx->nframes = 1 ;
				}
			else if (packet_count == 1)
			{	spx_print_comments ((const char*) odata->opacket.packet, odata->opacket.bytes) ;
				}
			else if (packet_count < 2 + spx->header.extra_headers)
			{	/* Ignore extra headers */
				}
			packet_count ++ ;
			} ;
		} ;

	psf_log_printf (psf, "End\n") ;

	psf_log_printf (psf, "packet_count %d\n", packet_count) ;
	psf_log_printf (psf, "page_nb_packets %d\n", page_nb_packets) ;
	psf_log_printf (psf, "page_granule %lld\n", page_granule) ;

	return 0 ;
} /* spx_read_header */
Ejemplo n.º 26
0
int
sd2_open (SF_PRIVATE *psf)
{	int subformat, error = 0, valid ;

	/* SD2 is always big endian. */
	psf->endian = SF_ENDIAN_BIG ;

	if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->rsrclength > 0))
	{	psf_use_rsrc (psf, SF_TRUE) ;
		valid = psf_file_valid (psf) ;
		psf_use_rsrc (psf, SF_FALSE) ;
		if (! valid)
		{	psf_log_printf (psf, "sd2_open : psf->rsrc.filedes < 0\n") ;
			return SFE_SD2_BAD_RSRC ;
			} ;

		error = sd2_parse_rsrc_fork (psf) ;

		if (error)
			goto error_cleanup ;
		} ;

	if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_SD2)
	{	error = SFE_BAD_OPEN_FORMAT ;
		goto error_cleanup ;
		} ;

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

	/* Only open and write the resource in RDWR mode is its current length is zero. */
	if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->rsrclength == 0))
	{	psf->rsrc.mode = psf->file.mode ;
		psf_open_rsrc (psf) ;

		error = sd2_write_rsrc_fork (psf, SF_FALSE) ;

		if (error)
			goto error_cleanup ;

		/* Not needed. */
		psf->write_header = NULL ;
		} ;

	psf->container_close = sd2_close ;

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

	switch (subformat)
	{	case SF_FORMAT_PCM_S8 :	/* 8-bit linear PCM. */
		case SF_FORMAT_PCM_16 :	/* 16-bit linear PCM. */
		case SF_FORMAT_PCM_24 :	/* 24-bit linear PCM */
		case SF_FORMAT_PCM_32 :	/* 32-bit linear PCM */
				error = pcm_init (psf) ;
				break ;

		default :
				error = SFE_UNIMPLEMENTED ;
				break ;
		} ;

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

error_cleanup:

	/* Close the resource fork regardless. We won't need it again. */
	psf_close_rsrc (psf) ;

	return error ;
} /* sd2_open */
Ejemplo n.º 27
0
static int 	
nist_read_header (SF_PRIVATE *psf)
{	char	*psf_header ;
	int		bitwidth = 0, bytes = 0, count, encoding ;
	char 	str [64], *cptr ;
	long	samples ;
	
		
	psf->sf.format = SF_FORMAT_NIST ;
	
	psf_header = (char*) psf->header ;
	
	if (sizeof (psf->header) <= NIST_HEADER_LENGTH)
		return SFE_INTERNAL ;
		
	/* Go to start of file and read in the whole header. */
	psf_binheader_readf (psf, "pb", 0, psf_header, NIST_HEADER_LENGTH) ;

	/* Header is a string, so make sure it is null terminated. */
	psf_header [NIST_HEADER_LENGTH] = 0 ;
	
	/* Now trim the header after the end marker. */
	if ((cptr = strstr (psf_header, "end_head")))
	{	cptr += strlen ("end_head") + 1 ;
		cptr [0] = 0 ;
		} ;

	psf_log_printf (psf, psf_header) ;
	
	/* Make sure its a NIST file. */
	if (strstr (psf_header, "NIST_1A\n   1024\n") != psf_header)
	{	printf ("Not a NIST file.\n") ;
		puts (psf_header) ;
		exit (1) ;
		} ;

	/* Determine sample encoding, start by assuming PCM. */		
	encoding = SF_FORMAT_PCM_U8 ;
	if ((cptr = strstr (psf_header, "sample_coding -s")))
	{	sscanf (cptr, "sample_coding -s%d %63s", &count, str) ;

		if (strcmp (str, "pcm") == 0)
			encoding = SF_FORMAT_PCM_U8 ;
		else if (strcmp (str, "alaw") == 0)
			encoding = SF_FORMAT_ALAW ;
		else if ((strcmp (str, "ulaw") == 0) || (strcmp (str, "mu-law") == 0))
			encoding = SF_FORMAT_ULAW ;
		else
		{	psf_log_printf (psf, "*** Unknown encoding : %s\n", str) ;
			encoding = 0 ;
			} ;
		} ;

	if ((cptr = strstr (psf_header, "channel_count -i ")))
		sscanf (cptr, "channel_count -i %d", &(psf->sf.channels)) ;
		
	if ((cptr = strstr (psf_header, "sample_rate -i ")))
		sscanf (cptr, "sample_rate -i %d", &(psf->sf.samplerate)) ;

	if ((cptr = strstr (psf_header, "sample_count -i ")))
	{	sscanf (psf_header, "sample_count -i %ld", &samples) ;
		psf->sf.frames = samples ;
		} ;

	if ((cptr = strstr (psf_header, "sample_n_bytes -i ")))
		sscanf (cptr, "sample_n_bytes -i %d", &(psf->bytewidth)) ;

	/* Default endian-ness (for 8 bit, u-law, A-law. */
	psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;

	/* This is where we figure out endian-ness. */
	if ((cptr = strstr (psf_header, "sample_byte_format -s")))
	{	sscanf (cptr, "sample_byte_format -s%d %8s", &bytes, str) ;
		if (bytes > 1)
		{	if (psf->bytewidth == 0)
				psf->bytewidth = bytes ;
			else if (psf->bytewidth != bytes)
			{	psf_log_printf (psf, "psf->bytewidth (%d) != bytes (%d)\n", psf->bytewidth, bytes) ;
				return SFE_NIST_BAD_ENCODING ;
				} ;

			if (strstr (str, "01") == str)
				psf->endian = SF_ENDIAN_LITTLE ;
			else if (strstr (str, "10"))
				psf->endian = SF_ENDIAN_BIG ;
			else
			{	psf_log_printf (psf, "Weird endian-ness : %s\n", str) ;
				return SFE_NIST_BAD_ENCODING ;
				} ;
			} ;

		psf->sf.format |= psf->endian ;
		} ;

	if ((cptr = strstr (psf_header, "sample_sig_bits -i ")))
		sscanf (cptr, "sample_sig_bits -i %d", &bitwidth) ;
		
	if (strstr (psf_header, "channels_interleaved -s5 FALSE"))
	{	psf_log_printf (psf, "Non-interleaved data unsupported.\n", str) ;
		return SFE_NIST_BAD_ENCODING ;
		} ;
		
 	psf->dataoffset = NIST_HEADER_LENGTH ;
	psf->blockwidth = psf->sf.channels * psf->bytewidth ;
	psf->datalength = psf->filelength - psf->dataoffset ;

	psf->close = nist_close ;

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

	if (encoding == SF_FORMAT_PCM_U8)
	{	switch (psf->bytewidth)
		{	case 1 :
					psf->sf.format |= SF_FORMAT_PCM_S8 ;
					break ;

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

			case 3 :
					psf->sf.format |= SF_FORMAT_PCM_24 ;
					break ;

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

			default : break ;
			} ;
		}
	else if (encoding != 0)
		psf->sf.format |= encoding ;
	else
		return SFE_UNIMPLEMENTED ;

	return 0 ;
} /* nist_read_header */
Ejemplo n.º 28
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 */
Ejemplo n.º 29
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 */
Ejemplo n.º 30
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 */