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

📄 pcm.c

📁 The Audio File Library provides a uniform programming interface to standard digital audio file form
💻 C
字号:
/*	Audio File Library	Copyright (C) 2000, Silicon Graphics, Inc.	This library is free software; you can redistribute it and/or	modify it under the terms of the GNU Library General Public	License as published by the Free Software Foundation; either	version 2 of the License, or (at your option) any later version.	This library 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	Library General Public License for more details.	You should have received a copy of the GNU Library General Public	License along with this library; if not, write to the	Free Software Foundation, Inc., 59 Temple Place - Suite 330,	Boston, MA  02111-1307  USA.*//*	pcm.c - read and file write module for uncompressed data*/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <errno.h>#include <assert.h>#include <string.h>#include <math.h>#include <audiofile.h>#include "afinternal.h"#include "compression.h"#include "modules.h"#include "util.h"#include "print.h"#ifdef DEBUG#define CHNK(X) (X)#else#define CHNK(X)#endifbool _af_pcm_format_ok (_AudioFormat *f){	assert(!isnan(f->pcm.slope));	assert(!isnan(f->pcm.intercept));	assert(!isnan(f->pcm.minClip));	assert(!isnan(f->pcm.maxClip));	return AF_TRUE;}/*	The pcm module does both reading and writing.*/static _AFmodule pcm;typedef struct pcm_data{	_Track *trk;	AFvirtualfile *fh;	bool seekok;	int bytes_per_frame;	/* saved_fpos_next_frame and saved_nextfframe apply only to writing. */	int saved_fpos_next_frame;	int saved_nextfframe;} pcm_data;_AFmoduleinst _AFpcminitcompress (_Track *trk, AFvirtualfile *fh, bool seekok,	bool headerless, AFframecount *chunkframes){	_AFmoduleinst ret = _AFnewmodinst(&pcm);	pcm_data *d;	d = (pcm_data *) _af_malloc(sizeof (pcm_data));	d->trk = trk;	d->fh = fh;	d->seekok = seekok;	d->bytes_per_frame = _af_format_frame_size(&trk->f, AF_FALSE);	d->trk->fpos_next_frame = d->trk->fpos_first_frame;	ret.modspec = d;	return ret;}static void pcmrun_push (_AFmoduleinst *i){	pcm_data *d = (pcm_data *) i->modspec;	AFframecount frames2write = i->inc->nframes;	AFframecount n;	/*		WARNING: due to the optimization explained at the end		of arrangemodules(), the pcm file module cannot depend		on the presence of the intermediate working buffer		which _AFsetupmodules usually allocates for file		modules in their input or output chunk (for reading or		writing, respectively).		Fortunately, the pcm module has no need for such a buffer.	*/	n = af_fwrite(i->inc->buf, d->bytes_per_frame, frames2write, d->fh);	CHNK(printf("writing %" AF_FRAMECOUNT_PRINT_FMT " frames to pcm file\n",		frames2write));	if (n != frames2write)	{		/* Report error if we haven't already. */		if (d->trk->filemodhappy)		{			/* I/O error */			if (n < 0)				_af_error(AF_BAD_WRITE,					"unable to write data (%s) -- "					"wrote %d out of %d frames",					strerror(errno),					d->trk->nextfframe + n,					d->trk->nextfframe + frames2write);			/* usual disk full error */			else				_af_error(AF_BAD_WRITE,					"unable to write data (disk full) -- "					"wrote %d out of %d frames",					d->trk->nextfframe + n,					d->trk->nextfframe + frames2write);			d->trk->filemodhappy = AF_FALSE;		}	}	d->trk->nextfframe += n;	d->trk->totalfframes = d->trk->nextfframe;	d->trk->fpos_next_frame += (n>0) ? n*d->bytes_per_frame : 0;	assert(!d->seekok || (af_ftell(d->fh) == d->trk->fpos_next_frame));}static void pcmsync1 (_AFmoduleinst *i){	pcm_data *d = (pcm_data *)i->modspec;	d->saved_fpos_next_frame = d->trk->fpos_next_frame;	d->saved_nextfframe = d->trk->nextfframe;}static void pcmsync2 (_AFmoduleinst *i){	pcm_data *d = (pcm_data *)i->modspec;	/* sanity check */	assert(!d->seekok || (af_ftell(d->fh) == d->trk->fpos_next_frame));	/* We can afford to do an lseek just in case cuz sync2 is rare. */	d->trk->fpos_after_data = af_ftell(d->fh);	d->trk->fpos_next_frame = d->saved_fpos_next_frame;	d->trk->nextfframe = d->saved_nextfframe;}_AFmoduleinst _AFpcminitdecompress (_Track *trk, AFvirtualfile *fh, bool seekok,	bool headerless, AFframecount *chunkframes){	_AFmoduleinst ret = _AFnewmodinst(&pcm);	pcm_data *d;	d = (pcm_data *) _af_malloc(sizeof (pcm_data));	d->trk = trk;	d->fh = fh;	d->seekok = seekok;	d->trk->f.compressionParams = AU_NULL_PVLIST;	d->bytes_per_frame = _af_format_frame_size(&trk->f, AF_FALSE);	ret.modspec = d;	return ret;}static void pcmrun_pull (_AFmoduleinst *i){	pcm_data *d = (pcm_data *) i->modspec;	AFframecount n, frames2read = i->outc->nframes;	/*		WARNING: Due to the optimization explained at the end of		arrangemodules(), the pcm file module cannot depend on		the presence of the intermediate working buffer which		_AFsetupmodules usually allocates for file modules in		their input or output chunk (for reading or writing,		respectively).		Fortunately, the pcm module has no need for such a buffer.	*/	/*		Limit the number of frames to be read to the number of		frames left in the track.	*/	if (d->trk->totalfframes != -1 &&		d->trk->nextfframe + frames2read > d->trk->totalfframes)	{		frames2read = d->trk->totalfframes - d->trk->nextfframe;	}	n = af_fread(i->outc->buf, d->bytes_per_frame, frames2read, d->fh);	CHNK(printf("reading %" AF_FRAMECOUNT_PRINT_FMT " frames from pcm file "		"(got %" AF_FRAMECOUNT_PRINT_FMT ")\n",		frames2read, n));	d->trk->nextfframe += n;	d->trk->fpos_next_frame += (n>0) ? n*d->bytes_per_frame : 0;	assert(!d->seekok || (af_ftell(d->fh) == d->trk->fpos_next_frame));	/*		If we got EOF from read, then we return the actual amount read.		Complain only if there should have been more frames in the file.	*/	if (n != frames2read && d->trk->totalfframes != -1)	{		/* Report error if we haven't already. */		if (d->trk->filemodhappy)		{			_af_error(AF_BAD_READ,				"file missing data -- read %d frames, "				"should be %d",				d->trk->nextfframe,				d->trk->totalfframes);			d->trk->filemodhappy = AF_FALSE;		}	}	i->outc->nframes = n;}static void pcmreset1 (_AFmoduleinst *i){#ifdef DONE	pcm_data *d = (pcm_data *) i->modspec;#endif	/* This function is supposed to be empty to fit into design. */}static void pcmreset2 (_AFmoduleinst *i){	pcm_data *d = (pcm_data *) i->modspec;	d->trk->fpos_next_frame = d->trk->fpos_first_frame +		d->bytes_per_frame * d->trk->nextfframe;	d->trk->frames2ignore = 0;}static _AFmodule pcm ={	"pcm",	AF_NULL,	AF_NULL, AF_NULL,	pcmrun_pull, pcmreset1, pcmreset2,	pcmrun_push, pcmsync1, pcmsync2,	AF_NULL,	_AFfreemodspec};

⌨️ 快捷键说明

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