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