예제 #1
0
파일: caf.c 프로젝트: weiwei22844/sox
static int
caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size)
{	const AIFF_CAF_CHANNEL_MAP * map_info ;
	unsigned channel_bitmap, channel_decriptions, bytesread ;
	int layout_tag ;

	bytesread = psf_binheader_readf (psf, "E444", &layout_tag, &channel_bitmap, &channel_decriptions) ;

	map_info = aiff_caf_of_channel_layout_tag (layout_tag) ;

	psf_log_printf (psf, "  Tag    : %x\n", layout_tag) ;
	if (map_info)
		psf_log_printf (psf, "  Layout : %s\n", map_info->name) ;

	if (bytesread < chunk_size)
		psf_binheader_readf (psf, "j", chunk_size - bytesread) ;

	if (map_info && map_info->channel_map != NULL)
	{	size_t chanmap_size = SF_MIN (psf->sf.channels, layout_tag & 0xff) * sizeof (psf->channel_map [0]) ;

		free (psf->channel_map) ;

		if ((psf->channel_map = malloc (chanmap_size)) == NULL)
			return SFE_MALLOC_FAILED ;

		memcpy (psf->channel_map, map_info->channel_map, chanmap_size) ;
		} ;

	return 0 ;
} /* caf_read_chanmap */
예제 #2
0
파일: pvf.c 프로젝트: 5in4/libsox.dll
static int
pvf_read_header (SF_PRIVATE *psf)
{	char	buffer [32] ;
	int		marker, channels, samplerate, bitwidth ;

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

	if (marker != PVF1_MARKER)
		return SFE_PVF_NO_PVF1 ;

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

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

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

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

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

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

		default :
				return SFE_PVF_BAD_BITWIDTH ;
		} ;

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

	psf->endian = SF_ENDIAN_BIG ;

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

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

	return 0 ;
} /* pvf_read_header */
예제 #3
0
static int
wve_read_header (SF_PRIVATE *psf)
{	int marker ;
	unsigned short version, padding, repeats, trash ;
	unsigned datalength ;

	/* Set position to start of file to begin reading header. */
	psf_binheader_readf (psf, "pm", 0, &marker) ;
	if (marker != ALAW_MARKER)
	{	psf_log_printf (psf, "Could not find '%M'\n", ALAW_MARKER) ;
		return SFE_WVE_NOT_WVE ;
		} ;

	psf_binheader_readf (psf, "m", &marker) ;
	if (marker != SOUN_MARKER)
	{	psf_log_printf (psf, "Could not find '%M'\n", SOUN_MARKER) ;
		return SFE_WVE_NOT_WVE ;
		} ;

	psf_binheader_readf (psf, "m", &marker) ;
	if (marker != DFIL_MARKER)
	{	psf_log_printf (psf, "Could not find '%M'\n", DFIL_MARKER) ;
		return SFE_WVE_NOT_WVE ;
		} ;

	psf_binheader_readf (psf, "m", &marker) ;
	if (marker != ESSN_MARKER)
	{	psf_log_printf (psf, "Could not find '%M'\n", ESSN_MARKER) ;
		return SFE_WVE_NOT_WVE ;
		} ;

	psf_binheader_readf (psf, "E2", &version) ;

	psf_log_printf (psf, "Psion Palmtop Alaw (.wve)\n"
			"  Sample Rate : 8000\n"
			"  Channels    : 1\n"
			"  Encoding    : A-law\n") ;

	if (version != PSION_VERSION)
		psf_log_printf (psf, "Psion version %d should be %d\n", version, PSION_VERSION) ;

	psf_binheader_readf (psf, "E4", &datalength) ;
	psf->dataoffset = PSION_DATAOFFSET ;
	if (datalength != psf->filelength - psf->dataoffset)
	{	psf->datalength = psf->filelength - psf->dataoffset ;
		psf_log_printf (psf, "Data length %d should be %D\n", datalength, psf->datalength) ;
		}
	else
		psf->datalength = datalength ;

	psf_binheader_readf (psf, "E22222", &padding, &repeats, &trash, &trash, &trash) ;

	psf->sf.format		= SF_FORMAT_WVE | SF_FORMAT_ALAW ;
	psf->sf.samplerate	= 8000 ;
	psf->sf.frames		= psf->datalength ;
	psf->sf.channels	= 1 ;

	return SFE_NO_ERROR ;
} /* wve_read_header */
예제 #4
0
파일: htk.c 프로젝트: erikd/libsndfile
static int
htk_read_header (SF_PRIVATE *psf)
{   int		sample_count, sample_period, marker ;

    psf_binheader_readf (psf, "pE444", 0, &sample_count, &sample_period, &marker) ;

    if (2 * sample_count + 12 != psf->filelength)
        return SFE_HTK_BAD_FILE_LEN ;

    if (marker != 0x20000)
        return SFE_HTK_NOT_WAVEFORM ;

    psf->sf.channels = 1 ;

    if (sample_period > 0)
    {   psf->sf.samplerate = 10000000 / sample_period ;
        psf_log_printf (psf, "HTK Waveform file\n  Sample Count  : %d\n  Sample Period : %d => %d Hz\n",
                        sample_count, sample_period, psf->sf.samplerate) ;
    }
    else
    {   psf->sf.samplerate = 16000 ;
        psf_log_printf (psf, "HTK Waveform file\n  Sample Count  : %d\n  Sample Period : %d (should be > 0) => Guessed sample rate %d Hz\n",
                        sample_count, sample_period, psf->sf.samplerate) ;
    } ;

    psf->sf.format = SF_FORMAT_HTK | SF_FORMAT_PCM_16 ;
    psf->bytewidth = 2 ;

    /* HTK always has a 12 byte header. */
    psf->dataoffset = 12 ;
    psf->endian = SF_ENDIAN_BIG ;

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

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

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

    return 0 ;
} /* htk_read_header */
예제 #5
0
static int
txw_read_header	(SF_PRIVATE *psf)
{	BUF_UNION	ubuf ;
	TXW_HEADER txwh ;
	const char	*strptr ;

	memset (&txwh, 0, sizeof (txwh)) ;
	memset (ubuf.cbuf, 0, sizeof (ubuf.cbuf)) ;
	psf_binheader_readf (psf, "pb", 0, ubuf.cbuf, 16) ;

	if (memcmp (ubuf.cbuf, "LM8953\0\0\0\0\0\0\0\0\0\0", 16) != 0)
		return ERROR_666 ;

	psf_log_printf (psf, "Read only : Yamaha TX-16 Sampler (.txw)\nLM8953\n") ;

	/* Jump 6 bytes (dummp_aeg), read format, read sample rate. */
	psf_binheader_readf (psf, "j11", 6, &txwh.format, &txwh.srate) ;

	/* 8 bytes (atc_length[3], rpt_length[3], unused[2]). */
	psf_binheader_readf (psf, "e33j", &txwh.attacklen, &txwh.repeatlen, 2) ;
	txwh.sr2 = (txwh.attacklen >> 16) & 0xFE ;
	txwh.sr3 = (txwh.repeatlen >> 16) & 0xFE ;
	txwh.attacklen &= 0x1FFFF ;
	txwh.repeatlen &= 0x1FFFF ;

	switch (txwh.format)
	{	case TXW_LOOPED :
				strptr = "looped" ;
				break ;

		case TXW_NO_LOOP :
				strptr = "non-looped" ;
				break ;

		default :
				psf_log_printf (psf, " Format      : 0x%02x => ?????\n", txwh.format) ;
				return ERROR_666 ;
		} ;

	psf_log_printf (psf, " Format      : 0x%02X => %s\n", txwh.format, strptr) ;

	strptr = NULL ;

	switch (txwh.srate)
	{	case 1 :
				psf->sf.samplerate = 33333 ;
				break ;

		case 2 :
				psf->sf.samplerate = 50000 ;
				break ;

		case 3 :
				psf->sf.samplerate = 16667 ;
				break ;

		default :
			/* This is ugly and braindead. */
			txwh.srhash = ((txwh.sr2 & 0xFE) << 8) | (txwh.sr3 & 0xFE) ;
			switch (txwh.srhash)
			{	case ((0x6 << 8) | 0x52) :
						psf->sf.samplerate = 33333 ;
						break ;

				case ((0x10 << 8) | 0x52) :
						psf->sf.samplerate = 50000 ;
						break ;

				case ((0xF6 << 8) | 0x52) :
						psf->sf.samplerate = 166667 ;
						break ;

				default :
						strptr = " Sample Rate : Unknown : forcing to 33333\n" ;
						psf->sf.samplerate = 33333 ;
						break ;
				} ;
		} ;


	if (strptr)
		psf_log_printf (psf, strptr) ;
	else if (txwh.srhash)
		psf_log_printf (psf, " Sample Rate : %d (0x%X) => %d\n", txwh.srate, txwh.srhash, psf->sf.samplerate) ;
	else
		psf_log_printf (psf, " Sample Rate : %d => %d\n", txwh.srate, psf->sf.samplerate) ;

	if (txwh.format == TXW_LOOPED)
	{	psf_log_printf (psf, " Attack Len  : %d\n", txwh.attacklen) ;
		psf_log_printf (psf, " Repeat Len  : %d\n", txwh.repeatlen) ;
		} ;

	psf->dataoffset = TXW_DATA_OFFSET ;
	psf->datalength = psf->filelength - TXW_DATA_OFFSET ;
	psf->sf.frames	= 2 * psf->datalength / 3 ;


	if (psf->datalength % 3 == 1)
		psf_log_printf (psf, "*** File seems to be truncated, %d extra bytes.\n",
			(int) (psf->datalength % 3)) ;

	if (txwh.attacklen + txwh.repeatlen > psf->sf.frames)
		psf_log_printf (psf, "*** File has been truncated.\n") ;

	psf->sf.format = SF_FORMAT_TXW | SF_FORMAT_PCM_16 ;
	psf->sf.channels = 1 ;
	psf->sf.sections = 1 ;
	psf->sf.seekable = SF_TRUE ;

	return 0 ;
} /* txw_read_header */
예제 #6
0
파일: voc.c 프로젝트: 74Labs/libsndfile
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 */
예제 #7
0
파일: avr.c 프로젝트: 5in4/libsox.dll
static int
avr_read_header (SF_PRIVATE *psf)
{	AVR_HEADER	hdr ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	psf->endian = SF_ENDIAN_BIG ;

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

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

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

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

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

	return 0 ;
} /* avr_read_header */
예제 #8
0
파일: nist.c 프로젝트: joshlong/libcd
static int 	
nist_read_header (SF_PRIVATE *psf)
{	char	*psf_header ;
	int		bitwidth = 0, bytes = 0, count, encoding ;
	char 	str [64], *cptr ;
	long	samples ;
	
		
	psf->sf.format = SF_FORMAT_NIST ;
	
	psf_header = (char*) psf->header ;
	
	if (sizeof (psf->header) <= NIST_HEADER_LENGTH)
		return SFE_INTERNAL ;
		
	/* Go to start of file and read in the whole header. */
	psf_binheader_readf (psf, "pb", 0, psf_header, NIST_HEADER_LENGTH) ;

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

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

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

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

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

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

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

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

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

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

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

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

	psf->close = nist_close ;

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

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

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

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

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

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

	return 0 ;
} /* nist_read_header */
예제 #9
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 */
예제 #10
0
static int
dwd_read_header (SF_PRIVATE *psf)
{	BUF_UNION	ubuf ;
	DWD_HEADER	dwdh ;

	memset (ubuf.cbuf, 0, sizeof (ubuf.cbuf)) ;
	/* Set position to start of file to begin reading header. */
	psf_binheader_readf (psf, "pb", 0, ubuf.cbuf, DWD_IDENTIFIER_LEN) ;

	if (memcmp (ubuf.cbuf, DWD_IDENTIFIER, DWD_IDENTIFIER_LEN) != 0)
		return SFE_DWD_NO_DWD ;

	psf_log_printf (psf, "Read only : DiamondWare Digitized (.dwd)\n", ubuf.cbuf) ;

	psf_binheader_readf (psf, "11", &dwdh.major, &dwdh.minor) ;
	psf_binheader_readf (psf, "e4j1", &dwdh.id, 1, &dwdh.compression) ;
	psf_binheader_readf (psf, "e211", &dwdh.srate, &dwdh.channels, &dwdh.bitwidth) ;
	psf_binheader_readf (psf, "e24", &dwdh.maxval, &dwdh.datalen) ;
	psf_binheader_readf (psf, "e44", &dwdh.frames, &dwdh.offset) ;

	psf_log_printf (psf, "  Version Major : %d\n  Version Minor : %d\n  Unique ID     : %08X\n",
									dwdh.major, dwdh.minor, dwdh.id) ;
	psf_log_printf (psf, "  Compression   : %d => ", dwdh.compression) ;

	if (dwdh.compression != 0)
	{	psf_log_printf (psf, "Unsupported compression\n") ;
		return SFE_DWD_COMPRESSION ;
	}
	else
		psf_log_printf (psf, "None\n") ;

	psf_log_printf (psf,	"  Sample Rate   : %d\n  Channels      : %d\n"
									"  Bit Width     : %d\n",
									dwdh.srate, dwdh.channels, dwdh.bitwidth) ;

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

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

		default :
			psf_log_printf (psf, "*** Bad bit width %d\n", dwdh.bitwidth) ;
			return SFE_DWD_BAND_BIT_WIDTH ;
	} ;

	if (psf->filelength != dwdh.offset + dwdh.datalen)
	{	psf_log_printf (psf, "  Data Length   : %d (should be %D)\n", dwdh.datalen, psf->filelength - dwdh.offset) ;
		dwdh.datalen = (unsigned int) (psf->filelength - dwdh.offset) ;
	}
	else
		psf_log_printf (psf, "  Data Length   : %d\n", dwdh.datalen) ;

	psf_log_printf (psf, "  Max Value     : %d\n", dwdh.maxval) ;
	psf_log_printf (psf, "  Frames        : %d\n", dwdh.frames) ;
	psf_log_printf (psf, "  Data Offset   : %d\n", dwdh.offset) ;

	psf->datalength = dwdh.datalen ;
	psf->dataoffset = dwdh.offset ;

	psf->endian = SF_ENDIAN_LITTLE ;

	psf->sf.samplerate = dwdh.srate ;
	psf->sf.channels = dwdh.channels ;
	psf->sf.sections = 1 ;

	return pcm_init (psf) ;
} /* dwd_read_header */
예제 #11
0
파일: au.c 프로젝트: 74Labs/libsndfile
static int
au_read_header (SF_PRIVATE *psf)
{	AU_FMT	au_fmt ;
	int		marker, dword ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return 0 ;
} /* au_read_header */
예제 #12
0
파일: rx2.c 프로젝트: joshlong/libcd
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 */
예제 #13
0
파일: sd2.c 프로젝트: elha/CDex
int 	
sd2_open	(SF_PRIVATE *psf)
{	int		marker, software, rsrc_offset, len ;
	int 	rsrc_data_offset, rsrc_map_offset, rsrc_data_length, rsrc_map_length ;
	char	slen ;
	float	srate ;	

	/* Read only so far. */

	psf_binheader_readf (psf, "Epmmj", 0x41, &marker, &software, 14) ;
	
	if (marker != Sd2f_MARKER)
	{	printf ("Whoops!!!\n") ;
		puts (psf->logbuffer) ;
		exit (1) ;
		} ;

	psf_log_printf (psf, "Marker   : %M\n"
						 "Software : %M\n", 
			marker, software) ;
	
	/* This seems to be a constant for binhex files. */
	psf->dataoffset = 0x80 ;
	
	/* All SD2 files are big endian. */
	psf->endian= SF_ENDIAN_BIG ;

	/*
	**	Resource header info from:
	**	http://developer.apple.com/techpubs/mac/MoreToolbox/MoreToolbox-99.html
	*/

	rsrc_offset = psf->datalength + psf->dataoffset ;
	if (rsrc_offset & 0x7F)
		rsrc_offset = rsrc_offset - (rsrc_offset & 0x7F) + psf->dataoffset ;

	psf_log_printf (psf, "Resource offset : 0x%X\n", rsrc_offset) ;

	/* Jump to the rsrc_offset fork section. */
	psf_binheader_readf (psf, "Ep", rsrc_offset) ;
	
	psf_binheader_readf (psf, "E4444", &rsrc_data_offset, &rsrc_map_offset, &rsrc_data_length, &rsrc_map_length) ;

	rsrc_data_offset += rsrc_offset ;
	rsrc_map_offset  += rsrc_offset ;

	psf_log_printf (psf, " data offset : 0x%X\n"
						 " map  offset : 0x%X\n"
						 " data length : 0x%X\n"
						 " map  length : 0x%X\n",
	
			rsrc_data_offset, rsrc_map_offset, rsrc_data_length, rsrc_map_length) ;
			
	if (rsrc_data_offset + rsrc_data_length > rsrc_map_offset || rsrc_map_offset + rsrc_map_length > psf->filelength)
	{	puts ("##############################") ;
		puts (psf->logbuffer) ;
		puts ("##############################") ;
		exit (1) ;
		} ;

	memset (psf->buffer, 0, sizeof (psf->buffer)) ;
	
	psf_binheader_readf (psf, "Ep41", rsrc_data_offset, &len, &slen) ;
	if (slen + 1 == len)
	{	psf_binheader_readf (psf, "Eb", psf->buffer, len - 1) ;
		((char*) psf->buffer) [len - 1] = 0 ;
		if (sscanf ((char*) psf->buffer, "%d", &len) == 1)
			psf->bytewidth = len ; 
		} ;
		
	psf_binheader_readf (psf, "E41", &len, &slen) ;
	if (slen + 1 == len)
	{	psf_binheader_readf (psf, "Eb", psf->buffer, len - 1) ;
		((char*) psf->buffer) [len - 1] = 0 ;
		if (sscanf ((char*) psf->buffer, "%f", &srate) == 1)
			psf->sf.samplerate = srate ; 
		} ;
		
	psf_binheader_readf (psf, "E41", &len, &slen) ;
	if (slen + 1 == len)
	{	psf_binheader_readf (psf, "Eb", psf->buffer, len - 1) ;
		((char*) psf->buffer) [len - 1] = 0 ;
		if (sscanf ((char*) psf->buffer, "%d", &len) == 1)
			psf->sf.channels = len ; 
		} ;
		
	psf_log_printf (psf, "  byte width  : %d\n", psf->bytewidth) ;
	psf_log_printf (psf, "  sample rate : %d\n", psf->sf.samplerate) ;
	psf_log_printf (psf, "  channels    : %d\n", psf->sf.channels) ;

	if (psf->bytewidth == 2)
	{	psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_16 ;
		
		psf->blockwidth = psf->bytewidth * psf->sf.channels ;
		
		psf->sf.frames = psf->datalength / psf->blockwidth ;
		} ;
	
	pcm_init (psf) ;

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

	psf->close = sd2_close ;
	
	return 0 ;
} /* sd2_open */
예제 #14
0
파일: caf.c 프로젝트: weiwei22844/sox
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 */
예제 #15
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 */
예제 #16
0
파일: nist.c 프로젝트: erikd/libsndfile
	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 */
