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

📄 wavfile.c

📁 qgo-1.5.4-r3.tar.gz linux下一个很好玩的游戏
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Header: /cvsroot/qgo/qgo/src/wavfile.c,v 1.8 2005/09/08 18:46:31 yfh2 Exp $ * Copyright: wavfile.c (c) Erik de Castro Lopo  erikd@zip.com.au * * wavfile.c - Functions for reading and writing MS-Windoze .WAV files. * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License as published by *	the Free Software Foundation; either version 2, 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 General Public License for more details. *	 *	This code was originally written to manipulate Windoze .WAV files *	under i386 Linux. Please send any bug reports or requests for  *	enhancements to : erikd@zip.com.au *	 * * Revision 1.4  2004/05/26 17:44:05  yfh2 * 0.2.1 b1 preparing BSD compatibiility * * Revision 1.3  2003/04/14 07:41:49  frosla * 0.0.16b8: skipped some widget; cosmetics * * Revision 1.1.1.1  1999/11/21 19:50:56  wwg * Import wavplay-1.3 into CVS * * Revision 1.2  1997/04/17 00:59:55  wwg * Fixed so that a fmt chunk that is larger than expected * is accepted, but if smaller - _then_ treat it as an * error. * * Revision 1.1  1997/04/14 00:14:38  wwg * Initial revision * *	change log: *	16.02.97 -	Erik de Castro Lopo		 *	Ported from MS-Windows to Linux for Warren W. Gay's *	wavplay project. */	#ifdef __linux__static const char rcsid[] = "@(#)wavfile.c $Revision: 1.8 $";#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <malloc.h>#include <string.h>#include <memory.h>#include <signal.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/ioctl.h>#include <assert.h>#include <linux/soundcard.h>#if WORDS_BIGENDIAN#define SwapLE16(x) ((((u_int16_t)x)<<8)|(((u_int16_t)x)>>8))#define SwapLE32(x) ((((u_int32_t)x)<<24)|((((u_int32_t)x)<<8)&0x00FF0000) \                     |((((u_int32_t)x)>>8)&0x0000FF00)|(((u_int32_t)x)>>24))#else#define SwapLE16(x) (x)#define SwapLE32(x) (x)#endif#include "wavplay.h"#define		BUFFERSIZE   		1024#define		PCM_WAVE_FORMAT   	1#define		TRUE			1#define		FALSE			0#define RECPLAY_UPDATES_PER_SEC                3typedef  struct{	u_int32_t  dwSize ;	u_int16_t  wFormatTag ;	u_int16_t  wChannels ;	u_int32_t  dwSamplesPerSec ;	u_int32_t  dwAvgBytesPerSec ;	u_int16_t  wBlockAlign ;	u_int16_t  wBitsPerSample ;} WAVEFORMAT ;typedef  struct{	char    	RiffID [4] ;	u_int32_t 	RiffSize ;	char    	WaveID [4] ;	char    	FmtID  [4] ;	u_int32_t  	FmtSize ;	u_int16_t 	wFormatTag ;	u_int16_t  	nChannels ;	u_int32_t	nSamplesPerSec ;	u_int32_t	nAvgBytesPerSec ;	u_int16_t	nBlockAlign ;	u_int16_t	wBitsPerSample ;	char		DataID [4] ;	u_int32_t	nDataBytes ;} WAVE_HEADER ;/*=================================================================================================*/char*  findchunk (char* s1, char* s2, size_t n) ;/*=================================================================================================*/static  WAVE_HEADER  waveheader ={	{ 'R', 'I', 'F', 'F' },		0,	{ 'W', 'A', 'V', 'E' },	{ 'f', 'm', 't', ' ' },		16,								/* FmtSize*/		PCM_WAVE_FORMAT,						/* wFormatTag*/		0,								/* nChannels*/		0,		0,		0,		0,	{ 'd', 'a', 't', 'a' },		0} ; /* waveheader*/static ErrFunc v_erf;				/* wwg: Error reporting function */static void _v_erf(const char *, va_list);	/* This module's error reporting function */static char emsg[2048];/* * Error reporting function for this source module: */static voiderr(const char *format,...) {	va_list ap;   fprintf(stdout, "error : %s \n",format);	/*/if ( v_erf == NULL )*/	/*/	return;				/* Only report error if we have function */	va_start(ap,format);	_v_erf(format,ap);			/* Use caller's supplied function */	va_end(ap);}static void_v_erf(const char *format,va_list ap) {	vsprintf(emsg,format,ap);		/* Capture message into emsg[] */}int  WaveReadHeader  (int wavefile, int* channels, u_long* samplerate, int* samplebits, u_long* samples, u_long* datastart,ErrFunc erf){	static  WAVEFORMAT  waveformat ;	static	char   buffer [ BUFFERSIZE ] ;		/* Function is not reentrant.*/	char*   ptr ;	u_long  databytes ;	v_erf = erf;					/* wwg: Set error reporting function */	if (lseek (wavefile, 0L, SEEK_SET)) {		err("%s",sys_errlist[errno]);		/* wwg: Report error */		return  WR_BADSEEK ;	}	read (wavefile, buffer, BUFFERSIZE) ;	if (findchunk (buffer, "RIFF", BUFFERSIZE) != buffer) {		err("Bad format: Cannot find RIFF file marker");	/* wwg: Report error */		return  WR_BADRIFF ;	}	if (! findchunk (buffer, "WAVE", BUFFERSIZE)) {		err("Bad format: Cannot find WAVE file marker");	/* wwg: report error */		return  WR_BADWAVE ;	}	ptr = findchunk (buffer, "fmt ", BUFFERSIZE) ;	if (! ptr) {		err("Bad format: Cannot find 'fmt' file marker");	/* wwg: report error */		return  WR_BADFORMAT ;	}	ptr += 4 ;	/* Move past "fmt ".*/	memcpy (&waveformat, ptr, sizeof (WAVEFORMAT)) ;	waveformat.dwSize = SwapLE32(waveformat.dwSize);	waveformat.wFormatTag = SwapLE16(waveformat.wFormatTag) ;	waveformat.wChannels = SwapLE16(waveformat.wChannels) ;	waveformat.dwSamplesPerSec = SwapLE32(waveformat.dwSamplesPerSec) ;	waveformat.dwAvgBytesPerSec = SwapLE32(waveformat.dwAvgBytesPerSec) ;	waveformat.wBlockAlign = SwapLE16(waveformat.wBlockAlign) ;	waveformat.wBitsPerSample = SwapLE16(waveformat.wBitsPerSample) ;		if (waveformat.dwSize < (sizeof (WAVEFORMAT) - sizeof (u_long))) {		err("Bad format: Bad fmt size");			/* wwg: report error */		return  WR_BADFORMATSIZE ;	}	if (waveformat.wFormatTag != PCM_WAVE_FORMAT) {		err("Only supports PCM wave format");			/* wwg: report error */		return  WR_NOTPCMFORMAT ;	}	ptr = findchunk (buffer, "data", BUFFERSIZE) ;	if (! ptr) {		err("Bad format: unable to find 'data' file marker");	/* wwg: report error */		return  WR_NODATACHUNK ;	}	ptr += 4 ;	/* Move past "data".*/	memcpy (&databytes, ptr, sizeof (u_long)) ;	/* Everything is now cool, so fill in output data.*/	*channels   = waveformat.wChannels ;	*samplerate = waveformat.dwSamplesPerSec ;	*samplebits = waveformat.wBitsPerSample ;	*samples    = databytes / waveformat.wBlockAlign ;		*datastart  = ((u_long) (ptr + 4)) - ((u_long) (&(buffer[0]))) ;	if (waveformat.dwSamplesPerSec != waveformat.dwAvgBytesPerSec / waveformat.wBlockAlign) {		err("Bad file format");			/* wwg: report error */		return  WR_BADFORMATDATA ;	}	if (waveformat.dwSamplesPerSec != waveformat.dwAvgBytesPerSec / waveformat.wChannels / ((waveformat.wBitsPerSample == 16) ? 2 : 1)) {		err("Bad file format");			/* wwg: report error */		return  WR_BADFORMATDATA ;	}  return  0 ;} ; /* WaveReadHeader*//*===========================================================================================*/#if 0char*  WaveFileError (int  errno){	switch (errno)	{	case	WW_BADOUTPUTFILE	: return "Bad output file.\n" ;		case	WW_BADWRITEHEADER 	: return "Not able to write WAV header.\n" ;				case	WR_BADALLOC			: return "Not able to allocate memory.\n" ;		case	WR_BADSEEK        	: return "fseek failed.\n" ;		case	WR_BADRIFF        	: return "Not able to find 'RIFF' file marker.\n" ;		case	WR_BADWAVE        	: return "Not able to find 'WAVE' file marker.\n" ;		case	WR_BADFORMAT      	: return "Not able to find 'fmt ' file marker.\n" ;		case	WR_BADFORMATSIZE  	: return "Format size incorrect.\n" ;		case	WR_NOTPCMFORMAT		: return "Not PCM format WAV file.\n" ;		case	WR_NODATACHUNK		: return "Not able to find 'data' file marker.\n" ;		case	WR_BADFORMATDATA	: return "Format data questionable.\n" ;		default           			:  return "No error\n" ;	} ;	return	NULL ;	} ; /* WaveFileError*/#endif/*===========================================================================================*/char* findchunk  (char* pstart, char* fourcc, size_t n){	char	*pend ;	int		k, test ;	pend = pstart + n ;	while (pstart < pend)	{ 	if (*pstart == *fourcc)       /* found match for first char*/		{	test = TRUE ;			for (k = 1 ; fourcc [k] != 0 ; k++)				test = (test ? ( pstart [k] == fourcc [k] ) : FALSE) ;			if (test)				return  pstart ;			} ; /* if*/		pstart ++ ;		} ; /* while lpstart*/	return  NULL ;} ; /* findchuck*//* $Source: /cvsroot/qgo/qgo/src/wavfile.c,v $ *//* * Internal routine to allocate WAVFILE structure: */static WAVFILE *wavfile_alloc(const char *Pathname) {	WAVFILE *wfile = (WAVFILE *) malloc(sizeof (WAVFILE));	if ( wfile == NULL ) {		err("%s: Allocating WAVFILE structure",sys_errlist[ENOMEM]);		return NULL;	}	memset(wfile,0,sizeof *wfile);	if ( (wfile->Pathname = strdup(Pathname)) == NULL ) {		free(wfile);		err("%s: Allocating storage for WAVFILE.Pathname",sys_errlist[ENOMEM]);		return NULL;	}	wfile->fd = -1;				/* Initialize fd as not open */	wfile->wavinfo.Channels = Mono;	wfile->wavinfo.DataBits = 8;	return wfile;}/* * Internal routine to release WAVFILE structure: * No errors reported. */static voidwavfile_free(WAVFILE *wfile) {	if ( wfile->Pathname != NULL )		free(wfile->Pathname);	free(wfile);}/* * Open a WAV file for reading: returns (WAVFILE *) * * The opened file is positioned at the first byte of WAV file data, or * NULL is returned if the open is unsuccessful. */WAVFILE *WavOpenForRead(const char *Pathname,ErrFunc erf) {	WAVFILE *wfile = wavfile_alloc(Pathname);	int e;					/* Saved errno value */	UInt32 offset;				/* File offset */	Byte ubuf[4];				/* 4 byte buffer */	UInt32 dbytes;				/* Data byte count */						/* wavfile.c values : */	int channels;				/* Channels recorded in this wav file */	u_long samplerate;			/* Sampling rate */	int sample_bits;			/* data bit size (8/12/16) */	u_long samples;				/* The number of samples in this file */	u_long datastart;			/* The offset to the wav data */	v_erf = erf;				/* Set error reporting function */	if ( wfile == NULL )		return NULL;			/* Insufficient memory (class B msg) */	/*	 * Open the file for reading:	 */	if ( (wfile->fd = open(wfile->Pathname,O_RDONLY)) < 0 ) {		err("%s:\nOpening WAV file %s",			sys_errlist[errno],			wfile->Pathname);		goto errxit;	}	if ( lseek(wfile->fd,0L,SEEK_SET) != 0L ) {		err("%s:\nRewinding WAV file %s",			sys_errlist[errno],			wfile->Pathname);		goto errxit;		/* Wav file must be seekable device */	}	if ( (e = WaveReadHeader(wfile->fd,&channels,&samplerate,&sample_bits,&samples,&datastart,_v_erf)) != 0 ) {		err("%s:\nReading WAV header from %s",			emsg,			wfile->Pathname);		goto errxit;	}	/*	 * Copy WAV data over to WAVFILE struct:	 */	if ( channels == 2 )		wfile->wavinfo.Channels = Stereo;	else	wfile->wavinfo.Channels = Mono;	wfile->wavinfo.SamplingRate = (UInt32) samplerate;	wfile->wavinfo.Samples = (UInt32) samples;	wfile->wavinfo.DataBits = (UInt16) sample_bits;	wfile->wavinfo.DataStart = (UInt32) datastart;        wfile->num_samples = wfile->wavinfo.Samples;	wfile->rw = 'R';			/* Read mode */	offset = wfile->wavinfo.DataStart - 4;	/*	 * Seek to byte count and read dbytes:	 */	if ( lseek(wfile->fd,offset,SEEK_SET) != offset ) {		err("%s:\nSeeking to WAV data in %s",sys_errlist[errno],wfile->Pathname);		goto errxit;			/* Seek failure */	}	if ( read(wfile->fd,ubuf,4) != 4 ) {		err("%s:\nReading dbytes from %s",sys_errlist[errno],wfile->Pathname);		goto errxit;	}

⌨️ 快捷键说明

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