Beispiel #1
0
int
psf_get_format_info (SF_FORMAT_INFO *data)
{	int k, format ;

	if (SF_CONTAINER (data->format))
	{	format = SF_CONTAINER (data->format) ;

		for (k = 0 ; k < (SIGNED_SIZEOF (major_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
		{	if (format == major_formats [k].format)
			{	memcpy (data, &(major_formats [k]), sizeof (SF_FORMAT_INFO)) ;
				return 0 ;
				} ;
			} ;
		}
	else if (SF_CODEC (data->format))
	{	format = SF_CODEC (data->format) ;

		for (k = 0 ; k < (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)) ; k++)
		{	if (format == subtype_formats [k].format)
			{	memcpy (data, &(subtype_formats [k]), sizeof (SF_FORMAT_INFO)) ;
				return 0 ;
				} ;
			} ;
		} ;

	memset (data, 0, sizeof (SF_FORMAT_INFO)) ;

	return SFE_BAD_COMMAND_PARAM ;
} /* psf_get_format_info */
Beispiel #2
0
int
psf_get_format_simple (SF_FORMAT_INFO *data)
{	int indx ;

	if (data->format < 0 || data->format >= (SIGNED_SIZEOF (simple_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
		return SFE_BAD_COMMAND_PARAM ;

	indx = data->format ;
	memcpy (data, &(simple_formats [indx]), SIGNED_SIZEOF (SF_FORMAT_INFO)) ;

	return 0 ;
} /* psf_get_format_simple */
Beispiel #3
0
void
hexdump_file (const char * filename, sf_count_t offset, sf_count_t length)
{
	FILE * file ;
	char buffer [16] ;
	int k, m, ch, readcount ;

	if (length > 1000000)
	{	printf ("\n\nError : length (%ld) too long.\n\n", SF_COUNT_TO_LONG (offset)) ;
		exit (1) ;
		} ;

	if ((file = fopen (filename, "r")) == NULL)
	{	printf ("\n\nError : hexdump_file (%s) could not open file for read.\n\n", filename) ;
		exit (1) ;
		} ;

	if (fseek (file, offset, SEEK_SET) != 0)
	{	printf ("\n\nError : fseek(file, %ld, SEEK_SET) failed : %s\n\n", SF_COUNT_TO_LONG (offset), strerror (errno)) ;
		exit (1) ;
		} ;

	puts ("\n\n") ;

	for (k = 0 ; k < length ; k+= sizeof (buffer))
	{	readcount = fread (buffer, 1, sizeof (buffer), file) ;

		printf ("%08lx : ", SF_COUNT_TO_LONG (offset + k)) ;

		for (m = 0 ; m < readcount ; m++)
			printf ("%02x ", buffer [m] & 0xFF) ;

		for (m = readcount ; m < SIGNED_SIZEOF (buffer) ; m++)
			printf ("   ") ;

		printf ("  ") ;
		for (m = 0 ; m < readcount ; m++)
		{	ch = isprint (buffer [m]) ? buffer [m] : '.' ;
			putchar (ch) ;
			} ;

		if (readcount < SIGNED_SIZEOF (buffer))
			break ;

		putchar ('\n') ;
		} ;

	puts ("\n") ;

	fclose (file) ;
} /* hexdump_file */
Beispiel #4
0
int
broadcast_add_coding_history (SF_BROADCAST_INFO* bext, unsigned int channels, unsigned int samplerate)
{	char chnstr [16] ;
	int count ;

	switch (channels)
	{	case 0 :
			return SF_FALSE ;

		case 1 :
			strncpy (chnstr, "mono", sizeof (chnstr)) ;
			break ;

		case 2 :
			strncpy (chnstr, "stereo", sizeof (chnstr)) ;
			break ;

	default :
		LSF_SNPRINTF (chnstr, sizeof (chnstr), "%uchn", channels) ;
		break ;
	}

	count = LSF_SNPRINTF (bext->coding_history, sizeof (bext->coding_history), "F=%u,A=PCM,M=%s,W=24,T=%s-%s", samplerate, chnstr, PACKAGE, VERSION) ;

	if (count >= SIGNED_SIZEOF (bext->coding_history))
		bext->coding_history_size = sizeof (bext->coding_history) ;
	else
	{	count += count & 1 ;
		bext->coding_history_size = count ;
		} ;

	return SF_TRUE ;
} /* broadcast_add_coding_history */
Beispiel #5
0
static void
show_lseek_error (void)
{	static const char *filename = "fstat.dat" ;
	static char data [256] ;

	INT64	retval ;
	int fd, mode, flags ;

	puts ("\n64 bit lseek() test.\n--------------------") ;

	printf ("0) Create a file, write %d bytes and close it.\n", SIGNED_SIZEOF (data)) ;
	mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
	flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
	if ((fd = open (filename, mode, flags)) < 0)
	{	printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
		return ;
		} ;
	assert (write (fd, data, sizeof (data)) > 0) ;
	close (fd) ;

	printf ("1) Re-open file in read/write mode and write another %d bytes at the end.\n", SIGNED_SIZEOF (data)) ;
	mode = O_RDWR | O_BINARY ;
	flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
	if ((fd = open (filename, mode, flags)) < 0)
	{	printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
		return ;
		} ;

	LSEEK (fd, 0, SEEK_END) ;
	assert (write (fd, data, sizeof (data)) > 0) ;

	printf ("2) Now use system (\"%s %s\") to show the file length.\n\n", dir_cmd, filename) ;

	/* Would use snprintf, but thats not really available on windows. */
	memset (data, 0, sizeof (data)) ;
	strncpy (data, dir_cmd, sizeof (data) - 1) ;
	strncat (data, " ", sizeof (data) - 1 - strlen (data)) ;
	strncat (data, filename, sizeof (data) - 1 - strlen (data)) ;

	assert (system (data) >= 0) ;
	puts ("") ;

	printf ("3) Now use lseek() to go to the end of the file.\n") ;
	retval = LSEEK (fd, 0, SEEK_END) ;

	printf ("4) We are now at position %ld, ", (long) retval) ;

	close (fd) ;

	if (retval != 2 * sizeof (data))
		printf ("but thats just plain ***WRONG***.\n\n") ;
	else
	{	printf ("which is correct.\n\n") ;
		unlink (filename) ;
		} ;

} /* show_lseek_error */
Beispiel #6
0
static void
show_stat_fstat_error (void)
{	static const char *filename = "stat_fstat.dat" ;
	static char data [256] ;

	int fd, mode, flags ;
	int stat_size, fstat_size ;
	struct stat buf ;

	/* Known to fail on WinXP. */
	puts ("\nstat/fstat test.\n----------------") ;

	printf ("0) Create a file and write %d bytes.\n", SIGNED_SIZEOF (data)) ;

	mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
	flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
	if ((fd = open (filename, mode, flags)) < 0)
	{	printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
		return ;
		} ;

	assert (write (fd, data, sizeof (data)) > 0) ;

	printf ("1) Now call stat and fstat on the file and retreive the file lengths.\n") ;

	if (stat (filename, &buf) != 0)
	{	printf ("\n\nLine %d: stat() failed : %s\n\n", __LINE__, strerror (errno)) ;
		goto error_exit ;
		} ;
	stat_size = buf.st_size ;

	if (fstat (fd, &buf) != 0)
	{	printf ("\n\nLine %d: fstat() failed : %s\n\n", __LINE__, strerror (errno)) ;
		goto error_exit ;
		} ;
	fstat_size = buf.st_size ;

	printf ("2) Size returned by stat and fstat is %d and %d, ", stat_size, fstat_size) ;


	if (stat_size == 0 || stat_size != fstat_size)
		printf ("but thats just plain ***WRONG***.\n\n") ;
	else
		printf ("which is correct.\n\n") ;

error_exit :

	close (fd) ;
	unlink (filename) ;

	return ;
} /* show_stat_fstat_error */
static sf_count_t
vfwrite (const void *ptr, sf_count_t count, void *user_data)
{	VIO_DATA *vf = (VIO_DATA *) user_data ;

	/*
	**	This will break badly for files over 2Gig in length, but
	**	is sufficient for testing.
	*/
	if (vf->offset >= SIGNED_SIZEOF (vf->data))
		return 0 ;

	if (vf->offset + count > SIGNED_SIZEOF (vf->data))
		count = sizeof (vf->data) - vf->offset ;

	memcpy (vf->data + vf->offset, ptr, (size_t) count) ;
	vf->offset += count ;

	if (vf->offset > vf->length)
		vf->length = vf->offset ;

	return count ;
} /* vfwrite */
Beispiel #8
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 */
Beispiel #9
0
static void
file_truncate_test (const char *filename)
{	SF_PRIVATE sf_data, *psf ;
	unsigned char buffer [256] ;
	int k ;

	/*
	** Open a new file and write two blocks of data to the file. After each
	** write, test that psf_get_filelen() returns the new length.
	*/

	printf ("    %-24s : ", "file_truncate_test") ;
	fflush (stdout) ;

	memset (&sf_data, 0, sizeof (sf_data)) ;
	memset (buffer, 0xEE, sizeof (buffer)) ;

	psf = &sf_data ;
	strncpy (psf->filename, filename, sizeof (psf->filename)) ;

	/*
	** Open the file write mode, write 0xEE data and then extend the file
	** using truncate (the extended data should be 0x00).
	*/
	psf->mode = SFM_WRITE ;
	test_open_or_die (psf, __LINE__) ;
	test_write_or_die (psf, buffer, sizeof (buffer) / 2, 1, sizeof (buffer) / 2, __LINE__) ;
	psf_ftruncate (psf, sizeof (buffer)) ;
	test_close_or_die (psf, __LINE__) ;

	/* Open the file in read mode and check the data. */
	psf->mode = SFM_READ ;
	test_open_or_die (psf, __LINE__) ;
	test_read_or_die (psf, buffer, sizeof (buffer), 1, sizeof (buffer), __LINE__) ;
	test_close_or_die (psf, __LINE__) ;

	for (k = 0 ; k < SIGNED_SIZEOF (buffer) / 2 ; k++)
		if (buffer [k] != 0xEE)
		{	printf ("\n\nLine %d : buffer [%d] = %d (should be 0xEE)\n\n", __LINE__, k, buffer [k]) ;
			exit (1) ;
			} ;

	for (k = SIGNED_SIZEOF (buffer) / 2 ; k < SIGNED_SIZEOF (buffer) ; k++)
		if (buffer [k] != 0)
		{	printf ("\n\nLine %d : buffer [%d] = %d (should be 0)\n\n", __LINE__, k, buffer [k]) ;
			exit (1) ;
			} ;

	/* Open the file in read/write and shorten the file using truncate. */
	psf->mode = SFM_RDWR ;
	test_open_or_die (psf, __LINE__) ;
	psf_ftruncate (psf, sizeof (buffer) / 4) ;
	test_close_or_die (psf, __LINE__) ;

	/* Check the file length. */
	psf->mode = SFM_READ ;
	test_open_or_die (psf, __LINE__) ;
	test_seek_or_die (psf, 0, SEEK_END, SIGNED_SIZEOF (buffer) / 4, __LINE__) ;
	test_close_or_die (psf, __LINE__) ;

	puts ("ok") ;
} /* file_truncate_test */
Beispiel #10
0
static void
file_read_write_test (const char *filename)
{	static int data_out	[512] ;
	static int data_in	[512] ;

	SF_PRIVATE sf_data, *psf ;
	sf_count_t retval ;

	/*
	** Open a new file and write two blocks of data to the file. After each
	** write, test that psf_get_filelen() returns the new length.
	*/

	printf ("    %-24s : ", "file_write_test") ;
	fflush (stdout) ;

	memset (&sf_data, 0, sizeof (sf_data)) ;
	psf = &sf_data ;
	strncpy (psf->filename, filename, sizeof (psf->filename)) ;

	/* Test file open in write mode. */
	psf->mode = SFM_WRITE ;
	test_open_or_die (psf, __LINE__) ;

	make_data (data_out, ARRAY_LEN (data_out), 1) ;
	test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), sizeof (data_out), __LINE__) ;

	if ((retval = psf_get_filelen (psf)) != sizeof (data_out))
	{	printf ("\n\nLine %d: file length after write is not correct (%ld should be %d).\n\n", __LINE__, (long) retval, (int) sizeof (data_out)) ;
		if (retval == 0)
			printf ("An fsync() may be necessary before fstat() in psf_get_filelen().\n\n") ;
		exit (1) ;
		} ;

	make_data (data_out, ARRAY_LEN (data_out), 2) ;
	test_write_or_die (psf, data_out, ARRAY_LEN (data_out), sizeof (data_out [0]), 2 * sizeof (data_out), __LINE__) ;

	if ((retval = psf_get_filelen (psf)) != 2 * sizeof (data_out))
	{	printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 2 * ((int) sizeof (data_out))) ;
		exit (1) ;
		} ;

	test_close_or_die (psf, __LINE__) ;
	puts ("ok") ;

	/*
	** Now open the file in read mode, check the file length and check
	** that the data is correct.
	*/

	printf ("    %-24s : ", "file_read_test") ;
	fflush (stdout) ;

	/* Test file open in write mode. */
	psf->mode = SFM_READ ;
	test_open_or_die (psf, __LINE__) ;

	make_data (data_out, ARRAY_LEN (data_out), 1) ;
	test_read_or_die (psf, data_in, 1, sizeof (data_in), sizeof (data_in), __LINE__) ;
	test_equal_or_die	(data_out, data_in, ARRAY_LEN (data_out), __LINE__) ;

	make_data (data_out, ARRAY_LEN (data_out), 2) ;
	test_read_or_die (psf, data_in, sizeof (data_in [0]), ARRAY_LEN (data_in), 2 * sizeof (data_in), __LINE__) ;
	test_equal_or_die	(data_out, data_in, ARRAY_LEN (data_out), __LINE__) ;

	test_close_or_die (psf, __LINE__) ;

	puts ("ok") ;

	/*
	** Open the file in read/write mode, seek around a bit and then seek to
	** the end of the file and write another block of data (3rd block). Then
	** go back and check that all three blocks are correct.
	*/

	printf ("    %-24s : ", "file_seek_test") ;
	fflush (stdout) ;

	/* Test file open in read/write mode. */
	psf->mode = SFM_RDWR ;
	test_open_or_die (psf, __LINE__) ;

	test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ;
	test_seek_or_die (psf, 0, SEEK_END, 2 * SIGNED_SIZEOF (data_out), __LINE__) ;
	test_seek_or_die (psf, -1 * SIGNED_SIZEOF (data_out), SEEK_CUR, (sf_count_t) sizeof (data_out), __LINE__) ;

	test_seek_or_die (psf, SIGNED_SIZEOF (data_out), SEEK_CUR, 2 * SIGNED_SIZEOF (data_out), __LINE__) ;
	make_data (data_out, ARRAY_LEN (data_out), 3) ;
	test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), 3 * sizeof (data_out), __LINE__) ;

	test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ;
	make_data (data_out, ARRAY_LEN (data_out), 1) ;
	test_read_or_die (psf, data_in, 1, sizeof (data_in), sizeof (data_in), __LINE__) ;
	test_equal_or_die	(data_out, data_in, ARRAY_LEN (data_out), __LINE__) ;

	test_seek_or_die (psf, 2 * SIGNED_SIZEOF (data_out), SEEK_SET, 2 * SIGNED_SIZEOF (data_out), __LINE__) ;
	make_data (data_out, ARRAY_LEN (data_out), 3) ;
	test_read_or_die (psf, data_in, 1, sizeof (data_in), 3 * sizeof (data_in), __LINE__) ;
	test_equal_or_die	(data_out, data_in, ARRAY_LEN (data_out), __LINE__) ;

	test_seek_or_die (psf, SIGNED_SIZEOF (data_out), SEEK_SET, SIGNED_SIZEOF (data_out), __LINE__) ;
	make_data (data_out, ARRAY_LEN (data_out), 2) ;
	test_read_or_die (psf, data_in, 1, sizeof (data_in), 2 * sizeof (data_in), __LINE__) ;
	test_equal_or_die	(data_out, data_in, ARRAY_LEN (data_out), __LINE__) ;

	test_close_or_die (psf, __LINE__) ;
	puts ("ok") ;

	/*
	** Now test operations with a non-zero psf->fileoffset field. This field
	** sets an artificial file start positions so that a seek to the start of
	** the file will actually be a seek to the value given by psf->fileoffset.
	*/

	printf ("    %-24s : ", "file_offset_test") ;
	fflush (stdout) ;

	/* Test file open in read/write mode. */
	psf->mode = SFM_RDWR ;
	psf->fileoffset = sizeof (data_out [0]) * ARRAY_LEN (data_out) ;
	test_open_or_die (psf, __LINE__) ;

	if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out))
	{	printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ;
		exit (1) ;
		} ;

	test_seek_or_die (psf, SIGNED_SIZEOF (data_out), SEEK_SET, SIGNED_SIZEOF (data_out), __LINE__) ;
	make_data (data_out, ARRAY_LEN (data_out), 5) ;
	test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), 2 * sizeof (data_out), __LINE__) ;
	test_close_or_die (psf, __LINE__) ;

	/* final test with psf->fileoffset == 0. */

	psf->mode = SFM_RDWR ;
	psf->fileoffset = 0 ;
	test_open_or_die (psf, __LINE__) ;

	if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out))
	{	printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ;
		exit (1) ;
		} ;

	make_data (data_out, ARRAY_LEN (data_out), 1) ;
	test_read_or_die (psf, data_in, 1, sizeof (data_in), sizeof (data_in), __LINE__) ;
	test_equal_or_die	(data_out, data_in, ARRAY_LEN (data_out), __LINE__) ;

	make_data (data_out, ARRAY_LEN (data_out), 2) ;
	test_read_or_die (psf, data_in, 1, sizeof (data_in), 2 * sizeof (data_in), __LINE__) ;
	test_equal_or_die	(data_out, data_in, ARRAY_LEN (data_out), __LINE__) ;

	make_data (data_out, ARRAY_LEN (data_out), 5) ;
	test_read_or_die (psf, data_in, 1, sizeof (data_in), 3 * sizeof (data_in), __LINE__) ;
	test_equal_or_die	(data_out, data_in, ARRAY_LEN (data_out), __LINE__) ;

	test_close_or_die (psf, __LINE__) ;

	puts ("ok") ;
} /* file_read_write_test */
Beispiel #11
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 */
Beispiel #12
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 */
Beispiel #13
0
static int
mat5_read_header (SF_PRIVATE *psf)
{	char	name [32] ;
	short	version, endian ;
	int		type, size, flags1, flags2, rows, cols ;

	psf_binheader_readf (psf, "pb", 0, psf->u.scbuf, 124) ;

	psf->u.scbuf [125] = 0 ;

	if (strlen (psf->u.scbuf) >= 124)
		return SFE_UNIMPLEMENTED ;

	if (strstr (psf->u.cbuf, "MATLAB 5.0 MAT-file") == psf->u.cbuf)
		psf_log_printf (psf, "%s\n", psf->u.scbuf) ;


	psf_binheader_readf (psf, "E22", &version, &endian) ;

	if (endian == MI_MARKER)
	{	psf->endian = psf->rwf_endian = SF_ENDIAN_BIG ;
		if (CPU_IS_LITTLE_ENDIAN) version = ENDSWAP_SHORT (version) ;
		}
	else if (endian == IM_MARKER)
	{	psf->endian = psf->rwf_endian = SF_ENDIAN_LITTLE ;
		if (CPU_IS_BIG_ENDIAN) version = ENDSWAP_SHORT (version) ;
		}
	else
		return SFE_MAT5_BAD_ENDIAN ;

	if ((CPU_IS_LITTLE_ENDIAN && endian == IM_MARKER) ||
			(CPU_IS_BIG_ENDIAN && endian == MI_MARKER))
		version = ENDSWAP_SHORT (version) ;

	psf_log_printf (psf, "Version : 0x%04X\n", version) ;
	psf_log_printf (psf, "Endian  : 0x%04X => %s\n", endian,
				(psf->endian == SF_ENDIAN_LITTLE) ? "Little" : "Big") ;

	/*========================================================*/
	psf_binheader_readf (psf, "44", &type, &size) ;
	psf_log_printf (psf, "Block\n Type : %X    Size : %d\n", type, size) ;

	if (type != MAT5_TYPE_ARRAY)
		return SFE_MAT5_NO_BLOCK ;

	psf_binheader_readf (psf, "44", &type, &size) ;
	psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;

	if (type != MAT5_TYPE_UINT32)
		return SFE_MAT5_NO_BLOCK ;

	psf_binheader_readf (psf, "44", &flags1, &flags2) ;
	psf_log_printf (psf, "    Flg1 : %X    Flg2 : %d\n", flags1, flags2) ;

	psf_binheader_readf (psf, "44", &type, &size) ;
	psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;

	if (type != MAT5_TYPE_INT32)
		return SFE_MAT5_NO_BLOCK ;

	psf_binheader_readf (psf, "44", &rows, &cols) ;
	psf_log_printf (psf, "    Rows : %X    Cols : %d\n", rows, cols) ;

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

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

	if (type == MAT5_TYPE_SCHAR)
	{	psf_binheader_readf (psf, "4", &size) ;
		psf_log_printf (psf, "    Type : %X    Size : %d\n", type, size) ;
		if (size > SIGNED_SIZEOF (name) - 1)
		{	psf_log_printf (psf, "Error : Bad name length.\n") ;
			return SFE_MAT5_NO_BLOCK ;
			} ;

		psf_binheader_readf (psf, "bj", name, size, (8 - (size % 8)) % 8) ;
		name [size] = 0 ;
		}
	else if ((type & 0xFFFF) == MAT5_TYPE_SCHAR)
	{	size = type >> 16 ;
		if (size > 4)
		{	psf_log_printf (psf, "Error : Bad name length.\n") ;
			return SFE_MAT5_NO_BLOCK ;
			} ;

		psf_log_printf (psf, "    Type : %X\n", type) ;
		psf_binheader_readf (psf, "4", &name) ;
		name [size] = 0 ;
		}
Beispiel #14
0
static int
voc_read_header	(SF_PRIVATE *psf)
{	VOC_DATA	*pvoc ;
	char	creative [20] ;
	unsigned char block_type, rate_byte ;
	short	version, checksum, encoding, dataoffset ;
	int		offset ;

	/* Set position to start of file to begin reading header. */
	offset = psf_binheader_readf (psf, "pb", 0, creative, SIGNED_SIZEOF (creative)) ;

	if (creative [sizeof (creative) - 1] != 0x1A)
		return SFE_VOC_NO_CREATIVE ;

	/* Terminate the string. */
	creative [sizeof (creative) - 1] = 0 ;

	if (strcmp ("Creative Voice File", creative))
		return SFE_VOC_NO_CREATIVE ;

	psf_log_printf (psf, "%s\n", creative) ;

	offset += psf_binheader_readf (psf, "e222", &dataoffset, &version, &checksum) ;

	psf->dataoffset = dataoffset ;

	psf_log_printf (psf, 	"dataoffset : %d\n"
							"version    : 0x%X\n"
							"checksum   : 0x%X\n", psf->dataoffset, version, checksum) ;

	if (version != 0x010A && version != 0x0114)
		return SFE_VOC_BAD_VERSION ;

	if (! (psf->codec_data = malloc (sizeof (VOC_DATA))))
		return SFE_MALLOC_FAILED ;

	pvoc = (VOC_DATA*) psf->codec_data ;

	memset (pvoc, 0, sizeof (VOC_DATA)) ;

	/* Set the default encoding now. */
	psf->sf.format = SF_FORMAT_VOC ; /* Major format */
	encoding = SF_FORMAT_PCM_U8 ; /* Minor format */
	psf->endian = SF_ENDIAN_LITTLE ;

	while (1)
	{	char header [256] ;
		unsigned size ;
		short count ;

		block_type = 0 ;
		offset += psf_binheader_readf (psf, "1", &block_type) ;

		switch (block_type)
		{	case VOC_ASCII :
					offset += psf_binheader_readf (psf, "e3", &size) ;

					psf_log_printf (psf, " ASCII : %d\n", size) ;

					if (size < sizeof (header) - 1)
					{	offset += psf_binheader_readf (psf, "b", header, size) ;
						header [size] = 0 ;
						psf_log_printf (psf, "  text : %s\n", header) ;
						continue ;
						}

					offset += psf_binheader_readf (psf, "j", size) ;
					continue ;

			case VOC_REPEAT :
					offset += psf_binheader_readf (psf, "e32", &size, &count) ;
					psf_log_printf (psf, " Repeat : %d\n", count) ;
					continue ;

			case VOC_SOUND_DATA :
			case VOC_EXTENDED :
			case VOC_EXTENDED_II :
					break ;

			default : psf_log_printf (psf, "*** Weird block marker (%d)\n", block_type) ;
			} ;

		break ;
		} ;

	if (block_type == VOC_SOUND_DATA)
	{	unsigned char compression ;
		int 	size ;

		offset += psf_binheader_readf (psf, "e311", &size, &rate_byte, &compression) ;

		psf->sf.samplerate = 1000000 / (256 - (rate_byte & 0xFF)) ;

		psf_log_printf (psf, " Sound Data : %d\n  sr   : %d => %dHz\n  comp : %d\n",
								size, rate_byte, psf->sf.samplerate, compression) ;

		if (offset + size - 1 > psf->filelength)
		{	psf_log_printf (psf, "Seems to be a truncated file.\n") ;
			psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
			return SFE_VOC_BAD_SECTIONS ;
			}
		else if (psf->filelength - offset - size > 4)
		{	psf_log_printf (psf, "Seems to be a multi-segment file (#1).\n") ;
			psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
			return SFE_VOC_BAD_SECTIONS ;
			} ;

		psf->dataoffset = offset ;
		psf->dataend	= psf->filelength - 1 ;

		psf->sf.channels = 1 ;
		psf->bytewidth = 1 ;

		psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;

		return 0 ;
		} ;

	if (block_type == VOC_EXTENDED)
	{	unsigned char pack, stereo, compression ;
		unsigned short rate_short ;
		int		size ;

		offset += psf_binheader_readf (psf, "e3211", &size, &rate_short, &pack, &stereo) ;

		psf_log_printf (psf, " Extended : %d\n", size) ;
		if (size == 4)
			psf_log_printf (psf, "  size   : 4\n") ;
		else
			psf_log_printf (psf, "  size   : %d (should be 4)\n", size) ;

		psf_log_printf (psf,	"  pack   : %d\n"
								"  stereo : %s\n", pack, (stereo ? "yes" : "no")) ;

		if (stereo)
		{	psf->sf.channels = 2 ;
			psf->sf.samplerate = 128000000 / (65536 - rate_short) ;
			}
		else
		{	psf->sf.channels = 1 ;
			psf->sf.samplerate = 256000000 / (65536 - rate_short) ;
			} ;

		psf_log_printf (psf, "  sr     : %d => %dHz\n", (rate_short & 0xFFFF), psf->sf.samplerate) ;

		offset += psf_binheader_readf (psf, "1", &block_type) ;

		if (block_type != VOC_SOUND_DATA)
		{	psf_log_printf (psf, "*** Expecting VOC_SOUND_DATA section.\n") ;
			return SFE_VOC_BAD_FORMAT ;
			} ;

		offset += psf_binheader_readf (psf, "e311", &size, &rate_byte, &compression) ;

		psf_log_printf (psf,	" Sound Data : %d\n"
								"  sr     : %d\n"
								"  comp   : %d\n", size, rate_byte, compression) ;


		if (offset + size - 1 > psf->filelength)
		{	psf_log_printf (psf, "Seems to be a truncated file.\n") ;
			psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
			return SFE_VOC_BAD_SECTIONS ;
			}
		else if (offset + size - 1 < psf->filelength)
		{	psf_log_printf (psf, "Seems to be a multi-segment file (#2).\n") ;
			psf_log_printf (psf, "offset: %d    size: %d    sum: %d    filelength: %D\n", offset, size, offset + size, psf->filelength) ;
			return SFE_VOC_BAD_SECTIONS ;
			} ;

		psf->dataoffset = offset ;
		psf->dataend = psf->filelength - 1 ;

		psf->bytewidth = 1 ;

		psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_PCM_U8 ;

		return 0 ;
		}

	if (block_type == VOC_EXTENDED_II)
	{	unsigned char bitwidth, channels ;
		int size, fourbytes ;

		offset += psf_binheader_readf (psf, "e341124", &size, &psf->sf.samplerate,
								&bitwidth, &channels, &encoding, &fourbytes) ;

		if (size * 2 == psf->filelength - 39)
		{	int temp_size = psf->filelength - 31 ;

			psf_log_printf (psf, " Extended II : %d (SoX bug: should be %d)\n", size, temp_size) ;
			size = temp_size ;
			}
		else
			psf_log_printf (psf, " Extended II : %d\n", size) ;

		psf_log_printf (psf,	"  sample rate : %d\n"
								"  bit width   : %d\n"
								"  channels    : %d\n", psf->sf.samplerate, bitwidth, channels) ;

		if (bitwidth == 16 && encoding == 0)
		{	encoding = 4 ;
			psf_log_printf (psf, "  encoding    : 0 (SoX bug: should be 4 for 16 bit signed PCM)\n") ;
			}
		else
			psf_log_printf (psf, "  encoding    : %d => %s\n", encoding, voc_encoding2str (encoding)) ;


		psf_log_printf (psf, "  fourbytes   : %X\n", fourbytes) ;

		psf->sf.channels = channels ;

		psf->dataoffset = offset ;
		psf->dataend	= psf->filelength - 1 ;

		if (size + 31 == psf->filelength + 1)
		{	/* Hack for reading files produced using
			** sf_command (SFC_UPDATE_HEADER_NOW).
			*/
			psf_log_printf (psf, "Missing zero byte at end of file.\n") ;
			size = psf->filelength - 30 ;
			psf->dataend = 0 ;
			}
		else if (size + 31 > psf->filelength)
		{	psf_log_printf (psf, "Seems to be a truncated file.\n") ;
			size = psf->filelength - 31 ;
			}
		else if (size + 31 < psf->filelength)
			psf_log_printf (psf, "Seems to be a multi-segment file (#3).\n") ;

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

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

			case 6 :
					psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_ALAW ;
					psf->bytewidth = 1 ;
					break ;

			case 7 :
					psf->sf.format = SF_FORMAT_VOC | SF_FORMAT_ULAW ;
					psf->bytewidth = 1 ;
					break ;

			default : /* Unknown */
					return SFE_UNKNOWN_FORMAT ;
					break ;
			} ;

		} ;

	return 0 ;
} /* voc_read_header */
Beispiel #15
0
int 	
rx2_open	(SF_PRIVATE *psf)
{	int error, marker, length, glob_offset, slce_count ;

	int sdat_length = 0, slce_total = 0 ;

	/* So far only doing read. */

	psf_binheader_readf (psf, "Epm4", 0, &marker, &length) ;
	
	if (marker != CAT_MARKER)
	{	psf_log_printf (psf, "length : %d\n", length) ;
		return -1000 ;
		} ;

	if (length != psf->filelength - 8)
		psf_log_printf (psf, "%M : %d (should be %d)\n", marker, length, psf->filelength - 8) ;
	else
		psf_log_printf (psf, "%M : %d\n", marker, length) ;

	/* 'REX2' marker */
	psf_binheader_readf (psf, "m", &marker) ;
	psf_log_printf (psf, "%M", marker) ;

	/* 'HEAD' marker */
	psf_binheader_readf (psf, "m", &marker) ;
	psf_log_printf (psf, "%M\n", marker) ;
	
	/* Grab 'GLOB' offset. */
	psf_binheader_readf (psf, "E4", &glob_offset) ;
	glob_offset += 0x14 ;  /* Add the current file offset. */

	/* Jump to offset 0x30 */
	psf_binheader_readf (psf, "p", 0x30) ;
	
	/* Get name length */
	length = 0 ;
	psf_binheader_readf (psf, "1", &length) ;
	if (length >= SIGNED_SIZEOF (psf->buffer))
	{	psf_log_printf (psf, "  Text : %d *** Error : Too sf_count_t!\n") ;
		return -1001 ;
		}
	
	memset (psf->buffer, 0, SIGNED_SIZEOF (psf->buffer)) ;
	psf_binheader_readf (psf, "b", psf->buffer, length) ;
	psf_log_printf (psf, " Text : \"%s\"\n", psf->buffer) ;
	
	/* Jump to GLOB offset position. */
	if (glob_offset & 1)
		glob_offset ++ ;
		
	psf_binheader_readf (psf, "p", glob_offset) ;

	slce_count = 0 ;
	/* GLOB */
	while (1)
	{	psf_binheader_readf (psf, "m", &marker) ;

		if (marker != SLCE_MARKER && slce_count > 0)
		{	psf_log_printf (psf, "   SLCE count : %d\n", slce_count) ;
			slce_count = 0 ;
			}
		switch (marker)
		{	case GLOB_MARKER:
					psf_binheader_readf (psf, "E4", &length) ;
					psf_log_printf (psf, " %M : %d\n", marker, length) ;
					psf_binheader_readf (psf, "j", length) ;
					break ;

			case RECY_MARKER:
					psf_binheader_readf (psf, "E4", &length) ;
					psf_log_printf (psf, " %M : %d\n", marker, length) ;
					psf_binheader_readf (psf, "j", (length+1) & 0xFFFFFFFE) ; /* ?????? */
					break ;

			case CAT_MARKER:
					psf_binheader_readf (psf, "E4", &length) ;
					psf_log_printf (psf, " %M : %d\n", marker, length) ;
					/*-psf_binheader_readf (psf, "j", length) ;-*/
					break ;
					
			case DEVL_MARKER:
					psf_binheader_readf (psf, "mE4", &marker, &length) ;
					psf_log_printf (psf, "  DEVL%M : %d\n", marker, length) ;
					if (length & 1)
						length ++ ;
					psf_binheader_readf (psf, "j", length) ;
					break ;
					
			case EQ_MARKER:
			case COMP_MARKER:
					psf_binheader_readf (psf, "E4", &length) ;
					psf_log_printf (psf, "   %M : %d\n", marker, length) ;
					/* This is weird!!!! why make this (length - 1) */
					if (length & 1)
						length ++ ;
					psf_binheader_readf (psf, "j", length) ;
					break ;

			case SLCL_MARKER:
					psf_log_printf (psf, "  %M\n", marker) ;
					slce_count = 0 ;
					break ;
					
			case SLCE_MARKER:
					/*-psf_log_printf (psf, "   %M\n", marker) ;-*/
					
					psf_binheader_readf (psf, "E4", &length) ;
					/*-psf_log_printf (psf, "    ???????? : 0x%X\n", length) ;-*/
					
					psf_binheader_readf (psf, "E4", &length) ;
					/*-psf_log_printf (psf, "    Start  ? : %d\n", length) ;-*/

					psf_binheader_readf (psf, "E4", &length) ;
					/*-psf_log_printf (psf, "    Length ? : %d\n", length) ;-*/

				slce_total += length ;
				
					psf_binheader_readf (psf, "E4", &length) ;
					/*-psf_log_printf (psf, "    ???????? : 0x%X\n", length) ;-*/
					
					slce_count ++ ;
					break ;
					
			case SINF_MARKER:
					psf_binheader_readf (psf, "E4", &length) ;
					psf_log_printf (psf, " %M : %d\n", marker, length) ;

					psf_binheader_readf (psf, "E2", &length) ;
					psf_log_printf (psf, "  REX Version : %X ?\n", length) ;

					psf_binheader_readf (psf, "E44", &psf->sf.samplerate, &psf->sf.frames) ;
					psf_log_printf (psf, "  Sample Rate : %d\n", psf->sf.samplerate) ;
					psf_log_printf (psf, "  Frames      : %d\n", psf->sf.frames) ;

					psf_binheader_readf (psf, "E4", &length) ;
					psf_log_printf (psf, "  ??????????? : %d\n", length) ;

					psf_binheader_readf (psf, "E4", &length) ;
					psf_log_printf (psf, "  ??????????? : %d\n", length) ;

					break ;

			case SDAT_MARKER:
					psf_binheader_readf (psf, "E4", &length) ;
					
				sdat_length = length ;

					/* Get the current offset. */
					psf->dataoffset = psf_binheader_readf (psf, NULL) ;

					if (psf->dataoffset + length != psf->filelength)
						psf_log_printf (psf, " %M : %d (should be %d)\n", marker, length, psf->dataoffset + psf->filelength) ;
					else
						psf_log_printf (psf, " %M : %d\n", marker, length) ;
					break ;

			default :
					psf_log_printf (psf, "Unknown marker : 0x%X %M", marker, marker) ;
					return -1003 ;
					break ;
			} ;
			
		/* SDAT always last marker in file. */
		if (marker == SDAT_MARKER)
			break ;
		} ;

	puts (psf->logbuffer) ;
	puts ("-----------------------------------") ;

	printf ("SDAT length  : %d\n", sdat_length) ;
	printf ("SLCE samples : %d\n", slce_total) ;

	/* Two bytes per sample. */
	printf ("Comp Ratio   : %f:1\n", (2.0 * slce_total) / sdat_length) ;
	
	puts (" ") ;
	
	psf->logbuffer [0] = 0 ;
	
	/* OK, have the header althought not too sure what it all means. */
	
	psf->endian = SF_ENDIAN_BIG ;

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

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

	psf->sf.format = (SF_FORMAT_REX2 | SF_FORMAT_DWVW_12) ;

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

	if ((error = dwvw_init (psf, 16)))
		return error ;

	psf->close = rx2_close ;

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

	/* All done. */

	return 0 ;
} /* rx2_open */
Beispiel #16
0
int
psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
{	char	new_str [128] ;
	size_t	len_remaining, str_len ;
	int		k, str_flags ;

	if (str == NULL)
		return SFE_STR_BAD_STRING ;

	str_len = strlen (str) ;

	/* A few extra checks for write mode. */
	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
	{	if ((psf->str_flags & SF_STR_ALLOW_START) == 0)
			return SFE_STR_NO_SUPPORT ;
		if (psf->have_written && (psf->str_flags & SF_STR_ALLOW_END) == 0)
			return SFE_STR_NO_SUPPORT ;
		/* Only allow zero length strings for software. */
		if (str_type != SF_STR_SOFTWARE && str_len == 0)
			return SFE_STR_BAD_STRING ;
		} ;

	/* Find the next free slot in table. */
	for (k = 0 ; k < SF_MAX_STRINGS ; k++)
	{	/* If we find a matching entry clear it. */
		if (psf->strings [k].type == str_type)
			psf->strings [k].type = -1 ;

		if (psf->strings [k].type == 0)
			break ;
		} ;

	/* Determine flags */
	str_flags = SF_STR_LOCATE_START ;
	if (psf->file.mode == SFM_RDWR || psf->have_written)
	{	if ((psf->str_flags & SF_STR_ALLOW_END) == 0)
			return SFE_STR_NO_ADD_END ;
		str_flags = SF_STR_LOCATE_END ;
		} ;

	/* More sanity checking. */
	if (k >= SF_MAX_STRINGS)
		return SFE_STR_MAX_COUNT ;

	if (k == 0 && psf->str_end != NULL)
	{	psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->str_end != NULL\n") ;
		return SFE_STR_WEIRD ;
		} ;

	if (k != 0 && psf->str_end == NULL)
	{	psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->str_end == NULL\n") ;
		return SFE_STR_WEIRD ;
		} ;

	/* Special case for the first string. */
	if (k == 0)
		psf->str_end = psf->str_storage ;

	switch (str_type)
	{	case SF_STR_SOFTWARE :
				/* In write mode, want to append libsndfile-version to string. */
				if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
				{	if (strstr (str, PACKAGE) == NULL)
					{	/*
						** If the supplied string does not already contain a
						** libsndfile-X.Y.Z component, then add it.
						*/
						if (strlen (str) == 0)
							snprintf (new_str, sizeof (new_str), "%s-%s", PACKAGE, VERSION) ;
						else
							snprintf (new_str, sizeof (new_str), "%s (%s-%s)", str, PACKAGE, VERSION) ;
						}
					else
						snprintf (new_str, sizeof (new_str), "%s", str) ;

					str = new_str ;
					} ;
				break ;

		case SF_STR_TITLE :
		case SF_STR_COPYRIGHT :
		case SF_STR_ARTIST :
		case SF_STR_COMMENT :
		case SF_STR_DATE :
		case SF_STR_ALBUM :
		case SF_STR_LICENSE :
		case SF_STR_TRACKNUMBER :
		case SF_STR_GENRE :
				break ;

		default :
			psf_log_printf (psf, "%s : SFE_STR_BAD_TYPE\n", __func__) ;
			return SFE_STR_BAD_TYPE ;
		} ;

	str_len = strlen (str) ;

	len_remaining = SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage) ;

	if (len_remaining < str_len + 2)
		return SFE_STR_MAX_DATA ;

	psf->strings [k].type = str_type ;
	psf->strings [k].str = psf->str_end ;
	psf->strings [k].flags = str_flags ;

	memcpy (psf->str_end, str, str_len + 1) ;
	/* Plus one to catch string terminator. */
	psf->str_end += str_len + 1 ;

	psf->str_flags |= str_flags ;

