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

📄 wavpack.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
			{	strat_eval[flags].hdr.dbase=input[nbytes++];				if(nbytes>=ninput) return 1;				strat_eval[flags|CHAN1].hdr.dbase=					input[nbytes++];				if(nbytes+2>ninput) return 1;				while(osam<runl && nbytes+2<=ninput)				{	chan_0[osam]=						input[nbytes]-input[nbytes-2];					nbytes++;					chan_1[osam++]=						input[nbytes]-input[nbytes-2];					nbytes++;				}			}			else					/* pcm */			{	if(nbytes+2>ninput) return 1;				while(osam<runl && nbytes+2<=ninput)				{	chan_0[osam]=input[nbytes++];					chan_1[osam++]=input[nbytes++];				}			}		}		else						/* mono */		{	if(flags&DIFF)				/* diff */			{	strat_eval[flags].hdr.dbase=input[nbytes++];				if(nbytes+1>ninput) return 1;				while(osam<runl && nbytes+1<=ninput)				{	chan_0[osam++]=						input[nbytes]-input[nbytes-1];					nbytes++;				}			}			else					/* pcm */			{	if(nbytes+1>ninput) return 1;				while(osam<runl && nbytes+1<=ninput)					chan_0[osam++]=input[nbytes++];			}		}	}	strat_eval[flags].nsam=osam;	if(flags&STEREO) strat_eval[flags|CHAN1].nsam=osam;	return 0;}static evaluate_strat(flags){	register int i,count;	register struct strat_eval *f0p,*f1p;				int flags1;	struct strat_eval f0[RUNL],f1[RUNL];				strat_eval[flags].obpib=1e5;	if(flags&CHAN1) perr("flags&CHAN1");	if(condition_data(flags)) return;	if(flags&STEREO)	{	flags1=flags|CHAN1;		if(strat_eval[flags].nsam!=strat_eval[flags1].nsam)			perr("STEREO: nsam!=");		if(flags&SHORT && flags&OFFSET) f0p= &f0so[0], f1p= &f1so[0];		else if(flags&SHORT) f0p= &f0s[0], f1p= &f1s[0];		else f0p= &f0b[0], f1p= &f1b[0];		if(flags&DIFF) f0p++, f1p++;		/* offset for DIFF */		evaluate_chan(flags,f0);		count=strat_eval[flags].count;		for(i=0;i<count;i++) if(f0[i].obpib<f0p[i].obpib) f0p[i]=f0[i];		evaluate_chan(flags1,f1);		count=strat_eval[flags1].count;		for(i=0;i<count;i++) if(f1[i].obpib<f1p[i].obpib) f1p[i]=f1[i];		/* must be finished in pack() */	}	else evaluate_chan(flags,f0);}static evaluate_chan(flags,f)		/* evaluate channel n */struct strat_eval *f;			{	register i,j,s;	unsigned short *chanp;	int dmin,dmax;	int chan,hbytes,obits,pflg;	int nsam,bitmask,maxbits,bpw;	struct strat_eval x,y;	float obpib,best;	nsam=strat_eval[flags].nsam;	if(flags&SHORT) bitmask=0xffff, maxbits=16, bpw=2;	/* 16 bit */	else bitmask=0xff, maxbits=8, bpw=1;			/* 8 bit */	if(flags&STEREO)	{	if(flags&SHORT)		{	if(flags&CHAN1)			{	if(flags&OFFSET) best=b1so;				else best=b1s;			}			else			{	if(flags&OFFSET) best=b0so;				else best=b0s;			}		}		else		{	if(flags&CHAN1) best=b1b;			else best=b0b;		}	}	else best=bm;	if(flags&CHAN1) chanp=chan_1, chan=1;	else chanp=chan_0, chan=0;	x=strat_eval[flags];	x.hdr.flags=flags;	x.hdr.count=0;	x.hdr.nbits=0;	x.hdr.pbase=chanp[0];	x.min=x.max=chanp[0];	x.range=0;	x.count=0;	x.obytes=0;	x.ibytes=0;	x.obpib=1000;	hbytes=3;				/* req header bytes */	if(chan==0 && flags&OFFSET) hbytes++;	/* for offset_byte */	if(flags&DIFF) hbytes+=bpw;		/* for dbase */	hbytes+=bpw;				/* for pbase if(nbits<maxbits)*/	x.obytes=hbytes;	obits=7;	x.ibytes=0;				/* initial input bytes */	if(chan==0 && flags&OFFSET) x.ibytes++;	/* for offset_byte */	if(flags&DIFF) x.ibytes+=bpw;		/* for dbase */	obpib=0.;	y=x;	for(i=pflg=0;i<nsam;i++)	{	s=chanp[i];	/* current sample */		if(x.hdr.nbits<maxbits)		{	dmin=mod(s-x.min);		/* outside zone */			dmax=mod(x.max-s);			if(dmin>x.range || dmax>x.range)			{	if(dmax>=dmin) x.max=s;				else x.min=x.hdr.pbase=s;				x.range=mod(x.max-x.min);					if(x.range>=pwr2[x.hdr.nbits])				{	for(j=x.hdr.nbits;j<17;j++)						if(x.range<pwr2[j]) break;					if(j==maxbits)					{	x.min=x.hdr.pbase=0;						x.max=x.range=bitmask;						hbytes-=bpw;					}					x.hdr.nbits=j;	/* bits req for pcm */					obits=j*x.count+7;    /* output bits */					x.obytes=hbytes+obits/8; /* and bytes */					obits%=8;					obpib=(float)j/maxbits;					if(obpib>y.obpib) break;					if(obpib>best) pflg=1;				}			}		}		x.count++;		x.hdr.count=x.count-1;		for(obits+=x.hdr.nbits;obits>=8;obits-=8) x.obytes++; /*output*/		x.ibytes+=bpw;				/* input bytes */		x.obpib=(float)x.obytes/x.ibytes;	/* obytes per ibytes */		f[i]=x;				/* save result */		if(x.obpib<y.obpib)		{	y=x;			/* best forward coding so far */			if(obpib>y.obpib) break;	/* can only get worse */		}		if(pflg && x.obpib>best) break;	/* occasional premature prune */	}	strat_eval[flags]=y;		/* best run for this coding */}static output_strat(flags,ofile)FILE *ofile;{	if(flags&CHAN1) perr("output: flags&CHAN1");	if(condition_data(flags)) perr("output: unable to make channel");	output_chan(flags,ofile);	if(flags&STEREO)	{	flags=strat_eval[flags].chan_1;		if(condition_data(flags&~CHAN1))			perr("output: unable to make channel");		output_chan(flags,ofile);	}}static output_chan(flags,ofile)FILE *ofile;{	register int i,j,k,pbase;	register unsigned short *chanp;	int bits,count;	unsigned char c[2],obuf[4*RUNL+5];	bits=strat_eval[flags].hdr.nbits;	count=strat_eval[flags].hdr.count+1;	if(strat_eval[flags].hdr.flags!=flags) perr("flags!=");	if(flags&CHAN1) chanp=chan_1;	else chanp=chan_0;	if(fwrite(&strat_eval[flags].hdr.flags,1,1,ofile)!=1 /*==0*/ )	/* header */		perr("fwrite err");	if(fwrite(&strat_eval[flags].hdr.count,1,1,ofile)!=1 /*==0*/ )	/* header */		perr("fwrite err");	if(fwrite(&strat_eval[flags].hdr.nbits,1,1,ofile)!=1 /*==0*/ )	/* header */		perr("fwrite err");	if(flags&OFFSET && (flags&CHAN1)==0 &&			/* offset */		fwrite(&strat_eval[flags].hdr.offset_byte,1,1,ofile)!=1 /*==0*/ )			perr("fwrite err");	if(flags&DIFF)						/* diff base */	{	if(flags&SHORT)		{	c[0]=strat_eval[flags].hdr.dbase>>8;			c[1]=strat_eval[flags].hdr.dbase;			if(fwrite(c,1,2,ofile)!=2 /*==0*/ ) perr("fwrite err");		}		else		{	c[0]=strat_eval[flags].hdr.dbase;			if(fwrite(c,1,1,ofile)!=1 /*==0*/ ) perr("fwrite err");		}	}	if(bits<8 || (flags&SHORT && bits<16))			/* pcm base */	{	if(flags&SHORT)		{	c[0]=strat_eval[flags].hdr.pbase>>8;			c[1]=strat_eval[flags].hdr.pbase;			if(fwrite(c,1,2,ofile)!=2 /*==0*/ ) perr("fwrite err");		}		else		{	c[0]=strat_eval[flags].hdr.pbase;			if(fwrite(c,1,1,ofile)!=1 /*==0*/ ) perr("fwrite err");		}		pbase=strat_eval[flags].hdr.pbase;	}	else pbase=0;		if(flags&CHAN1) chanp=chan_1;	else chanp=chan_0;	if(bits>0)	{	if(pbase) for(i=0;i<count;i++) chanp[i]-=pbase;		for(i=0;i<(bits*count+7)/8;i++) obuf[i]=0;#if 0		for(i=0;i<bits*count;i++)		{	if((1<<(bits-1-i%bits))&chanp[i/bits])				obuf[i/8]|=1<<(7-i%8);		}#endif		for(i=k=0;i<count;i++) for(j=bits-1;j>=0;j--,k++)			if((1<<j)&chanp[i]) obuf[k>>3]|=0x80>>(k&7);		{ int nitems;		nitems = (bits*count+7)/8;		if(fwrite(obuf,1,nitems,ofile)!=nitems /*==0*/ )	/* pcm data */			perr("fwrite err");		}	}}wavpack_unpack(ifile,ofile)FILE *ifile,*ofile;{	int k;	char str[100];	unsigned char ibuf[2][4*RUNL+5];	unsigned short sobuf[2][RUNL+1];	int nsobuf[2];	struct hdr hdr[2];	nstrat = wavpack_get_nstrat();	if(fread(str,strlen(magic)+1,1,ifile)==0)		/* read magic */		perr("fread err");	if(strcmp(str,magic)!=0) perr("not a wavpacked file");	for(k=0;;k++)	{	if(vflg>1) fprintf(stderr,"k=%d\t",k);		if(readchan(ifile,&hdr[0],ibuf[0])) break;		if(vflg>1)		{	printstrat((int)hdr[0].flags);			fprintf(stderr,"\n");			if(hdr[0].flags&STEREO)			{	fprintf(stderr,"k=%d\t",k);				printstrat((int)hdr[1].flags);				fprintf(stderr,"\n");			}		}		decode_data(&hdr[0],ibuf[0],sobuf[0],&nsobuf[0]);		if(hdr[0].flags&STEREO)		{	if(readchan(ifile,&hdr[1],ibuf[1]))				perr("illegal chan 1");			decode_data(&hdr[1],ibuf[1],sobuf[1],&nsobuf[1]);		}		write_data(hdr,sobuf,nsobuf,ofile);	}	if(vflg>1) fprintf(stderr,"\n");}static int readchan(ifile,hp,ibuf)FILE *ifile;struct hdr *hp;unsigned char *ibuf;{	int i;	int count;	unsigned char c[2];	if(fread(&hp->flags,1,1,ifile)==0 /*NULL*/ ) return 1;	/* header */	if(fread(&hp->count,1,1,ifile)==0 /*NULL*/ )		/* header */		perr("incomplete header");	if(fread(&hp->nbits,1,1,ifile)==0 /*NULL*/ )		/* header */		perr("incomplete header");	for(i=0;i<nstrat;i++) if((hp->flags&~CHAN1)==strat[i]) break;	if(i>=nstrat) perr("illegal header");	count=hp->count+1;	if(hp->flags&OFFSET && (hp->flags&CHAN1)==0)	/* offset */	{	if(fread(&hp->offset_byte,1,1,ifile)==0 /*NULL*/ )			perr("incomplete header");	}	if(hp->flags&DIFF)				/* diff base */	{	if(hp->flags&SHORT)		{	if(fread(c,1,2,ifile)==0 /*NULL*/ )				perr("incomplete header");			hp->dbase=(c[0]<<8) | c[1];		}		else		{	if(fread(c,1,1,ifile)==0 /*NULL*/ )				perr("incomplete header");			hp->dbase=c[0];		}	}	if(hp->nbits<8 || (hp->flags&SHORT && hp->nbits<16)) /* pcm */	{	if(hp->flags&SHORT)		{	if(fread(c,1,2,ifile)==0 /*NULL*/ )				perr("incomplete header");			hp->pbase=(c[0]<<8) | c[1];		}		else		{	if(fread(c,1,1,ifile)==0 /*NULL*/ )				perr("incomplete header");			hp->pbase=c[0];		}	}	else hp->pbase=0;	if(hp->nbits>0)	{	if(fread(ibuf,(hp->nbits*count+7)/8,1,ifile)==0 /*NULL*/ )			perr("incomplete data");	}	return 0;}static decode_data(hp,ibuf,sobuf,nsobuf)struct hdr *hp;unsigned char *ibuf;register unsigned short *sobuf;int *nsobuf;{	register int i,j,k,bits,count,pbase;	count=hp->count+1;	bits=hp->nbits;	if(hp->flags&DIFF)	{	sobuf[0]=hp->dbase;		sobuf++;	}	pbase=hp->pbase;	for(i=0;i<count;i++) sobuf[i]=pbase;#if 0	if(bits>0) for(i=0;i<bits*count;i++) if(1<<(7-i%8)&ibuf[i/8])			sobuf[i/bits]+=1<<(bits-1-i%bits);#endif	if(bits>0)	{	for(i=k=0;i<count;i++) for(j=bits-1;j>=0;j--,k++)			if(ibuf[k>>3]&(0x80>>(k&7))) sobuf[i]+=1<<j;	}	if(hp->flags&DIFF)	{	for(i=0;i<count;i++) sobuf[i]+=sobuf[i-1];		*nsobuf=count+1;	}	else *nsobuf=count;}static write_data(hdr,sobuf,nsobuf,ofile)struct hdr hdr[];unsigned short sobuf[][RUNL+1];int nsobuf[];FILE *ofile;{	int i,k;	unsigned char obuf[4*RUNL+5];	k=0;	if(hdr[0].flags&OFFSET) obuf[k++]=hdr[0].offset_byte;	if(nsobuf[0]>RUNL+1) perr("nsobuf>RUNL+1");	if(hdr[0].flags&STEREO)	{	if(nsobuf[0]!=nsobuf[1]) perr("nsobuf !=");		if(hdr[0].flags&SHORT)		{	for(i=0;i<nsobuf[0];i++)			{	if(hdr[0].flags&REV)				{	obuf[k++]=sobuf[0][i];					obuf[k++]=sobuf[0][i]>>8;				}				else				{	obuf[k++]=sobuf[0][i]>>8;					obuf[k++]=sobuf[0][i];				}				if(hdr[1].flags&REV)				{	obuf[k++]=sobuf[1][i];					obuf[k++]=sobuf[1][i]>>8;				}				else				{	obuf[k++]=sobuf[1][i]>>8;					obuf[k++]=sobuf[1][i];				}			}		}		else for(i=0;i<nsobuf[0];i++)		{	obuf[k++]=sobuf[0][i];			obuf[k++]=sobuf[1][i];		}	}	else	{	if(hdr[0].flags&SHORT) for(i=0;i<nsobuf[0];i++)		{	if(hdr[0].flags&REV)			{	obuf[k++]=sobuf[0][i];				obuf[k++]=sobuf[0][i]>>8;			}			else			{	obuf[k++]=sobuf[0][i]>>8;				obuf[k++]=sobuf[0][i];			}		}		else for(i=0;i<nsobuf[0];i++) obuf[k++]=sobuf[0][i];	}	if(fwrite(obuf,1,k,ofile)!=k /*==0*/ ) perr("fwrite err");}static printstrat(x){	int i;	char str[9];	for(i=0;i<5;i++) str[i]='_';	str[5]='\0';		if(x&SHORT) str[0]='S';	else str[0]='B';	if(x&REV) str[1]='R';	if(x&OFFSET) str[2]='O';	if(x&DIFF) str[3]='D';	if(x&STEREO) str[4]='2';	fprintf(stderr,"%s",str);}perr(s)char *s;{	if(oflg && unlink(oname))		/* delete the output file */		fprintf(stderr,"%s err: unable to remove output file\n",			progname);	fprintf(stderr,"%s err: %s\n",progname,s);	exit(1);}

⌨️ 快捷键说明

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