Ejemplo n.º 1
0
static int
mat4_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t	current ;
	int			encoding ;
	double		samplerate ;

	current = psf_ftell (psf) ;

	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.º 2
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.º 3
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.º 4
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.º 5
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.º 6
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 */
Ejemplo n.º 7
0
static int
au_write_header (SF_PRIVATE *psf, int calc_length)
{	sf_count_t	current ;
	int			encoding, datalength ;

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

	current = psf_ftell (psf) ;

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

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

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

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

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

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

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

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

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

	psf->dataoffset = psf->headindex ;

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

	return psf->error ;
} /* au_write_header */
Ejemplo n.º 8
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 */
Ejemplo n.º 9
0
static int
caf_write_header (SF_PRIVATE *psf, int calc_length)
{	BUF_UNION	ubuf ;
	CAF_PRIVATE	*pcaf ;
	DESC_CHUNK desc ;
	sf_count_t current, free_len ;
	uint32_t uk ;
	int subformat, append_free_block = SF_TRUE ;

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

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

	current = psf_ftell (psf) ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		default :
			return SFE_UNIMPLEMENTED ;
		} ;

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

	caf_write_strings (psf, SF_STR_LOCATE_START) ;

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

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

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

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

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

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

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

	return psf->error ;
} /* caf_write_header */
Ejemplo n.º 10
0
static int
nist_write_header (SF_PRIVATE *psf, int calc_length)
{	const char	*end_str ;
	long		samples ;
	sf_count_t	current ;

	current = psf_ftell (psf) ;

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

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

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

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

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

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

	psf_fseek (psf, 0, SEEK_SET) ;

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

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

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

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

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

		default : return SFE_UNIMPLEMENTED ;
		} ;

	psf->dataoffset = NIST_HEADER_LENGTH ;

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

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

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

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

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

	return psf->error ;
} /* nist_write_header */