#if STRINGS_DEBUG
	psf_log_printf (psf, "str_storage          : %X\n", (int) psf->str_storage) ;
	psf_log_printf (psf, "str_end              : %X\n", (int) psf->str_end) ;
	psf_log_printf (psf, "sizeof (str_storage) : %d\n", SIGNED_SIZEOF (psf->str_storage)) ;
	psf_log_printf (psf, "used                 : %d\n", (int ) (psf->str_end - psf->str_storage)) ;
	psf_log_printf (psf, "remaining            : %d\n", SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage)) ;

	hexdump (psf->str_storage, 300) ;
#endif

	return 0 ;
} /* psf_store_string */
Beispiel #17
0
static int
caf_read_header (SF_PRIVATE *psf)
{   DESC_CHUNK desc ;
    sf_count_t chunk_size ;
    double srate ;
    short version, flags ;
    int marker, k, have_data = 0, error ;

    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, psf->u.ucbuf, 8) ;
    srate = double64_be_read (psf->u.ucbuf) ;
    snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), "%5.3f", srate) ;
    psf_log_printf (psf, "%M : %D\n  Sample rate  : %s\n", marker, chunk_size, psf->u.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.pkt_frames,
                         &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.pkt_frames, 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 (have_data == 0 && psf_ftell (psf) < psf->filelength - SIGNED_SIZEOF (marker))
    {   psf_binheader_readf (psf, "mE8", &marker, &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", (int) 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 (psf->u.cbuf, sizeof (psf->u.cbuf), "    %2d   %-12" PRId64 "   %g\n", k, position, value) ;
                psf_log_printf (psf, psf->u.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", (int) 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", (int) chunk_size) ;
            break ;

        case data_MARKER :
            psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
            psf_binheader_readf (psf, "E4", &k) ;
            psf_log_printf (psf, "  edit : %u\n", k) ;
            have_data = 1 ;
            break ;

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

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

    psf_log_printf (psf, "End\n") ;

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

    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 */
Beispiel #18
0
int
psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
{	static char lsf_name [] = PACKAGE "-" VERSION ;
	static char bracket_name [] = " (" PACKAGE "-" VERSION ")" ;
	int		k, str_len, len_remaining, str_flags ;

	if (str == NULL)
		return SFE_STR_BAD_STRING ;

	str_len = strlen (str) ;

	/* A few extra checks for write mode. */
	if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
	{	if ((psf->str_flags & SF_STR_ALLOW_START) == 0)
			return SFE_STR_NO_SUPPORT ;
		if ((psf->str_flags & SF_STR_ALLOW_END) == 0)
			return SFE_STR_NO_SUPPORT ;
		/* Only allow zero length strings for software. */
		if (str_type != SF_STR_SOFTWARE && str_len == 0)
			return SFE_STR_BAD_STRING ;
		} ;

	/* Determine flags */
	str_flags = SF_STR_LOCATE_START ;
	if (psf->have_written)
	{	if ((psf->str_flags & SF_STR_ALLOW_END) == 0)
			return SFE_STR_NO_ADD_END ;
		str_flags = SF_STR_LOCATE_END ;
		} ;

	/* Find next free slot in table. */
	for (k = 0 ; k < SF_MAX_STRINGS ; k++)
		if (psf->strings [k].type == 0)
			break ;

	/* More sanity checking. */
	if (k >= SF_MAX_STRINGS)
		return SFE_STR_MAX_COUNT ;

	if (k == 0 && psf->str_end != NULL)
	{	psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->str_end != NULL\n") ;
		return SFE_STR_WEIRD ;
		} ;

	if (k != 0 && psf->str_end == NULL)
	{	psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->str_end == NULL\n") ;
		return SFE_STR_WEIRD ;
		} ;

	/* Special case for the first string. */
	if (k == 0)
		psf->str_end = psf->str_storage ;


#if STRINGS_DEBUG
	psf_log_printf (psf, "str_storage          : %X\n", (int) psf->str_storage) ;
	psf_log_printf (psf, "str_end              : %X\n", (int) psf->str_end) ;
	psf_log_printf (psf, "sizeof (str_storage) : %d\n", SIGNED_SIZEOF (psf->str_storage)) ;
#endif

	len_remaining = SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage) ;

	if (len_remaining < str_len + 2)
		return SFE_STR_MAX_DATA ;

	switch (str_type)
	{	case SF_STR_SOFTWARE :
				/* In write mode, want to append libsndfile-version to string. */
				if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
				{	psf->strings [k].type = str_type ;
					psf->strings [k].str = psf->str_end ;
					psf->strings [k].flags = str_flags ;

					memcpy (psf->str_end, str, str_len + 1) ;
					psf->str_end += str_len ;

					/*
					** If the supplied string does not already contain a
					** libsndfile-X.Y.Z component, then add it.
					*/
					if (strstr (str, PACKAGE) == NULL && len_remaining > (int) (strlen (bracket_name) + str_len + 2))
					{	if (strlen (str) == 0)
							strncat (psf->str_end, lsf_name, len_remaining) ;
						else
							strncat (psf->str_end, bracket_name, len_remaining) ;
						psf->str_end += strlen (psf->str_end) ;
						} ;

					/* Plus one to catch string terminator. */
					psf->str_end += 1 ;
					break ;
					} ;

				/* Fall though if not write mode. */

		case SF_STR_TITLE :
		case SF_STR_COPYRIGHT :
		case SF_STR_ARTIST :
		case SF_STR_COMMENT :
		case SF_STR_DATE :
				psf->strings [k].type = str_type ;
				psf->strings [k].str = psf->str_end ;
				psf->strings [k].flags = str_flags ;

				/* Plus one to catch string terminator. */
				memcpy (psf->str_end, str, str_len + 1) ;
				psf->str_end += str_len + 1 ;
				break ;

		default :
			return SFE_STR_BAD_TYPE ;
		} ;

	psf->str_flags |= (psf->have_written) ? SF_STR_LOCATE_END : SF_STR_LOCATE_START ;

#if STRINGS_DEBUG
	hexdump (psf->str_storage, 300) ;
#endif

	return 0 ;
} /* psf_store_string */
Beispiel #19
0
static void
show_fstat_error (void)
{	static const char *filename = "fstat.dat" ;
	static char data [256] ;

	STATBUF 	statbuf ;
	int fd, mode, flags ;

	if (sizeof (statbuf.st_size) != sizeof (INT64))
	{	printf ("\n\nLine %d: Error, sizeof (statbuf.st_size) != 8.\n\n", __LINE__) ;
		return ;
		} ;

	puts ("\n64 bit fstat() test.\n--------------------") ;

	printf ("0) Create a file, write %d bytes and close it.\n", SIGNED_SIZEOF (data)) ;
	mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
	flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
	if ((fd = open (filename, mode, flags)) < 0)
	{	printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
		return ;
		} ;
	assert (write (fd, data, sizeof (data)) > 0) ;
	close (fd) ;

	printf ("1) Re-open file in read/write mode and write another %d bytes at the end.\n", SIGNED_SIZEOF (data)) ;
	mode = O_RDWR | O_BINARY ;
	flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
	if ((fd = open (filename, mode, flags)) < 0)
	{	printf ("\n\nLine %d: open() failed : %s\n\n", __LINE__, strerror (errno)) ;
		return ;
		} ;
	LSEEK (fd, 0, SEEK_END) ;
	assert (write (fd, data, sizeof (data)) > 0) ;

	printf ("2) Now use system (\"%s %s\") to show the file length.\n\n", dir_cmd, filename) ;

	/* Would use snprintf, but thats not really available on windows. */
	memset (data, 0, sizeof (data)) ;
	strncpy (data, dir_cmd, sizeof (data) - 1) ;
	strncat (data, " ", sizeof (data) - 1 - strlen (data)) ;
	strncat (data, filename, sizeof (data) - 1 - strlen (data)) ;

	assert (system (data) >= 0) ;
	puts ("") ;

	printf ("3) Now use fstat() to get the file length.\n") ;
	if (FSTAT (fd, &statbuf) != 0)
	{	printf ("\n\nLine %d: fstat() returned error : %s\n", __LINE__, strerror (errno)) ;
		return ;
		} ;

	printf ("4) According to fstat(), the file length is %ld, ", (long) statbuf.st_size) ;

	close (fd) ;

	if (statbuf.st_size != 2 * sizeof (data))
		printf ("but thats just plain ***WRONG***.\n\n") ;
	else
	{	printf ("which is correct.\n\n") ;
		unlink (filename) ;
		} ;

} /* show_fstat_error */