int main(int argc,char *argv[]){ int eos=0; float nonz=0.f; float acc=0.f; float tot=0.f; float ampmax=-9999,newmax; float local_ampmax[2]; int framesize=2048; float ampmax_att_per_sec=-6.; float *pcm[2],*out[2],*window,*flr[2],*mask[2],*work[2]; signed char *buffer,*buffer2; mdct_lookup m_look; drft_lookup f_look; vorbis_look_psy p_look; vorbis_look_psy_global *pg_look; vorbis_look_floor *floor_look; vorbis_info vi; long i,j,k; int ath=0; int decayp=0; argv++; while(*argv){ if(*argv[0]=='-'){ /* option */ if(argv[0][1]=='v'){ noisy=0; } }else if(*argv[0]=='+'){ /* option */ if(argv[0][1]=='v'){ noisy=1; } }else framesize=atoi(argv[0]); argv++; } vi.channels=2; vi.codec_setup=&codec_setup0; pcm[0]=_ogg_malloc(framesize*sizeof(float)); pcm[1]=_ogg_malloc(framesize*sizeof(float)); out[0]=_ogg_calloc(framesize/2,sizeof(float)); out[1]=_ogg_calloc(framesize/2,sizeof(float)); work[0]=_ogg_calloc(framesize,sizeof(float)); work[1]=_ogg_calloc(framesize,sizeof(float)); flr[0]=_ogg_calloc(framesize/2,sizeof(float)); flr[1]=_ogg_calloc(framesize/2,sizeof(float)); buffer=_ogg_malloc(framesize*4); buffer2=buffer+framesize*2; window=_vorbis_window(0,framesize,framesize/2,framesize/2); mdct_init(&m_look,framesize); drft_init(&f_look,framesize); _vp_psy_init(&p_look,&_psy_set0,&_psy_set0G,framesize/2,44100); pg_look=_vp_global_look(&vi); floor_look=_floor_P[1]->look(NULL,NULL,&_floor_set0); /* we cheat on the WAV header; we just bypass 44 bytes and never verify that it matches 16bit/stereo/44.1kHz. */ fread(buffer,1,44,stdin); fwrite(buffer,1,44,stdout); memset(buffer,0,framesize*2); analysis("window",0,window,framesize,0,0); fprintf(stderr,"Processing for frame size %d...\n",framesize); while(!eos){ long bytes=fread(buffer2,1,framesize*2,stdin); if(bytes<framesize*2) memset(buffer2+bytes,0,framesize*2-bytes); if(bytes!=0){ int nonzero[2]; /* uninterleave samples */ for(i=0;i<framesize;i++){ pcm[0][i]=((buffer[i*4+1]<<8)| (0x00ff&(int)buffer[i*4]))/32768.f; pcm[1][i]=((buffer[i*4+3]<<8)| (0x00ff&(int)buffer[i*4+2]))/32768.f; } { float secs=framesize/44100.; ampmax+=secs*ampmax_att_per_sec; if(ampmax<-9999)ampmax=-9999; } for(i=0;i<2;i++){ float scale=4.f/framesize; float *fft=work[i]; float *mdct=pcm[i]; float *logmdct=mdct+framesize/2; analysis("pre",frameno+i,pcm[i],framesize,0,0); /* fft and mdct transforms */ for(j=0;j<framesize;j++) fft[j]=pcm[i][j]*=window[j]; drft_forward(&f_look,fft); local_ampmax[i]=-9999.f; fft[0]*=scale; fft[0]=todB(fft); for(j=1;j<framesize-1;j+=2){ float temp=scale*FAST_HYPOT(fft[j],fft[j+1]); temp=fft[(j+1)>>1]=todB(&temp); if(temp>local_ampmax[i])local_ampmax[i]=temp; } if(local_ampmax[i]>ampmax)ampmax=local_ampmax[i]; mdct_forward(&m_look,pcm[i],mdct); for(j=0;j<framesize/2;j++) logmdct[j]=todB(mdct+j); analysis("mdct",frameno+i,logmdct,framesize/2,1,0); analysis("fft",frameno+i,fft,framesize/2,1,0); } for(i=0;i<2;i++){ float amp; float *fft=work[i]; float *logmax=fft; float *mdct=pcm[i]; float *logmdct=mdct+framesize/2; float *mask=fft+framesize/2; /* floor psychoacoustics */ _vp_compute_mask(&p_look, pg_look, i, fft, logmdct, mask, ampmax, local_ampmax[i], framesize/2); analysis("mask",frameno+i,mask,framesize/2,1,0); { vorbis_block vb; vorbis_dsp_state vd; memset(&vd,0,sizeof(vd)); vd.vi=&vi; vb.vd=&vd; vb.pcmend=framesize; /* floor quantization/application */ nonzero[i]=_floor_P[1]->forward(&vb,floor_look, mdct, logmdct, mask, logmax, flr[i]); } _vp_remove_floor(&p_look, pg_look, logmdct, mdct, flr[i], pcm[i], local_ampmax[i]); for(j=0;j<framesize/2;j++) if(fabs(pcm[i][j])>1500) fprintf(stderr,"%ld ",frameno+i); analysis("res",frameno+i,pcm[i],framesize/2,1,0); analysis("codedflr",frameno+i,flr[i],framesize/2,1,1); } /* residue prequantization */ _vp_partition_prequant(&p_look, &vi, pcm, nonzero); for(i=0;i<2;i++) analysis("quant",frameno+i,pcm[i],framesize/2,1,0); /* channel coupling / stereo quantization */ _vp_couple(&p_look, &mapping_info, pcm, nonzero); for(i=0;i<2;i++) analysis("coupled",frameno+i,pcm[i],framesize/2,1,0); /* decoupling */ for(i=mapping_info.coupling_steps-1;i>=0;i--){ float *pcmM=pcm[mapping_info.coupling_mag[i]]; float *pcmA=pcm[mapping_info.coupling_ang[i]]; for(j=0;j<framesize/2;j++){ float mag=pcmM[j]; float ang=pcmA[j]; if(mag>0) if(ang>0){ pcmM[j]=mag; pcmA[j]=mag-ang; }else{ pcmA[j]=mag; pcmM[j]=mag+ang; } else if(ang>0){ pcmM[j]=mag; pcmA[j]=mag+ang; }else{ pcmA[j]=mag; pcmM[j]=mag-ang; } } } for(i=0;i<2;i++) analysis("decoupled",frameno+i,pcm[i],framesize/2,1,0); for(i=0;i<2;i++){ float amp; for(j=0;j<framesize/2;j++) pcm[i][j]*=flr[i][j]; analysis("final",frameno+i,pcm[i],framesize/2,1,1); /* take it back to time */ mdct_backward(&m_look,pcm[i],pcm[i]); for(j=0;j<framesize/2;j++) out[i][j]+=pcm[i][j]*window[j]; analysis("out",frameno+i,out[i],framesize/2,0,0); } /* write data. Use the part of buffer we're about to shift out */ for(i=0;i<2;i++){ char *ptr=buffer+i*2; float *mono=out[i]; int flag=0; for(j=0;j<framesize/2;j++){ int val=mono[j]*32767.; /* might as well guard against clipping */ if(val>32767){ if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i); flag=1; val=32767; } if(val<-32768){ if(!flag)fprintf(stderr,"clipping in frame %ld ",frameno+i); flag=1; val=-32768; } ptr[0]=val&0xff; ptr[1]=(val>>8)&0xff; ptr+=4; } } fprintf(stderr,"*"); fwrite(buffer,1,framesize*2,stdout); memmove(buffer,buffer2,framesize*2); for(i=0;i<2;i++){ for(j=0,k=framesize/2;j<framesize/2;j++,k++) out[i][j]=pcm[i][k]*window[k]; } frameno+=2; }else
static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){ int i; codec_setup_info *ci=vi->codec_setup; private_state *b=NULL; int hs; if(ci==NULL) return 1; hs=ci->halfrate_flag; memset(v,0,sizeof(*v)); b=v->backend_state=_ogg_calloc(1,sizeof(*b)); v->vi=vi; b->modebits=ilog2(ci->modes); b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0])); b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1])); /* MDCT is tranform 0 */ b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup)); b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup)); mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs); mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs); /* Vorbis I uses only window type 0 */ b->window[0]=ilog2(ci->blocksizes[0])-6; b->window[1]=ilog2(ci->blocksizes[1])-6; if(encp){ /* encode/decode differ here */ /* analysis always needs an fft */ drft_init(&b->fft_look[0],ci->blocksizes[0]); drft_init(&b->fft_look[1],ci->blocksizes[1]); /* finish the codebooks */ if(!ci->fullbooks){ ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); for(i=0;i<ci->books;i++) vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]); } b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy)); for(i=0;i<ci->psys;i++){ _vp_psy_init(b->psy+i, ci->psy_param[i], &ci->psy_g_param, ci->blocksizes[ci->psy_param[i]->blockflag]/2, vi->rate); } v->analysisp=1; }else{ /* finish the codebooks */ if(!ci->fullbooks){ ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks)); for(i=0;i<ci->books;i++){ if(ci->book_param[i]==NULL) goto abort_books; if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i])) goto abort_books; /* decode codebooks are now standalone after init */ vorbis_staticbook_destroy(ci->book_param[i]); ci->book_param[i]=NULL; } } } /* initialize the storage vectors. blocksize[1] is small for encode, but the correct size for decode */ v->pcm_storage=ci->blocksizes[1]; v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm)); v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret)); { int i; for(i=0;i<vi->channels;i++) v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); } /* all 1 (large block) or 0 (small block) */ /* explicitly set for the sake of clarity */ v->lW=0; /* previous window size */ v->W=0; /* current window size */ /* all vector indexes */ v->centerW=ci->blocksizes[1]/2; v->pcm_current=v->centerW; /* initialize all the backend lookups */ b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr)); b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue)); for(i=0;i<ci->floors;i++) b->flr[i]=_floor_P[ci->floor_type[i]]-> look(v,ci->floor_param[i]); for(i=0;i<ci->residues;i++) b->residue[i]=_residue_P[ci->residue_type[i]]-> look(v,ci->residue_param[i]); return 0; abort_books: for(i=0;i<ci->books;i++){ if(ci->book_param[i]!=NULL){ vorbis_staticbook_destroy(ci->book_param[i]); ci->book_param[i]=NULL; } } vorbis_dsp_clear(v); return -1; }
static vorbis_look_mapping *mapping0_look(vorbis_dsp_state *vd,vorbis_info_mode *vm, vorbis_info_mapping *m){ int i; vorbis_info *vi=vd->vi; codec_setup_info *ci=vi->codec_setup; vorbis_look_mapping0 *look=_ogg_calloc(1,sizeof(vorbis_look_mapping0)); vorbis_info_mapping0 *info=look->map=(vorbis_info_mapping0 *)m; look->mode=vm; look->time_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_time *)); look->floor_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_floor *)); look->residue_look=_ogg_calloc(info->submaps,sizeof(vorbis_look_residue *)); look->time_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_time *)); look->floor_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_floor *)); look->residue_func=_ogg_calloc(info->submaps,sizeof(vorbis_func_residue *)); for(i=0;i<info->submaps;i++){ int timenum=info->timesubmap[i]; int floornum=info->floorsubmap[i]; int resnum=info->residuesubmap[i]; look->time_func[i]=_time_P[ci->time_type[timenum]]; look->time_look[i]=look->time_func[i]-> look(vd,vm,ci->time_param[timenum]); look->floor_func[i]=_floor_P[ci->floor_type[floornum]]; look->floor_look[i]=look->floor_func[i]-> look(vd,vm,ci->floor_param[floornum]); look->residue_func[i]=_residue_P[ci->residue_type[resnum]]; look->residue_look[i]=look->residue_func[i]-> look(vd,vm,ci->residue_param[resnum]); } if(ci->psys && vd->analysisp){ if(info->psy[0] != info->psy[1]){ int psynum=info->psy[0]; look->psy_look[0]=_ogg_calloc(1,sizeof(vorbis_look_psy)); _vp_psy_init(look->psy_look[0],ci->psy_param[psynum], ci->psy_g_param, ci->blocksizes[vm->blockflag]/2,vi->rate); psynum=info->psy[1]; look->psy_look[1]=_ogg_calloc(1,sizeof(vorbis_look_psy)); _vp_psy_init(look->psy_look[1],ci->psy_param[psynum], ci->psy_g_param, ci->blocksizes[vm->blockflag]/2,vi->rate); }else{ int psynum=info->psy[0]; look->psy_look[0]=_ogg_calloc(1,sizeof(vorbis_look_psy)); look->psy_look[1]=look->psy_look[0]; _vp_psy_init(look->psy_look[0],ci->psy_param[psynum], ci->psy_g_param, ci->blocksizes[vm->blockflag]/2,vi->rate); } } look->ch=vi->channels; if(vd->analysisp)drft_init(&look->fft_look,ci->blocksizes[vm->blockflag]); return(look); }