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

📄 wav.c

📁 Vovida 社区开源的 SIP 协议源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*** Copyright (C) 1999-2001 Erik de Castro Lopo <erikd@zip.com.au>**  ** 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.*/#include	<stdio.h>#include	<unistd.h>#include	<string.h>#include	<ctype.h>#include	<time.h>#include	"sndfile.h"#include	"config.h"#include	"sfendian.h"#include	"common.h"#include	"wav.h"/*------------------------------------------------------------------------------** List of known WAV format tags*/enum{		WAVE_FORMAT_UNKNOWN				= 0x0000,		/* Microsoft Corporation */	WAVE_FORMAT_PCM     		    = 0x0001, 		/* Microsoft PCM format */	WAVE_FORMAT_MS_ADPCM			= 0x0002,		/* Microsoft ADPCM */	WAVE_FORMAT_IEEE_FLOAT			= 0x0003,		/* Micrososft 32 bit float format */		WAVE_FORMAT_IBM_CVSD			= 0x0005,		/* IBM Corporation */	WAVE_FORMAT_ALAW				= 0x0006,		/* Microsoft Corporation */	WAVE_FORMAT_MULAW				= 0x0007,		/* Microsoft Corporation */	WAVE_FORMAT_OKI_ADPCM			= 0x0010,		/* OKI */	WAVE_FORMAT_IMA_ADPCM			= 0x0011,		/* Intel Corporation */	WAVE_FORMAT_MEDIASPACE_ADPCM	= 0x0012,		/* Videologic */	WAVE_FORMAT_SIERRA_ADPCM		= 0x0013,		/* Sierra Semiconductor Corp */	WAVE_FORMAT_G723_ADPCM			= 0x0014,		/* Antex Electronics Corporation */	WAVE_FORMAT_DIGISTD				= 0x0015,		/* DSP Solutions, Inc. */	WAVE_FORMAT_DIGIFIX				= 0x0016,		/* DSP Solutions, Inc. */	WAVE_FORMAT_DIALOGIC_OKI_ADPCM	= 0x0017,		/*  Dialogic Corporation  */	WAVE_FORMAT_MEDIAVISION_ADPCM	= 0x0018,		/*  Media Vision, Inc. */	WAVE_FORMAT_YAMAHA_ADPCM		= 0x0020,		/* Yamaha Corporation of America */	WAVE_FORMAT_SONARC				= 0x0021,		/* Speech Compression */	WAVE_FORMAT_DSPGROUP_TRUESPEECH = 0x0022,		/* DSP Group, Inc */	WAVE_FORMAT_ECHOSC1				= 0x0023,		/* Echo Speech Corporation */	WAVE_FORMAT_AUDIOFILE_AF18  	= 0x0024,		/* Audiofile, Inc. */	WAVE_FORMAT_APTX				= 0x0025,		/* Audio Processing Technology */	WAVE_FORMAT_AUDIOFILE_AF10  	= 0x0026,		/* Audiofile, Inc. */	WAVE_FORMAT_DOLBY_AC2			= 0x0030,		/* Dolby Laboratories */	WAVE_FORMAT_GSM610				= 0x0031,		/* Microsoft Corporation */	WAVE_FORMAT_MSNAUDIO			= 0x0032,		/* Microsoft Corporation */	WAVE_FORMAT_ANTEX_ADPCME		= 0x0033, 		/* Antex Electronics Corporation */	WAVE_FORMAT_CONTROL_RES_VQLPC	= 0x0034,		/* Control Resources Limited */	WAVE_FORMAT_DIGIREAL			= 0x0035,		/* DSP Solutions, Inc. */	WAVE_FORMAT_DIGIADPCM			= 0x0036,		/* DSP Solutions, Inc. */	WAVE_FORMAT_CONTROL_RES_CR10	= 0x0037,		/* Control Resources Limited */	WAVE_FORMAT_NMS_VBXADPCM		= 0x0038,		/* Natural MicroSystems */	WAVE_FORMAT_ROCKWELL_ADPCM		= 0x003B,		/* Rockwell International */	WAVE_FORMAT_ROCKWELL_DIGITALK	= 0x003C, 		/* Rockwell International */	WAVE_FORMAT_G721_ADPCM			= 0x0040,		/* Antex Electronics Corporation */	WAVE_FORMAT_MPEG				= 0x0050,		/* Microsoft Corporation */	WAVE_FORMAT_MPEGLAYER3			= 0x0055,		/* MPEG 3 Layer 1 */	IBM_FORMAT_MULAW				= 0x0101,		/* IBM mu-law format */	IBM_FORMAT_ALAW					= 0x0102,		/* IBM a-law format */	IBM_FORMAT_ADPCM				= 0x0103,		/* IBM AVC Adaptive Differential PCM format */	WAVE_FORMAT_CREATIVE_ADPCM		= 0x0200,		/* Creative Labs, Inc */	WAVE_FORMAT_FM_TOWNS_SND		= 0x0300,		/* Fujitsu Corp. */	WAVE_FORMAT_OLIGSM				= 0x1000,		/* Ing C. Olivetti & C., S.p.A. */	WAVE_FORMAT_OLIADPCM			= 0x1001,		/* Ing C. Olivetti & C., S.p.A. */	WAVE_FORMAT_OLICELP				= 0x1002,		/* Ing C. Olivetti & C., S.p.A. */	WAVE_FORMAT_OLISBC				= 0x1003,		/* Ing C. Olivetti & C., S.p.A. */	WAVE_FORMAT_OLIOPR				= 0x1004,		/* Ing C. Olivetti & C., S.p.A. */	WAVE_FORMAT_EXTENSIBLE			= 0xFFFE} ;#define	FACT_CHUNK_SIZE	sizeof (int)/*------------------------------------------------------------------------------ * Macros to handle big/little endian issues. */#define RIFF_MARKER	(MAKE_MARKER ('R', 'I', 'F', 'F')) #define WAVE_MARKER	(MAKE_MARKER ('W', 'A', 'V', 'E')) #define fmt_MARKER	(MAKE_MARKER ('f', 'm', 't', ' ')) #define data_MARKER	(MAKE_MARKER ('d', 'a', 't', 'a')) #define fact_MARKER	(MAKE_MARKER ('f', 'a', 'c', 't')) #define PEAK_MARKER	(MAKE_MARKER ('P', 'E', 'A', 'K')) #define cue_MARKER	(MAKE_MARKER ('c', 'u', 'e', ' ')) #define LIST_MARKER	(MAKE_MARKER ('L', 'I', 'S', 'T')) #define slnt_MARKER	(MAKE_MARKER ('s', 'l', 'n', 't')) #define wavl_MARKER	(MAKE_MARKER ('w', 'a', 'v', 'l')) #define INFO_MARKER	(MAKE_MARKER ('I', 'N', 'F', 'O')) #define plst_MARKER	(MAKE_MARKER ('p', 'l', 's', 't')) #define adtl_MARKER	(MAKE_MARKER ('a', 'd', 't', 'l')) #define labl_MARKER	(MAKE_MARKER ('l', 'a', 'b', 'l')) #define note_MARKER	(MAKE_MARKER ('n', 'o', 't', 'e')) #define smpl_MARKER	(MAKE_MARKER ('s', 'm', 'p', 'l')) #define bext_MARKER	(MAKE_MARKER ('b', 'e', 'x', 't')) #define MEXT_MARKER	(MAKE_MARKER ('M', 'E', 'X', 'T')) #define DISP_MARKER	(MAKE_MARKER ('D', 'I', 'S', 'P')) #define acid_MARKER	(MAKE_MARKER ('a', 'c', 'i', 'd')) #define PAD_MARKER	(MAKE_MARKER ('P', 'A', 'D', ' ')) enum {	HAVE_RIFF	= 0x01,	HAVE_WAVE	= 0x02,	HAVE_fmt	= 0x04,	HAVE_fact	= 0x08,	HAVE_PEAK	= 0x10,	HAVE_data	= 0x20} ;/*------------------------------------------------------------------------------ * Private static functions. */static int		wav_close	(SF_PRIVATE  *psf) ;static int		read_fmt_chunk	(SF_PRIVATE *psf, WAV_FMT *wav_fmt) ;static int		wav_write_header (SF_PRIVATE *psf) ;static int		wav_write_tailer (SF_PRIVATE *psf) ;static const 	char* wav_format_str (int k) ;/*------------------------------------------------------------------------------** Public functions.*/intwav_open_read	(SF_PRIVATE *psf){	WAV_FMT			wav_fmt ;	FACT_CHUNK		fact_chunk ;	unsigned int	dword, marker, RIFFsize ;	int				parsestage = 0, error, format = 0 ;	char			*cptr ;			/* Set position to start of file to begin reading header. */	psf_binheader_readf (psf, "p", 0) ;				psf->sf.seekable = SF_TRUE ;	while (1)	{	psf_binheader_readf (psf, "m", &marker) ;		switch (marker)		{	case RIFF_MARKER :					if (parsestage)						return SFE_WAV_NO_RIFF ;					psf_binheader_readf (psf, "l", &RIFFsize) ;										if (psf->filelength  < RIFFsize + 2 * sizeof (dword))					{	dword = psf->filelength - 2 * sizeof (dword);						psf_log_printf (psf, "RIFF : %d (should be %d)\n", RIFFsize, dword) ;						RIFFsize = dword ;						}					else						psf_log_printf (psf, "RIFF : %d\n", RIFFsize) ;					parsestage |= HAVE_RIFF ;					break ;								case WAVE_MARKER :					if ((parsestage & HAVE_RIFF) != HAVE_RIFF)						return SFE_WAV_NO_WAVE ;					psf_log_printf (psf, "WAVE\n") ;					parsestage |= HAVE_WAVE ;					break ;						case fmt_MARKER :					if ((parsestage & (HAVE_RIFF | HAVE_WAVE)) != (HAVE_RIFF | HAVE_WAVE))						return SFE_WAV_NO_FMT ;					if ((error = read_fmt_chunk (psf, &wav_fmt)))						return error ;											format     = wav_fmt.format ;					parsestage |= HAVE_fmt ;					break ;								case data_MARKER :					if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))						return SFE_WAV_NO_DATA ;										psf_binheader_readf (psf, "l", &(psf->datalength)) ;					psf->dataoffset = ftell (psf->file) ;										if (psf->filelength < psf->dataoffset + psf->datalength)					{	psf_log_printf (psf, "data : %d (should be %d)\n", psf->datalength, psf->filelength - psf->dataoffset) ;						psf->datalength = psf->filelength - psf->dataoffset ;						}					else						psf_log_printf (psf, "data : %d\n", psf->datalength) ;					if (format == WAVE_FORMAT_MS_ADPCM && psf->datalength % 2)					{	psf->datalength ++ ;						psf_log_printf (psf, "*** Data length odd. Increasing it by 1.\n") ;						} ;							parsestage |= HAVE_data ;					if (! psf->sf.seekable)						break ;										/* Seek past data and continue reading header. */					fseek (psf->file, psf->datalength, SEEK_CUR) ;					dword = ftell (psf->file) ;					if (dword != (off_t) (psf->dataoffset + psf->datalength))						psf_log_printf (psf, "*** fseek past end error ***\n", dword, psf->dataoffset + psf->datalength) ;					break ;			case fact_MARKER :					if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))						return SFE_WAV_BAD_FACT ;					psf_binheader_readf (psf, "ll", &dword, &(fact_chunk.samples)) ;										if (dword > sizeof (fact_chunk))						psf_binheader_readf (psf, "j", (int) (dword - sizeof (fact_chunk))) ;					psf_log_printf (psf, "%D : %d\n", marker, dword) ;					psf_log_printf (psf, "  samples : %d\n", fact_chunk.samples) ;					parsestage |= HAVE_fact ;					break ;			case PEAK_MARKER :					if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))						return SFE_WAV_PEAK_B4_FMT ;					psf_binheader_readf (psf, "l", &dword) ;										psf_log_printf (psf, "%D : %d\n", marker, dword) ;					if (dword > sizeof (psf->peak))					{	psf_binheader_readf (psf, "j", dword) ;						psf_log_printf (psf, "*** File PEAK chunk bigger than sizeof (PEAK_CHUNK).\n") ;						return SFE_WAV_BAD_PEAK ;						} ;					if (dword != sizeof (psf->peak) - sizeof (psf->peak.peak) + psf->sf.channels * sizeof (PEAK_POS))					{	psf_binheader_readf (psf, "j", dword) ;						psf_log_printf (psf, "*** File PEAK chunk size doesn't fit with number of channels.\n") ;						return SFE_WAV_BAD_PEAK ;						} ;										psf_binheader_readf (psf, "ll", &(psf->peak.version), &(psf->peak.timestamp)) ;					if (psf->peak.version != 1)						psf_log_printf (psf, "  version    : %d *** (should be version 1)\n", psf->peak.version) ;					else						psf_log_printf (psf, "  version    : %d\n", psf->peak.version) ;											psf_log_printf (psf, "  time stamp : %d\n", psf->peak.timestamp) ;					psf_log_printf (psf, "    Ch   Position       Value\n") ;					cptr = (char *) psf->buffer ;					for (dword = 0 ; dword < psf->sf.channels ; dword++)					{	psf_binheader_readf (psf, "fl", &(psf->peak.peak[dword].value), 														&(psf->peak.peak[dword].position)) ;											snprintf (cptr, sizeof (psf->buffer), "    %2d   %-12d   %g\n", 								dword, psf->peak.peak[dword].position, psf->peak.peak[dword].value) ;						cptr [sizeof (psf->buffer) - 1] = 0 ;						psf_log_printf (psf, cptr) ;						};					psf->has_peak = SF_TRUE ;					break ;			case cue_MARKER :			case LIST_MARKER :			case INFO_MARKER :			case smpl_MARKER :			case bext_MARKER :			case MEXT_MARKER :			case DISP_MARKER :			case acid_MARKER :			case PAD_MARKER :					psf_binheader_readf (psf, "l", &dword);					psf_log_printf (psf, "%D : %d\n", marker, dword) ;					psf_binheader_readf (psf, "j", dword) ;					break ;			default : 					if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)						&& isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))					{	psf_binheader_readf (psf, "l", &dword);						psf_log_printf (psf, "%D : %d (unknown marker)\n", marker, dword) ;						psf_binheader_readf (psf, "j", dword);

⌨️ 快捷键说明

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