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