tor-browser

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

vorbis_mapping0.c (28765B)


      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-2010             *
      9 * by the Xiph.Org Foundation https://xiph.org/                     *
     10 *                                                                  *
     11 ********************************************************************
     12 
     13 function: channel mapping 0 implementation
     14 
     15 ********************************************************************/
     16 
     17 #include <stdlib.h>
     18 #include <stdio.h>
     19 #include <string.h>
     20 #include <math.h>
     21 #include <ogg/ogg.h>
     22 #include "vorbis/codec.h"
     23 #include "codec_internal.h"
     24 #include "codebook.h"
     25 #include "window.h"
     26 #include "registry.h"
     27 #include "psy.h"
     28 #include "misc.h"
     29 
     30 /* simplistic, wasteful way of doing this (unique lookup for each
     31   mode/submapping); there should be a central repository for
     32   identical lookups.  That will require minor work, so I'm putting it
     33   off as low priority.
     34 
     35   Why a lookup for each backend in a given mode?  Because the
     36   blocksize is set by the mode, and low backend lookups may require
     37   parameters from other areas of the mode/mapping */
     38 
     39 static void mapping0_free_info(vorbis_info_mapping *i){
     40  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i;
     41  if(info){
     42    memset(info,0,sizeof(*info));
     43    _ogg_free(info);
     44  }
     45 }
     46 
     47 static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
     48                          oggpack_buffer *opb){
     49  int i;
     50  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
     51 
     52  /* another 'we meant to do it this way' hack...  up to beta 4, we
     53     packed 4 binary zeros here to signify one submapping in use.  We
     54     now redefine that to mean four bitflags that indicate use of
     55     deeper features; bit0:submappings, bit1:coupling,
     56     bit2,3:reserved. This is backward compatable with all actual uses
     57     of the beta code. */
     58 
     59  if(info->submaps>1){
     60    oggpack_write(opb,1,1);
     61    oggpack_write(opb,info->submaps-1,4);
     62  }else
     63    oggpack_write(opb,0,1);
     64 
     65  if(info->coupling_steps>0){
     66    oggpack_write(opb,1,1);
     67    oggpack_write(opb,info->coupling_steps-1,8);
     68 
     69    for(i=0;i<info->coupling_steps;i++){
     70      oggpack_write(opb,info->coupling_mag[i],ov_ilog(vi->channels-1));
     71      oggpack_write(opb,info->coupling_ang[i],ov_ilog(vi->channels-1));
     72    }
     73  }else
     74    oggpack_write(opb,0,1);
     75 
     76  oggpack_write(opb,0,2); /* 2,3:reserved */
     77 
     78  /* we don't write the channel submappings if we only have one... */
     79  if(info->submaps>1){
     80    for(i=0;i<vi->channels;i++)
     81      oggpack_write(opb,info->chmuxlist[i],4);
     82  }
     83  for(i=0;i<info->submaps;i++){
     84    oggpack_write(opb,0,8); /* time submap unused */
     85    oggpack_write(opb,info->floorsubmap[i],8);
     86    oggpack_write(opb,info->residuesubmap[i],8);
     87  }
     88 }
     89 
     90 /* also responsible for range checking */
     91 static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
     92  int i,b;
     93  vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info));
     94  codec_setup_info     *ci=vi->codec_setup;
     95  if(vi->channels<=0)goto err_out;
     96 
     97  b=oggpack_read(opb,1);
     98  if(b<0)goto err_out;
     99  if(b){
    100    info->submaps=oggpack_read(opb,4)+1;
    101    if(info->submaps<=0)goto err_out;
    102  }else
    103    info->submaps=1;
    104 
    105  b=oggpack_read(opb,1);
    106  if(b<0)goto err_out;
    107  if(b){
    108    info->coupling_steps=oggpack_read(opb,8)+1;
    109    if(info->coupling_steps<=0)goto err_out;
    110    for(i=0;i<info->coupling_steps;i++){
    111      /* vi->channels > 0 is enforced in the caller */
    112      int testM=info->coupling_mag[i]=
    113        oggpack_read(opb,ov_ilog(vi->channels-1));
    114      int testA=info->coupling_ang[i]=
    115        oggpack_read(opb,ov_ilog(vi->channels-1));
    116 
    117      if(testM<0 ||
    118         testA<0 ||
    119         testM==testA ||
    120         testM>=vi->channels ||
    121         testA>=vi->channels) goto err_out;
    122    }
    123 
    124  }
    125 
    126  if(oggpack_read(opb,2)!=0)goto err_out; /* 2,3:reserved */
    127 
    128  if(info->submaps>1){
    129    for(i=0;i<vi->channels;i++){
    130      info->chmuxlist[i]=oggpack_read(opb,4);
    131      if(info->chmuxlist[i]>=info->submaps || info->chmuxlist[i]<0)goto err_out;
    132    }
    133  }
    134  for(i=0;i<info->submaps;i++){
    135    oggpack_read(opb,8); /* time submap unused */
    136    info->floorsubmap[i]=oggpack_read(opb,8);
    137    if(info->floorsubmap[i]>=ci->floors || info->floorsubmap[i]<0)goto err_out;
    138    info->residuesubmap[i]=oggpack_read(opb,8);
    139    if(info->residuesubmap[i]>=ci->residues || info->residuesubmap[i]<0)goto err_out;
    140  }
    141 
    142  return info;
    143 
    144 err_out:
    145  mapping0_free_info(info);
    146  return(NULL);
    147 }
    148 
    149 #include "os.h"
    150 #include "lpc.h"
    151 #include "lsp.h"
    152 #include "envelope.h"
    153 #include "mdct.h"
    154 #include "psy.h"
    155 #include "scales.h"
    156 
    157 #if 0
    158 static long seq=0;
    159 static ogg_int64_t total=0;
    160 static float FLOOR1_fromdB_LOOKUP[256]={
    161  1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
    162  1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
    163  1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
    164  2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
    165  2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
    166  3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
    167  4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
    168  6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
    169  7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
    170  1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
    171  1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
    172  1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
    173  2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
    174  2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
    175  3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
    176  4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
    177  5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
    178  7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
    179  9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
    180  1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
    181  1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
    182  2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
    183  2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
    184  3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
    185  4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
    186  5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
    187  7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
    188  9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
    189  0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
    190  0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
    191  0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
    192  0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
    193  0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
    194  0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
    195  0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
    196  0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
    197  0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
    198  0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
    199  0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
    200  0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
    201  0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
    202  0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
    203  0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
    204  0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
    205  0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
    206  0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
    207  0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
    208  0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
    209  0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
    210  0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
    211  0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
    212  0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
    213  0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
    214  0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
    215  0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
    216  0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
    217  0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
    218  0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
    219  0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
    220  0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
    221  0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
    222  0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
    223  0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
    224  0.82788260F, 0.88168307F, 0.9389798F, 1.F,
    225 };
    226 
    227 #endif
    228 
    229 
    230 static int mapping0_forward(vorbis_block *vb){
    231  vorbis_dsp_state      *vd=vb->vd;
    232  vorbis_info           *vi=vd->vi;
    233  codec_setup_info      *ci=vi->codec_setup;
    234  private_state         *b=vb->vd->backend_state;
    235  vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
    236  int                    n=vb->pcmend;
    237  int i,j,k;
    238 
    239  int    *nonzero    = alloca(sizeof(*nonzero)*vi->channels);
    240  float  **gmdct     = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct));
    241  int    **iwork      = _vorbis_block_alloc(vb,vi->channels*sizeof(*iwork));
    242  int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts));
    243 
    244  float global_ampmax=vbi->ampmax;
    245  float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels);
    246  int blocktype=vbi->blocktype;
    247 
    248  int modenumber=vb->W;
    249  vorbis_info_mapping0 *info=ci->map_param[modenumber];
    250  vorbis_look_psy *psy_look=b->psy+blocktype+(vb->W?2:0);
    251 
    252  vb->mode=modenumber;
    253 
    254  for(i=0;i<vi->channels;i++){
    255    float scale=4.f/n;
    256    float scale_dB;
    257 
    258    float *pcm     =vb->pcm[i];
    259    float *logfft  =pcm;
    260 
    261    iwork[i]=_vorbis_block_alloc(vb,n/2*sizeof(**iwork));
    262    gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
    263 
    264    scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original
    265                                     todB estimation used on IEEE 754
    266                                     compliant machines had a bug that
    267                                     returned dB values about a third
    268                                     of a decibel too high.  The bug
    269                                     was harmless because tunings
    270                                     implicitly took that into
    271                                     account.  However, fixing the bug
    272                                     in the estimator requires
    273                                     changing all the tunings as well.
    274                                     For now, it's easier to sync
    275                                     things back up here, and
    276                                     recalibrate the tunings in the
    277                                     next major model upgrade. */
    278 
    279 #if 0
    280    if(vi->channels==2){
    281      if(i==0)
    282        _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2);
    283      else
    284        _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2);
    285    }else{
    286      _analysis_output("pcm",seq,pcm,n,0,0,total-n/2);
    287    }
    288 #endif
    289 
    290    /* window the PCM data */
    291    _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
    292 
    293 #if 0
    294    if(vi->channels==2){
    295      if(i==0)
    296        _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2);
    297      else
    298        _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2);
    299    }else{
    300      _analysis_output("windowed",seq,pcm,n,0,0,total-n/2);
    301    }
    302 #endif
    303 
    304    /* transform the PCM data */
    305    /* only MDCT right now.... */
    306    mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]);
    307 
    308    /* FFT yields more accurate tonal estimation (not phase sensitive) */
    309    drft_forward(&b->fft_look[vb->W],pcm);
    310    logfft[0]=scale_dB+todB(pcm)  + .345; /* + .345 is a hack; the
    311                                     original todB estimation used on
    312                                     IEEE 754 compliant machines had a
    313                                     bug that returned dB values about
    314                                     a third of a decibel too high.
    315                                     The bug was harmless because
    316                                     tunings implicitly took that into
    317                                     account.  However, fixing the bug
    318                                     in the estimator requires
    319                                     changing all the tunings as well.
    320                                     For now, it's easier to sync
    321                                     things back up here, and
    322                                     recalibrate the tunings in the
    323                                     next major model upgrade. */
    324    local_ampmax[i]=logfft[0];
    325    for(j=1;j<n-1;j+=2){
    326      float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1];
    327      temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp)  + .345; /* +
    328                                     .345 is a hack; the original todB
    329                                     estimation used on IEEE 754
    330                                     compliant machines had a bug that
    331                                     returned dB values about a third
    332                                     of a decibel too high.  The bug
    333                                     was harmless because tunings
    334                                     implicitly took that into
    335                                     account.  However, fixing the bug
    336                                     in the estimator requires
    337                                     changing all the tunings as well.
    338                                     For now, it's easier to sync
    339                                     things back up here, and
    340                                     recalibrate the tunings in the
    341                                     next major model upgrade. */
    342      if(temp>local_ampmax[i])local_ampmax[i]=temp;
    343    }
    344 
    345    if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
    346    if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
    347 
    348 #if 0
    349    if(vi->channels==2){
    350      if(i==0){
    351        _analysis_output("fftL",seq,logfft,n/2,1,0,0);
    352      }else{
    353        _analysis_output("fftR",seq,logfft,n/2,1,0,0);
    354      }
    355    }else{
    356      _analysis_output("fft",seq,logfft,n/2,1,0,0);
    357    }
    358 #endif
    359 
    360  }
    361 
    362  {
    363    float   *noise        = _vorbis_block_alloc(vb,n/2*sizeof(*noise));
    364    float   *tone         = _vorbis_block_alloc(vb,n/2*sizeof(*tone));
    365 
    366    for(i=0;i<vi->channels;i++){
    367      /* the encoder setup assumes that all the modes used by any
    368         specific bitrate tweaking use the same floor */
    369 
    370      int submap=info->chmuxlist[i];
    371 
    372      /* the following makes things clearer to *me* anyway */
    373      float *mdct    =gmdct[i];
    374      float *logfft  =vb->pcm[i];
    375 
    376      float *logmdct =logfft+n/2;
    377      float *logmask =logfft;
    378 
    379      vb->mode=modenumber;
    380 
    381      floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts));
    382      memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS);
    383 
    384      for(j=0;j<n/2;j++)
    385        logmdct[j]=todB(mdct+j)  + .345; /* + .345 is a hack; the original
    386                                     todB estimation used on IEEE 754
    387                                     compliant machines had a bug that
    388                                     returned dB values about a third
    389                                     of a decibel too high.  The bug
    390                                     was harmless because tunings
    391                                     implicitly took that into
    392                                     account.  However, fixing the bug
    393                                     in the estimator requires
    394                                     changing all the tunings as well.
    395                                     For now, it's easier to sync
    396                                     things back up here, and
    397                                     recalibrate the tunings in the
    398                                     next major model upgrade. */
    399 
    400 #if 0
    401      if(vi->channels==2){
    402        if(i==0)
    403          _analysis_output("mdctL",seq,logmdct,n/2,1,0,0);
    404        else
    405          _analysis_output("mdctR",seq,logmdct,n/2,1,0,0);
    406      }else{
    407        _analysis_output("mdct",seq,logmdct,n/2,1,0,0);
    408      }
    409 #endif
    410 
    411      /* first step; noise masking.  Not only does 'noise masking'
    412         give us curves from which we can decide how much resolution
    413         to give noise parts of the spectrum, it also implicitly hands
    414         us a tonality estimate (the larger the value in the
    415         'noise_depth' vector, the more tonal that area is) */
    416 
    417      _vp_noisemask(psy_look,
    418                    logmdct,
    419                    noise); /* noise does not have by-frequency offset
    420                               bias applied yet */
    421 #if 0
    422      if(vi->channels==2){
    423        if(i==0)
    424          _analysis_output("noiseL",seq,noise,n/2,1,0,0);
    425        else
    426          _analysis_output("noiseR",seq,noise,n/2,1,0,0);
    427      }else{
    428        _analysis_output("noise",seq,noise,n/2,1,0,0);
    429      }
    430 #endif
    431 
    432      /* second step: 'all the other crap'; all the stuff that isn't
    433         computed/fit for bitrate management goes in the second psy
    434         vector.  This includes tone masking, peak limiting and ATH */
    435 
    436      _vp_tonemask(psy_look,
    437                   logfft,
    438                   tone,
    439                   global_ampmax,
    440                   local_ampmax[i]);
    441 
    442 #if 0
    443      if(vi->channels==2){
    444        if(i==0)
    445          _analysis_output("toneL",seq,tone,n/2,1,0,0);
    446        else
    447          _analysis_output("toneR",seq,tone,n/2,1,0,0);
    448      }else{
    449        _analysis_output("tone",seq,tone,n/2,1,0,0);
    450      }
    451 #endif
    452 
    453      /* third step; we offset the noise vectors, overlay tone
    454         masking.  We then do a floor1-specific line fit.  If we're
    455         performing bitrate management, the line fit is performed
    456         multiple times for up/down tweakage on demand. */
    457 
    458 #if 0
    459      {
    460      float aotuv[psy_look->n];
    461 #endif
    462 
    463        _vp_offset_and_mix(psy_look,
    464                           noise,
    465                           tone,
    466                           1,
    467                           logmask,
    468                           mdct,
    469                           logmdct);
    470 
    471 #if 0
    472        if(vi->channels==2){
    473          if(i==0)
    474            _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0);
    475          else
    476            _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0);
    477        }else{
    478          _analysis_output("aotuvM1",seq,aotuv,psy_look->n,1,1,0);
    479        }
    480      }
    481 #endif
    482 
    483 
    484 #if 0
    485      if(vi->channels==2){
    486        if(i==0)
    487          _analysis_output("mask1L",seq,logmask,n/2,1,0,0);
    488        else
    489          _analysis_output("mask1R",seq,logmask,n/2,1,0,0);
    490      }else{
    491        _analysis_output("mask1",seq,logmask,n/2,1,0,0);
    492      }
    493 #endif
    494 
    495      /* this algorithm is hardwired to floor 1 for now; abort out if
    496         we're *not* floor1.  This won't happen unless someone has
    497         broken the encode setup lib.  Guard it anyway. */
    498      if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1);
    499 
    500      floor_posts[i][PACKETBLOBS/2]=
    501        floor1_fit(vb,b->flr[info->floorsubmap[submap]],
    502                   logmdct,
    503                   logmask);
    504 
    505      /* are we managing bitrate?  If so, perform two more fits for
    506         later rate tweaking (fits represent hi/lo) */
    507      if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){
    508        /* higher rate by way of lower noise curve */
    509 
    510        _vp_offset_and_mix(psy_look,
    511                           noise,
    512                           tone,
    513                           2,
    514                           logmask,
    515                           mdct,
    516                           logmdct);
    517 
    518 #if 0
    519        if(vi->channels==2){
    520          if(i==0)
    521            _analysis_output("mask2L",seq,logmask,n/2,1,0,0);
    522          else
    523            _analysis_output("mask2R",seq,logmask,n/2,1,0,0);
    524        }else{
    525          _analysis_output("mask2",seq,logmask,n/2,1,0,0);
    526        }
    527 #endif
    528 
    529        floor_posts[i][PACKETBLOBS-1]=
    530          floor1_fit(vb,b->flr[info->floorsubmap[submap]],
    531                     logmdct,
    532                     logmask);
    533 
    534        /* lower rate by way of higher noise curve */
    535        _vp_offset_and_mix(psy_look,
    536                           noise,
    537                           tone,
    538                           0,
    539                           logmask,
    540                           mdct,
    541                           logmdct);
    542 
    543 #if 0
    544        if(vi->channels==2){
    545          if(i==0)
    546            _analysis_output("mask0L",seq,logmask,n/2,1,0,0);
    547          else
    548            _analysis_output("mask0R",seq,logmask,n/2,1,0,0);
    549        }else{
    550          _analysis_output("mask0",seq,logmask,n/2,1,0,0);
    551        }
    552 #endif
    553 
    554        floor_posts[i][0]=
    555          floor1_fit(vb,b->flr[info->floorsubmap[submap]],
    556                     logmdct,
    557                     logmask);
    558 
    559        /* we also interpolate a range of intermediate curves for
    560           intermediate rates */
    561        for(k=1;k<PACKETBLOBS/2;k++)
    562          floor_posts[i][k]=
    563            floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
    564                                   floor_posts[i][0],
    565                                   floor_posts[i][PACKETBLOBS/2],
    566                                   k*65536/(PACKETBLOBS/2));
    567        for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++)
    568          floor_posts[i][k]=
    569            floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
    570                                   floor_posts[i][PACKETBLOBS/2],
    571                                   floor_posts[i][PACKETBLOBS-1],
    572                                   (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2));
    573      }
    574    }
    575  }
    576  vbi->ampmax=global_ampmax;
    577 
    578  /*
    579    the next phases are performed once for vbr-only and PACKETBLOB
    580    times for bitrate managed modes.
    581 
    582    1) encode actual mode being used
    583    2) encode the floor for each channel, compute coded mask curve/res
    584    3) normalize and couple.
    585    4) encode residue
    586    5) save packet bytes to the packetblob vector
    587 
    588  */
    589 
    590  /* iterate over the many masking curve fits we've created */
    591 
    592  {
    593    int **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels);
    594    int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
    595 
    596    for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
    597        k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
    598        k++){
    599      oggpack_buffer *opb=vbi->packetblob[k];
    600 
    601      /* start out our new packet blob with packet type and mode */
    602      /* Encode the packet type */
    603      oggpack_write(opb,0,1);
    604      /* Encode the modenumber */
    605      /* Encode frame mode, pre,post windowsize, then dispatch */
    606      oggpack_write(opb,modenumber,b->modebits);
    607      if(vb->W){
    608        oggpack_write(opb,vb->lW,1);
    609        oggpack_write(opb,vb->nW,1);
    610      }
    611 
    612      /* encode floor, compute masking curve, sep out residue */
    613      for(i=0;i<vi->channels;i++){
    614        int submap=info->chmuxlist[i];
    615        int *ilogmask=iwork[i];
    616 
    617        nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]],
    618                                 floor_posts[i][k],
    619                                 ilogmask);
    620 #if 0
    621        {
    622          char buf[80];
    623          sprintf(buf,"maskI%c%d",i?'R':'L',k);
    624          float work[n/2];
    625          for(j=0;j<n/2;j++)
    626            work[j]=FLOOR1_fromdB_LOOKUP[iwork[i][j]];
    627          _analysis_output(buf,seq,work,n/2,1,1,0);
    628        }
    629 #endif
    630      }
    631 
    632      /* our iteration is now based on masking curve, not prequant and
    633         coupling.  Only one prequant/coupling step */
    634 
    635      /* quantize/couple */
    636      /* incomplete implementation that assumes the tree is all depth
    637         one, or no tree at all */
    638      _vp_couple_quantize_normalize(k,
    639                                    &ci->psy_g_param,
    640                                    psy_look,
    641                                    info,
    642                                    gmdct,
    643                                    iwork,
    644                                    nonzero,
    645                                    ci->psy_g_param.sliding_lowpass[vb->W][k],
    646                                    vi->channels);
    647 
    648 #if 0
    649      for(i=0;i<vi->channels;i++){
    650        char buf[80];
    651        sprintf(buf,"res%c%d",i?'R':'L',k);
    652        float work[n/2];
    653        for(j=0;j<n/2;j++)
    654          work[j]=iwork[i][j];
    655        _analysis_output(buf,seq,work,n/2,1,0,0);
    656      }
    657 #endif
    658 
    659      /* classify and encode by submap */
    660      for(i=0;i<info->submaps;i++){
    661        int ch_in_bundle=0;
    662        long **classifications;
    663        int resnum=info->residuesubmap[i];
    664 
    665        for(j=0;j<vi->channels;j++){
    666          if(info->chmuxlist[j]==i){
    667            zerobundle[ch_in_bundle]=0;
    668            if(nonzero[j])zerobundle[ch_in_bundle]=1;
    669            couple_bundle[ch_in_bundle++]=iwork[j];
    670          }
    671        }
    672 
    673        classifications=_residue_P[ci->residue_type[resnum]]->
    674          class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle);
    675 
    676        ch_in_bundle=0;
    677        for(j=0;j<vi->channels;j++)
    678          if(info->chmuxlist[j]==i)
    679            couple_bundle[ch_in_bundle++]=iwork[j];
    680 
    681        _residue_P[ci->residue_type[resnum]]->
    682          forward(opb,vb,b->residue[resnum],
    683                  couple_bundle,zerobundle,ch_in_bundle,classifications,i);
    684      }
    685 
    686      /* ok, done encoding.  Next protopacket. */
    687    }
    688 
    689  }
    690 
    691 #if 0
    692  seq++;
    693  total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;
    694 #endif
    695  return(0);
    696 }
    697 
    698 static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
    699  vorbis_dsp_state     *vd=vb->vd;
    700  vorbis_info          *vi=vd->vi;
    701  codec_setup_info     *ci=vi->codec_setup;
    702  private_state        *b=vd->backend_state;
    703  vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
    704 
    705  int                   i,j;
    706  long                  n=vb->pcmend=ci->blocksizes[vb->W];
    707 
    708  float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels);
    709  int    *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
    710 
    711  int   *nonzero  =alloca(sizeof(*nonzero)*vi->channels);
    712  void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
    713 
    714  /* recover the spectral envelope; store it in the PCM vector for now */
    715  for(i=0;i<vi->channels;i++){
    716    int submap=info->chmuxlist[i];
    717    floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
    718      inverse1(vb,b->flr[info->floorsubmap[submap]]);
    719    if(floormemo[i])
    720      nonzero[i]=1;
    721    else
    722      nonzero[i]=0;
    723    memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
    724  }
    725 
    726  /* channel coupling can 'dirty' the nonzero listing */
    727  for(i=0;i<info->coupling_steps;i++){
    728    if(nonzero[info->coupling_mag[i]] ||
    729       nonzero[info->coupling_ang[i]]){
    730      nonzero[info->coupling_mag[i]]=1;
    731      nonzero[info->coupling_ang[i]]=1;
    732    }
    733  }
    734 
    735  /* recover the residue into our working vectors */
    736  for(i=0;i<info->submaps;i++){
    737    int ch_in_bundle=0;
    738    for(j=0;j<vi->channels;j++){
    739      if(info->chmuxlist[j]==i){
    740        if(nonzero[j])
    741          zerobundle[ch_in_bundle]=1;
    742        else
    743          zerobundle[ch_in_bundle]=0;
    744        pcmbundle[ch_in_bundle++]=vb->pcm[j];
    745      }
    746    }
    747 
    748    _residue_P[ci->residue_type[info->residuesubmap[i]]]->
    749      inverse(vb,b->residue[info->residuesubmap[i]],
    750              pcmbundle,zerobundle,ch_in_bundle);
    751  }
    752 
    753  /* channel coupling */
    754  for(i=info->coupling_steps-1;i>=0;i--){
    755    float *pcmM=vb->pcm[info->coupling_mag[i]];
    756    float *pcmA=vb->pcm[info->coupling_ang[i]];
    757 
    758    for(j=0;j<n/2;j++){
    759      float mag=pcmM[j];
    760      float ang=pcmA[j];
    761 
    762      if(mag>0)
    763        if(ang>0){
    764          pcmM[j]=mag;
    765          pcmA[j]=mag-ang;
    766        }else{
    767          pcmA[j]=mag;
    768          pcmM[j]=mag+ang;
    769        }
    770      else
    771        if(ang>0){
    772          pcmM[j]=mag;
    773          pcmA[j]=mag+ang;
    774        }else{
    775          pcmA[j]=mag;
    776          pcmM[j]=mag-ang;
    777        }
    778    }
    779  }
    780 
    781  /* compute and apply spectral envelope */
    782  for(i=0;i<vi->channels;i++){
    783    float *pcm=vb->pcm[i];
    784    int submap=info->chmuxlist[i];
    785    _floor_P[ci->floor_type[info->floorsubmap[submap]]]->
    786      inverse2(vb,b->flr[info->floorsubmap[submap]],
    787               floormemo[i],pcm);
    788  }
    789 
    790  /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
    791  /* only MDCT right now.... */
    792  for(i=0;i<vi->channels;i++){
    793    float *pcm=vb->pcm[i];
    794    mdct_backward(b->transform[vb->W][0],pcm,pcm);
    795  }
    796 
    797  /* all done! */
    798  return(0);
    799 }
    800 
    801 /* export hooks */
    802 const vorbis_func_mapping mapping0_exportbundle={
    803  &mapping0_pack,
    804  &mapping0_unpack,
    805  &mapping0_free_info,
    806  &mapping0_forward,
    807  &mapping0_inverse
    808 };