Пример #1
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) ;

#if 0
	if (psf->strings.flags & SF_STR_LOCATE_START)
		caf_write_strings (psf, SF_STR_LOCATE_START) ;
#endif

	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 */
Пример #2
0
int
caf_open (SF_PRIVATE *psf)
{	CAF_PRIVATE * pcaf ;
	int	subformat, format, error = 0 ;

	if ((psf->container_data = calloc (1, sizeof (CAF_PRIVATE))) == NULL)
		return SFE_MALLOC_FAILED ;

	pcaf = psf->container_data ;

	if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
	{	if ((error = caf_read_header (psf)))
			return error ;

		psf->next_chunk_iterator = caf_next_chunk_iterator ;
		psf->get_chunk_size = caf_get_chunk_size ;
		psf->get_chunk_data = caf_get_chunk_data ;
		} ;

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

	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
	{	if (psf->is_pipe)
			return SFE_NO_PIPE_WRITE ;

		format = SF_CONTAINER (psf->sf.format) ;
		if (format != SF_FORMAT_CAF)
			return	SFE_BAD_OPEN_FORMAT ;

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

		if (psf->file.mode != SFM_RDWR || psf->filelength < 44)
		{	psf->filelength = 0 ;
			psf->datalength = 0 ;
			psf->dataoffset = 0 ;
			psf->sf.frames = 0 ;
			} ;

		psf->strings.flags = SF_STR_ALLOW_START | SF_STR_ALLOW_END ;

		/*
		**	By default, add the peak chunk to floating point files. Default behaviour
		**	can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
		*/
		if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
		{	if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
				return SFE_MALLOC_FAILED ;
			psf->peak_info->peak_loc = SF_PEAK_START ;
			} ;

		if ((error = caf_write_header (psf, SF_FALSE)) != 0)
			return error ;

		psf->write_header	= caf_write_header ;
		psf->set_chunk		= caf_set_chunk ;
		} ;

	psf->container_close = caf_close ;
	psf->command = caf_command ;

	switch (subformat)
	{	case SF_FORMAT_PCM_S8 :
		case SF_FORMAT_PCM_16 :
		case SF_FORMAT_PCM_24 :
		case SF_FORMAT_PCM_32 :
					error = pcm_init (psf) ;
					break ;

		case SF_FORMAT_ULAW :
					error = ulaw_init (psf) ;
					break ;

		case SF_FORMAT_ALAW :
					error = alaw_init (psf) ;
					break ;

		/* Lite remove start */
		case SF_FORMAT_FLOAT :
					error = float32_init (psf) ;
					break ;

		case SF_FORMAT_DOUBLE :
					error = double64_init (psf) ;
					break ;

		case SF_FORMAT_ALAC_16 :
		case SF_FORMAT_ALAC_20 :
		case SF_FORMAT_ALAC_24 :
		case SF_FORMAT_ALAC_32 :
					if (psf->file.mode == SFM_READ)
						/* Only pass the ALAC_DECODER_INFO in read mode. */
						error = alac_init (psf, &pcaf->alac) ;
					else
						error = alac_init (psf, NULL) ;
					break ;

		/* Lite remove end */

		default :
			return SFE_UNSUPPORTED_ENCODING ;
		} ;

	return error ;
} /* caf_open */
Пример #3
0
	static int