예제 #17
0
파일: mat5.c 프로젝트: andreipaga/audacity
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 ;
		}
예제 #18
0
파일: w64.c 프로젝트: joshlong/libcd
static int
w64_read_header	(SF_PRIVATE *psf, int *blockalign, int *framesperblock)
{	WAV_FMT wav_fmt ;
	int		dword = 0, marker, format = 0 ;
	sf_count_t	chunk_size, bytesread = 0 ;
	int		parsestage = 0, error, done = 0 ;
	
	/* Set position to start of file to begin reading header. */
	psf_binheader_readf (psf, "p", 0) ;	
		
	while (! done)
	{	/* Read the 4 byte marker and jump 12 bytes. */
		bytesread += psf_binheader_readf (psf, "h", &marker) ;
		chunk_size = 0 ;
		
		switch (marker)
		{	case riff_HASH16 :
					if (parsestage)
						return SFE_W64_NO_RIFF ;

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

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

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

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

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

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

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

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

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

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

					parsestage |= HAVE_data ;

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

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

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

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

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

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

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

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

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

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

	return 0 ;
} /* w64_read_header */
예제 #19
0
static int
ircam_read_header	(SF_PRIVATE *psf)
{	unsigned int	marker, encoding ;
	float			samplerate ;
	int				error = SFE_NO_ERROR ;

	psf_binheader_readf (psf, "epmf44", 0, &marker, &samplerate, &(psf->sf.channels), &encoding) ;

	if (((marker & IRCAM_BE_MASK) != IRCAM_BE_MARKER) && ((marker & IRCAM_LE_MASK) != IRCAM_LE_MARKER))
	{	psf_log_printf (psf, "marker: 0x%X\n", marker) ;
		return SFE_IRCAM_NO_MARKER ;
		} ;

	psf->endian = SF_ENDIAN_LITTLE ;

	if (psf->sf.channels > SF_MAX_CHANNELS)
	{	psf_binheader_readf (psf, "Epmf44", 0, &marker, &samplerate, &(psf->sf.channels), &encoding) ;

		/* Sanity checking for endian-ness detection. */
		if (psf->sf.channels > SF_MAX_CHANNELS)
		{	psf_log_printf (psf, "marker: 0x%X\n", marker) ;
			return SFE_IRCAM_BAD_CHANNELS ;
			} ;

		psf->endian = SF_ENDIAN_BIG ;
		} ;

	psf_log_printf (psf, "marker: 0x%X\n", marker) ;

	psf->sf.samplerate = (int) samplerate ;

	psf_log_printf (psf,	"  Sample Rate : %d\n"
							"  Channels    : %d\n"
							"  Encoding    : %X => %s\n",
						psf->sf.samplerate, psf->sf.channels, encoding, get_encoding_str (encoding)) ;

	switch (encoding)
	{	case IRCAM_PCM_16 :
				psf->bytewidth = 2 ;
				psf->blockwidth = psf->sf.channels * psf->bytewidth ;

				psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_PCM_16 ;
				break ;

		case IRCAM_PCM_32 :
				psf->bytewidth = 4 ;
				psf->blockwidth = psf->sf.channels * psf->bytewidth ;

				psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_PCM_32 ;
				break ;

		case IRCAM_FLOAT :
				psf->bytewidth = 4 ;
				psf->blockwidth = psf->sf.channels * psf->bytewidth ;

				psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_FLOAT ;
				break ;

		case IRCAM_ALAW :
				psf->bytewidth = 1 ;
				psf->blockwidth = psf->sf.channels * psf->bytewidth ;

				psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_ALAW ;
				break ;

		case IRCAM_ULAW :
				psf->bytewidth = 1 ;
				psf->blockwidth = psf->sf.channels * psf->bytewidth ;

				psf->sf.format = SF_FORMAT_IRCAM | SF_FORMAT_ULAW ;
				break ;

		default :
				error = SFE_IRCAM_UNKNOWN_FORMAT ;
				break ;
		} ;

	if (psf->endian == SF_ENDIAN_BIG)
		psf->sf.format |= SF_ENDIAN_BIG ;
	else
		psf->sf.format |= SF_ENDIAN_LITTLE ;

	if (error)
		return error ;

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

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

	psf_log_printf (psf, "  Samples     : %d\n", psf->sf.frames) ;

	psf_binheader_readf (psf, "p", IRCAM_DATA_OFFSET) ;

	return 0 ;
} /* ircam_read_header */
예제 #20
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 */
예제 #21
0
파일: caf.c 프로젝트: weiwei22844/sox
static int caf_read_strings (SF_PRIVATE * psf, sf_count_t chunk_size)
{
    //char buf [chunk_size - 4] ;
    char *buf = (char*)malloc(chunk_size-4);
    char *key, *value ;
    uint32_t count, hash ;

    psf_binheader_readf (psf, "E4b", &count, buf, make_size_t (chunk_size - 4)) ;
    psf_log_printf (psf, " count: %u\n", count) ;

    /* Force terminate `buf` to make sure. */
    buf [chunk_size-4 - 1] = 0 ;

    for (key = buf ; key < buf + chunk_size-4 ; )
    {	value = key + strlen (key) + 1 ;
    if (value > buf + chunk_size-4)
        break ;
    psf_log_printf (psf, "   %-12s : %s\n", key, value) ;

    hash = string_hash32 (key) ;
    switch (hash)
    {	case 0xC4861943 : /* 'title' */
    psf_store_string (psf, SF_STR_TITLE, value) ;
    break ;
    case 0xAD47A394 : /* 'software' */
        psf_store_string (psf, SF_STR_SOFTWARE, value) ;
        break ;
    case 0x5D178E2A : /* 'copyright' */
        psf_store_string (psf, SF_STR_COPYRIGHT, value) ;
        break ;
    case 0x60E4D0C8 : /* 'artist' */
        psf_store_string (psf, SF_STR_ARTIST, value) ;
        break ;
    case 0x83B5D16A : /* 'genre' */
        psf_store_string (psf, SF_STR_GENRE, value) ;
        break ;
    case 0x15E5FC88 : /* 'comment' */
    case 0x7C297D5B : /* 'comments' */
        psf_store_string (psf, SF_STR_COMMENT, value) ;
        break ;
    case 0x24A7C347 : /* 'tracknumber' */
        psf_store_string (psf, SF_STR_TRACKNUMBER, value) ;
        break ;
    case 0x50A31EB7 : /* 'date' */
        psf_store_string (psf, SF_STR_DATE, value) ;
        break ;
    case 0x6583545A : /* 'album' */
        psf_store_string (psf, SF_STR_ALBUM, value) ;
        break ;
    case 0xE7C64B6C : /* 'license' */
        psf_store_string (psf, SF_STR_LICENSE, value) ;
        break ;
    default :
        psf_log_printf (psf, " Unhandled hash 0x%x : /* '%s' */\n", hash, key) ;
        break ;
    } ;

    key = value + strlen (value) + 1 ;
    } ;
    free(buf);

    return 0 ;
}
예제 #22
0
int
wav_w64_read_fmt_chunk (SF_PRIVATE *psf, int fmtsize)
{   WAV_PRIVATE * wpriv ;
    WAV_FMT *wav_fmt ;
    int	bytesread, k, bytespersec = 0 ;

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

    memset (wav_fmt, 0, sizeof (WAV_FMT)) ;

    if (fmtsize < 16)
        return SFE_WAV_FMT_SHORT ;

    /* assume psf->rwf_endian is already properly set */

    /* Read the minimal WAV file header here. */
    bytesread = psf_binheader_readf (psf, "224422",
                                     &(wav_fmt->format), &(wav_fmt->min.channels),
                                     &(wav_fmt->min.samplerate), &(wav_fmt->min.bytespersec),
                                     &(wav_fmt->min.blockalign), &(wav_fmt->min.bitwidth)) ;

    psf_log_printf (psf, "  Format        : 0x%X => %s\n", wav_fmt->format, wav_w64_format_str (wav_fmt->format)) ;
    psf_log_printf (psf, "  Channels      : %d\n", wav_fmt->min.channels) ;
    psf_log_printf (psf, "  Sample Rate   : %d\n", wav_fmt->min.samplerate) ;
    psf_log_printf (psf, "  Block Align   : %d\n", wav_fmt->min.blockalign) ;

    if (wav_fmt->min.blockalign == 0)
    {   psf_log_printf (psf, "*** Error : wav_fmt->min.blockalign should not be zero.\n") ;
        return SFE_INTERNAL ;
    } ;

    if (wav_fmt->format == WAVE_FORMAT_PCM && wav_fmt->min.bitwidth == 24 &&
            wav_fmt->min.blockalign == 4 * wav_fmt->min.channels)
    {   psf_log_printf (psf, "  Bit Width     : 24\n") ;

        psf_log_printf (psf, "\n"
                        "  Ambiguous information in 'fmt ' chunk. Possibile file types:\n"
                        "    0) Invalid IEEE float file generated by Syntrillium's Cooledit!\n"
                        "    1) File generated by ALSA's arecord containing 24 bit samples in 32 bit containers.\n"
                        "    2) 24 bit file with incorrect Block Align value.\n"
                        "\n") ;

        wpriv->fmt_is_broken = 1 ;
    }
    else if (wav_fmt->min.bitwidth == 0)
    {   switch (wav_fmt->format)
        {
        case WAVE_FORMAT_GSM610 :
        case WAVE_FORMAT_IPP_ITU_G_723_1 :
            psf_log_printf (psf, "  Bit Width     : %d\n", wav_fmt->min.bitwidth) ;
            break ;
        default :
            psf_log_printf (psf, "  Bit Width     : %d (should not be 0)\n", wav_fmt->min.bitwidth) ;
        }
    }
    else
    {   switch (wav_fmt->format)
        {
        case WAVE_FORMAT_GSM610 :
        case WAVE_FORMAT_IPP_ITU_G_723_1 :
            psf_log_printf (psf, "  Bit Width     : %d (should be 0)\n", wav_fmt->min.bitwidth) ;
            break ;
        default :
            psf_log_printf (psf, "  Bit Width     : %d\n", wav_fmt->min.bitwidth) ;
        }
    } ;

    psf->sf.samplerate	= wav_fmt->min.samplerate ;
    psf->sf.frames 		= 0 ;					/* Correct this when reading data chunk. */
    psf->sf.channels	= wav_fmt->min.channels ;

    switch (wav_fmt->format)
    {
    case WAVE_FORMAT_PCM :
    case WAVE_FORMAT_IEEE_FLOAT :
        bytespersec = wav_fmt->min.samplerate * wav_fmt->min.blockalign ;
        if (wav_fmt->min.bytespersec != (unsigned) bytespersec)
            psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->min.bytespersec, bytespersec) ;
        else
            psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->min.bytespersec) ;

        psf->bytewidth = BITWIDTH2BYTES (wav_fmt->min.bitwidth) ;
        break ;

    case WAVE_FORMAT_ALAW :
    case WAVE_FORMAT_MULAW :
        if (wav_fmt->min.bytespersec / wav_fmt->min.blockalign != wav_fmt->min.samplerate)
            psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->min.bytespersec, wav_fmt->min.samplerate * wav_fmt->min.blockalign) ;
        else
            psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->min.bytespersec) ;

        psf->bytewidth = 1 ;
        if (fmtsize >= 18)
        {   bytesread += psf_binheader_readf (psf, "2", &(wav_fmt->size20.extrabytes)) ;
            psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->size20.extrabytes) ;
        } ;
        break ;

    case WAVE_FORMAT_IMA_ADPCM :
        if (wav_fmt->min.bitwidth != 4)
            return SFE_WAV_ADPCM_NOT4BIT ;
        if (wav_fmt->min.channels < 1 || wav_fmt->min.channels > 2)
            return SFE_WAV_ADPCM_CHANNELS ;

        bytesread +=
            psf_binheader_readf (psf, "22", &(wav_fmt->ima.extrabytes), &(wav_fmt->ima.samplesperblock)) ;

        bytespersec = (wav_fmt->ima.samplerate * wav_fmt->ima.blockalign) / wav_fmt->ima.samplesperblock ;
        if (wav_fmt->ima.bytespersec != (unsigned) bytespersec)
            psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->ima.bytespersec, bytespersec) ;
        else
            psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->ima.bytespersec) ;

        psf->bytewidth = 2 ;
        psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->ima.extrabytes) ;
        psf_log_printf (psf, "  Samples/Block : %d\n", wav_fmt->ima.samplesperblock) ;
        break ;

    case WAVE_FORMAT_MS_ADPCM :
        if (wav_fmt->msadpcm.bitwidth != 4)
            return SFE_WAV_ADPCM_NOT4BIT ;
        if (wav_fmt->msadpcm.channels < 1 || wav_fmt->msadpcm.channels > 2)
            return SFE_WAV_ADPCM_CHANNELS ;

        bytesread +=
            psf_binheader_readf (psf, "222", &(wav_fmt->msadpcm.extrabytes),
                                 &(wav_fmt->msadpcm.samplesperblock), &(wav_fmt->msadpcm.numcoeffs)) ;

        bytespersec = (wav_fmt->min.samplerate * wav_fmt->min.blockalign) / wav_fmt->msadpcm.samplesperblock ;
        if (wav_fmt->min.bytespersec == (unsigned) bytespersec)
            psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->min.bytespersec) ;
        else if (wav_fmt->min.bytespersec == (wav_fmt->min.samplerate / wav_fmt->msadpcm.samplesperblock) * wav_fmt->min.blockalign)
            psf_log_printf (psf, "  Bytes/sec     : %d (should be %d (MS BUG!))\n", wav_fmt->min.bytespersec, bytespersec) ;
        else
            psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->min.bytespersec, bytespersec) ;


        psf->bytewidth = 2 ;
        psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->msadpcm.extrabytes) ;
        psf_log_printf (psf, "  Samples/Block : %d\n", wav_fmt->msadpcm.samplesperblock) ;
        if (wav_fmt->msadpcm.numcoeffs > ARRAY_LEN (wav_fmt->msadpcm.coeffs))
        {   psf_log_printf (psf, "  No. of Coeffs : %d (should be <= %d)\n", wav_fmt->msadpcm.numcoeffs, ARRAY_LEN (wav_fmt->msadpcm.coeffs)) ;
            wav_fmt->msadpcm.numcoeffs = ARRAY_LEN (wav_fmt->msadpcm.coeffs) ;
        }
        else
            psf_log_printf (psf, "  No. of Coeffs : %d\n", wav_fmt->msadpcm.numcoeffs) ;

        psf_log_printf (psf, "    Index   Coeffs1   Coeffs2\n") ;
        for (k = 0 ; k < wav_fmt->msadpcm.numcoeffs ; k++)
        {   bytesread +=
                psf_binheader_readf (psf, "22", &(wav_fmt->msadpcm.coeffs [k].coeff1), &(wav_fmt->msadpcm.coeffs [k].coeff2)) ;
            snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), "     %2d     %7d   %7d\n", k, wav_fmt->msadpcm.coeffs [k].coeff1, wav_fmt->msadpcm.coeffs [k].coeff2) ;
            psf_log_printf (psf, psf->u.cbuf) ;
        } ;
        break ;

    case WAVE_FORMAT_GSM610 :
        if (wav_fmt->gsm610.channels != 1 || wav_fmt->gsm610.blockalign != 65)
            return SFE_WAV_GSM610_FORMAT ;

        bytesread +=
            psf_binheader_readf (psf, "22", &(wav_fmt->gsm610.extrabytes), &(wav_fmt->gsm610.samplesperblock)) ;

        if (wav_fmt->gsm610.samplesperblock != 320)
            return SFE_WAV_GSM610_FORMAT ;

        bytespersec = (wav_fmt->gsm610.samplerate * wav_fmt->gsm610.blockalign) / wav_fmt->gsm610.samplesperblock ;
        if (wav_fmt->gsm610.bytespersec != (unsigned) bytespersec)
            psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->gsm610.bytespersec, bytespersec) ;
        else
            psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->gsm610.bytespersec) ;

        psf->bytewidth = 2 ;
        psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->gsm610.extrabytes) ;
        psf_log_printf (psf, "  Samples/Block : %d\n", wav_fmt->gsm610.samplesperblock) ;
        break ;

    case WAVE_FORMAT_EXTENSIBLE :
        if (wav_fmt->ext.bytespersec / wav_fmt->ext.blockalign != wav_fmt->ext.samplerate)
            psf_log_printf (psf, "  Bytes/sec     : %d (should be %d)\n", wav_fmt->ext.bytespersec, wav_fmt->ext.samplerate * wav_fmt->ext.blockalign) ;
        else
            psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->ext.bytespersec) ;

        bytesread +=
            psf_binheader_readf (psf, "224", &(wav_fmt->ext.extrabytes), &(wav_fmt->ext.validbits),
                                 &(wav_fmt->ext.channelmask)) ;

        psf_log_printf (psf, "  Valid Bits    : %d\n", wav_fmt->ext.validbits) ;
        psf_log_printf (psf, "  Channel Mask  : 0x%X\n", wav_fmt->ext.channelmask) ;

        bytesread +=
            psf_binheader_readf (psf, "422", &(wav_fmt->ext.esf.esf_field1), &(wav_fmt->ext.esf.esf_field2),
                                 &(wav_fmt->ext.esf.esf_field3)) ;

        /* compare the esf_fields with each known GUID? and print? */
        psf_log_printf (psf, "  Subformat\n") ;
        psf_log_printf (psf, "    esf_field1 : 0x%X\n", wav_fmt->ext.esf.esf_field1) ;
        psf_log_printf (psf, "    esf_field2 : 0x%X\n", wav_fmt->ext.esf.esf_field2) ;
        psf_log_printf (psf, "    esf_field3 : 0x%X\n", wav_fmt->ext.esf.esf_field3) ;
        psf_log_printf (psf, "    esf_field4 : ") ;
        for (k = 0 ; k < 8 ; k++)
        {   bytesread += psf_binheader_readf (psf, "1", &(wav_fmt->ext.esf.esf_field4 [k])) ;
            psf_log_printf (psf, "0x%X ", wav_fmt->ext.esf.esf_field4 [k] & 0xFF) ;
        } ;
        psf_log_printf (psf, "\n") ;
        psf->bytewidth = BITWIDTH2BYTES (wav_fmt->ext.bitwidth) ;

        /* Compare GUIDs for known ones. */
        if (wavex_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_PCM))
        {   psf->sf.format = SF_FORMAT_WAVEX | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
            psf_log_printf (psf, "    format : pcm\n") ;
        }
        else if (wavex_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_MS_ADPCM))
        {   psf->sf.format = (SF_FORMAT_WAVEX | SF_FORMAT_MS_ADPCM) ;
            psf_log_printf (psf, "    format : ms adpcm\n") ;
        }
        else if (wavex_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_IEEE_FLOAT))
        {   psf->sf.format = SF_FORMAT_WAVEX | ((psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT) ;
            psf_log_printf (psf, "    format : IEEE float\n") ;
        }
        else if (wavex_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_ALAW))
        {   psf->sf.format = (SF_FORMAT_WAVEX | SF_FORMAT_ALAW) ;
            psf_log_printf (psf, "    format : A-law\n") ;
        }
        else if (wavex_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_MULAW))
        {   psf->sf.format = (SF_FORMAT_WAVEX | SF_FORMAT_ULAW) ;
            psf_log_printf (psf, "    format : u-law\n") ;
        }
        else if (wavex_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM))
        {   psf->sf.format = SF_FORMAT_WAVEX | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
            psf_log_printf (psf, "    format : pcm (Ambisonic B)\n") ;
            wpriv->wavex_ambisonic = SF_AMBISONIC_B_FORMAT ;
        }
        else if (wavex_guid_equal (&wav_fmt->ext.esf, &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT))
        {   psf->sf.format = SF_FORMAT_WAVEX | ((psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT) ;
            psf_log_printf (psf, "    format : IEEE float (Ambisonic B)\n") ;
            wpriv->wavex_ambisonic = SF_AMBISONIC_B_FORMAT ;
        }
        else
            return SFE_UNIMPLEMENTED ;

        break ;

    case WAVE_FORMAT_G721_ADPCM :
        psf_log_printf (psf, "  Bytes/sec     : %d\n", wav_fmt->g72x.bytespersec) ;
        if (fmtsize >= 20)
        {   bytesread += psf_binheader_readf (psf, "22", &(wav_fmt->g72x.extrabytes), &(wav_fmt->g72x.auxblocksize)) ;
            if (wav_fmt->g72x.extrabytes == 0)
                psf_log_printf (psf, "  Extra Bytes   : %d (should be 2)\n", wav_fmt->g72x.extrabytes) ;
            else
                psf_log_printf (psf, "  Extra Bytes   : %d\n", wav_fmt->g72x.extrabytes) ;
            psf_log_printf (psf, "  Aux Blk Size  : %d\n", wav_fmt->g72x.auxblocksize) ;
        }
        else if (fmtsize == 18)
        {   bytesread += psf_binheader_readf (psf, "2", &(wav_fmt->g72x.extrabytes)) ;
            psf_log_printf (psf, "  Extra Bytes   : %d%s\n", wav_fmt->g72x.extrabytes, wav_fmt->g72x.extrabytes != 0 ? " (should be 0)" : "") ;
        }
        else
            psf_log_printf (psf, "*** 'fmt ' chunk should be bigger than this!\n") ;
        break ;

    default :
        psf_log_printf (psf, "*** No 'fmt ' chunk dumper for this format!\n") ;
        return SFE_WAV_BAD_FMT ;
    } ;

    if (bytesread > fmtsize)
    {   psf_log_printf (psf, "*** wav_w64_read_fmt_chunk (bytesread > fmtsize)\n") ;
        return SFE_WAV_BAD_FMT ;
    }
    else
        psf_binheader_readf (psf, "j", fmtsize - bytesread) ;

    psf->blockwidth = wav_fmt->min.channels * psf->bytewidth ;

    return 0 ;
} /* wav_w64_read_fmt_chunk */