⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nist.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
字号:
/*** Copyright (C) 1999-2004 Erik de Castro Lopo <erikd@mega-nerd.com>**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU Lesser General Public License as published by** the Free Software Foundation; either version 2.1 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the** GNU Lesser General Public License for more details.**** You should have received a copy of the GNU Lesser General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//***	Some of the information used to read NIST files was gleaned from**	reading the code of Bill Schottstaedt's sndlib library**		ftp://ccrma-ftp.stanford.edu/pub/Lisp/sndlib.tar.gz**	However, no code from that package was used.*/#include	<stdio.h>#include	<fcntl.h>#include	<string.h>#include	<ctype.h>#include	"sndfile.h"#include	"config.h"#include	"sfendian.h"#include	"common.h"/*------------------------------------------------------------------------------*/#define	NIST_HEADER_LENGTH	1024/*------------------------------------------------------------------------------** Private static functions.*/static	int	nist_close	(SF_PRIVATE *psf) ;static	int nist_write_header	(SF_PRIVATE *psf, int calc_length) ;static	int nist_read_header	(SF_PRIVATE *psf) ;/*------------------------------------------------------------------------------*/intnist_open	(SF_PRIVATE *psf){	int subformat, error ;	if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))	{	if ((error = nist_read_header (psf)))			return error ;		} ;	subformat = psf->sf.format & SF_FORMAT_SUBMASK ;	if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)	{	if (psf->is_pipe)			return SFE_NO_PIPE_WRITE ;		if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_NIST)			return	SFE_BAD_OPEN_FORMAT ;		psf->endian = psf->sf.format & SF_FORMAT_ENDMASK ;		if (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU)			psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;		psf->blockwidth = psf->bytewidth * psf->sf.channels ;		if ((error = nist_write_header (psf, SF_FALSE)))			return error ;		psf->write_header = nist_write_header ;		} ;	psf->close = nist_close ;	switch (psf->sf.format & SF_FORMAT_SUBMASK)	{	case SF_FORMAT_PCM_S8 :				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 ;		default : error = SFE_UNIMPLEMENTED ;				break ;		} ;	return error ;} /* nist_open *//*------------------------------------------------------------------------------*/static char bad_header [] ={	'N', 'I', 'S', 'T', '_', '1', 'A', 0x0d, 0x0a,	' ', ' ', ' ', '1', '0', '2', '4', 0x0d, 0x0a,	0} ;	static intnist_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 = psf->u.cbuf ;	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 ;		} ;	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   1024\n") != psf_header)	{	psf_log_printf (psf, "Not a NIST file.\n") ;		return SFE_NIST_BAD_HEADER ;		} ;	/* 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, 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 */static intnist_close	(SF_PRIVATE *psf){	if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)		nist_write_header (psf, SF_TRUE) ;	return 0 ;} /* nist_close *//*=========================================================================*/static intnist_write_header (SF_PRIVATE *psf, int calc_length){	const char	*end_str ;	long		samples ;	sf_count_t	current ;	current = psf_ftell (psf) ;	/* Prevent compiler warning. */	calc_length = calc_length ;	if (psf->endian == SF_ENDIAN_BIG)		end_str = "10" ;	else if (psf->endian == SF_ENDIAN_LITTLE)		end_str = "01" ;	else		end_str = "error" ;	/* Clear the whole header. */	memset (psf->header, 0, sizeof (psf->header)) ;	psf->headindex = 0 ;	psf_fseek (psf, 0, SEEK_SET) ;	psf_asciiheader_printf (psf, "NIST_1A\n   1024\n") ;	psf_asciiheader_printf (psf, "channel_count -i %d\n", psf->sf.channels) ;	psf_asciiheader_printf (psf, "sample_rate -i %d\n", psf->sf.samplerate) ;	switch (psf->sf.format & SF_FORMAT_SUBMASK)	{	case SF_FORMAT_PCM_S8 :				psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n") ;				psf_asciiheader_printf (psf, "sample_n_bytes -i 1\n"											"sample_sig_bits -i 8\n") ;				break ;		case SF_FORMAT_PCM_16 :		case SF_FORMAT_PCM_24 :		case SF_FORMAT_PCM_32 :				psf_asciiheader_printf (psf, "sample_n_bytes -i %d\n", psf->bytewidth) ;				psf_asciiheader_printf (psf, "sample_sig_bits -i %d\n", psf->bytewidth * 8) ;				psf_asciiheader_printf (psf, "sample_coding -s3 pcm\n"								"sample_byte_format -s%d %s\n", psf->bytewidth, end_str) ;				break ;		case SF_FORMAT_ALAW :				psf_asciiheader_printf (psf, "sample_coding -s4 alaw\n") ;				psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ;				break ;		case SF_FORMAT_ULAW :				psf_asciiheader_printf (psf, "sample_coding -s4 ulaw\n") ;				psf_asciiheader_printf (psf, "sample_n_bytes -s1 1\n") ;				break ;		default : return SFE_UNIMPLEMENTED ;		} ;	psf->dataoffset = NIST_HEADER_LENGTH ;	/* Fix this */	samples = psf->sf.frames ;	psf_asciiheader_printf (psf, "sample_count -i %ld\n", samples) ;	psf_asciiheader_printf (psf, "end_head\n") ;	/* Zero fill to dataoffset. */	psf_binheader_writef (psf, "z", (size_t) (NIST_HEADER_LENGTH - psf->headindex)) ;	psf_fwrite (psf->header, psf->headindex, 1, psf) ;	if (psf->error)		return psf->error ;	if (current > 0)		psf_fseek (psf, current, SEEK_SET) ;	return psf->error ;} /* nist_write_header *//*** Do not edit or modify anything in this comment block.** The arch-tag line is a file identity tag for the GNU Arch ** revision control system.**** arch-tag: b45ed85d-9e22-4ad9-b78c-4b58b67152a8*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -