static void vorbis_encode_residue_setup(vorbis_info *vi, int number, int block, const vorbis_residue_template *res){ codec_setup_info *ci=vi->codec_setup; int i,n; vorbis_info_residue0 *r=ci->residue_param[number]= _ogg_malloc(sizeof(*r)); memcpy(r,res->res,sizeof(*r)); if(ci->residues<=number)ci->residues=number+1; switch(ci->blocksizes[block]){ case 64:case 128:case 256: r->grouping=16; break; default: r->grouping=32; break; } ci->residue_type[number]=res->res_type; /* to be adjusted by lowpass/pointlimit later */ n=r->end=ci->blocksizes[block]>>1; if(res->res_type==2) n=r->end*=vi->channels; /* fill in all the books */ { int booklist=0,k; if(ci->hi.managed){ for(i=0;i<r->partitions;i++) for(k=0;k<3;k++) if(res->books_base_managed->books[i][k]) r->secondstages[i]|=(1<<k); r->groupbook=book_dup_or_new(ci,res->book_aux_managed); ci->book_param[r->groupbook]=(static_codebook *)res->book_aux_managed; for(i=0;i<r->partitions;i++){ for(k=0;k<3;k++){ if(res->books_base_managed->books[i][k]){ int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]); r->booklist[booklist++]=bookid; ci->book_param[bookid]=(static_codebook *)res->books_base_managed->books[i][k]; } } } }else{ for(i=0;i<r->partitions;i++) for(k=0;k<3;k++) if(res->books_base->books[i][k]) r->secondstages[i]|=(1<<k); r->groupbook=book_dup_or_new(ci,res->book_aux); ci->book_param[r->groupbook]=(static_codebook *)res->book_aux; for(i=0;i<r->partitions;i++){ for(k=0;k<3;k++){ if(res->books_base->books[i][k]){ int bookid=book_dup_or_new(ci,res->books_base->books[i][k]); r->booklist[booklist++]=bookid; ci->book_param[bookid]=(static_codebook *)res->books_base->books[i][k]; } } } } } /* lowpass setup/pointlimit */ { double freq=ci->hi.lowpass_kHz*1000.; vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */ double nyq=vi->rate/2.; long blocksize=ci->blocksizes[block]>>1; /* lowpass needs to be set in the floor and the residue. */ if(freq>nyq)freq=nyq; /* in the floor, the granularity can be very fine; it doesn't alter the encoding structure, only the samples used to fit the floor approximation */ f->n=freq/nyq*blocksize; /* this res may by limited by the maximum pointlimit of the mode, not the lowpass. the floor is always lowpass limited. */ if(res->limit_type){ if(ci->hi.managed) freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.; else freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.; if(freq>nyq)freq=nyq; } /* in the residue, we're constrained, physically, by partition boundaries. We still lowpass 'wherever', but we have to round up here to next boundary, or the vorbis spec will round it *down* to previous boundary in encode/decode */ if(ci->residue_type[block]==2){ r->end=(int)((freq/nyq*blocksize*2)/r->grouping+.9)* /* round up only if we're well past */ r->grouping; ci->block_lowpassr[block]=r->end/2; /* lowpass (residue) */ }else{ r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */ r->grouping; ci->block_lowpassr[block]=r->end; /* lowpass (residue) */ } } }
static void vorbis_encode_residue_setup(vorbis_info *vi, int number, int block, const vorbis_residue_template *res){ codec_setup_info *ci=vi->codec_setup; int i; vorbis_info_residue0 *r=ci->residue_param[number]= _ogg_malloc(sizeof(*r)); memcpy(r,res->res,sizeof(*r)); if(ci->residues<=number)ci->residues=number+1; r->grouping=res->grouping; ci->residue_type[number]=res->res_type; /* fill in all the books */ { int booklist=0,k; if(ci->hi.managed){ for(i=0;i<r->partitions;i++) for(k=0;k<4;k++) if(res->books_base_managed->books[i][k]) r->secondstages[i]|=(1<<k); r->groupbook=book_dup_or_new(ci,res->book_aux_managed); ci->book_param[r->groupbook]=(static_codebook *)res->book_aux_managed; for(i=0;i<r->partitions;i++){ for(k=0;k<4;k++){ if(res->books_base_managed->books[i][k]){ int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]); r->booklist[booklist++]=bookid; ci->book_param[bookid]=(static_codebook *)res->books_base_managed->books[i][k]; } } } }else{ for(i=0;i<r->partitions;i++) for(k=0;k<4;k++) if(res->books_base->books[i][k]) r->secondstages[i]|=(1<<k); r->groupbook=book_dup_or_new(ci,res->book_aux); ci->book_param[r->groupbook]=(static_codebook *)res->book_aux; for(i=0;i<r->partitions;i++){ for(k=0;k<4;k++){ if(res->books_base->books[i][k]){ int bookid=book_dup_or_new(ci,res->books_base->books[i][k]); r->booklist[booklist++]=bookid; ci->book_param[bookid]=(static_codebook *)res->books_base->books[i][k]; } } } } } /* lowpass setup/pointlimit */ { double freq=ci->hi.lowpass_kHz*1000.; vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */ double nyq=vi->rate/2.; long blocksize=ci->blocksizes[block]>>1; /* lowpass needs to be set in the floor and the residue. */ if(freq>nyq)freq=nyq; /* in the floor, the granularity can be very fine; it doesn't alter the encoding structure, only the samples used to fit the floor approximation */ f->n=freq/nyq*blocksize; /* this res may by limited by the maximum pointlimit of the mode, not the lowpass. the floor is always lowpass limited. */ switch(res->limit_type){ case 1: /* point stereo limited */ if(ci->hi.managed) freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.; else freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.; if(freq>nyq)freq=nyq; break; case 2: /* LFE channel; lowpass at ~ 250Hz */ freq=250; break; default: /* already set */ break; } /* in the residue, we're constrained, physically, by partition boundaries. We still lowpass 'wherever', but we have to round up here to next boundary, or the vorbis spec will round it *down* to previous boundary in encode/decode */ if(ci->residue_type[number]==2){ /* residue 2 bundles together multiple channels; used by stereo and surround. Count the channels in use */ /* Multiple maps/submaps can point to the same residue. In the case of residue 2, they all better have the same number of channels/samples. */ int j,k,ch=0; for(i=0;i<ci->maps&&ch==0;i++){ vorbis_info_mapping0 *mi=(vorbis_info_mapping0 *)ci->map_param[i]; for(j=0;j<mi->submaps && ch==0;j++) if(mi->residuesubmap[j]==number) /* we found a submap referencing theis residue backend */ for(k=0;k<vi->channels;k++) if(mi->chmuxlist[k]==j) /* this channel belongs to the submap */ ch++; } r->end=(int)((freq/nyq*blocksize*ch)/r->grouping+.9)* /* round up only if we're well past */ r->grouping; /* the blocksize and grouping may disagree at the end */ if(r->end>blocksize*ch)r->end=blocksize*ch/r->grouping*r->grouping; }else{ r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */ r->grouping; /* the blocksize and grouping may disagree at the end */ if(r->end>blocksize)r->end=blocksize/r->grouping*r->grouping; } if(r->end==0)r->end=r->grouping; /* LFE channel */ } }