/******************************************************************** * * * 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-2015 * * by the Xiph.Org Foundation https://xiph.org/ * * * ********************************************************************
function: simple programmatic interface for encoder mode setup
/* 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 > 12 partition types, or a different division of iteration,
this needs to be updated. */ typedefstruct { const static_codebook *books[12][4];
} static_bookblock;
typedefstruct { int res_type; int limit_type; /* 0 lowpass limited, 1 point stereo limited */ int grouping; const vorbis_info_residue0 *res; const static_codebook *book_aux; const static_codebook *book_aux_managed; const static_bookblock *books_base; const static_bookblock *books_base_managed;
} vorbis_residue_template;
typedefstruct vp_adjblock{ int block[P_BANDS];
} vp_adjblock;
typedefstruct { int data[NOISE_COMPAND_LEVELS];
} compandblock;
/* high level configuration information for setting things up step-by-step with the detailed vorbis_encode_ctl interface. There's a fair amount of redundancy such that interactive setup does not directly deal with any vorbis_info or codec_setup_info initialization; it's all stored (until full init) in this highlevel
setup, then flushed out to the real codec setup structs later. */
typedefstruct { int att[P_NOISECURVES]; float boost; float decay;
} att3; typedefstruct { int data[P_NOISECURVES]; } adj3;
typedefstruct { int pre[PACKETBLOBS]; int post[PACKETBLOBS]; float kHz[PACKETBLOBS]; float lowpasskHz[PACKETBLOBS];
} adj_stereo;
typedefstruct { int lo; int hi; int fixed;
} noiseguard; typedefstruct { int data[P_NOISECURVES][17];
} noise3;
typedefstruct { int mappings; constdouble *rate_mapping; constdouble *quality_mapping; int coupling_restriction; long samplerate_min_restriction; long samplerate_max_restriction;
/* 0 and 2 are only used by bitmanagement, but there's no harm to always
filling the values in here */
p->tone_masteratt[0]=att[is].att[0]*(1.-ds)+att[is+1].att[0]*ds;
p->tone_masteratt[1]=att[is].att[1]*(1.-ds)+att[is+1].att[1]*ds;
p->tone_masteratt[2]=att[is].att[2]*(1.-ds)+att[is+1].att[2]*ds;
p->tone_centerboost=att[is].boost*(1.-ds)+att[is+1].boost*ds;
p->tone_decay=att[is].decay*(1.-ds)+att[is+1].decay*ds;
/* impulse blocks may take a user specified bias to boost the
nominal/high noise encoding depth */ for(j=0;j<P_NOISECURVES;j++){ float min=p->noiseoff[j][0]+6; /* the lowest it can go */ for(i=0;i<P_BANDS;i++){
p->noiseoff[j][i]+=userbias; if(p->noiseoff[j][i]<min)p->noiseoff[j][i]=min;
}
}
/* 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;
/* the template matches. Does the requested quality mode
fall within this template's modes? */ if(req<map[0]){++i;continue;} if(req>map[setup_list[i]->mappings]){++i;continue;} for(j=0;j<mappings;j++) if(req>=map[j] && req<map[j+1])break; /* an all-points match */ if(j==mappings)
*base_setting=j-.001; else{ float low=map[j]; float high=map[j+1]; float del=(req-low)/(high-low);
*base_setting=j+del;
}
return(setup_list[i]);
}
}
i++;
}
return NULL;
}
/* encoders will need to use vorbis_info_init beforehand and call
vorbis_info clear when all done */
/* two interfaces; this, more detailed one, and later a convenience
layer on top */
/* the final setup call */ int vorbis_encode_setup_init(vorbis_info *vi){ int i,i0=0,singleblock=0;
codec_setup_info *ci=vi->codec_setup;
ve_setup_data_template *setup=NULL;
highlevel_encode_setup *hi=&ci->hi;
/* too low/high an ATH floater is nonsensical, but doesn't break anything */ if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80; if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200;
/* again, bound this to avoid the app shooting itself int he foot
too badly */ if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.; if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.;
/* get the appropriate setup template; matches the fetch in previous
stages */
setup=(ve_setup_data_template *)hi->setup; if(setup==NULL)return(OV_EINVAL);
hi->set_in_stone=1; /* choose block sizes from configured sizes as well as paying attention to long_block_p and short_block_p. If the configured short and long blocks are the same length, we set long_block_p
and unset short_block_p */
vorbis_encode_blocksize_setup(vi,hi->base_setting,
setup->blocksize_short,
setup->blocksize_long); if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1;
/* floor setup; choose proper floor params. Allocated on the floor
stack in order; if we alloc only a single long floor, it's 0 */ for(i=0;i<setup->floor_mappings;i++)
vorbis_encode_floor_setup(vi,hi->base_setting,
setup->floor_books,
setup->floor_params,
setup->floor_mapping_list[i]);
/* setup of [mostly] short block detection and stereo*/
vorbis_encode_global_psych_setup(vi,hi->trigger_setting,
setup->global_params,
setup->global_mapping);
vorbis_encode_global_stereo(vi,hi,setup->stereo_modes);
/* initialize management with sane defaults */
hi->coupling_p=1;
hi->managed=1;
hi->bitrate_min=min_bitrate;
hi->bitrate_max=max_bitrate;
hi->bitrate_av=tnominal;
hi->bitrate_av_damp=1.5f; /* full range in no less than 1.5 second */
hi->bitrate_reservoir=nominal_bitrate*2;
hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */
return(0);
}
int vorbis_encode_init(vorbis_info *vi, long channels, long rate,
long max_bitrate, long nominal_bitrate, long min_bitrate){
int ret=vorbis_encode_setup_managed(vi,channels,rate,
max_bitrate,
nominal_bitrate,
min_bitrate); if(ret){
vorbis_info_clear(vi); return(ret);
}
int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){ if(vi){
codec_setup_info *ci=vi->codec_setup;
highlevel_encode_setup *hi=&ci->hi; int setp=(number&0xf); /* a read request has a low nibble of 0 */
if(setp && hi->set_in_stone)return(OV_EINVAL);
switch(number){
/* now deprecated *****************/ case OV_ECTL_RATEMANAGE_GET:
{
if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.; if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.;
} return(0); case OV_ECTL_COUPLING_GET:
{ int *iarg=(int *)arg;
*iarg=hi->coupling_p;
} return(0); case OV_ECTL_COUPLING_SET:
{ constvoid *new_template; double new_base=0.; int *iarg=(int *)arg;
hi->coupling_p=((*iarg)!=0);
/* Fetching a new template can alter the base_setting, which many other parameters are based on. Right now, the only parameter drawn from the base_setting that can be altered by an encctl is the lowpass, so that is explictly flagged to not be overwritten when we fetch a new template and
recompute the dependant settings */
new_template = get_setup_template(hi->coupling_p?vi->channels:-1,
vi->rate,
hi->req,
hi->managed,
&new_base); if(!new_template)return OV_EIMPL;
hi->setup=new_template;
hi->base_setting=new_base;
vorbis_encode_setup_setting(vi,vi->channels,vi->rate);
} return(0);
} return(OV_EIMPL);
} return(OV_EINVAL);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.4 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.