📄 res0.c
字号:
/******************************************************************** * * * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * by the XIPHOPHORUS Company http://www.xiph.org/ * * * ******************************************************************** function: residue backend 0, 1 and 2 implementation last mod: $Id: res0.c,v 1.45 2002/01/22 08:06:07 xiphmont Exp $ ********************************************************************//* Slow, slow, slow, simpleminded and did I mention it was slow? The encode/decode loops are coded for clarity and performance is not yet even a nagging little idea lurking in the shadows. Oh and BTW, it's slow. */#include <stdlib.h>#include <string.h>#include <math.h>#include "ogg.h"#include "vorbis_codec.h"#include "codec_internal.h"#include "registry.h"#include "codebook.h"#include "misc.h"#include "os.h"#ifdef TRAIN_RES#include <stdio.h>#endif typedef struct { vorbis_info_residue0 *info; int map; int parts; int stages; codebook *fullbooks; codebook *phrasebook; codebook ***partbooks; int partvals; int **decodemap; long postbits; long phrasebits; long frames; int qoffsets[BITTRACK_DIVISOR+1];} vorbis_look_residue0;void res0_free_info(vorbis_info_residue *i){ vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; if(info){ memset(info,0,sizeof(*info)); _ogg_free(info); }}void res0_free_look(vorbis_look_residue *i){ int j; if(i){ vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; /*vorbis_info_residue0 *info=look->info; fprintf(stderr, "%ld frames encoded in %ld phrasebits and %ld residue bits " "(%g/frame) \n",look->frames,look->phrasebits, look->resbitsflat, (look->phrasebits+look->resbitsflat)/(float)look->frames); for(j=0;j<look->parts;j++){ long acc=0; fprintf(stderr,"\t[%d] == ",j); for(k=0;k<look->stages;k++) if((info->secondstages[j]>>k)&1){ fprintf(stderr,"%ld,",look->resbits[j][k]); acc+=look->resbits[j][k]; } fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j], acc?(float)acc/(look->resvals[j]*info->grouping):0); } fprintf(stderr,"\n");*/ for(j=0;j<look->parts;j++) if(look->partbooks[j])_ogg_free(look->partbooks[j]); _ogg_free(look->partbooks); for(j=0;j<look->partvals;j++) _ogg_free(look->decodemap[j]); _ogg_free(look->decodemap); memset(look,0,sizeof(*look)); _ogg_free(look); }}static int ilog(unsigned int v){ int ret=0; while(v){ ret++; v>>=1; } return(ret);}static int icount(unsigned int v){ int ret=0; while(v){ ret+=v&1; v>>=1; } return(ret);}/* vorbis_info is for range checking */vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ int j,acc=0; vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info)); codec_setup_info *ci=vi->codec_setup; info->begin=oggpack_read(opb,24); info->end=oggpack_read(opb,24); info->grouping=oggpack_read(opb,24)+1; info->partitions=oggpack_read(opb,6)+1; info->groupbook=oggpack_read(opb,8); for(j=0;j<info->partitions;j++){ int cascade=oggpack_read(opb,3); if(oggpack_read(opb,1)) cascade|=(oggpack_read(opb,5)<<3); info->secondstages[j]=cascade; acc+=icount(cascade); } for(j=0;j<acc;j++) info->booklist[j]=oggpack_read(opb,8); if(info->groupbook>=ci->books)goto errout; for(j=0;j<acc;j++) if(info->booklist[j]>=ci->books)goto errout; return(info); errout: res0_free_info(info); return(NULL);}vorbis_look_residue *res0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm, vorbis_info_residue *vr){ vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look)); codec_setup_info *ci=vd->vi->codec_setup; int j,k,acc=0; int dim; int maxstage=0; look->info=info; look->map=vm->mapping; look->parts=info->partitions; look->fullbooks=ci->fullbooks; look->phrasebook=ci->fullbooks+info->groupbook; dim=look->phrasebook->dim; look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks)); for(j=0;j<look->parts;j++){ int stages=ilog(info->secondstages[j]); if(stages){ if(stages>maxstage)maxstage=stages; look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j])); for(k=0;k<stages;k++) if(info->secondstages[j]&(1<<k)){ look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];#ifdef TRAIN_RES look->training_data[k][j]=calloc(look->partbooks[j][k]->entries, sizeof(***look->training_data));#endif } } } look->partvals=rint(pow((float)look->parts,(float)dim)); look->stages=maxstage; look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap)); for(j=0;j<look->partvals;j++){ long val=j; long mult=look->partvals/look->parts; look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j])); for(k=0;k<dim;k++){ long deco=val/mult; val-=deco*mult; mult/=look->parts; look->decodemap[j][k]=deco; } } { int samples_per_partition=info->grouping; int n=info->end-info->begin,i; int partvals=n/samples_per_partition; for(i=0;i<BITTRACK_DIVISOR;i++) look->qoffsets[i]=partvals*(i+1)/BITTRACK_DIVISOR; look->qoffsets[i]=9999999; } return(look);}/* a truncated packet here just means 'stop working'; it's not an error */static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, FIXP **in,int ch, long (*decodepart)(codebook *, FIXP *, oggpack_buffer *,int)){ long i,j,k,l,s; vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; vorbis_info_residue0 *info=look->info; /* move all this setup out later */ int samples_per_partition=info->grouping; int partitions_per_word=look->phrasebook->dim; int n=info->end-info->begin; int partvals=n/samples_per_partition; int partwords=(partvals+partitions_per_word-1)/partitions_per_word; int ***partword=alloca(ch*sizeof(*partword)); for(j=0;j<ch;j++) partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(*partword[j])); for(s=0;s<look->stages;s++){ /* each loop decodes on partition codeword containing partitions_pre_word partitions */ for(i=0,l=0;i<partvals;l++){ if(s==0){ /* fetch the partition word for each channel */ for(j=0;j<ch;j++){ int temp=vorbis_book_decode(look->phrasebook,&vb->opb); if(temp==-1)goto eopbreak; partword[j][l]=look->decodemap[temp]; if(partword[j][l]==NULL)goto errout; } } /* now we decode residual values for the partitions */ for(k=0;k<partitions_per_word && i<partvals;k++,i++) for(j=0;j<ch;j++){ long offset=info->begin+i*samples_per_partition; if(info->secondstages[partword[j][l][k]]&(1<<s)){ codebook *stagebook=look->partbooks[partword[j][l][k]][s]; if(stagebook){ if(decodepart(stagebook,in[j]+offset,&vb->opb, samples_per_partition)==-1)goto eopbreak; } } } } } errout: eopbreak: return(0);}/* residue 0 and 1 are just slight variants of one another. 0 is interleaved, 1 is not */int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl, FIXP **in,int *nonzero,int ch){ int i,used=0; for(i=0;i<ch;i++) if(nonzero[i]) in[used++]=in[i]; if(used) return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add)); else return(0);}int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl, FIXP **in,int *nonzero,int ch){ int i,used=0; for(i=0;i<ch;i++) if(nonzero[i]) in[used++]=in[i]; if(used) return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add)); else return(0);}/* duplicate code here as speed is somewhat more important */int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, FIXP **in,int *nonzero,int ch){ long i,k,l,s; vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; vorbis_info_residue0 *info=look->info; /* move all this setup out later */ int samples_per_partition=info->grouping; int partitions_per_word=look->phrasebook->dim; int n=info->end-info->begin; int partvals=n/samples_per_partition; int partwords=(partvals+partitions_per_word-1)/partitions_per_word; int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword)); for(i=0;i<ch;i++)if(nonzero[i])break; if(i==ch)return(0); /* no nonzero vectors */ for(s=0;s<look->stages;s++){ for(i=0,l=0;i<partvals;l++){ if(s==0){ /* fetch the partition word */ int temp=vorbis_book_decode(look->phrasebook,&vb->opb); if(temp==-1)goto eopbreak; partword[l]=look->decodemap[temp]; if(partword[l]==NULL)goto errout; } /* now we decode residual values for the partitions */ for(k=0;k<partitions_per_word && i<partvals;k++,i++) if(info->secondstages[partword[l][k]]&(1<<s)){ codebook *stagebook=look->partbooks[partword[l][k]][s]; if(stagebook){ if(vorbis_book_decodevv_add(stagebook,in, i*samples_per_partition+info->begin,ch, &vb->opb,samples_per_partition)==-1) goto eopbreak; } } } } errout: eopbreak: return(0);}vorbis_func_residue residue0_exportbundle={ NULL, &res0_unpack, &res0_look, NULL, &res0_free_info, &res0_free_look, NULL, NULL, &res0_inverse};vorbis_func_residue residue1_exportbundle={ NULL, &res0_unpack, &res0_look, NULL, &res0_free_info, &res0_free_look, NULL, NULL, &res1_inverse};vorbis_func_residue residue2_exportbundle={ NULL, &res0_unpack, &res0_look, NULL, &res0_free_info, &res0_free_look, NULL, NULL, &res2_inverse};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -