tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

vorbisenc.c (39310B)


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