nist_read_header (SF_PRIVATE *psf)
{	char	psf_header [NIST_HEADER_LENGTH + 2] ;
	int		bitwidth = 0, count, encoding ;
	unsigned bytes = 0 ;
	char 	str [64], *cptr ;
	long	samples ;

	/* Go to start of file and read in the whole header. */
	psf_binheader_readf (psf, "pb", 0, psf_header, NIST_HEADER_LENGTH) ;

	/* Header is a string, so make sure it is null terminated. */
	psf_header [NIST_HEADER_LENGTH] = 0 ;

	/* Now trim the header after the end marker. */
	if ((cptr = strstr (psf_header, "end_head")))
	{	cptr += strlen ("end_head") + 1 ;
		cptr [0] = 0 ;
		} ;

	if (strstr (psf_header, bad_header) == psf_header)
		return SFE_NIST_CRLF_CONVERISON ;

	/* Make sure its a NIST file. */
	if (strstr (psf_header, "NIST_1A\n") != psf_header)
	{	psf_log_printf (psf, "Not a NIST file.\n") ;
		return SFE_NIST_BAD_HEADER ;
		} ;

	if (sscanf (psf_header, "NIST_1A\n%d\n", &count) == 1)
		psf->dataoffset = count ;
	else
	{	psf_log_printf (psf, "*** Suspicious header length.\n") ;
		psf->dataoffset = NIST_HEADER_LENGTH ;
		} ;

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

		if (strcmp (str, "pcm") == 0)
		{	/* Correct this later when we find out the bitwidth. */
			encoding = SF_FORMAT_PCM_U8 ;
			}
		else if (strcmp (str, "alaw") == 0)
			encoding = SF_FORMAT_ALAW ;
		else if ((strcmp (str, "ulaw") == 0) || (strcmp (str, "mu-law") == 0))
			encoding = SF_FORMAT_ULAW ;
		else
		{	psf_log_printf (psf, "*** Unknown encoding : %s\n", str) ;
			encoding = 0 ;
			} ;
		} ;

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

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

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

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

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

	/* This is where we figure out endian-ness. */
	if ((cptr = strstr (psf_header, "sample_byte_format -s"))
		&& sscanf (cptr, "sample_byte_format -s%u %8s", &bytes, str) == 2)
	{
		if (bytes != strlen (str))
			psf_log_printf (psf, "Weird sample_byte_format : strlen '%s' != %d\n", str, bytes) ;

		if (bytes > 1)
		{	if (psf->bytewidth == 0)
				psf->bytewidth = bytes ;
			else if (psf->bytewidth - bytes != 0)
			{	psf_log_printf (psf, "psf->bytewidth (%d) != bytes (%d)\n", psf->bytewidth, bytes) ;
				return SFE_NIST_BAD_ENCODING ;
				} ;

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

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

	if ((cptr = strstr (psf_header, "sample_sig_bits -i ")))
		sscanf (cptr, "sample_sig_bits -i %d", &bitwidth) ;

	if (strstr (psf_header, "channels_interleaved -s5 FALSE"))
	{	psf_log_printf (psf, "Non-interleaved data unsupported.\n", str) ;
		return SFE_NIST_BAD_ENCODING ;
		} ;

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

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

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

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

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

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

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

	/* Sanitize psf->sf.format. */
	switch (SF_CODEC (psf->sf.format))
	{	case SF_FORMAT_ULAW :
		case SF_FORMAT_ALAW :
		case SF_FORMAT_PCM_U8 :
			/* Blank out endian bits. */
			psf->sf.format = SF_FORMAT_NIST | SF_CODEC (psf->sf.format) ;
			break ;

		default :
			break ;
		} ;

	return 0 ;
} /* nist_read_header */
Пример #4
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 */
Пример #5
0
static int
gen_coding_history (char * added_history, int added_history_max, const SF_INFO * psfinfo)
{	char chnstr [16] ;
	int count, width ;

	/*
	**	From : http://www.sr.se/utveckling/tu/bwf/docs/codhist2.htm
	**
	**	Parameter            Variable string <allowed option>                 Unit
	**	==========================================================================================
	**	Coding Algorithm     A=<ANALOGUE, PCM, MPEG1L1, MPEG1L2, MPEG1L3,
	**	                     MPEG2L1, MPEG2L2, MPEG2L3>
	**	Sampling frequency   F=<11000,22050,24000,32000,44100,48000>          [Hz]
	**	Bit-rate             B=<any bit-rate allowed in MPEG 2 (ISO/IEC       [kbit/s per channel]
	**	                     13818-3)>
	**	Word Length          W=<8, 12, 14, 16, 18, 20, 22, 24>                [bits]
	**	Mode                 M=<mono, stereo, dual-mono, joint-stereo>
	**	Text, free string    T=<a free ASCII-text string for in house use.
	**	                     This string should contain no commas (ASCII
	**	                     2Chex). Examples of the contents: ID-No; codec
	**	                     type; A/D type>
	*/

	switch (psfinfo->channels)
	{	case 0 :
			return SF_FALSE ;

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

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

		default :
			snprintf (chnstr, sizeof (chnstr), "%uchn", psfinfo->channels) ;
			break ;
		} ;

	switch (SF_CODEC (psfinfo->format))
	{	case SF_FORMAT_PCM_U8 :
		case SF_FORMAT_PCM_S8 :
			width = 8 ;
			break ;
		case SF_FORMAT_PCM_16 :
			width = 16 ;
			break ;
		case SF_FORMAT_PCM_24 :
			width = 24 ;
			break ;
		case SF_FORMAT_PCM_32 :
			width = 32 ;
			break ;
		case SF_FORMAT_FLOAT :
			width = 24 ; /* Bits in the mantissa + 1 */
			break ;
		case SF_FORMAT_DOUBLE :
			width = 53 ; /* Bits in the mantissa + 1 */
			break ;
		case SF_FORMAT_ULAW :
		case SF_FORMAT_ALAW :
			width = 12 ;
			break ;
		default :
			width = 42 ;
			break ;
		} ;

	count = snprintf (added_history, added_history_max,
							"A=PCM,F=%u,W=%hu,M=%s,T=%s-%s\r\n",
							psfinfo->samplerate, (unsigned short)width, chnstr, PACKAGE, VERSION) ;

	if (count >= added_history_max)
		return 0 ;

	return count ;
} /* gen_coding_history */
Пример #6
0
int
sd2_open (SF_PRIVATE *psf)
{	int subformat, error = 0, valid ;

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

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

		error = sd2_parse_rsrc_fork (psf) ;

		if (error)
			goto error_cleanup ;
		} ;

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

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

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

		error = sd2_write_rsrc_fork (psf, SF_FALSE) ;

		if (error)
			goto error_cleanup ;

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

	psf->container_close = sd2_close ;

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

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

		default :
				error = SFE_UNIMPLEMENTED ;
				break ;
		} ;

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

