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

📄 file.c

📁 使用在嵌入式linux平台或pc机上的wave文件录制和播放软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Header: /home/cvs/wavplay/file.c,v 1.2 1999/12/04 00:01:20 wwg Exp $ * Warren W. Gay VE3WWG		Sun Feb 16 20:43:59 1997 * * WAV FILE OPERATIONS: * * 	X LessTif WAV Play : *  * 	Copyright (C) 1997  Warren W. Gay VE3WWG *  * 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 version 2 of the License. *  * 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 (see enclosed file COPYING). *  * You  should have received a copy of the GNU General Public License along * with this  program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. *  * Send correspondance to: *  * 	Warren W. Gay VE3WWG *  * Email: *	ve3wwg@yahoo.com *	wgay@mackenziefinancial.com * * $Log: file.c,v $ * Revision 1.2  1999/12/04 00:01:20  wwg * Implement wavplay-1.4 release changes * * Revision 1.1.1.1  1999/11/21 19:50:56  wwg * Import wavplay-1.3 into CVS * * Revision 1.3  1997/04/22 00:37:56  wwg * Patched to update the RIFF block size, after patching * the data block size, when the xltwavplay client * terminates the recording session. This is a temp. fix * until a real RIFF block module is added to this suite. * * Revision 1.2  1997/04/14 00:49:07  wwg * Added ioctl(fd,SNDCTL_DSP_SYNC) calls * * Revision 1.1  1997/04/14 00:12:15  wwg * Initial revision * */static const char rcsid[] = "@(#)file.c $Revision: 1.2 $";#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>#include "wavplay.h"extern int clntIPC;    /* Needed for message passing in PlayDSP *//* Number of updates sent to the client per second during playback and *//* record.  For high sample rates in stereo, too many per second floods the *//* client.  3 is a compromise between update speed and smoothness; 4 tends *//* to cause "jumpy" updates.  (The cause of the jumps probably lie in *//* LessTif and/or X since the IPC messages are sent regularly). */#define RECPLAY_UPDATES_PER_SEC                3static ErrFunc v_erf;				/* 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;	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[] */}/* * 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;	}	/*	 * Put little endian value into 32 bit value:	 */	dbytes = ubuf[3];	dbytes = (dbytes << 8) | ubuf[2];	dbytes = (dbytes << 8) | ubuf[1];	dbytes = (dbytes << 8) | ubuf[0];	wfile->wavinfo.DataBytes = dbytes;	/*	 * Open succeeded:	 */	return wfile;				/* Return open descriptor */	/*	 * Return error after failed open:	 */errxit:	e = errno;				/* Save errno */	free(wfile->Pathname);			/* Dispose of copied pathname */	free(wfile);				/* Dispose of WAVFILE struct */	errno = e;				/* Restore error number */	return NULL;				/* Return error indication */}/* * Apply command line option overrides to the interpretation of the input * wav file: * */voidWavReadOverrides(WAVFILE *wfile,WavPlayOpts *wavopts) {	UInt32 num_samples;	/*	 * Override sampling rate: -s sampling_rate	 */	if ( wavopts->SamplingRate.optChar != 0 ) {		wfile->wavinfo.SamplingRate = wavopts->SamplingRate.optValue;		wfile->wavinfo.bOvrSampling = 1;	}	/*	 * Override mono/stereo mode: -S / -M	 */	if ( wavopts->Channels.optChar != 0 ) {		wfile->wavinfo.Channels = wavopts->Channels.optValue;		wfile->wavinfo.bOvrMode = 1;	}		/*	 * Override the sample size in bits: -b bits	 */	if ( wavopts->DataBits.optChar != 0 ) {		wfile->wavinfo.DataBits = wavopts->DataBits.optValue;		wfile->wavinfo.bOvrBits = 1;	}        /*         * Set the first sample:         */        wfile->StartSample = 0;        num_samples = wfile->wavinfo.Samples = wfile->num_samples;        if ( wavopts->StartSample != 0 ) {                wfile->StartSample = wavopts->StartSample;                wfile->wavinfo.Samples -= wfile->StartSample;        }         /*         * Override # of samples if -t seconds option given:         */        if ( wavopts->Seconds != 0 ) {                wfile->wavinfo.Samples = wavopts->Seconds * wfile->wavinfo.SamplingRate;                if (wfile->StartSample+wfile->wavinfo.Samples > num_samples)                        wfile->wavinfo.Samples = num_samples-1;        }}/* * Close a WAVFILE */intWavClose(WAVFILE *wfile,ErrFunc erf) {	int e = 0;				/* Returned error code */	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 */	long fpos;				/* File position in bytes */	v_erf = erf;				/* Set error reporting function */	if ( wfile == NULL ) {		err("%s: WAVFILE pointer is NULL!",sys_errlist[EINVAL]);		errno = EINVAL;		return -1;	}	/*	 * If the wav file was open for write, update the actual number	 * of samples written to the file:	 */	if ( wfile->rw == 'W' ) {		fpos = lseek(wfile->fd,0L,SEEK_CUR);	/* Get out file position */		if ( (e = WaveReadHeader(wfile->fd,&channels,&samplerate,&sample_bits,&samples,&datastart,_v_erf)) != 0 )			err("%s:\nReading WAV header from %s",emsg,wfile->Pathname);		else if ( lseek(wfile->fd,(long)(datastart-4),SEEK_SET) != (long)(datastart-4) )			err("%s:\nSeeking in WAV header file %s",sys_errlist[errno],wfile->Pathname);		else if ( write(wfile->fd,&wfile->wavinfo.Samples,sizeof wfile->wavinfo.Samples) != sizeof wfile->wavinfo.Samples )			err("%s:\nWriting in WAV header file %s",sys_errlist[errno],wfile->Pathname);		else	{			/*			 * 'data' chunk was updated OK: Now we have to update the RIFF block			 * count. Someday very soon, a real RIFF module is going to replace			 * this fudging.			 */			if ( ftruncate(wfile->fd,(size_t)fpos) )				err("%s:\nTruncating file %s to correct size",					sys_errlist[errno],					wfile->Pathname);			else if ( lseek(wfile->fd,4L,SEEK_SET) < 0L )				err("%s:\nSeek 4 for RIFF block update of %s",					sys_errlist[errno],					wfile->Pathname);			else	{				fpos -= 8;		/* Byte count for RIFF block */				if ( write(wfile->fd,&fpos,sizeof fpos) != sizeof fpos )					err("%s:\nUpdate of RIFF block count in %s failed",						sys_errlist[errno],						wfile->Pathname);			}		}	}	if ( close(wfile->fd) < 0 ) {		err("%s:\nClosing WAV file",sys_errlist[errno]);		e = errno;			/* Save errno value to return */	}	wavfile_free(wfile);			/* Release WAVFILE structure */	if ( (errno = e) != 0 )		return -1;			/* Failed exit */	return 0;				/* Successful exit */}/* * Open a WAV file for writing: */WAVFILE *WavOpenForWrite(const char *Pathname,Chan chmode,UInt32 sample_rate,UInt16 bits,UInt32 samples,ErrFunc erf) {	WAVFILE *wfile = wavfile_alloc(Pathname);	int e;					/* Saved errno value */	v_erf = erf;				/* Set error reporting function */	if ( wfile == NULL )		return NULL;			/* ENOMEM (class_b msg) */	wfile->rw = 'W';			/* Mark as for writing */	wfile->wavinfo.SamplingRate = sample_rate;	wfile->wavinfo.Channels = chmode;	/* Mono / Stereo */	wfile->wavinfo.Samples = samples;	wfile->wavinfo.DataBits = bits;		/*	 * Open/create the file for writing:	 */	if ( (wfile->fd = open(wfile->Pathname,O_RDWR|O_TRUNC|O_CREAT,0666)) < 0 ) {		err("%s:\nOpening %s for WAV writing",			sys_errlist[errno],			wfile->Pathname);		return NULL;			/* Open error */	}	/*	 * Write out a WAV file header:	 */	e = WaveWriteHeader(wfile->fd,		wfile->wavinfo.Channels == Mono ? 1 : 2,		wfile->wavinfo.SamplingRate,		wfile->wavinfo.DataBits,		wfile->wavinfo.Samples,		_v_erf);			/* Capture error messages to emsg[] */	if ( e != 0 ) {		wavfile_free(wfile);		err("%s:\nWriting WAV header to %s",			emsg,			wfile->Pathname);		return NULL;	}	/*	 * Return successfuly opened file:

⌨️ 快捷键说明

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