Home | History | Annotate | Download | only in lib
      1 /********************************************************************
      2  *                                                                  *
      3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
      4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
      5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
      6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
      7  *                                                                  *
      8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
      9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
     10  *                                                                  *
     11  ********************************************************************
     12 
     13  function: simple programmatic interface for encoder mode setup
     14  last mod: $Id: vorbisenc.c 17028 2010-03-25 05:22:15Z xiphmont $
     15 
     16  ********************************************************************/
     17 
     18 #include <stdlib.h>
     19 #include <string.h>
     20 #include <math.h>
     21 
     22 #include "vorbis/codec.h"
     23 #include "vorbis/vorbisenc.h"
     24 
     25 #include "codec_internal.h"
     26 
     27 #include "os.h"
     28 #include "misc.h"
     29 
     30 /* careful with this; it's using static array sizing to make managing
     31    all the modes a little less annoying.  If we use a residue backend
     32    with > 12 partition types, or a different division of iteration,
     33    this needs to be updated. */
     34 typedef struct {
     35   const static_codebook *books[12][4];
     36 } static_bookblock;
     37 
     38 typedef struct {
     39   int res_type;
     40   int limit_type; /* 0 lowpass limited, 1 point stereo limited */
     41   int grouping;
     42   const vorbis_info_residue0 *res;
     43   const static_codebook  *book_aux;
     44   const static_codebook  *book_aux_managed;
     45   const static_bookblock *books_base;
     46   const static_bookblock *books_base_managed;
     47 } vorbis_residue_template;
     48 
     49 typedef struct {
     50   const vorbis_info_mapping0    *map;
     51   const vorbis_residue_template *res;
     52 } vorbis_mapping_template;
     53 
     54 typedef struct vp_adjblock{
     55   int block[P_BANDS];
     56 } vp_adjblock;
     57 
     58 typedef struct {
     59   int data[NOISE_COMPAND_LEVELS];
     60 } compandblock;
     61 
     62 /* high level configuration information for setting things up
     63    step-by-step with the detailed vorbis_encode_ctl interface.
     64    There's a fair amount of redundancy such that interactive setup
     65    does not directly deal with any vorbis_info or codec_setup_info
     66    initialization; it's all stored (until full init) in this highlevel
     67    setup, then flushed out to the real codec setup structs later. */
     68 
     69 typedef struct {
     70   int att[P_NOISECURVES];
     71   float boost;
     72   float decay;
     73 } att3;
     74 typedef struct { int data[P_NOISECURVES]; } adj3;
     75 
     76 typedef struct {
     77   int   pre[PACKETBLOBS];
     78   int   post[PACKETBLOBS];
     79   float kHz[PACKETBLOBS];
     80   float lowpasskHz[PACKETBLOBS];
     81 } adj_stereo;
     82 
     83 typedef struct {
     84   int lo;
     85   int hi;
     86   int fixed;
     87 } noiseguard;
     88 typedef struct {
     89   int data[P_NOISECURVES][17];
     90 } noise3;
     91 
     92 typedef struct {
     93   int      mappings;
     94   const double  *rate_mapping;
     95   const double  *quality_mapping;
     96   int      coupling_restriction;
     97   long     samplerate_min_restriction;
     98   long     samplerate_max_restriction;
     99 
    100 
    101   const int     *blocksize_short;
    102   const int     *blocksize_long;
    103 
    104   const att3    *psy_tone_masteratt;
    105   const int     *psy_tone_0dB;
    106   const int     *psy_tone_dBsuppress;
    107 
    108   const vp_adjblock *psy_tone_adj_impulse;
    109   const vp_adjblock *psy_tone_adj_long;
    110   const vp_adjblock *psy_tone_adj_other;
    111 
    112   const noiseguard  *psy_noiseguards;
    113   const noise3      *psy_noise_bias_impulse;
    114   const noise3      *psy_noise_bias_padding;
    115   const noise3      *psy_noise_bias_trans;
    116   const noise3      *psy_noise_bias_long;
    117   const int         *psy_noise_dBsuppress;
    118 
    119   const compandblock  *psy_noise_compand;
    120   const double        *psy_noise_compand_short_mapping;
    121   const double        *psy_noise_compand_long_mapping;
    122 
    123   const int      *psy_noise_normal_start[2];
    124   const int      *psy_noise_normal_partition[2];
    125   const double   *psy_noise_normal_thresh;
    126 
    127   const int      *psy_ath_float;
    128   const int      *psy_ath_abs;
    129 
    130   const double   *psy_lowpass;
    131 
    132   const vorbis_info_psy_global *global_params;
    133   const double     *global_mapping;
    134   const adj_stereo *stereo_modes;
    135 
    136   const static_codebook *const *const *const floor_books;
    137   const vorbis_info_floor1 *floor_params;
    138   const int floor_mappings;
    139   const int **floor_mapping_list;
    140 
    141   const vorbis_mapping_template *maps;
    142 } ve_setup_data_template;
    143 
    144 /* a few static coder conventions */
    145 static const vorbis_info_mode _mode_template[2]={
    146   {0,0,0,0},
    147   {1,0,0,1}
    148 };
    149 
    150 static const vorbis_info_mapping0 _map_nominal[2]={
    151   {1, {0,0}, {0}, {0}, 1,{0},{1}},
    152   {1, {0,0}, {1}, {1}, 1,{0},{1}}
    153 };
    154 
    155 #include "modes/setup_44.h"
    156 #include "modes/setup_44u.h"
    157 #include "modes/setup_44p51.h"
    158 #include "modes/setup_32.h"
    159 #include "modes/setup_8.h"
    160 #include "modes/setup_11.h"
    161 #include "modes/setup_16.h"
    162 #include "modes/setup_22.h"
    163 #include "modes/setup_X.h"
    164 
    165 static const ve_setup_data_template *const setup_list[]={
    166   &ve_setup_44_stereo,
    167   &ve_setup_44_51,
    168   &ve_setup_44_uncoupled,
    169 
    170   &ve_setup_32_stereo,
    171   &ve_setup_32_uncoupled,
    172 
    173   &ve_setup_22_stereo,
    174   &ve_setup_22_uncoupled,
    175   &ve_setup_16_stereo,
    176   &ve_setup_16_uncoupled,
    177 
    178   &ve_setup_11_stereo,
    179   &ve_setup_11_uncoupled,
    180   &ve_setup_8_stereo,
    181   &ve_setup_8_uncoupled,
    182 
    183   &ve_setup_X_stereo,
    184   &ve_setup_X_uncoupled,
    185   &ve_setup_XX_stereo,
    186   &ve_setup_XX_uncoupled,
    187   0
    188 };
    189 
    190 static void vorbis_encode_floor_setup(vorbis_info *vi,int s,
    191                                      const static_codebook *const *const *const books,
    192                                      const vorbis_info_floor1 *in,
    193                                      const int *x){
    194   int i,k,is=s;
    195   vorbis_info_floor1 *f=_ogg_calloc(1,sizeof(*f));
    196   codec_setup_info *ci=vi->codec_setup;
    197 
    198   memcpy(f,in+x[is],sizeof(*f));
    199 
    200   /* books */
    201   {
    202     int partitions=f->partitions;
    203     int maxclass=-1;
    204     int maxbook=-1;
    205     for(i=0;i<partitions;i++)
    206       if(f->partitionclass[i]>maxclass)maxclass=f->partitionclass[i];
    207     for(i=0;i<=maxclass;i++){
    208       if(f->class_book[i]>maxbook)maxbook=f->class_book[i];
    209       f->class_book[i]+=ci->books;
    210       for(k=0;k<(1<<f->class_subs[i]);k++){
    211         if(f->class_subbook[i][k]>maxbook)maxbook=f->class_subbook[i][k];
    212         if(f->class_subbook[i][k]>=0)f->class_subbook[i][k]+=ci->books;
    213       }
    214     }
    215 
    216     for(i=0;i<=maxbook;i++)
    217       ci->book_param[ci->books++]=(static_codebook *)books[x[is]][i];
    218   }
    219 
    220   /* for now, we're only using floor 1 */
    221   ci->floor_type[ci->floors]=1;
    222   ci->floor_param[ci->floors]=f;
    223   ci->floors++;
    224 
    225   return;
    226 }
    227 
    228 static void vorbis_encode_global_psych_setup(vorbis_info *vi,double s,
    229                                             const vorbis_info_psy_global *in,
    230                                             const double *x){
    231   int i,is=s;
    232   double ds=s-is;
    233   codec_setup_info *ci=vi->codec_setup;
    234   vorbis_info_psy_global *g=&ci->psy_g_param;
    235 
    236   memcpy(g,in+(int)x[is],sizeof(*g));
    237 
    238   ds=x[is]*(1.-ds)+x[is+1]*ds;
    239   is=(int)ds;
    240   ds-=is;
    241   if(ds==0 && is>0){
    242     is--;
    243     ds=1.;
    244   }
    245 
    246   /* interpolate the trigger threshholds */
    247   for(i=0;i<4;i++){
    248     g->preecho_thresh[i]=in[is].preecho_thresh[i]*(1.-ds)+in[is+1].preecho_thresh[i]*ds;
    249     g->postecho_thresh[i]=in[is].postecho_thresh[i]*(1.-ds)+in[is+1].postecho_thresh[i]*ds;
    250   }
    251   g->ampmax_att_per_sec=ci->hi.amplitude_track_dBpersec;
    252   return;
    253 }
    254 
    255 static void vorbis_encode_global_stereo(vorbis_info *vi,
    256                                         const highlevel_encode_setup *const hi,
    257                                         const adj_stereo *p){
    258   float s=hi->stereo_point_setting;
    259   int i,is=s;
    260   double ds=s-is;
    261   codec_setup_info *ci=vi->codec_setup;
    262   vorbis_info_psy_global *g=&ci->psy_g_param;
    263 
    264   if(p){
    265     memcpy(g->coupling_prepointamp,p[is].pre,sizeof(*p[is].pre)*PACKETBLOBS);
    266     memcpy(g->coupling_postpointamp,p[is].post,sizeof(*p[is].post)*PACKETBLOBS);
    267 
    268     if(hi->managed){
    269       /* interpolate the kHz threshholds */
    270       for(i=0;i<PACKETBLOBS;i++){
    271         float kHz=p[is].kHz[i]*(1.-ds)+p[is+1].kHz[i]*ds;
    272         g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
    273         g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
    274         g->coupling_pkHz[i]=kHz;
    275 
    276         kHz=p[is].lowpasskHz[i]*(1.-ds)+p[is+1].lowpasskHz[i]*ds;
    277         g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
    278         g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
    279 
    280       }
    281     }else{
    282       float kHz=p[is].kHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].kHz[PACKETBLOBS/2]*ds;
    283       for(i=0;i<PACKETBLOBS;i++){
    284         g->coupling_pointlimit[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
    285         g->coupling_pointlimit[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
    286         g->coupling_pkHz[i]=kHz;
    287       }
    288 
    289       kHz=p[is].lowpasskHz[PACKETBLOBS/2]*(1.-ds)+p[is+1].lowpasskHz[PACKETBLOBS/2]*ds;
    290       for(i=0;i<PACKETBLOBS;i++){
    291         g->sliding_lowpass[0][i]=kHz*1000./vi->rate*ci->blocksizes[0];
    292         g->sliding_lowpass[1][i]=kHz*1000./vi->rate*ci->blocksizes[1];
    293       }
    294     }
    295   }else{
    296     for(i=0;i<PACKETBLOBS;i++){
    297       g->sliding_lowpass[0][i]=ci->blocksizes[0];
    298       g->sliding_lowpass[1][i]=ci->blocksizes[1];
    299     }
    300   }
    301   return;
    302 }
    303 
    304 static void vorbis_encode_psyset_setup(vorbis_info *vi,double s,
    305                                        const int *nn_start,
    306                                        const int *nn_partition,
    307                                        const double *nn_thresh,
    308                                        int block){
    309   codec_setup_info *ci=vi->codec_setup;
    310   vorbis_info_psy *p=ci->psy_param[block];
    311   highlevel_encode_setup *hi=&ci->hi;
    312   int is=s;
    313 
    314   if(block>=ci->psys)
    315     ci->psys=block+1;
    316   if(!p){
    317     p=_ogg_calloc(1,sizeof(*p));
    318     ci->psy_param[block]=p;
    319   }
    320 
    321   memcpy(p,&_psy_info_template,sizeof(*p));
    322   p->blockflag=block>>1;
    323 
    324   if(hi->noise_normalize_p){
    325     p->normal_p=1;
    326     p->normal_start=nn_start[is];
    327     p->normal_partition=nn_partition[is];
    328     p->normal_thresh=nn_thresh[is];
    329   }
    330 
    331   return;
    332 }
    333 
    334 static void vorbis_encode_tonemask_setup(vorbis_info *vi,double s,int block,
    335                                          const att3 *att,
    336                                          const int  *max,
    337                                          const vp_adjblock *in){
    338   int i,is=s;
    339   double ds=s-is;
    340   codec_setup_info *ci=vi->codec_setup;
    341   vorbis_info_psy *p=ci->psy_param[block];
    342 
    343   /* 0 and 2 are only used by bitmanagement, but there's no harm to always
    344      filling the values in here */
    345   p->tone_masteratt[0]=att[is].att[0]*(1.-ds)+att[is+1].att[0]*ds;
    346   p->tone_masteratt[1]=att[is].att[1]*(1.-ds)+att[is+1].att[1]*ds;
    347   p->tone_masteratt[2]=att[is].att[2]*(1.-ds)+att[is+1].att[2]*ds;
    348   p->tone_centerboost=att[is].boost*(1.-ds)+att[is+1].boost*ds;
    349   p->tone_decay=att[is].decay*(1.-ds)+att[is+1].decay*ds;
    350 
    351   p->max_curve_dB=max[is]*(1.-ds)+max[is+1]*ds;
    352 
    353   for(i=0;i<P_BANDS;i++)
    354     p->toneatt[i]=in[is].block[i]*(1.-ds)+in[is+1].block[i]*ds;
    355   return;
    356 }
    357 
    358 
    359 static void vorbis_encode_compand_setup(vorbis_info *vi,double s,int block,
    360                                         const compandblock *in,
    361                                         const double *x){
    362   int i,is=s;
    363   double ds=s-is;
    364   codec_setup_info *ci=vi->codec_setup;
    365   vorbis_info_psy *p=ci->psy_param[block];
    366 
    367   ds=x[is]*(1.-ds)+x[is+1]*ds;
    368   is=(int)ds;
    369   ds-=is;
    370   if(ds==0 && is>0){
    371     is--;
    372     ds=1.;
    373   }
    374 
    375   /* interpolate the compander settings */
    376   for(i=0;i<NOISE_COMPAND_LEVELS;i++)
    377     p->noisecompand[i]=in[is].data[i]*(1.-ds)+in[is+1].data[i]*ds;
    378   return;
    379 }
    380 
    381 static void vorbis_encode_peak_setup(vorbis_info *vi,double s,int block,
    382                                     const int *suppress){
    383   int is=s;
    384   double ds=s-is;
    385   codec_setup_info *ci=vi->codec_setup;
    386   vorbis_info_psy *p=ci->psy_param[block];
    387 
    388   p->tone_abs_limit=suppress[is]*(1.-ds)+suppress[is+1]*ds;
    389 
    390   return;
    391 }
    392 
    393 static void vorbis_encode_noisebias_setup(vorbis_info *vi,double s,int block,
    394                                          const int *suppress,
    395                                          const noise3 *in,
    396                                          const noiseguard *guard,
    397                                          double userbias){
    398   int i,is=s,j;
    399   double ds=s-is;
    400   codec_setup_info *ci=vi->codec_setup;
    401   vorbis_info_psy *p=ci->psy_param[block];
    402 
    403   p->noisemaxsupp=suppress[is]*(1.-ds)+suppress[is+1]*ds;
    404   p->noisewindowlomin=guard[block].lo;
    405   p->noisewindowhimin=guard[block].hi;
    406   p->noisewindowfixed=guard[block].fixed;
    407 
    408   for(j=0;j<P_NOISECURVES;j++)
    409     for(i=0;i<P_BANDS;i++)
    410       p->noiseoff[j][i]=in[is].data[j][i]*(1.-ds)+in[is+1].data[j][i]*ds;
    411 
    412   /* impulse blocks may take a user specified bias to boost the
    413      nominal/high noise encoding depth */
    414   for(j=0;j<P_NOISECURVES;j++){
    415     float min=p->noiseoff[j][0]+6; /* the lowest it can go */
    416     for(i=0;i<P_BANDS;i++){
    417       p->noiseoff[j][i]+=userbias;
    418       if(p->noiseoff[j][i]<min)p->noiseoff[j][i]=min;
    419     }
    420   }
    421 
    422   return;
    423 }
    424 
    425 static void vorbis_encode_ath_setup(vorbis_info *vi,int block){
    426   codec_setup_info *ci=vi->codec_setup;
    427   vorbis_info_psy *p=ci->psy_param[block];
    428 
    429   p->ath_adjatt=ci->hi.ath_floating_dB;
    430   p->ath_maxatt=ci->hi.ath_absolute_dB;
    431   return;
    432 }
    433 
    434 
    435 static int book_dup_or_new(codec_setup_info *ci,const static_codebook *book){
    436   int i;
    437   for(i=0;i<ci->books;i++)
    438     if(ci->book_param[i]==book)return(i);
    439 
    440   return(ci->books++);
    441 }
    442 
    443 static void vorbis_encode_blocksize_setup(vorbis_info *vi,double s,
    444                                          const int *shortb,const int *longb){
    445 
    446   codec_setup_info *ci=vi->codec_setup;
    447   int is=s;
    448 
    449   int blockshort=shortb[is];
    450   int blocklong=longb[is];
    451   ci->blocksizes[0]=blockshort;
    452   ci->blocksizes[1]=blocklong;
    453 
    454 }
    455 
    456 static void vorbis_encode_residue_setup(vorbis_info *vi,
    457                                         int number, int block,
    458                                         const vorbis_residue_template *res){
    459 
    460   codec_setup_info *ci=vi->codec_setup;
    461   int i;
    462 
    463   vorbis_info_residue0 *r=ci->residue_param[number]=
    464     _ogg_malloc(sizeof(*r));
    465 
    466   memcpy(r,res->res,sizeof(*r));
    467   if(ci->residues<=number)ci->residues=number+1;
    468 
    469   r->grouping=res->grouping;
    470   ci->residue_type[number]=res->res_type;
    471 
    472   /* fill in all the books */
    473   {
    474     int booklist=0,k;
    475 
    476     if(ci->hi.managed){
    477       for(i=0;i<r->partitions;i++)
    478         for(k=0;k<4;k++)
    479           if(res->books_base_managed->books[i][k])
    480             r->secondstages[i]|=(1<<k);
    481 
    482       r->groupbook=book_dup_or_new(ci,res->book_aux_managed);
    483       ci->book_param[r->groupbook]=(static_codebook *)res->book_aux_managed;
    484 
    485       for(i=0;i<r->partitions;i++){
    486         for(k=0;k<4;k++){
    487           if(res->books_base_managed->books[i][k]){
    488             int bookid=book_dup_or_new(ci,res->books_base_managed->books[i][k]);
    489             r->booklist[booklist++]=bookid;
    490             ci->book_param[bookid]=(static_codebook *)res->books_base_managed->books[i][k];
    491           }
    492         }
    493       }
    494 
    495     }else{
    496 
    497       for(i=0;i<r->partitions;i++)
    498         for(k=0;k<4;k++)
    499           if(res->books_base->books[i][k])
    500             r->secondstages[i]|=(1<<k);
    501 
    502       r->groupbook=book_dup_or_new(ci,res->book_aux);
    503       ci->book_param[r->groupbook]=(static_codebook *)res->book_aux;
    504 
    505       for(i=0;i<r->partitions;i++){
    506         for(k=0;k<4;k++){
    507           if(res->books_base->books[i][k]){
    508             int bookid=book_dup_or_new(ci,res->books_base->books[i][k]);
    509             r->booklist[booklist++]=bookid;
    510             ci->book_param[bookid]=(static_codebook *)res->books_base->books[i][k];
    511           }
    512         }
    513       }
    514     }
    515   }
    516 
    517   /* lowpass setup/pointlimit */
    518   {
    519     double freq=ci->hi.lowpass_kHz*1000.;
    520     vorbis_info_floor1 *f=ci->floor_param[block]; /* by convention */
    521     double nyq=vi->rate/2.;
    522     long blocksize=ci->blocksizes[block]>>1;
    523 
    524     /* lowpass needs to be set in the floor and the residue. */
    525     if(freq>nyq)freq=nyq;
    526     /* in the floor, the granularity can be very fine; it doesn't alter
    527        the encoding structure, only the samples used to fit the floor
    528        approximation */
    529     f->n=freq/nyq*blocksize;
    530 
    531     /* this res may by limited by the maximum pointlimit of the mode,
    532        not the lowpass. the floor is always lowpass limited. */
    533     switch(res->limit_type){
    534     case 1: /* point stereo limited */
    535       if(ci->hi.managed)
    536         freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS-1]*1000.;
    537       else
    538         freq=ci->psy_g_param.coupling_pkHz[PACKETBLOBS/2]*1000.;
    539       if(freq>nyq)freq=nyq;
    540       break;
    541     case 2: /* LFE channel; lowpass at ~ 250Hz */
    542       freq=250;
    543       break;
    544     default:
    545       /* already set */
    546       break;
    547     }
    548 
    549     /* in the residue, we're constrained, physically, by partition
    550        boundaries.  We still lowpass 'wherever', but we have to round up
    551        here to next boundary, or the vorbis spec will round it *down* to
    552        previous boundary in encode/decode */
    553     if(ci->residue_type[number]==2){
    554       /* residue 2 bundles together multiple channels; used by stereo
    555          and surround.  Count the channels in use */
    556       /* Multiple maps/submaps can point to the same residue.  In the case
    557          of residue 2, they all better have the same number of
    558          channels/samples. */
    559       int j,k,ch=0;
    560       for(i=0;i<ci->maps&&ch==0;i++){
    561         vorbis_info_mapping0 *mi=(vorbis_info_mapping0 *)ci->map_param[i];
    562         for(j=0;j<mi->submaps && ch==0;j++)
    563           if(mi->residuesubmap[j]==number) /* we found a submap referencing theis residue backend */
    564             for(k=0;k<vi->channels;k++)
    565               if(mi->chmuxlist[k]==j) /* this channel belongs to the submap */
    566                 ch++;
    567       }
    568 
    569       r->end=(int)((freq/nyq*blocksize*ch)/r->grouping+.9)* /* round up only if we're well past */
    570         r->grouping;
    571       /* the blocksize and grouping may disagree at the end */
    572       if(r->end>blocksize*ch)r->end=blocksize*ch/r->grouping*r->grouping;
    573 
    574     }else{
    575 
    576       r->end=(int)((freq/nyq*blocksize)/r->grouping+.9)* /* round up only if we're well past */
    577         r->grouping;
    578       /* the blocksize and grouping may disagree at the end */
    579       if(r->end>blocksize)r->end=blocksize/r->grouping*r->grouping;
    580 
    581     }
    582 
    583     if(r->end==0)r->end=r->grouping; /* LFE channel */
    584 
    585   }
    586 }
    587 
    588 /* we assume two maps in this encoder */
    589 static void vorbis_encode_map_n_res_setup(vorbis_info *vi,double s,
    590                                           const vorbis_mapping_template *maps){
    591 
    592   codec_setup_info *ci=vi->codec_setup;
    593   int i,j,is=s,modes=2;
    594   const vorbis_info_mapping0 *map=maps[is].map;
    595   const vorbis_info_mode *mode=_mode_template;
    596   const vorbis_residue_template *res=maps[is].res;
    597 
    598   if(ci->blocksizes[0]==ci->blocksizes[1])modes=1;
    599 
    600   for(i=0;i<modes;i++){
    601 
    602     ci->map_param[i]=_ogg_calloc(1,sizeof(*map));
    603     ci->mode_param[i]=_ogg_calloc(1,sizeof(*mode));
    604 
    605     memcpy(ci->mode_param[i],mode+i,sizeof(*_mode_template));
    606     if(i>=ci->modes)ci->modes=i+1;
    607 
    608     ci->map_type[i]=0;
    609     memcpy(ci->map_param[i],map+i,sizeof(*map));
    610     if(i>=ci->maps)ci->maps=i+1;
    611 
    612     for(j=0;j<map[i].submaps;j++)
    613       vorbis_encode_residue_setup(vi,map[i].residuesubmap[j],i
    614                                   ,res+map[i].residuesubmap[j]);
    615   }
    616 }
    617 
    618 static double setting_to_approx_bitrate(vorbis_info *vi){
    619   codec_setup_info *ci=vi->codec_setup;
    620   highlevel_encode_setup *hi=&ci->hi;
    621   ve_setup_data_template *setup=(ve_setup_data_template *)hi->setup;
    622   int is=hi->base_setting;
    623   double ds=hi->base_setting-is;
    624   int ch=vi->channels;
    625   const double *r=setup->rate_mapping;
    626 
    627   if(r==NULL)
    628     return(-1);
    629 
    630   return((r[is]*(1.-ds)+r[is+1]*ds)*ch);
    631 }
    632 
    633 static const void *get_setup_template(long ch,long srate,
    634                                       double req,int q_or_bitrate,
    635                                       double *base_setting){
    636   int i=0,j;
    637   if(q_or_bitrate)req/=ch;
    638 
    639   while(setup_list[i]){
    640     if(setup_list[i]->coupling_restriction==-1 ||
    641        setup_list[i]->coupling_restriction==ch){
    642       if(srate>=setup_list[i]->samplerate_min_restriction &&
    643          srate<=setup_list[i]->samplerate_max_restriction){
    644         int mappings=setup_list[i]->mappings;
    645         const double *map=(q_or_bitrate?
    646                      setup_list[i]->rate_mapping:
    647                      setup_list[i]->quality_mapping);
    648 
    649         /* the template matches.  Does the requested quality mode
    650            fall within this template's modes? */
    651         if(req<map[0]){++i;continue;}
    652         if(req>map[setup_list[i]->mappings]){++i;continue;}
    653         for(j=0;j<mappings;j++)
    654           if(req>=map[j] && req<map[j+1])break;
    655         /* an all-points match */
    656         if(j==mappings)
    657           *base_setting=j-.001;
    658         else{
    659           float low=map[j];
    660           float high=map[j+1];
    661           float del=(req-low)/(high-low);
    662           *base_setting=j+del;
    663         }
    664 
    665         return(setup_list[i]);
    666       }
    667     }
    668     i++;
    669   }
    670 
    671   return NULL;
    672 }
    673 
    674 /* encoders will need to use vorbis_info_init beforehand and call
    675    vorbis_info clear when all done */
    676 
    677 /* two interfaces; this, more detailed one, and later a convenience
    678    layer on top */
    679 
    680 /* the final setup call */
    681 int vorbis_encode_setup_init(vorbis_info *vi){
    682   int i,i0=0,singleblock=0;
    683   codec_setup_info *ci=vi->codec_setup;
    684   ve_setup_data_template *setup=NULL;
    685   highlevel_encode_setup *hi=&ci->hi;
    686 
    687   if(ci==NULL)return(OV_EINVAL);
    688   if(!hi->impulse_block_p)i0=1;
    689 
    690   /* too low/high an ATH floater is nonsensical, but doesn't break anything */
    691   if(hi->ath_floating_dB>-80)hi->ath_floating_dB=-80;
    692   if(hi->ath_floating_dB<-200)hi->ath_floating_dB=-200;
    693 
    694   /* again, bound this to avoid the app shooting itself int he foot
    695      too badly */
    696   if(hi->amplitude_track_dBpersec>0.)hi->amplitude_track_dBpersec=0.;
    697   if(hi->amplitude_track_dBpersec<-99999.)hi->amplitude_track_dBpersec=-99999.;
    698 
    699   /* get the appropriate setup template; matches the fetch in previous
    700      stages */
    701   setup=(ve_setup_data_template *)hi->setup;
    702   if(setup==NULL)return(OV_EINVAL);
    703 
    704   hi->set_in_stone=1;
    705   /* choose block sizes from configured sizes as well as paying
    706      attention to long_block_p and short_block_p.  If the configured
    707      short and long blocks are the same length, we set long_block_p
    708      and unset short_block_p */
    709   vorbis_encode_blocksize_setup(vi,hi->base_setting,
    710                                 setup->blocksize_short,
    711                                 setup->blocksize_long);
    712   if(ci->blocksizes[0]==ci->blocksizes[1])singleblock=1;
    713 
    714   /* floor setup; choose proper floor params.  Allocated on the floor
    715      stack in order; if we alloc only a single long floor, it's 0 */
    716   for(i=0;i<setup->floor_mappings;i++)
    717     vorbis_encode_floor_setup(vi,hi->base_setting,
    718                               setup->floor_books,
    719                               setup->floor_params,
    720                               setup->floor_mapping_list[i]);
    721 
    722   /* setup of [mostly] short block detection and stereo*/
    723   vorbis_encode_global_psych_setup(vi,hi->trigger_setting,
    724                                    setup->global_params,
    725                                    setup->global_mapping);
    726   vorbis_encode_global_stereo(vi,hi,setup->stereo_modes);
    727 
    728   /* basic psych setup and noise normalization */
    729   vorbis_encode_psyset_setup(vi,hi->base_setting,
    730                              setup->psy_noise_normal_start[0],
    731                              setup->psy_noise_normal_partition[0],
    732                              setup->psy_noise_normal_thresh,
    733                              0);
    734   vorbis_encode_psyset_setup(vi,hi->base_setting,
    735                              setup->psy_noise_normal_start[0],
    736                              setup->psy_noise_normal_partition[0],
    737                              setup->psy_noise_normal_thresh,
    738                              1);
    739   if(!singleblock){
    740     vorbis_encode_psyset_setup(vi,hi->base_setting,
    741                                setup->psy_noise_normal_start[1],
    742                                setup->psy_noise_normal_partition[1],
    743                                     setup->psy_noise_normal_thresh,
    744                                2);
    745     vorbis_encode_psyset_setup(vi,hi->base_setting,
    746                                setup->psy_noise_normal_start[1],
    747                                setup->psy_noise_normal_partition[1],
    748                                setup->psy_noise_normal_thresh,
    749                                3);
    750   }
    751 
    752   /* tone masking setup */
    753   vorbis_encode_tonemask_setup(vi,hi->block[i0].tone_mask_setting,0,
    754                                setup->psy_tone_masteratt,
    755                                setup->psy_tone_0dB,
    756                                setup->psy_tone_adj_impulse);
    757   vorbis_encode_tonemask_setup(vi,hi->block[1].tone_mask_setting,1,
    758                                setup->psy_tone_masteratt,
    759                                setup->psy_tone_0dB,
    760                                setup->psy_tone_adj_other);
    761   if(!singleblock){
    762     vorbis_encode_tonemask_setup(vi,hi->block[2].tone_mask_setting,2,
    763                                  setup->psy_tone_masteratt,
    764                                  setup->psy_tone_0dB,
    765                                  setup->psy_tone_adj_other);
    766     vorbis_encode_tonemask_setup(vi,hi->block[3].tone_mask_setting,3,
    767                                  setup->psy_tone_masteratt,
    768                                  setup->psy_tone_0dB,
    769                                  setup->psy_tone_adj_long);
    770   }
    771 
    772   /* noise companding setup */
    773   vorbis_encode_compand_setup(vi,hi->block[i0].noise_compand_setting,0,
    774                               setup->psy_noise_compand,
    775                               setup->psy_noise_compand_short_mapping);
    776   vorbis_encode_compand_setup(vi,hi->block[1].noise_compand_setting,1,
    777                               setup->psy_noise_compand,
    778                               setup->psy_noise_compand_short_mapping);
    779   if(!singleblock){
    780     vorbis_encode_compand_setup(vi,hi->block[2].noise_compand_setting,2,
    781                                 setup->psy_noise_compand,
    782                                 setup->psy_noise_compand_long_mapping);
    783     vorbis_encode_compand_setup(vi,hi->block[3].noise_compand_setting,3,
    784                                 setup->psy_noise_compand,
    785                                 setup->psy_noise_compand_long_mapping);
    786   }
    787 
    788   /* peak guarding setup  */
    789   vorbis_encode_peak_setup(vi,hi->block[i0].tone_peaklimit_setting,0,
    790                            setup->psy_tone_dBsuppress);
    791   vorbis_encode_peak_setup(vi,hi->block[1].tone_peaklimit_setting,1,
    792                            setup->psy_tone_dBsuppress);
    793   if(!singleblock){
    794     vorbis_encode_peak_setup(vi,hi->block[2].tone_peaklimit_setting,2,
    795                              setup->psy_tone_dBsuppress);
    796     vorbis_encode_peak_setup(vi,hi->block[3].tone_peaklimit_setting,3,
    797                              setup->psy_tone_dBsuppress);
    798   }
    799 
    800   /* noise bias setup */
    801   vorbis_encode_noisebias_setup(vi,hi->block[i0].noise_bias_setting,0,
    802                                 setup->psy_noise_dBsuppress,
    803                                 setup->psy_noise_bias_impulse,
    804                                 setup->psy_noiseguards,
    805                                 (i0==0?hi->impulse_noisetune:0.));
    806   vorbis_encode_noisebias_setup(vi,hi->block[1].noise_bias_setting,1,
    807                                 setup->psy_noise_dBsuppress,
    808                                 setup->psy_noise_bias_padding,
    809                                 setup->psy_noiseguards,0.);
    810   if(!singleblock){
    811     vorbis_encode_noisebias_setup(vi,hi->block[2].noise_bias_setting,2,
    812                                   setup->psy_noise_dBsuppress,
    813                                   setup->psy_noise_bias_trans,
    814                                   setup->psy_noiseguards,0.);
    815     vorbis_encode_noisebias_setup(vi,hi->block[3].noise_bias_setting,3,
    816                                   setup->psy_noise_dBsuppress,
    817                                   setup->psy_noise_bias_long,
    818                                   setup->psy_noiseguards,0.);
    819   }
    820 
    821   vorbis_encode_ath_setup(vi,0);
    822   vorbis_encode_ath_setup(vi,1);
    823   if(!singleblock){
    824     vorbis_encode_ath_setup(vi,2);
    825     vorbis_encode_ath_setup(vi,3);
    826   }
    827 
    828   vorbis_encode_map_n_res_setup(vi,hi->base_setting,setup->maps);
    829 
    830   /* set bitrate readonlies and management */
    831   if(hi->bitrate_av>0)
    832     vi->bitrate_nominal=hi->bitrate_av;
    833   else{
    834     vi->bitrate_nominal=setting_to_approx_bitrate(vi);
    835   }
    836 
    837   vi->bitrate_lower=hi->bitrate_min;
    838   vi->bitrate_upper=hi->bitrate_max;
    839   if(hi->bitrate_av)
    840     vi->bitrate_window=(double)hi->bitrate_reservoir/hi->bitrate_av;
    841   else
    842     vi->bitrate_window=0.;
    843 
    844   if(hi->managed){
    845     ci->bi.avg_rate=hi->bitrate_av;
    846     ci->bi.min_rate=hi->bitrate_min;
    847     ci->bi.max_rate=hi->bitrate_max;
    848 
    849     ci->bi.reservoir_bits=hi->bitrate_reservoir;
    850     ci->bi.reservoir_bias=
    851       hi->bitrate_reservoir_bias;
    852 
    853     ci->bi.slew_damp=hi->bitrate_av_damp;
    854 
    855   }
    856 
    857   return(0);
    858 
    859 }
    860 
    861 static void vorbis_encode_setup_setting(vorbis_info *vi,
    862                                        long  channels,
    863                                        long  rate){
    864   int i,is;
    865   codec_setup_info *ci=vi->codec_setup;
    866   highlevel_encode_setup *hi=&ci->hi;
    867   const ve_setup_data_template *setup=hi->setup;
    868   double ds;
    869 
    870   vi->version=0;
    871   vi->channels=channels;
    872   vi->rate=rate;
    873 
    874   hi->impulse_block_p=1;
    875   hi->noise_normalize_p=1;
    876 
    877   is=hi->base_setting;
    878   ds=hi->base_setting-is;
    879 
    880   hi->stereo_point_setting=hi->base_setting;
    881 
    882   if(!hi->lowpass_altered)
    883     hi->lowpass_kHz=
    884       setup->psy_lowpass[is]*(1.-ds)+setup->psy_lowpass[is+1]*ds;
    885 
    886   hi->ath_floating_dB=setup->psy_ath_float[is]*(1.-ds)+
    887     setup->psy_ath_float[is+1]*ds;
    888   hi->ath_absolute_dB=setup->psy_ath_abs[is]*(1.-ds)+
    889     setup->psy_ath_abs[is+1]*ds;
    890 
    891   hi->amplitude_track_dBpersec=-6.;
    892   hi->trigger_setting=hi->base_setting;
    893 
    894   for(i=0;i<4;i++){
    895     hi->block[i].tone_mask_setting=hi->base_setting;
    896     hi->block[i].tone_peaklimit_setting=hi->base_setting;
    897     hi->block[i].noise_bias_setting=hi->base_setting;
    898     hi->block[i].noise_compand_setting=hi->base_setting;
    899   }
    900 }
    901 
    902 int vorbis_encode_setup_vbr(vorbis_info *vi,
    903                             long  channels,
    904                             long  rate,
    905                             float quality){
    906   codec_setup_info *ci=vi->codec_setup;
    907   highlevel_encode_setup *hi=&ci->hi;
    908 
    909   quality+=.0000001;
    910   if(quality>=1.)quality=.9999;
    911 
    912   hi->req=quality;
    913   hi->setup=get_setup_template(channels,rate,quality,0,&hi->base_setting);
    914   if(!hi->setup)return OV_EIMPL;
    915 
    916   vorbis_encode_setup_setting(vi,channels,rate);
    917   hi->managed=0;
    918   hi->coupling_p=1;
    919 
    920   return 0;
    921 }
    922 
    923 int vorbis_encode_init_vbr(vorbis_info *vi,
    924                            long channels,
    925                            long rate,
    926 
    927                            float base_quality /* 0. to 1. */
    928                            ){
    929   int ret=0;
    930 
    931   ret=vorbis_encode_setup_vbr(vi,channels,rate,base_quality);
    932 
    933   if(ret){
    934     vorbis_info_clear(vi);
    935     return ret;
    936   }
    937   ret=vorbis_encode_setup_init(vi);
    938   if(ret)
    939     vorbis_info_clear(vi);
    940   return(ret);
    941 }
    942 
    943 int vorbis_encode_setup_managed(vorbis_info *vi,
    944                                 long channels,
    945                                 long rate,
    946 
    947                                 long max_bitrate,
    948                                 long nominal_bitrate,
    949                                 long min_bitrate){
    950 
    951   codec_setup_info *ci=vi->codec_setup;
    952   highlevel_encode_setup *hi=&ci->hi;
    953   double tnominal=nominal_bitrate;
    954 
    955   if(nominal_bitrate<=0.){
    956     if(max_bitrate>0.){
    957       if(min_bitrate>0.)
    958         nominal_bitrate=(max_bitrate+min_bitrate)*.5;
    959       else
    960         nominal_bitrate=max_bitrate*.875;
    961     }else{
    962       if(min_bitrate>0.){
    963         nominal_bitrate=min_bitrate;
    964       }else{
    965         return(OV_EINVAL);
    966       }
    967     }
    968   }
    969 
    970   hi->req=nominal_bitrate;
    971   hi->setup=get_setup_template(channels,rate,nominal_bitrate,1,&hi->base_setting);
    972   if(!hi->setup)return OV_EIMPL;
    973 
    974   vorbis_encode_setup_setting(vi,channels,rate);
    975 
    976   /* initialize management with sane defaults */
    977   hi->coupling_p=1;
    978   hi->managed=1;
    979   hi->bitrate_min=min_bitrate;
    980   hi->bitrate_max=max_bitrate;
    981   hi->bitrate_av=tnominal;
    982   hi->bitrate_av_damp=1.5f; /* full range in no less than 1.5 second */
    983   hi->bitrate_reservoir=nominal_bitrate*2;
    984   hi->bitrate_reservoir_bias=.1; /* bias toward hoarding bits */
    985 
    986   return(0);
    987 
    988 }
    989 
    990 int vorbis_encode_init(vorbis_info *vi,
    991                        long channels,
    992                        long rate,
    993 
    994                        long max_bitrate,
    995                        long nominal_bitrate,
    996                        long min_bitrate){
    997 
    998   int ret=vorbis_encode_setup_managed(vi,channels,rate,
    999                                       max_bitrate,
   1000                                       nominal_bitrate,
   1001                                       min_bitrate);
   1002   if(ret){
   1003     vorbis_info_clear(vi);
   1004     return(ret);
   1005   }
   1006 
   1007   ret=vorbis_encode_setup_init(vi);
   1008   if(ret)
   1009     vorbis_info_clear(vi);
   1010   return(ret);
   1011 }
   1012 
   1013 int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
   1014   if(vi){
   1015     codec_setup_info *ci=vi->codec_setup;
   1016     highlevel_encode_setup *hi=&ci->hi;
   1017     int setp=(number&0xf); /* a read request has a low nibble of 0 */
   1018 
   1019     if(setp && hi->set_in_stone)return(OV_EINVAL);
   1020 
   1021     switch(number){
   1022 
   1023     /* now deprecated *****************/
   1024     case OV_ECTL_RATEMANAGE_GET:
   1025       {
   1026 
   1027         struct ovectl_ratemanage_arg *ai=
   1028           (struct ovectl_ratemanage_arg *)arg;
   1029 
   1030         ai->management_active=hi->managed;
   1031         ai->bitrate_hard_window=ai->bitrate_av_window=
   1032           (double)hi->bitrate_reservoir/vi->rate;
   1033         ai->bitrate_av_window_center=1.;
   1034         ai->bitrate_hard_min=hi->bitrate_min;
   1035         ai->bitrate_hard_max=hi->bitrate_max;
   1036         ai->bitrate_av_lo=hi->bitrate_av;
   1037         ai->bitrate_av_hi=hi->bitrate_av;
   1038 
   1039       }
   1040       return(0);
   1041 
   1042     /* now deprecated *****************/
   1043     case OV_ECTL_RATEMANAGE_SET:
   1044       {
   1045         struct ovectl_ratemanage_arg *ai=
   1046           (struct ovectl_ratemanage_arg *)arg;
   1047         if(ai==NULL){
   1048           hi->managed=0;
   1049         }else{
   1050           hi->managed=ai->management_active;
   1051           vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_AVG,arg);
   1052           vorbis_encode_ctl(vi,OV_ECTL_RATEMANAGE_HARD,arg);
   1053         }
   1054       }
   1055       return 0;
   1056 
   1057     /* now deprecated *****************/
   1058     case OV_ECTL_RATEMANAGE_AVG:
   1059       {
   1060         struct ovectl_ratemanage_arg *ai=
   1061           (struct ovectl_ratemanage_arg *)arg;
   1062         if(ai==NULL){
   1063           hi->bitrate_av=0;
   1064         }else{
   1065           hi->bitrate_av=(ai->bitrate_av_lo+ai->bitrate_av_hi)*.5;
   1066         }
   1067       }
   1068       return(0);
   1069     /* now deprecated *****************/
   1070     case OV_ECTL_RATEMANAGE_HARD:
   1071       {
   1072         struct ovectl_ratemanage_arg *ai=
   1073           (struct ovectl_ratemanage_arg *)arg;
   1074         if(ai==NULL){
   1075           hi->bitrate_min=0;
   1076           hi->bitrate_max=0;
   1077         }else{
   1078           hi->bitrate_min=ai->bitrate_hard_min;
   1079           hi->bitrate_max=ai->bitrate_hard_max;
   1080           hi->bitrate_reservoir=ai->bitrate_hard_window*
   1081             (hi->bitrate_max+hi->bitrate_min)*.5;
   1082         }
   1083         if(hi->bitrate_reservoir<128.)
   1084           hi->bitrate_reservoir=128.;
   1085       }
   1086       return(0);
   1087 
   1088       /* replacement ratemanage interface */
   1089     case OV_ECTL_RATEMANAGE2_GET:
   1090       {
   1091         struct ovectl_ratemanage2_arg *ai=
   1092           (struct ovectl_ratemanage2_arg *)arg;
   1093         if(ai==NULL)return OV_EINVAL;
   1094 
   1095         ai->management_active=hi->managed;
   1096         ai->bitrate_limit_min_kbps=hi->bitrate_min/1000;
   1097         ai->bitrate_limit_max_kbps=hi->bitrate_max/1000;
   1098         ai->bitrate_average_kbps=hi->bitrate_av/1000;
   1099         ai->bitrate_average_damping=hi->bitrate_av_damp;
   1100         ai->bitrate_limit_reservoir_bits=hi->bitrate_reservoir;
   1101         ai->bitrate_limit_reservoir_bias=hi->bitrate_reservoir_bias;
   1102       }
   1103       return (0);
   1104     case OV_ECTL_RATEMANAGE2_SET:
   1105       {
   1106         struct ovectl_ratemanage2_arg *ai=
   1107           (struct ovectl_ratemanage2_arg *)arg;
   1108         if(ai==NULL){
   1109           hi->managed=0;
   1110         }else{
   1111           /* sanity check; only catch invariant violations */
   1112           if(ai->bitrate_limit_min_kbps>0 &&
   1113              ai->bitrate_average_kbps>0 &&
   1114              ai->bitrate_limit_min_kbps>ai->bitrate_average_kbps)
   1115             return OV_EINVAL;
   1116 
   1117           if(ai->bitrate_limit_max_kbps>0 &&
   1118              ai->bitrate_average_kbps>0 &&
   1119              ai->bitrate_limit_max_kbps<ai->bitrate_average_kbps)
   1120             return OV_EINVAL;
   1121 
   1122           if(ai->bitrate_limit_min_kbps>0 &&
   1123              ai->bitrate_limit_max_kbps>0 &&
   1124              ai->bitrate_limit_min_kbps>ai->bitrate_limit_max_kbps)
   1125             return OV_EINVAL;
   1126 
   1127           if(ai->bitrate_average_damping <= 0.)
   1128             return OV_EINVAL;
   1129 
   1130           if(ai->bitrate_limit_reservoir_bits < 0)
   1131             return OV_EINVAL;
   1132 
   1133           if(ai->bitrate_limit_reservoir_bias < 0.)
   1134             return OV_EINVAL;
   1135 
   1136           if(ai->bitrate_limit_reservoir_bias > 1.)
   1137             return OV_EINVAL;
   1138 
   1139           hi->managed=ai->management_active;
   1140           hi->bitrate_min=ai->bitrate_limit_min_kbps * 1000;
   1141           hi->bitrate_max=ai->bitrate_limit_max_kbps * 1000;
   1142           hi->bitrate_av=ai->bitrate_average_kbps * 1000;
   1143           hi->bitrate_av_damp=ai->bitrate_average_damping;
   1144           hi->bitrate_reservoir=ai->bitrate_limit_reservoir_bits;
   1145           hi->bitrate_reservoir_bias=ai->bitrate_limit_reservoir_bias;
   1146         }
   1147       }
   1148       return 0;
   1149 
   1150     case OV_ECTL_LOWPASS_GET:
   1151       {
   1152         double *farg=(double *)arg;
   1153         *farg=hi->lowpass_kHz;
   1154       }
   1155       return(0);
   1156     case OV_ECTL_LOWPASS_SET:
   1157       {
   1158         double *farg=(double *)arg;
   1159         hi->lowpass_kHz=*farg;
   1160 
   1161         if(hi->lowpass_kHz<2.)hi->lowpass_kHz=2.;
   1162         if(hi->lowpass_kHz>99.)hi->lowpass_kHz=99.;
   1163         hi->lowpass_altered=1;
   1164       }
   1165       return(0);
   1166     case OV_ECTL_IBLOCK_GET:
   1167       {
   1168         double *farg=(double *)arg;
   1169         *farg=hi->impulse_noisetune;
   1170       }
   1171       return(0);
   1172     case OV_ECTL_IBLOCK_SET:
   1173       {
   1174         double *farg=(double *)arg;
   1175         hi->impulse_noisetune=*farg;
   1176 
   1177         if(hi->impulse_noisetune>0.)hi->impulse_noisetune=0.;
   1178         if(hi->impulse_noisetune<-15.)hi->impulse_noisetune=-15.;
   1179       }
   1180       return(0);
   1181     case OV_ECTL_COUPLING_GET:
   1182       {
   1183         int *iarg=(int *)arg;
   1184         *iarg=hi->coupling_p;
   1185       }
   1186       return(0);
   1187     case OV_ECTL_COUPLING_SET:
   1188       {
   1189         const void *new_template;
   1190         double new_base=0.;
   1191         int *iarg=(int *)arg;
   1192         hi->coupling_p=((*iarg)!=0);
   1193 
   1194         /* Fetching a new template can alter the base_setting, which
   1195            many other parameters are based on.  Right now, the only
   1196            parameter drawn from the base_setting that can be altered
   1197            by an encctl is the lowpass, so that is explictly flagged
   1198            to not be overwritten when we fetch a new template and
   1199            recompute the dependant settings */
   1200         new_template = get_setup_template(hi->coupling_p?vi->channels:-1,
   1201                                           vi->rate,
   1202                                           hi->req,
   1203                                           hi->managed,
   1204                                           &new_base);
   1205         if(!hi->setup)return OV_EIMPL;
   1206         hi->setup=new_template;
   1207         hi->base_setting=new_base;
   1208         vorbis_encode_setup_setting(vi,vi->channels,vi->rate);
   1209       }
   1210       return(0);
   1211     }
   1212     return(OV_EIMPL);
   1213   }
   1214   return(OV_EINVAL);
   1215 }
   1216