error_cleanup:

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

	return error ;
} /* sd2_open */
Пример #7
0
int
au_open	(SF_PRIVATE *psf)
{	int		subformat ;
	int		error = 0 ;

	if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
	{	if ((error = au_read_header (psf)))
			return error ;
	} ;

	if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_AU)
		return	SFE_BAD_OPEN_FORMAT ;

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

	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
	{	psf->endian = SF_ENDIAN (psf->sf.format) ;
		if (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU)
			psf->endian = SF_ENDIAN_LITTLE ;
		else if (psf->endian != SF_ENDIAN_LITTLE)
			psf->endian = SF_ENDIAN_BIG ;

		if (au_write_header (psf, SF_FALSE))
			return psf->error ;

		psf->write_header = au_write_header ;
	} ;

	psf->container_close = au_close ;

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

	switch (subformat)
	{	case SF_FORMAT_ULAW :	/* 8-bit Ulaw encoding. */
			ulaw_init (psf) ;
			break ;

		case SF_FORMAT_PCM_S8 :	/* 8-bit linear PCM. */
			error = pcm_init (psf) ;
			break ;

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

		case SF_FORMAT_ALAW :	/* 8-bit Alaw encoding. */
			alaw_init (psf) ;
			break ;

		/* Lite remove start */
		case SF_FORMAT_FLOAT :	/* 32-bit floats. */
			error = float32_init (psf) ;
			break ;

		case SF_FORMAT_DOUBLE :	/* 64-bit double precision floats. */
			error = double64_init (psf) ;
			break ;

		case SF_FORMAT_G721_32 :
			error = g72x_init (psf) ;
			psf->sf.seekable = SF_FALSE ;
			break ;

		case SF_FORMAT_G723_24 :
			error = g72x_init (psf) ;
			psf->sf.seekable = SF_FALSE ;
			break ;

		case SF_FORMAT_G723_40 :
			error = g72x_init (psf) ;
			psf->sf.seekable = SF_FALSE ;
			break ;
		/* Lite remove end */

		default :
			break ;
	} ;

	return error ;
} /* au_open */
Пример #8
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 */
Пример #9
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 */
Пример #10
0
static int
mat5_write_header (SF_PRIVATE *psf, int calc_length)
{	static const char	*filename = "MATLAB 5.0 MAT-file, written by " PACKAGE "-" VERSION ", " ;
	static const char	*sr_name = "samplerate\0\0\0\0\0\0\0\0\0\0\0" ;
	static const char	*wd_name = "wavedata\0" ;
	char		buffer [256] ;
	sf_count_t	current, datasize ;
	int			encoding ;

	current = psf_ftell (psf) ;

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

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

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

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

		case SF_FORMAT_PCM_16 :
				encoding = MAT5_TYPE_INT16 ;
				break ;

		case SF_FORMAT_PCM_32 :
				encoding = MAT5_TYPE_INT32 ;
				break ;

		case SF_FORMAT_FLOAT :
				encoding = MAT5_TYPE_FLOAT ;
				break ;

		case SF_FORMAT_DOUBLE :
				encoding = MAT5_TYPE_DOUBLE ;
				break ;

		default :
				return SFE_BAD_OPEN_FORMAT ;
		} ;

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

	psf_get_date_str (buffer, sizeof (buffer)) ;
	psf_binheader_writef (psf, "bb", filename, strlen (filename), buffer, strlen (buffer) + 1) ;

	memset (buffer, ' ', 124 - psf->headindex) ;
	psf_binheader_writef (psf, "b", buffer, make_size_t (124 - psf->headindex)) ;

	psf->rwf_endian = psf->endian ;

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

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

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

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

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

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

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

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

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

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

	psf->dataoffset = psf->headindex ;

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

	return psf->error ;
} /* mat5_write_header */
Пример #11
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) ((fmt_size & 0x7) ? 8 - (fmt_size & 0x7) : 0) ;
			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) ((fmt_size & 0x7) ? 8 - (fmt_size & 0x7) : 0) ;
			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) ((fmt_size & 0x7) ? 8 - (fmt_size & 0x7) : 0) ;
			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) ((fmt_size & 0x7) ? 8 - (fmt_size & 0x7) : 0) ;
			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		= wavlike_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) ((fmt_size & 0x7) ? 8 - (fmt_size & 0x7) : 0) ;
			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		= wavlike_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 + WAVLIKE_MSADPCM_ADAPT_COEFF_COUNT * (2 + 2) ;
			fmt_size	= 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + extrabytes ;
			fmt_pad = (size_t) ((fmt_size & 0x7) ? 8 - (fmt_size & 0x7) : 0) ;
			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) ;

			wavlike_msadpcm_write_adapt_coeffs (psf) ;
		} ;

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

		case SF_FORMAT_GSM610 :
		{	int bytespersec ;

			bytespersec = (psf->sf.samplerate * WAVLIKE_GSM610_BLOCKSIZE) / WAVLIKE_GSM610_SAMPLES ;

			/* fmt chunk. */
			fmt_size = 24 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
			fmt_pad = (size_t) ((fmt_size & 0x7) ? 8 - (fmt_size & 0x7) : 0) ;
			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", WAVLIKE_GSM610_BLOCKSIZE, 0, 2, WAVLIKE_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 */
Пример #12
0
int
w64_open	(SF_PRIVATE *psf)
{	WAVLIKE_PRIVATE * wpriv ;
	int	subformat, error, blockalign = 0, framesperblock = 0 ;

	if ((wpriv = calloc (1, sizeof (WAVLIKE_PRIVATE))) == NULL)
		return SFE_MALLOC_FAILED ;
	psf->container_data = wpriv ;

	if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR &&psf->filelength > 0))
	{	if ((error = w64_read_header (psf, &blockalign, &framesperblock)))
			return error ;
	} ;

	if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_W64)
		return	SFE_BAD_OPEN_FORMAT ;

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

	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
	{	if (psf->is_pipe)
			return SFE_NO_PIPE_WRITE ;

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

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

		if (subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM)
		{	blockalign = wavlike_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
			framesperblock = -1 ;

			/*
			** At this point we don't know the file length so set it stupidly high, but not
			** so high that it triggers undefined behaviour whan something is added to it.
			*/
			psf->filelength = SF_COUNT_MAX - 10000 ;
			psf->datalength = psf->filelength ;
			if (psf->sf.frames <= 0)
				psf->sf.frames = (psf->blockwidth) ? psf->filelength / psf->blockwidth : psf->filelength ;
		} ;

		if ((error = w64_write_header (psf, SF_FALSE)))
			return error ;

		psf->write_header = w64_write_header ;
	} ;

	psf->container_close = w64_close ;

	switch (subformat)
	{	case SF_FORMAT_PCM_U8 :
			error = pcm_init (psf) ;
			break ;

		case SF_FORMAT_PCM_16 :
		case SF_FORMAT_PCM_24 :
		case SF_FORMAT_PCM_32 :
			error = pcm_init (psf) ;
			break ;

		case SF_FORMAT_ULAW :
			error = ulaw_init (psf) ;
			break ;

		case SF_FORMAT_ALAW :
			error = alaw_init (psf) ;
			break ;

		/* Lite remove start */
		case SF_FORMAT_FLOAT :
			error = float32_init (psf) ;
			break ;

		case SF_FORMAT_DOUBLE :
			error = double64_init (psf) ;
			break ;

		case SF_FORMAT_IMA_ADPCM :
			error = wavlike_ima_init (psf, blockalign, framesperblock) ;
			break ;

		case SF_FORMAT_MS_ADPCM :
			error = wavlike_msadpcm_init (psf, blockalign, framesperblock) ;
			break ;
		/* Lite remove end */

		case SF_FORMAT_GSM610 :
			error = gsm610_init (psf) ;
			break ;

		default :
			return SFE_UNIMPLEMENTED ;
	} ;

	return error ;
} /* w64_open */
Пример #13
0
int
raw_open	(SF_PRIVATE *psf)
{	int	subformat, error = SFE_NO_ERROR ;

	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 == 0 || psf->endian == SF_ENDIAN_CPU))
		psf->endian = SF_ENDIAN_LITTLE ;

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

	switch (subformat)
	{	case SF_FORMAT_PCM_S8 :
				error = pcm_init (psf) ;
				break ;

		case SF_FORMAT_PCM_U8 :
				error = pcm_init (psf) ;
				break ;

		case SF_FORMAT_PCM_16 :
		case SF_FORMAT_PCM_24 :
		case SF_FORMAT_PCM_32 :
				error = pcm_init (psf) ;
				break ;

		case SF_FORMAT_ULAW :
				error = ulaw_init (psf) ;
				break ;

		case SF_FORMAT_ALAW :
				error = alaw_init (psf) ;
				break ;

		case SF_FORMAT_GSM610 :
				error = gsm610_init (psf) ;
				break ;

		/* Lite remove start */
		case SF_FORMAT_FLOAT :
				error = float32_init (psf) ;
				break ;

		case SF_FORMAT_DOUBLE :
				error = double64_init (psf) ;
				break ;

		case SF_FORMAT_DWVW_12 :
				error = dwvw_init (psf, 12) ;
				break ;

		case SF_FORMAT_DWVW_16 :
				error = dwvw_init (psf, 16) ;
				break ;

		case SF_FORMAT_DWVW_24 :
				error = dwvw_init (psf, 24) ;
				break ;

		case SF_FORMAT_VOX_ADPCM :
				error = vox_adpcm_init (psf) ;
				break ;
		/* Lite remove end */

		default : return SFE_BAD_OPEN_FORMAT ;
		} ;

	return error ;
} /* raw_open */