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

📄 wavpack.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
/* LINTLIBRARY */#ifndef lint    static char copyright[]="***************************************************************************\n\	Copyright (C) 1992 Massachusetts Institute of Technology. \n\			All rights reserved \n\***************************************************************************\n";#endif/* * This software is being provided to you, the LICENSEE, by the Massachusetts * Institute of Technology (M.I.T.) under the following license.  By * obtaining, using and/or copying this software, you agree that you have * read, understood, and will comply with these terms and conditions:   *   * Permission to use, copy, modify and distribute, including the right to * grant others the right to distribute at any tier, this software and its * documentation for any purpose and without fee or royalty is hereby granted, * provided that you agree to comply with the following copyright notice and * statements, including the disclaimer, and that the same appear on ALL * copies of the software and documentation, including modifications that you * make for internal use or for distribution: * * Copyright 1992 by the Massachusetts Institute of Technology.  All rights * reserved.  * * THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS OR * WARRANTIES, EXPRESS OR IMPLIED.  By way of example, but not limitation, * M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS * FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE OR * DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, * TRADEMARKS OR OTHER RIGHTS.    *   * The name of the Massachusetts Institute of Technology or M.I.T. may NOT be * used in advertising or publicity pertaining to distribution of the * software.  Title to copyright in this software and any associated * documentation shall at all times remain with M.I.T., and USER agrees to * preserve same.  */#ifndef lint    static char rcsid[] = "$Header: /home/beldar/stan/sphere/RCS/wavpack.c,v 1.10 1993/03/25 00:20:51 stan Exp stan $";#endif/* wavpack: machine indpendent waveform packing routine * assumes only that data is organized in bytes * tries a number of strategies: includes mono/stereo, byte/short, data * lossless (bit preserving) for any kind of input data */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sp/wavpack/wavpack.h>static char magic[] = WAVPACK_MAGIC;	/* magic string to identify wavpack files */static int strat[]=		/* strategy info */{	BYTE,				/* 0 */	BYTE|DIFF,			/* 1 */	BYTE|STEREO,			/* 2 */	BYTE|DIFF|STEREO,		/* 3 */	SHORT,				/* 4 */	SHORT|REV,			/* 5 */	SHORT|DIFF,			/* 6 */	SHORT|REV|DIFF,			/* 7 */	SHORT|OFFSET,			/* 8 */	SHORT|OFFSET|REV,		/* 9 */	SHORT|OFFSET|DIFF,		/* 10 */	SHORT|OFFSET|REV|DIFF,		/* 11 */	SHORT|STEREO,			/* 12 */	SHORT|REV|STEREO,		/* 13 */	SHORT|DIFF|STEREO,		/* 14 */	SHORT|REV|DIFF|STEREO,		/* 15 */	SHORT|OFFSET|STEREO,		/* 16 */	SHORT|OFFSET|REV|STEREO,	/* 17 */	SHORT|OFFSET|DIFF|STEREO,	/* 18 */	SHORT|OFFSET|REV|DIFF|STEREO,	/* 19 */	-1};static int nstrat;struct hdr			/* compressed data header */{	unsigned char flags;		/* strategy and channel info */	unsigned char count;		/* nr samples -1 */	unsigned char nbits;		/* nr pcm bits */	unsigned char offset_byte;	/* (opt) offst byte */	unsigned short dbase;		/* (opt) diff base, byte/short */	unsigned short pbase;		/* (opt) pcm base, byte/short */};static struct strat_eval	/* strat evaluation with sample hdrs */{	struct hdr hdr;	int nsam;	/* samples available (from condition_data) */	int min, max;	/* min and max of data */	int range;	/* range of data */	int count;	/* nr samples */	int obytes;	/* total output bytes (including header) */	int ibytes;	/* input bytes consumed */	float obpib;	/* output bytes per input byte */	int chan_1;	/* if chan0, stereo pair (chan1) */} strat_eval[256];	/* address microcoded through strat[] */static struct strat_eval f0b[RUNL+1],f1b[RUNL+1];	/* for mixed strat stereo */static struct strat_eval f0s[RUNL+1],f1s[RUNL+1];			static struct strat_eval f0so[RUNL+1],f1so[RUNL+1];			static float bm,b0b,b1b,b0s,b1s,b0so,b1so;		/* bests for pruning */static unsigned char input[4*RUNL+5];		/* raw input */static int ninput;					/* input channels for strategies */static unsigned short chan_0[RUNL];		/* byte/short chan 0 */static unsigned short chan_1[RUNL];		/* byte/short chan 1 */static int vflg=0;		/* verbosity */static int monoflg = 0;		/* mono data only */static int byteflg = 0;		/* byte data only */static int sflg= -1;static int runl=128;		/* max run length */static char *progname = (char *) NULL;static char *oname = (char *) NULL;static int oflg = 0;		/* if non-zero, unlink(oname) on error */static int pwr2[17]={1,2,4,8,16,32,64,128,256,	512,1024,2048,4096,8192,16384,32678,65536};#define mod(x) ((x)&bitmask)/* #define maxm(x,y) ((x)>(y)?(x):(y)) */#define perr(s)			wavpack_perr(s)int wavpack_set_monoflg(){	monoflg = 1;}int wavpack_get_monoflg(){	return monoflg;}int wavpack_set_byteflg(){	byteflg = 1;}int wavpack_get_byteflg(){	return byteflg;}int wavpack_set_vflg( value )	int value;{	vflg = value;}int wavpack_set_oname( s )	char * s;{	if ( oname != (char *) NULL )		free( oname );	oname = strdup( s );	return (oname == (char *) NULL) ? -1 : 0;}int wavpack_set_oflg( value )	int value;{	oflg = value;}int wavpack_set_progname( s )	char * s;{	if ( progname != (char *) NULL )		free( progname );	progname = strdup( s );	return ( progname == (char *) NULL ) ? -1 : 0;}int wavpack_get_nstrat(){	int n;	for ( n=0; strat[n] >= 0; n++ ) ;	return n;}#ifdef fread#	undef fread#endif#define fread(a,b,c,d)		fob_fread((a),(b),(c),(d))#ifdef fwrite#	undef fwrite#endif#define fwrite(a,b,c,d)		fob_fwrite((a),(b),(c),(d))#ifdef ferror#	undef ferror#endif#define ferror(a)		fob_ferror((a))wavpack_pack(ifile,ofile)FILE *ifile, *ofile;{	register i,j,k,n;	int m,eof,ibytes,obytes,inbytes,flags;	int hist[256];	float obpib,x,*bp;	nstrat = wavpack_get_nstrat();								/* magic */	if(fwrite(magic,strlen(magic)+1,1,ofile)!=1/*==0*/ ) perr("fwrite err");	for(i=0;i<256;i++) hist[i]=0;	obytes=strlen(magic)+1;	ibytes=inbytes=ninput=eof=0;	for(m=0;;m++)	{	if(!eof)		{	n=fread(&input[ninput],1,4*RUNL+5-ninput,ifile);			if(n==0)			{	if(ferror(ifile)) perr("input file error");				eof=1;				if(ninput==0) break;			}			ninput+=n;			inbytes+=n;		}		for(i=0;i<nstrat;i++)		{	strat_eval[strat[i]].obpib=1e5;			if(strat[i]&STEREO)				strat_eval[strat[i]|CHAN1].obpib=1e5;		}		if(!monoflg) for(i=0;i<runl+1;i++)			f0b[i].obpib=f1b[i].obpib=1e5;		if(!byteflg && !monoflg)			for(i=0;i<runl+1;i++) f0s[i].obpib=f1s[i].obpib=				f0so[i].obpib=f1so[i].obpib=1e5;		bm=b0b=b1b=b0s=b1s=b0so=b1so=1e5;		if(sflg>=0) evaluate_strat(strat[sflg]);	/* debug */		else for(i=0;i<nstrat;i++)		{	flags=strat[i];			if(monoflg && (flags&STEREO)) continue;			if(byteflg && (flags&SHORT)) continue;			evaluate_strat(flags);			if(flags&STEREO)			{	if(flags&SHORT)				{	if(flags&CHAN1)					{	if(flags&OFFSET) bp= &b1so;						else bp= &b1s;					}					else					{	if(flags&OFFSET) bp= &b0so;						else bp= &b0s;					}				}				else				{	if(flags&CHAN1) bp= &b1b;					else bp= &b0b;				}			}			else bp= &bm;			if(strat_eval[flags].obpib<*bp)				*bp=strat_eval[flags].obpib;		}		if(!monoflg)				/* finish stereo */		{	for(i=0;i<nstrat;i++) if(strat[i]&STEREO)   				strat_eval[strat[i]].obpib=1e5;			for(i=0,j= -1,x=1000;i<runl+1;i++)	/* byte */			{	if(f0b[i].obpib+f1b[i].obpib<10.)				{	f0b[i].obytes+=f1b[i].obytes;					f0b[i].ibytes+=f1b[i].ibytes;					f0b[i].obpib=(float)						f0b[i].obytes/f0b[i].ibytes;					if(f0b[i].obpib<x) x=f0b[i].obpib, j=i;					f0b[i].chan_1=f1b[i].hdr.flags;				}			}			if(j>=0)			{	strat_eval[f0b[j].hdr.flags]=f0b[j];				strat_eval[f1b[j].hdr.flags]=f1b[j];			}		}		if(!monoflg && !byteflg)		/* finish stereo */		{	for(i=0,j= -1,x=1000;i<runl+1;i++)	/* short */			{	if(f0s[i].obpib+f1s[i].obpib<10.)				{	f0s[i].obytes+=f1s[i].obytes;					f0s[i].ibytes+=f1s[i].ibytes;					f0s[i].obpib=(float)						f0s[i].obytes/f0s[i].ibytes;					if(f0s[i].obpib<x) x=f0s[i].obpib, j=i;					f0s[i].chan_1=f1s[i].hdr.flags;				}			}			if(j>=0)			{	strat_eval[f0s[j].hdr.flags]=f0s[j];				strat_eval[f1s[j].hdr.flags]=f1s[j];			}			for(i=0,j= -1,x=1000;i<runl+1;i++)   /* short, offset */			{	if(f0so[i].obpib+f1so[i].obpib<10.)				{	f0so[i].obytes+=f1so[i].obytes;					f0so[i].ibytes+=f1so[i].ibytes;					f0so[i].obpib=(float)						f0so[i].obytes/f0so[i].ibytes;					if(f0so[i].obpib<x) x=f0so[i].obpib,j=i;					f0so[i].chan_1=f1so[i].hdr.flags;				}			}			if(j>=0)			{	strat_eval[f0so[j].hdr.flags]=f0so[j];				strat_eval[f1so[j].hdr.flags]=f1so[j];			}		}		k= -1;				/* choose winning strategy */		obpib=100;		for(i=0;i<nstrat;i++) if(strat_eval[strat[i]].obpib<obpib)		{	k=strat[i];			obpib=strat_eval[k].obpib;		}		if(obpib<=0) perr("pack: illegal obpib");		if(k<0) perr("pack: no channel found");		if(sflg>=0 && k!=strat[sflg]) perr("k!=strat[sflg]");		hist[k]++;		output_strat(k,ofile);		if(vflg>2)		{	fprintf(stderr,"%d\t",m);			fprintf(stderr,"%d\t",ibytes);			printstrat(k);			fprintf(stderr,"\tib=%d\tob=%d",				strat_eval[k].ibytes,strat_eval[k].obytes);			fprintf(stderr,"\t%d",strat_eval[k].hdr.nbits);			fprintf(stderr,"\t%.2f",strat_eval[k].obpib);			fprintf(stderr,"\n");			if(k&STEREO)			{	fprintf(stderr,"%d\t",m);				fprintf(stderr,"%d\t",ibytes);				j=strat_eval[k].chan_1;				printstrat(j);				fprintf(stderr,"\tib=%d\tob=%d",				    strat_eval[j].ibytes,strat_eval[j].obytes);				fprintf(stderr,"\t%d",strat_eval[j].hdr.nbits);				fprintf(stderr,"\t%.2f",strat_eval[j].obpib);				fprintf(stderr,"\n");			}		}		j=strat_eval[k].ibytes;			/* shift input */		for(i=0;j<ninput;i++,j++) input[i]=input[j];		ninput-=strat_eval[k].ibytes;		if(ninput<0) perr("ninput<0");		ibytes+=strat_eval[k].ibytes;		obytes+=strat_eval[k].obytes;		if(eof && ninput==0) break;	}	if(ibytes!=inbytes) perr("ibytes!=inbytes");	if(vflg)	{	if(vflg>1)		{	fprintf(stderr,"ib=%d\tob=%d\t",ibytes,obytes);			fprintf(stderr,"rec=%d\t",m);		}		fprintf(stderr,"compression=%.1f%%\n",100.-100.*obytes/ibytes);		if(vflg>1)		{	for(i=0;i<256;i++) if(hist[i])			{	printstrat(i);				fprintf(stderr,"\t%d\t",hist[i]);			}			fprintf(stderr,"\n");		}	}}static int condition_data(flags){	register int i,j,n;	int osam,nbytes;	unsigned short sinput[4*RUNL+5];	if(flags&CHAN1) perr("flags&CHAN1");	strat_eval[flags].hdr.flags=flags;	nbytes=0;	/* input bytes consumed */	osam=0;		/* ouput samples generated */	if(flags&SHORT)						/* short data */	{	if(flags&OFFSET)		{	strat_eval[flags].hdr.offset_byte=input[nbytes++];			if(nbytes>=ninput) return 1;		}		i=nbytes;			/* construct short array */		if(flags&REV)			/* rev (lsByte first) */		{	for(j=0;i<ninput;i+=2,j++) sinput[j]=				((input[i])&0377) | (((input[i+1])&0377)<<8);		}		else				/* normal (msByte first) */		{	for(j=0;i<ninput;i+=2,j++) sinput[j]=				(((input[i])&0377)<<8) | ((input[i+1])&0377);		}		n=0;		if(flags&STEREO)				/* stereo */		{	if(flags&DIFF)				/* diff */			{	strat_eval[flags].hdr.dbase=sinput[n++];				nbytes+=2;				if(nbytes>=ninput) return 1;				strat_eval[flags+CHAN1].hdr.dbase=sinput[n++];				nbytes+=2;				if(nbytes+4>ninput) return 1;				while(osam<runl && nbytes+4<=ninput)				{	chan_0[osam]=sinput[n]-sinput[n-2];					n++;					chan_1[osam++]=sinput[n]-sinput[n-2];					n++;					nbytes+=4;				}			}			else					/* pcm */			{	if(nbytes+4>ninput) return 1;				while(osam<runl && nbytes+4<=ninput)				{	chan_0[osam]=sinput[n++];					chan_1[osam++]=sinput[n++];					nbytes+=4;				}			}		}		else						/* mono */		{	if(flags&DIFF)				/* diff */			{	strat_eval[flags].hdr.dbase=sinput[n++];				nbytes+=2;				if(nbytes+2>ninput) return 1;				while(osam<runl && nbytes+2<=ninput)				{	chan_0[osam++]=						sinput[n]-sinput[n-1];					n++;					nbytes+=2;				}			}			else					/* pcm */			{	if(nbytes+2>ninput) return 1;				while(osam<runl && nbytes+2<=ninput)				{	chan_0[osam++]=sinput[n++];					nbytes+=2;				}			}		}	}	else							/* byte data */	{	if(flags&OFFSET) perr("byte && offset");		if(flags&REV) perr("byte && byte_rev");		if(flags&STEREO)				/* stereo */		{	if(flags&DIFF)				/* diff */

⌨️ 快捷键说明

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