+typedef struct {
+ 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;
+
+typedef struct {
+ const vorbis_info_mapping0 *map;
+ const vorbis_residue_template *res;
+} vorbis_mapping_template;
+
+typedef struct vp_adjblock{
+ int block[P_BANDS];
+} vp_adjblock;
+
+typedef struct {
+ 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. */
+
+typedef struct {
+ int att[P_NOISECURVES];
+ float boost;
+ float decay;
+} att3;
+typedef struct { int data[P_NOISECURVES]; } adj3;
+
+typedef struct {
+ int pre[PACKETBLOBS];
+ int post[PACKETBLOBS];
+ float kHz[PACKETBLOBS];
+ float lowpasskHz[PACKETBLOBS];
+} adj_stereo;
+
+typedef struct {
+ int lo;
+ int hi;
+ int fixed;
+} noiseguard;
+typedef struct {
+ int data[P_NOISECURVES][17];
+} noise3;
+
+typedef struct {
+ int mappings;
+ const double *rate_mapping;
+ const double *quality_mapping;
+ int coupling_restriction;
+ long samplerate_min_restriction;
+ long samplerate_max_restriction;
+
+
+ const int *blocksize_short;
+ const int *blocksize_long;
+
+ const att3 *psy_tone_masteratt;
+ const int *psy_tone_0dB;
+ const int *psy_tone_dBsuppress;
+
+ const vp_adjblock *psy_tone_adj_impulse;
+ const vp_adjblock *psy_tone_adj_long;
+ const vp_adjblock *psy_tone_adj_other;
+
+ const noiseguard *psy_noiseguards;
+ const noise3 *psy_noise_bias_impulse;
+ const noise3 *psy_noise_bias_padding;
+ const noise3 *psy_noise_bias_trans;
+ const noise3 *psy_noise_bias_long;
+ const int *psy_noise_dBsuppress;
+
+ const compandblock *psy_noise_compand;
+ const double *psy_noise_compand_short_mapping;
+ const double *psy_noise_compand_long_mapping;
+
+ const int *psy_noise_normal_start[2];
+ const int *psy_noise_normal_partition[2];
+ const double *psy_noise_normal_thresh;
+
+ const int *psy_ath_float;
+ const int *psy_ath_abs;
+
+ const double *psy_lowpass;
+
+ const vorbis_info_psy_global *global_params;
+ const double *global_mapping;
+ const adj_stereo *stereo_modes;
+
+ const static_codebook *const *const *const floor_books;
+ const vorbis_info_floor1 *floor_params;
+ const int floor_mappings;
+ const int **floor_mapping_list;
+
+ const vorbis_mapping_template *maps;
+} ve_setup_data_template;
+
+/* a few static coder conventions */
+static const vorbis_info_mode _mode_template[2]={
+ {0,0,0,0},
+ {1,0,0,1}
+};
+
+static const vorbis_info_mapping0 _map_nominal[2]={
+ {1, {0,0}, {0}, {0}, 1,{0},{1}},
+ {1, {0,0}, {1}, {1}, 1,{0},{1}}
+};
+
+#include "modes/setup_44.h"
+#include "modes/setup_44u.h"
+#include "modes/setup_44p51.h"
+#include "modes/setup_32.h"
+#include "modes/setup_8.h"
+#include "modes/setup_11.h"
+#include "modes/setup_16.h"
+#include "modes/setup_22.h"
+#include "modes/setup_X.h"
+
+static const ve_setup_data_template *const setup_list[]={
+ &ve_setup_44_stereo,
+ &ve_setup_44_51,
+ &ve_setup_44_uncoupled,
+
+ &ve_setup_32_stereo,
+ &ve_setup_32_uncoupled,
+
+ &ve_setup_22_stereo,
+ &ve_setup_22_uncoupled,
+ &ve_setup_16_stereo,
+ &ve_setup_16_uncoupled,
+
+ &ve_setup_11_stereo,
+ &ve_setup_11_uncoupled,
+ &ve_setup_8_stereo,
+ &ve_setup_8_uncoupled,
+
+ &ve_setup_X_stereo,
+ &ve_setup_X_uncoupled,
+ &ve_setup_XX_stereo,
+ &ve_setup_XX_uncoupled,
+ 0
+};
+
+static void vorbis_encode_floor_setup(vorbis_info *vi,int s,
+ const static_codebook *const *const *const books,
+ const vorbis_info_floor1 *in,
+ const int *x){
+ int i,k,is=s;
+ vorbis_info_floor1 *f=_ogg_calloc(1,sizeof(*f));
+ codec_setup_info *ci=vi->codec_setup;
+
+ memcpy(f,in+x[is],sizeof(*f));
+
+ /* 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++]=(static_codebook *)books[x[is]][i];
+ }
+
+ /* for now, we're only using floor 1 */
+ ci->floor_type[ci->floors]=1;
+ ci->floor_param[ci->floors]=f;
+ ci->floors++;
+
+ return;
+}
+
+static void vorbis_encode_global_psych_setup(vorbis_info *vi,double s,
+ const vorbis_info_psy_global *in,
+ const double *x){
+ int i,is=s;
+ double ds=s-is;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_psy_global *g=&ci->psy_g_param;
+
+ memcpy(g,in+(int)x[is],sizeof(*g));
+
+ ds=x[is]*(1.-ds)+x[is+1]*ds;
+ is=(int)ds;
+ ds-=is;
+ if(ds==0 && is>0){
+ is--;
+ ds=1.;
+ }
+
+ /* interpolate the trigger threshholds */
+ for(i=0;i<4;i++){
+ g->preecho_thresh[i]=in[is].preecho_thresh[i]*(1.-ds)+in[is+1].preecho_thresh[i]*ds;
+ g->postecho_thresh[i]=in[is].postecho_thresh[i]*(1.-ds)+in[is+1].postecho_thresh[i]*ds;
+ }
+ g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec;
+ return;
+}
+
+static void vorbis_encode_global_stereo(vorbis_info *vi,
+ const highlevel_encode_setup *const hi,
+ const adj_stereo *p){
+ float s=hi->stereo_point_setting;
+ int i,is=s;
+ double ds=s-is;
+ codec_setup_info *ci=vi->codec_setup;
+ vorbis_info_psy_global *g=&ci->psy_g_param;
+
+ if(p){
+ memcpy(g->coupling_prepointamp,p[is].pre,sizeof(*p[is].pre)*PACKETBLOBS);
+ memcpy(g->coupling_postpointamp,p[is].post,sizeof(*p[is].post)*PACKETBLOBS);
+
+ if(hi->managed){
+ /* interpolate the kHz threshholds */
+ for(i=0;i<PACKETBLOBS;i++){
+ float kHz=p[is].kHz[i]*(1.-ds)+p[is+1].kHz[i]*ds;
+ g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
+ g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
+ g->coupling_pkHz[i]=kHz;
+
+ kHz=p[is].lowpasskHz[i]*(1.-ds)+p[is+1].lowpasskHz[i]*ds;
+ g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
+ g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
+
+ }
+ }else{
+ float kHz=p[is].kHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].kHz[PACKETBLOBS/2]*ds;
+ for(i=0;i<PACKETBLOBS;i++){
+ g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
+ g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
+ g->coupling_pkHz[i]=kHz;
+ }
+
+ kHz=p[is].lowpasskHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].lowpasskHz[PACKETBLOBS/2]*ds;
+ for(i=0;i<PACKETBLOBS;i++){
+ g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
+ g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
+ }
+ }
+ }else{
+ for(i=0;i<PACKETBLOBS;i++){
+ g->sliding_lowpass[0][i]=ci->blocksizes[0];
+ g->sliding_lowpass[1][i]=ci->blocksizes[1];
+ }
+ }
+ return;
+}