diff options
author | Monty <xiphmont@xiph.org> | 2001-12-12 09:45:57 +0000 |
---|---|---|
committer | Monty <xiphmont@xiph.org> | 2001-12-12 09:45:57 +0000 |
commit | 3a8db75a3792eaba84ec9fad0db8d29ec1ce493f (patch) | |
tree | b46509e4436b838f6ff951105f43dc251131688e /lib/vorbisenc.c | |
parent | 2308d84646f0367d8cf6738aaafe2bf74b8002fb (diff) | |
download | libvorbis-git-3a8db75a3792eaba84ec9fad0db8d29ec1ce493f.tar.gz |
Initial branch merge toward rc3
monty_branch_20011009 is officially dead
svn path=/trunk/vorbis/; revision=2590
Diffstat (limited to 'lib/vorbisenc.c')
-rw-r--r-- | lib/vorbisenc.c | 768 |
1 files changed, 646 insertions, 122 deletions
diff --git a/lib/vorbisenc.c b/lib/vorbisenc.c index 03c069a3..65fec3b5 100644 --- a/lib/vorbisenc.c +++ b/lib/vorbisenc.c @@ -7,79 +7,577 @@ * * * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * * by the XIPHOPHORUS Company http://www.xiph.org/ * - + * * ******************************************************************** function: simple programmatic interface for encoder mode setup - last mod: $Id: vorbisenc.c,v 1.18 2001/10/18 17:39:34 cwolf Exp $ + last mod: $Id: vorbisenc.c,v 1.19 2001/12/12 09:45:26 xiphmont Exp $ ********************************************************************/ #include <stdlib.h> #include <string.h> #include <math.h> +#include <stdarg.h> #include "vorbis/codec.h" #include "vorbis/vorbisenc.h" #include "codec_internal.h" -#include "registry.h" -#include "modes/modes.h" +#include "registry-api.h" #include "os.h" #include "misc.h" -/* deepcopy all but the codebooks; in this usage, they're static - (don't copy as they could be big) */ -static void codec_setup_partialcopy(codec_setup_info *ci, - codec_setup_info *cs){ - int i; +/* careful with this; it's using static array sizing to make managing + all the modes a little less annoying. If we use a residue backend + with > 10 partition types, or a different division of iteration, + this needs to be updated. */ +typedef struct { + vorbis_info_residue0 *res[2]; + static_codebook *book_aux[2]; + static_codebook *books_base[5][10][3]; + static_codebook *books_stereo_backfill[5][10]; + static_codebook *books_residue_backfill[5][10][2]; +} vorbis_residue_template; + +static double stereo_threshholds[]={0.0, 2.5, 4.5, 8.5, 16.5}; + +typedef struct vp_adjblock{ + int block[P_BANDS][P_LEVELS]; +} vp_adjblock; + +#include "modes/residue_44.h" +#include "modes/psych_44.h" +#include "modes/floor_44.h" + +/* a few static coder conventions */ +static vorbis_info_time0 _time_dummy={0}; +static vorbis_info_mode _mode_set_short={0,0,0,0}; +static vorbis_info_mode _mode_set_long={1,0,0,1}; + +/* mapping conventions: + only one submap (this would change for efficient 5.1 support for example)*/ +/* Four psychoacoustic profiles are used, one for each blocktype */ +static vorbis_info_mapping0 _mapping_set_short={ + 1, {0,0}, {0}, {0}, {0}, {0,1}, 0,{0},{0}}; +static vorbis_info_mapping0 _mapping_set_long={ + 1, {0,0}, {0}, {1}, {1}, {2,3}, 0,{0},{0}}; + +static int vorbis_encode_toplevel_init(vorbis_info *vi,int small,int large,int ch,long rate){ + if(vi && vi->codec_setup){ + codec_setup_info *ci=vi->codec_setup; + + vi->version=0; + vi->channels=ch; + vi->rate=rate; + + ci->blocksizes[0]=small; + ci->blocksizes[1]=large; + + /* time mapping hooks are unused in vorbis I */ + ci->times=1; + ci->time_type[0]=0; + ci->time_param[0]=calloc(1,sizeof(_time_dummy)); + memcpy(ci->time_param[0],&_time_dummy,sizeof(_time_dummy)); + + /* by convention, two modes: one for short, one for long blocks. + short block mode uses mapping sero, long block uses mapping 1 */ + ci->modes=2; + ci->mode_param[0]=calloc(1,sizeof(_mode_set_short)); + memcpy(ci->mode_param[0],&_mode_set_short,sizeof(_mode_set_short)); + ci->mode_param[1]=calloc(1,sizeof(_mode_set_long)); + memcpy(ci->mode_param[1],&_mode_set_long,sizeof(_mode_set_long)); + + /* by convention two mappings, both mapping type zero (polyphonic + PCM), first for short, second for long blocks */ + ci->maps=2; + ci->map_type[0]=0; + ci->map_param[0]=calloc(1,sizeof(_mapping_set_short)); + memcpy(ci->map_param[0],&_mapping_set_short,sizeof(_mapping_set_short)); + ci->map_type[1]=0; + ci->map_param[1]=calloc(1,sizeof(_mapping_set_long)); + memcpy(ci->map_param[1],&_mapping_set_long,sizeof(_mapping_set_long)); + + return(0); + } + return(OV_EINVAL); +} + +static int vorbis_encode_floor_init(vorbis_info *vi,double q,int block, + static_codebook ***books, + vorbis_info_floor1 *in, + ...){ + int x[11],i,k,iq=rint(q*10); + vorbis_info_floor1 *f=calloc(1,sizeof(*f)); + codec_setup_info *ci=vi->codec_setup; + va_list ap; + + va_start(ap,in); + for(i=0;i<11;i++) + x[i]=va_arg(ap,int); + va_end(ap); + + memcpy(f,in+x[iq],sizeof(*f)); + /* fill in the lowpass field, even if it's temporary */ + f->n=ci->blocksizes[block]>>1; + + /* books */ + { + int partitions=f->partitions; + int maxclass=-1; + int maxbook=-1; + for(i=0;i<partitions;i++) + if(f->partitionclass[i]>maxclass)maxclass=f->partitionclass[i]; + for(i=0;i<=maxclass;i++){ + if(f->class_book[i]>maxbook)maxbook=f->class_book[i]; + f->class_book[i]+=ci->books; + for(k=0;k<(1<<f->class_subs[i]);k++){ + if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k]; + if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books; + } + } + + for(i=0;i<=maxbook;i++) + ci->book_param[ci->books++]=books[x[iq]][i]; + } + + /* for now, we're only using floor 1 */ + ci->floor_type[ci->floors]=1; + ci->floor_param[ci->floors]=f; + ci->floors++; + + return(0); +} + +static int vorbis_encode_global_psych_init(vorbis_info *vi,double q, + vorbis_info_psy_global *in, ...){ + int i,iq=q*10; + double x[11],dq; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy_global *g=&ci->psy_g_param; + va_list ap; + + va_start(ap,in); + for(i=0;i<11;i++) + x[i]=va_arg(ap,double); + va_end(ap); + + if(iq==10){ + iq=9; + dq=1.; + }else{ + dq=q*10.-iq; + } + + memcpy(g,in+(int)x[iq],sizeof(*g)); + + dq=x[iq]*(1.-dq)+x[iq+1]*dq; + iq=(int)dq; + dq-=iq; + if(dq==0 && iq>0){ + iq--; + dq=1.; + } + + /* interpolate the trigger threshholds */ + for(i=0;i<4;i++){ + g->preecho_thresh[i]=in[iq].preecho_thresh[i]*(1.-dq)+in[iq+1].preecho_thresh[i]*dq; + g->postecho_thresh[i]=in[iq].postecho_thresh[i]*(1.-dq)+in[iq+1].postecho_thresh[i]*dq; + } + g->ampmax_att_per_sec=in[iq].ampmax_att_per_sec*(1.-dq)+in[iq+1].ampmax_att_per_sec*dq; + return(0); +} + +static int vorbis_encode_psyset_init(vorbis_info *vi,double q,int block, + vorbis_info_psy *in){ + int iq=q*10; + double dq; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + if(iq==10){ + iq=9; + dq=1.; + }else{ + dq=q*10.-iq; + } + + if(block>=ci->psys) + ci->psys=block+1; + if(!p){ + p=calloc(1,sizeof(*p)); + ci->psy_param[block]=p; + } + + memcpy(p,in+(int)(q*10.),sizeof(*p)); + + p->ath_adjatt=in[iq].ath_adjatt*(1.-dq)+in[iq+1].ath_adjatt*dq; + p->ath_maxatt=in[iq].ath_maxatt*(1.-dq)+in[iq+1].ath_maxatt*dq; + + p->tone_masteratt=in[iq].tone_masteratt*(1.-dq)+in[iq+1].tone_masteratt*dq; + p->tone_guard=in[iq].tone_guard*(1.-dq)+in[iq+1].tone_guard*dq; + p->tone_abs_limit=in[iq].tone_abs_limit*(1.-dq)+in[iq+1].tone_abs_limit*dq; + + p->noisemaxsupp=in[iq].noisemaxsupp*(1.-dq)+in[iq+1].noisemaxsupp*dq; + + return(0); +} + +static int vorbis_encode_compand_init(vorbis_info *vi,double q,int block, + float in[][NOISE_COMPAND_LEVELS], ...){ + int i,iq=q*10; + double x[11],dq; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + va_list ap; + + va_start(ap,in); + for(i=0;i<11;i++) + x[i]=va_arg(ap,double); + va_end(ap); + + if(iq==10){ + iq=9; + dq=1.; + }else{ + dq=q*10.-iq; + } + + dq=x[iq]*(1.-dq)+x[iq+1]*dq; + iq=(int)dq; + dq-=iq; + if(dq==0 && iq>0){ + iq--; + dq=1.; + } + + /* interpolate the compander settings */ + for(i=0;i<NOISE_COMPAND_LEVELS;i++) + p->noisecompand[i]=in[iq][i]*(1.-dq)+in[iq+1][i]*dq; + return(0); +} + +static int vorbis_encode_tonemask_init(vorbis_info *vi,double q,int block, + vp_adjblock *in){ + int i,j,iq=q*5.; + double dq; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + if(iq==5){ + iq=5; + dq=1.; + }else{ + dq=q*5.-iq; + } + + for(i=0;i<P_BANDS;i++) + for(j=0;j<P_LEVELS;j++) + p->toneatt.block[i][j]=(j<4?4:j)*-10.+ + in[iq].block[i][j]*(1.-dq)+in[iq+1].block[i][j]*dq; + return(0); +} + +static int vorbis_encode_peak_init(vorbis_info *vi,double q,int block, + vp_adjblock *in){ + int i,j,iq=q*5.; + double dq; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + if(iq==5){ + iq=5; + dq=1.; + }else{ + dq=q*5.-iq; + } + + for(i=0;i<P_BANDS;i++) + for(j=0;j<P_LEVELS;j++) + p->peakatt.block[i][j]=(j<4?4:j)*-10.+ + in[iq].block[i][j]*(1.-dq)+in[iq+1].block[i][j]*dq; + return(0); +} + +static int vorbis_encode_noisebias_init(vorbis_info *vi,double q,int block, + int in[][17],int guard[33]){ + int i,iq=q*10; + double dq; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + + if(iq==10){ + iq=9; + dq=1.; + }else{ + dq=q*10.-iq; + } + + p->noisewindowlomin=guard[iq*3]; + p->noisewindowhimin=guard[iq*3+1]; + p->noisewindowfixed=guard[iq*3+2]; - memcpy(ci,cs,sizeof(*ci)); /* to get the flat numbers */ + for(i=0;i<P_BANDS;i++) + p->noiseoff[i]=in[iq][i]*(1.-dq)+in[iq+1][i]*dq; + return(0); +} - /* codebooks */ - for(i=0;i<ci->books;i++){ - ci->book_param[i]=cs->book_param[i]; +static int vorbis_encode_ath_init(vorbis_info *vi,double q,int block, + float in[][27], ...){ + int i,iq=q*10; + double x[11],dq; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_psy *p=ci->psy_param[block]; + va_list ap; + + va_start(ap,in); + for(i=0;i<11;i++) + x[i]=va_arg(ap,double); + va_end(ap); + + if(iq==10){ + iq=9; + dq=1.; + }else{ + dq=q*10.-iq; } - /* time backend settings */ - for(i=0;i<ci->times;i++){ - ci->time_param[i]=_time_P[ci->time_type[i]]-> - copy_info(cs->time_param[i]); + dq=x[iq]*(1.-dq)+x[iq+1]*dq; + iq=(int)dq; + dq-=iq; + if(dq==0 && iq>0){ + iq--; + dq=1.; } - /* floor backend settings */ - for(i=0;i<ci->floors;i++){ - ci->floor_param[i]=_floor_P[ci->floor_type[i]]-> - copy_info(cs->floor_param[i]); + for(i=0;i<27;i++) + p->ath[i]=in[iq][i]*(1.-dq)+in[iq+1][i]*dq; + return(0); +} + +static int vorbis_encode_residue_init(vorbis_info *vi,double q,int block, + int coupled_p, + int stereo_backfill_p, + int residue_backfill_p, + vorbis_residue_template *in, ...){ + + int i,iq=q*10; + int a[11]; + double c[11]; + int n; + int partition_position; + int res_position; + int iterations=1; + int amplitude_select; + + codec_setup_info *ci=vi->codec_setup; + vorbis_info_residue0 *r; + vorbis_info_psy *psy=ci->psy_param[block*2]; + va_list ap; + + va_start(ap,in); + for(i=0;i<11;i++) + a[i]=va_arg(ap,int); + for(i=0;i<11;i++) + c[i]=va_arg(ap,double); + va_end(ap); + + /* may be re-called due to ctl */ + if(ci->residue_param[block]) + /* free preexisting instance */ + residue_free_info(ci->residue_param[block],ci->residue_type[block]); + + r=ci->residue_param[block]=malloc(sizeof(*r)); + memcpy(r,in[iq].res[block],sizeof(*r)); + if(ci->residues<=block)ci->residues=block+1; + + if(block){ + r->grouping=32; + }else{ + r->grouping=16; } - /* residue backend settings */ - for(i=0;i<ci->residues;i++){ - ci->residue_param[i]=_residue_P[ci->residue_type[i]]-> - copy_info(cs->residue_param[i]); + /* for uncoupled, we use type 1, else type 2 */ + if(coupled_p){ + ci->residue_type[block]=2; + }else{ + ci->residue_type[block]=1; } - /* map backend settings */ - for(i=0;i<ci->maps;i++){ - ci->map_param[i]=_mapping_P[ci->map_type[i]]-> - copy_info(cs->map_param[i]); + switch(ci->residue_type[block]){ + case 1: + n=r->end=ci->blocksizes[block?1:0]>>1; /* to be adjusted by lowpass later */ + partition_position=rint((double)c[iq]*1000/(vi->rate/2)*n/r->grouping); + res_position=partition_position*r->grouping; + break; + case 2: + n=r->end=(ci->blocksizes[block?1:0]>>1)*vi->channels; /* to be adjusted by lowpass later */ + partition_position=rint((double)c[iq]*1000/(vi->rate/2)*n/r->grouping); + res_position=partition_position*r->grouping/vi->channels; + break; } + + for(i=0;i<r->partitions;i++) + if(r->blimit[i]<0)r->blimit[i]=partition_position; - /* mode settings */ - for(i=0;i<ci->modes;i++){ - ci->mode_param[i]=_ogg_calloc(1,sizeof(*ci->mode_param[i])); - ci->mode_param[i]->blockflag=cs->mode_param[i]->blockflag; - ci->mode_param[i]->windowtype=cs->mode_param[i]->windowtype; - ci->mode_param[i]->transformtype=cs->mode_param[i]->transformtype; - ci->mode_param[i]->mapping=cs->mode_param[i]->mapping; + if(coupled_p){ + int k; + vorbis_info_mapping0 *map=ci->map_param[block]; + + map->coupling_steps=1; + map->coupling_mag[0]=0; + map->coupling_ang[0]=1; + + psy->couple_pass[0].granulem=1.; + psy->couple_pass[0].igranulem=1.; + + psy->couple_pass[0].couple_pass[0].limit=res_position; + psy->couple_pass[0].couple_pass[0].outofphase_redundant_flip_p=1; + psy->couple_pass[0].couple_pass[0].outofphase_requant_limit=9e10; + psy->couple_pass[0].couple_pass[0].amppost_point=0; + psy->couple_pass[0].couple_pass[1].limit=9999; + psy->couple_pass[0].couple_pass[1].outofphase_redundant_flip_p=1; + psy->couple_pass[0].couple_pass[1].outofphase_requant_limit=9e10; + psy->couple_pass[0].couple_pass[1].amppost_point=stereo_threshholds[a[iq]]; + amplitude_select=a[iq]; + + for(i=0;i<r->partitions;i++) + for(k=0;k<3;k++) + if(in[iq].books_base[a[iq]][i][k]) + r->secondstages[i]|=(1<<k); + + ci->passlimit[0]=3; + + if(stereo_backfill_p && a[iq]){ + memcpy(psy->couple_pass+iterations,psy->couple_pass+iterations-1, + sizeof(*psy->couple_pass)); + amplitude_select=a[iq]-1; + psy->couple_pass[1].couple_pass[1].amppost_point=stereo_threshholds[a[iq]-1]; + ci->passlimit[1]=4; + for(i=0;i<r->partitions;i++) + if(in[iq].books_stereo_backfill[a[iq]-1][i]) + r->secondstages[i]|=8; + iterations++; + } + + if(residue_backfill_p){ + memcpy(psy->couple_pass+iterations,psy->couple_pass+iterations-1, + sizeof(*psy->couple_pass)); + psy->couple_pass[iterations].granulem=.333333333; + psy->couple_pass[iterations].igranulem=3.; + for(i=0;i<r->partitions;i++) + if(in[iq].books_residue_backfill[amplitude_select][i][0]) + r->secondstages[i]|=(1<<(iterations+2)); + ci->passlimit[iterations]=ci->passlimit[iterations-1]+1; + iterations++; + + memcpy(psy->couple_pass+iterations,psy->couple_pass+iterations-1, + sizeof(*psy->couple_pass)); + psy->couple_pass[iterations].granulem=.1111111111; + psy->couple_pass[iterations].igranulem=9.; + for(i=0;i<r->partitions;i++) + if(in[iq].books_residue_backfill[amplitude_select][i][1]) + r->secondstages[i]|=(1<<(iterations+2)); + ci->passlimit[iterations]=ci->passlimit[iterations-1]+1; + iterations++; + } + ci->coupling_passes=iterations; + + }else{ + ci->passlimit[0]=3; + + if(residue_backfill_p){ + for(i=0;i<r->partitions;i++){ + if(in[iq].books_residue_backfill[amplitude_select][i][0]) + r->secondstages[i]|=8; + if(in[iq].books_residue_backfill[amplitude_select][i][1]) + r->secondstages[i]|=16; + } + ci->passlimit[1]=4; + ci->passlimit[2]=5; + ci->coupling_passes=3; + }else + ci->coupling_passes=1; } - /* psy settings */ - for(i=0;i<ci->psys;i++){ - ci->psy_param[i]=_vi_psy_copy(cs->psy_param[i]); + memcpy(&ci->psy_param[block*2+1]->couple_pass, + &ci->psy_param[block*2]->couple_pass, + sizeof(psy->couple_pass[0])); + + /* fill in all the books */ + { + int booklist=0,k; + r->groupbook=ci->books; + ci->book_param[ci->books++]=in[iq].book_aux[block]; + for(i=0;i<r->partitions;i++){ + for(k=0;k<3;k++){ + if(in[iq].books_base[a[iq]][i][k]){ + r->booklist[booklist++]=ci->books; + ci->book_param[ci->books++]=in[iq].books_base[a[iq]][i][k]; + } + if(coupled_p && stereo_backfill_p && a[iq] && + in[iq].books_stereo_backfill[a[iq]][i]){ + r->booklist[booklist++]=ci->books; + ci->book_param[ci->books++]=in[iq].books_stereo_backfill[a[iq]][i]; + } + if(residue_backfill_p) + for(k=0;k<2;k++){ + if(in[iq].books_residue_backfill[amplitude_select][i][k]){ + r->booklist[booklist++]=ci->books; + ci->book_param[ci->books++]=in[iq].books_residue_backfill[amplitude_select][i][k]; + } + } + } + } } + return(0); +} + +static int vorbis_encode_lowpass_init(vorbis_info *vi,double q,int block,...){ + int i,iq=q*10; + double x[11],dq; + double freq; + codec_setup_info *ci=vi->codec_setup; + vorbis_info_floor1 *f=ci->floor_param[block]; + vorbis_info_residue0 *r=ci->residue_param[block]; + int blocksize=ci->blocksizes[block]>>1; + double nyq=vi->rate/2.; + va_list ap; + + va_start(ap,block); + for(i=0;i<11;i++) + x[i]=va_arg(ap,double); + va_end(ap); + + if(iq==10){ + iq=9; + dq=1.; + }else{ + dq=q*10.-iq; + } + + freq=(x[iq]*(1.-dq)+x[iq+1]*dq)*1000.; + + /* lowpass needs to be set in the floor and the residue. */ + + /* 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; + + /* 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=rint((freq/nyq*blocksize*2)/r->grouping+.9)* /* round up only if we're well past */ + r->grouping; + else + r->end=rint((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */ + r->grouping; + return(0); } /* encoders will need to use vorbis_info_init beforehand and call @@ -91,18 +589,110 @@ int vorbis_encode_init_vbr(vorbis_info *vi, float base_quality /* 0. to 1. */ ){ + int ret=0; + + base_quality=.4; + + if(rate>40000){ + ret|=vorbis_encode_toplevel_init(vi,256,2048,channels,rate); + ret|=vorbis_encode_floor_init(vi,base_quality,0,_floor_44_128_books,_floor_44_128, + 0,1,1,2,2,2,2,2,2,2,2); + ret|=vorbis_encode_floor_init(vi,base_quality,1,_floor_44_1024_books,_floor_44_1024, + 0,0,0,0,0,0,0,0,0,0,0); + + ret|=vorbis_encode_global_psych_init(vi,base_quality,_psy_global_44, + 0., 1., 1.5, 2., 2., 2., 2., 2., 2., 2., 2.); + + ret|=vorbis_encode_psyset_init(vi,base_quality,0,_psy_settings); + ret|=vorbis_encode_psyset_init(vi,base_quality,1,_psy_settings); + ret|=vorbis_encode_psyset_init(vi,base_quality,2,_psy_settings); + ret|=vorbis_encode_psyset_init(vi,base_quality,3,_psy_settings); + + ret|=vorbis_encode_tonemask_init(vi,base_quality,0,_vp_tonemask_adj_otherblock); + ret|=vorbis_encode_tonemask_init(vi,base_quality,1,_vp_tonemask_adj_otherblock); + ret|=vorbis_encode_tonemask_init(vi,base_quality,2,_vp_tonemask_adj_otherblock); + ret|=vorbis_encode_tonemask_init(vi,base_quality,3,_vp_tonemask_adj_longblock); + + ret|=vorbis_encode_compand_init(vi,base_quality,0,_psy_compand_44_short, + 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.); + ret|=vorbis_encode_compand_init(vi,base_quality,1,_psy_compand_44_short, + 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.); + ret|=vorbis_encode_compand_init(vi,base_quality,2,_psy_compand_44, + 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.); + ret|=vorbis_encode_compand_init(vi,base_quality,3,_psy_compand_44, + 1., 1., 1.3, 1.6, 2., 2., 2., 2., 2., 2., 2.); + + ret|=vorbis_encode_peak_init(vi,base_quality,0,_vp_peakguard); + ret|=vorbis_encode_peak_init(vi,base_quality,1,_vp_peakguard); + ret|=vorbis_encode_peak_init(vi,base_quality,2,_vp_peakguard); + ret|=vorbis_encode_peak_init(vi,base_quality,3,_vp_peakguard); + + ret|=vorbis_encode_noisebias_init(vi,base_quality,0,_psy_noisebias_impulse, + _psy_noiseguards_short); + ret|=vorbis_encode_noisebias_init(vi,base_quality,1,_psy_noisebias_other, + _psy_noiseguards_short); + ret|=vorbis_encode_noisebias_init(vi,base_quality,2,_psy_noisebias_other, + _psy_noiseguards_long); + ret|=vorbis_encode_noisebias_init(vi,base_quality,3,_psy_noisebias_long, + _psy_noiseguards_long); + + ret|=vorbis_encode_ath_init(vi,base_quality,0,ATH_Bark_dB, + 0., 0., 0., 0., .2, .5, 1., 1., 1.5, 2., 2.); + ret|=vorbis_encode_ath_init(vi,base_quality,1,ATH_Bark_dB, + 0., 0., 0., 0., .2, .5, 1., 1., 1.5, 2., 2.); + ret|=vorbis_encode_ath_init(vi,base_quality,2,ATH_Bark_dB, + 0., 0., 0., 0., .2, .5, 1., 1., 1.5, 2., 2.); + ret|=vorbis_encode_ath_init(vi,base_quality,3,ATH_Bark_dB, + 0., 0., 0., 0., .2, .5, 1., 1., 1.5, 2., 2.); + + if(ret){ + vorbis_info_clear(vi); + return ret; + } - switch(channels){ - case 2: - return(OV_EIMPL); - - - break; - default: + switch(channels){ + case 2: + /* setup specific to stereo coupling */ + + /* unmanaged, one iteration residue setup */ + ret|=vorbis_encode_residue_init(vi,base_quality,0, + 1, /* coupled */ + 0, /* no mid stereo backfill */ + 0, /* no residue backfill */ + _residue_template_44_stereo, + 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 4., 6., 6., 6., 10., 6., 6., 6., 6., 6., 6.); + + ret|=vorbis_encode_residue_init(vi,base_quality,1, + 1, /* coupled */ + 0, /* no mid stereo backfill */ + 0, /* no residue backfill */ + _residue_template_44_stereo, + 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 6., 6., 6., 10., 10., 6., 6., 6., 6., 6., 6.); + + ret|=vorbis_encode_lowpass_init(vi,base_quality,0, + 15.1,15.8,16.5,17.9,20.5, + 999.,999.,999.,999.,999.,999.); + ret|=vorbis_encode_lowpass_init(vi,base_quality,1, + 15.1,15.8,16.5,17.9,20.5, + 999.,999.,999.,999.,999.,999.); + + return(ret); + + break; + default: + return(OV_EIMPL); + + break; + } + return(0); + }else return(OV_EIMPL); - break; - } + if(ret) + vorbis_info_clear(vi); + return(ret); } @@ -114,86 +704,20 @@ int vorbis_encode_init(vorbis_info *vi, long nominal_bitrate, long min_bitrate){ - long bpch; - int i,j; - codec_setup_info *ci=vi->codec_setup; - codec_setup_info *mode=NULL; - if(!ci)return(OV_EFAULT); - - vi->version=0; - vi->channels=channels; - vi->rate=rate; - - vi->bitrate_upper=max_bitrate; - vi->bitrate_nominal=nominal_bitrate; - vi->bitrate_lower=min_bitrate; - vi->bitrate_window=2; + /* it's temporary while I do the merge; relax */ + return(vorbis_encode_init_vbr(vi,channels,rate, .4)); - /* copy a mode into our allocated storage */ - bpch=nominal_bitrate/channels; + return(OV_EIMPL); +} -#if 0 - switch(channels){ - case 2: -/* if(rate>40000){ */ - - if(bpch<35000){ - mode=&info_44c_Z; - }else if(bpch<45000){ - mode=&info_44c_Y; - }else if(bpch<55000){ - mode=&info_44c_X; - }else if(bpch<75000){ - mode=&info_44c_A; - }else if(bpch<90000){ - mode=&info_44c_B; - }else if(bpch<110000){ - mode=&info_44c_C; - }else if(bpch<160000){ - mode=&info_44c_D; - }else{ - mode=&info_44c_E; - } -/* } */ +int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ + return(OV_EIMPL); +} + - break; - default: - - if(bpch<40000){ - mode=&info_44_Z; - }else if(bpch<50000){ - mode=&info_44_Y; - }else if(bpch<70000){ - mode=&info_44_X; - }else if(bpch<90000){ - mode=&info_44_A; - }else if(bpch<120000){ - mode=&info_44_B; - }else{ - mode=&info_44_C; - } - break; - } -#endif - mode=&info_44c_A; - /* now we have to deepcopy */ - codec_setup_partialcopy(ci,mode); - /* adjust for sample rate */ - /* we don't have any floor 0 modes anymore - for(i=0;i<ci->floors;i++) - if(ci->floor_type[i]==0) - ((vorbis_info_floor0 *)(ci->floor_param[i]))->rate=rate; */ - /* adjust for channels */ - /* but all our mappings use submap zero now! */ - return(0); -} -int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ - return(OV_EIMPL); -} - |