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

📄 paf.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 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.*/#include "config.h"#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <string.h>#include <ctype.h>#include "sndfile.h"#include "sfendian.h"#include "float_cast.h"#include "common.h"/*------------------------------------------------------------------------------** Macros to handle big/little endian issues.*/#define FAP_MARKER	(MAKE_MARKER ('f', 'a', 'p', ' '))#define PAF_MARKER	(MAKE_MARKER (' ', 'p', 'a', 'f'))/*------------------------------------------------------------------------------** Other defines.*/#define	PAF_HEADER_LENGTH 			2048#define	PAF24_SAMPLES_PER_BLOCK		10#define	PAF24_BLOCK_SIZE			32/*------------------------------------------------------------------------------** Typedefs.*/typedef	struct{	int	version ;	int	endianness ;    int	samplerate ;    int	format ;	int	channels ;	int	source ;} PAF_FMT ;typedef struct{	int				max_blocks, channels, samplesperblock, blocksize ;	int				read_block, write_block, read_count, write_count ;	sf_count_t		sample_count ;	int				*samples ;	unsigned char	*block ;#if HAVE_FLEXIBLE_ARRAY	int				data [] ; /* ISO C99 struct flexible array. */#else	int				data [1] ; /* This is a hack and may not work. */#endif} PAF24_PRIVATE ;/*------------------------------------------------------------------------------** Private static functions.*/static int paf24_init (SF_PRIVATE *psf) ;static int	paf_read_header	(SF_PRIVATE *psf) ;static int	paf_write_header (SF_PRIVATE *psf, int calc_length) ;static sf_count_t paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t paf24_write_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;static sf_count_t paf24_write_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;static sf_count_t paf24_write_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;static sf_count_t paf24_write_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;static sf_count_t paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;enum{	PAF_PCM_16 = 0,	PAF_PCM_24 = 1,	PAF_PCM_S8 = 2} ;/*------------------------------------------------------------------------------** Public function.*/intpaf_open	(SF_PRIVATE *psf){	int		subformat, error, endian ; 	psf->dataoffset = PAF_HEADER_LENGTH ;	if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))	{	if ((error = paf_read_header (psf)))			return error ;		} ;	subformat = psf->sf.format & SF_FORMAT_SUBMASK ;	if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)	{	if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_PAF)			return	SFE_BAD_OPEN_FORMAT ;		endian = psf->sf.format & SF_FORMAT_ENDMASK ;		/* PAF is by default big endian. */		psf->endian = SF_ENDIAN_BIG ;		if (endian == SF_ENDIAN_LITTLE || (CPU_IS_LITTLE_ENDIAN && (endian == SF_ENDIAN_CPU)))			psf->endian = SF_ENDIAN_LITTLE ;		if ((error = paf_write_header (psf, SF_FALSE)))			return error ;		psf->write_header = paf_write_header ;		} ;	switch (subformat)	{	case SF_FORMAT_PCM_S8 :					psf->bytewidth = 1 ;					error = pcm_init (psf) ;					break ;		case SF_FORMAT_PCM_16 :					psf->bytewidth = 2 ;					error = pcm_init (psf) ;					break ;		case SF_FORMAT_PCM_24 :					/* No bytewidth because of whacky 24 bit encoding. */					error = paf24_init (psf) ;					break ;		default : return SFE_PAF_UNKNOWN_FORMAT ;		} ;	return error ;} /* paf_open *//*------------------------------------------------------------------------------*/static intpaf_read_header	(SF_PRIVATE *psf){	PAF_FMT		paf_fmt ;	int			marker ;	psf_binheader_readf (psf, "pm", 0, &marker) ;	psf_log_printf (psf, "Signature   : '%M'\n", marker) ;	if (marker == PAF_MARKER)	{	psf_binheader_readf (psf, "E444444", &(paf_fmt.version), &(paf_fmt.endianness),			&(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ;		}	else if (marker == FAP_MARKER)	{	psf_binheader_readf (psf, "e444444", &(paf_fmt.version), &(paf_fmt.endianness),			&(paf_fmt.samplerate), &(paf_fmt.format), &(paf_fmt.channels), &(paf_fmt.source)) ;		}	else		return SFE_PAF_NO_MARKER ;	psf_log_printf (psf, "Version     : %d\n", paf_fmt.version) ;	if (paf_fmt.version != 0)	{	psf_log_printf (psf, "*** Bad version number. should be zero.\n") ;		return SFE_PAF_VERSION ;		} ;	psf_log_printf (psf, "Sample Rate : %d\n", paf_fmt.samplerate) ;	psf_log_printf (psf, "Channels    : %d\n", paf_fmt.channels) ;	psf_log_printf (psf, "Endianness  : %d => ", paf_fmt.endianness) ;	if (paf_fmt.endianness)	{	psf_log_printf (psf, "Little\n", paf_fmt.endianness) ;		psf->endian = SF_ENDIAN_LITTLE ;		}	else	{	psf_log_printf (psf, "Big\n", paf_fmt.endianness) ;		psf->endian = SF_ENDIAN_BIG ;		} ;	if (psf->filelength < PAF_HEADER_LENGTH)		return SFE_PAF_SHORT_HEADER ;	psf->datalength = psf->filelength - psf->dataoffset ;	psf_binheader_readf (psf, "p", (int) psf->dataoffset) ;	psf->sf.samplerate	= paf_fmt.samplerate ;	psf->sf.channels 	= paf_fmt.channels ;	/* Only fill in type major. */	psf->sf.format = SF_FORMAT_PAF ;	psf_log_printf (psf, "Format      : %d => ", paf_fmt.format) ;	/* PAF is by default big endian. */	psf->sf.format |= paf_fmt.endianness ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;	switch (paf_fmt.format)	{	case PAF_PCM_S8 :					psf_log_printf (psf, "8 bit linear PCM\n") ;					psf->bytewidth = 1 ;					psf->sf.format |= SF_FORMAT_PCM_S8 ;					psf->blockwidth = psf->bytewidth * psf->sf.channels ;					psf->sf.frames = psf->datalength / psf->blockwidth ;					break ;		case PAF_PCM_16 :					psf_log_printf (psf, "16 bit linear PCM\n") ;					psf->bytewidth = 2 ;					psf->sf.format |= SF_FORMAT_PCM_16 ;					psf->blockwidth = psf->bytewidth * psf->sf.channels ;					psf->sf.frames = psf->datalength / psf->blockwidth ;					break ;		case PAF_PCM_24 :					psf_log_printf (psf, "24 bit linear PCM\n") ;					psf->bytewidth = 3 ;					psf->sf.format |= SF_FORMAT_PCM_24 ;					psf->blockwidth = 0 ;					psf->sf.frames = PAF24_SAMPLES_PER_BLOCK * psf->datalength /											(PAF24_BLOCK_SIZE * psf->sf.channels) ;					break ;		default :	psf_log_printf (psf, "Unknown\n") ;					return SFE_PAF_UNKNOWN_FORMAT ;					break ;		} ;	psf_log_printf (psf, "Source      : %d => ", paf_fmt.source) ;	switch (paf_fmt.source)	{	case 1 : psf_log_printf (psf, "Analog Recording\n") ;					break ;		case 2 : psf_log_printf (psf, "Digital Transfer\n") ;					break ;		case 3 : psf_log_printf (psf, "Multi-track Mixdown\n") ;					break ;		case 5 : psf_log_printf (psf, "Audio Resulting From DSP Processing\n") ;					break ;		default : psf_log_printf (psf, "Unknown\n") ;					break ;		} ;	return 0 ;} /* paf_read_header */static intpaf_write_header (SF_PRIVATE *psf, int calc_length){	int			paf_format ;	/* PAF header already written so no need to re-write. */	if (psf_ftell (psf) >= PAF_HEADER_LENGTH)		return 0 ;	psf->dataoffset = PAF_HEADER_LENGTH ;	psf->dataoffset = PAF_HEADER_LENGTH ;	/* Prevent compiler warning. */	calc_length = calc_length ;	switch (psf->sf.format & SF_FORMAT_SUBMASK)	{	case SF_FORMAT_PCM_S8 :					paf_format = PAF_PCM_S8 ;					break ;		case SF_FORMAT_PCM_16 :					paf_format = PAF_PCM_16 ;					break ;		case SF_FORMAT_PCM_24 :					paf_format = PAF_PCM_24 ;					break ;		default : return SFE_PAF_UNKNOWN_FORMAT ;		} ;	/* Reset the current header length to zero. */	psf->header [0] = 0 ;	psf->headindex = 0 ;	if (psf->endian == SF_ENDIAN_BIG)	{	/* Marker, version, endianness, samplerate */		psf_binheader_writef (psf, "Em444", PAF_MARKER, 0, 0, psf->sf.samplerate) ;		/* format, channels, source */		psf_binheader_writef (psf, "E444", paf_format, psf->sf.channels, 0) ;		}	else if (psf->endian == SF_ENDIAN_LITTLE)	{	/* Marker, version, endianness, samplerate */		psf_binheader_writef (psf, "em444", FAP_MARKER, 0, 1, psf->sf.samplerate) ;		/* format, channels, source */		psf_binheader_writef (psf, "e444", paf_format, psf->sf.channels, 0) ;		} ;	/* Zero fill to dataoffset. */	psf_binheader_writef (psf, "z", (size_t) (psf->dataoffset - psf->headindex)) ;	psf_fwrite (psf->header, psf->headindex, 1, psf) ;	return psf->error ;} /* paf_write_header *//*===============================================================================**	24 bit PAF files have a really weird encoding.**  For a mono file, 10 samples (each being 3 bytes) are packed into a 32 byte**	block. The 8 ints in this 32 byte block are then endian swapped (as ints)**	if necessary before being written to disk.**  For a stereo file, blocks of 10 samples from the same channel are encoded**  into 32 bytes as for the mono case. The 32 byte blocks are then interleaved**	on disk.**	Reading has to reverse the above process :-).**	Weird!!!****	The code below attempts to gain efficiency while maintaining readability.*/static int paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ;static int paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24) ;static int paf24_close (SF_PRIVATE *psf) ;static intpaf24_init (SF_PRIVATE *psf){	PAF24_PRIVATE	*ppaf24 ;	int	paf24size, max_blocks ;	paf24size = sizeof (PAF24_PRIVATE) + psf->sf.channels *					(PAF24_BLOCK_SIZE + PAF24_SAMPLES_PER_BLOCK * sizeof (int)) ;	/*	**	Not exatly sure why this needs to be here but the tests	**	fail without it.	*/	psf->last_op = 0 ;	if (! (psf->fdata = malloc (paf24size)))		return SFE_MALLOC_FAILED ;	ppaf24 = (PAF24_PRIVATE*) psf->fdata ;	memset (ppaf24, 0, paf24size) ;	ppaf24->channels	= psf->sf.channels ;	ppaf24->samples		= ppaf24->data ;	ppaf24->block		= (unsigned char*) (ppaf24->data + PAF24_SAMPLES_PER_BLOCK * ppaf24->channels) ;	ppaf24->blocksize = PAF24_BLOCK_SIZE * ppaf24->channels ;	ppaf24->samplesperblock = PAF24_SAMPLES_PER_BLOCK ;	if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)	{	paf24_read_block (psf, ppaf24) ;	/* Read first block. */		psf->read_short		= paf24_read_s ;		psf->read_int		= paf24_read_i ;		psf->read_float		= paf24_read_f ;		psf->read_double	= paf24_read_d ;		} ;	if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)	{	psf->write_short	= paf24_write_s ;		psf->write_int		= paf24_write_i ;		psf->write_float	= paf24_write_f ;		psf->write_double	= paf24_write_d ;		} ;	psf->seek	= paf24_seek ;	psf->close	= paf24_close ;	psf->filelength = psf_get_filelen (psf) ;	psf->datalength = psf->filelength - psf->dataoffset ;	if (psf->datalength % PAF24_BLOCK_SIZE)	{	if (psf->mode == SFM_READ)			psf_log_printf (psf, "*** Warning : file seems to be truncated.\n") ;		max_blocks = psf->datalength / ppaf24->blocksize + 1 ;		}	else		max_blocks = psf->datalength / ppaf24->blocksize ;	ppaf24->read_block = 0 ;	if (psf->mode == SFM_RDWR)		ppaf24->write_block = max_blocks ;	else		ppaf24->write_block = 0 ;	psf->sf.frames = ppaf24->samplesperblock * max_blocks ;	ppaf24->sample_count = psf->sf.frames ;	return 0 ;} /* paf24_init */static sf_count_tpaf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset){	PAF24_PRIVATE	*ppaf24 ;	int				newblock, newsample ;	if (psf->fdata == NULL)	{	psf->error = SFE_INTERNAL ;

⌨️ 快捷键说明

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