]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/audio/libvorbis/mapping0.c
merge
[plan9front.git] / sys / src / cmd / audio / libvorbis / 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-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    = malloc(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=malloc(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){
499         free(nonzero);
500         free(local_ampmax);
501         return(-1);
502       }
503
504       floor_posts[i][PACKETBLOBS/2]=
505         floor1_fit(vb,b->flr[info->floorsubmap[submap]],
506                    logmdct,
507                    logmask);
508
509       /* are we managing bitrate?  If so, perform two more fits for
510          later rate tweaking (fits represent hi/lo) */
511       if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){
512         /* higher rate by way of lower noise curve */
513
514         _vp_offset_and_mix(psy_look,
515                            noise,
516                            tone,
517                            2,
518                            logmask,
519                            mdct,
520                            logmdct);
521
522 #if 0
523         if(vi->channels==2){
524           if(i==0)
525             _analysis_output("mask2L",seq,logmask,n/2,1,0,0);
526           else
527             _analysis_output("mask2R",seq,logmask,n/2,1,0,0);
528         }else{
529           _analysis_output("mask2",seq,logmask,n/2,1,0,0);
530         }
531 #endif
532
533         floor_posts[i][PACKETBLOBS-1]=
534           floor1_fit(vb,b->flr[info->floorsubmap[submap]],
535                      logmdct,
536                      logmask);
537
538         /* lower rate by way of higher noise curve */
539         _vp_offset_and_mix(psy_look,
540                            noise,
541                            tone,
542                            0,
543                            logmask,
544                            mdct,
545                            logmdct);
546
547 #if 0
548         if(vi->channels==2){
549           if(i==0)
550             _analysis_output("mask0L",seq,logmask,n/2,1,0,0);
551           else
552             _analysis_output("mask0R",seq,logmask,n/2,1,0,0);
553         }else{
554           _analysis_output("mask0",seq,logmask,n/2,1,0,0);
555         }
556 #endif
557
558         floor_posts[i][0]=
559           floor1_fit(vb,b->flr[info->floorsubmap[submap]],
560                      logmdct,
561                      logmask);
562
563         /* we also interpolate a range of intermediate curves for
564            intermediate rates */
565         for(k=1;k<PACKETBLOBS/2;k++)
566           floor_posts[i][k]=
567             floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
568                                    floor_posts[i][0],
569                                    floor_posts[i][PACKETBLOBS/2],
570                                    k*65536/(PACKETBLOBS/2));
571         for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++)
572           floor_posts[i][k]=
573             floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
574                                    floor_posts[i][PACKETBLOBS/2],
575                                    floor_posts[i][PACKETBLOBS-1],
576                                    (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2));
577       }
578     }
579   }
580   vbi->ampmax=global_ampmax;
581
582   /*
583     the next phases are performed once for vbr-only and PACKETBLOB
584     times for bitrate managed modes.
585
586     1) encode actual mode being used
587     2) encode the floor for each channel, compute coded mask curve/res
588     3) normalize and couple.
589     4) encode residue
590     5) save packet bytes to the packetblob vector
591
592   */
593
594   /* iterate over the many masking curve fits we've created */
595
596   {
597     int **couple_bundle=malloc(sizeof(*couple_bundle)*vi->channels);
598     int *zerobundle=malloc(sizeof(*zerobundle)*vi->channels);
599
600     for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
601         k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
602         k++){
603       oggpack_buffer *opb=vbi->packetblob[k];
604
605       /* start out our new packet blob with packet type and mode */
606       /* Encode the packet type */
607       oggpack_write(opb,0,1);
608       /* Encode the modenumber */
609       /* Encode frame mode, pre,post windowsize, then dispatch */
610       oggpack_write(opb,modenumber,b->modebits);
611       if(vb->W){
612         oggpack_write(opb,vb->lW,1);
613         oggpack_write(opb,vb->nW,1);
614       }
615
616       /* encode floor, compute masking curve, sep out residue */
617       for(i=0;i<vi->channels;i++){
618         int submap=info->chmuxlist[i];
619         int *ilogmask=iwork[i];
620
621         nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]],
622                                  floor_posts[i][k],
623                                  ilogmask);
624 #if 0
625         {
626           char buf[80];
627           sprintf(buf,"maskI%c%d",i?'R':'L',k);
628           float work[n/2];
629           for(j=0;j<n/2;j++)
630             work[j]=FLOOR1_fromdB_LOOKUP[iwork[i][j]];
631           _analysis_output(buf,seq,work,n/2,1,1,0);
632         }
633 #endif
634       }
635
636       /* our iteration is now based on masking curve, not prequant and
637          coupling.  Only one prequant/coupling step */
638
639       /* quantize/couple */
640       /* incomplete implementation that assumes the tree is all depth
641          one, or no tree at all */
642       _vp_couple_quantize_normalize(k,
643                                     &ci->psy_g_param,
644                                     psy_look,
645                                     info,
646                                     gmdct,
647                                     iwork,
648                                     nonzero,
649                                     ci->psy_g_param.sliding_lowpass[vb->W][k],
650                                     vi->channels);
651
652 #if 0
653       for(i=0;i<vi->channels;i++){
654         char buf[80];
655         sprintf(buf,"res%c%d",i?'R':'L',k);
656         float work[n/2];
657         for(j=0;j<n/2;j++)
658           work[j]=iwork[i][j];
659         _analysis_output(buf,seq,work,n/2,1,0,0);
660       }
661 #endif
662
663       /* classify and encode by submap */
664       for(i=0;i<info->submaps;i++){
665         int ch_in_bundle=0;
666         long **classifications;
667         int resnum=info->residuesubmap[i];
668
669         for(j=0;j<vi->channels;j++){
670           if(info->chmuxlist[j]==i){
671             zerobundle[ch_in_bundle]=0;
672             if(nonzero[j])zerobundle[ch_in_bundle]=1;
673             couple_bundle[ch_in_bundle++]=iwork[j];
674           }
675         }
676
677         classifications=_residue_P[ci->residue_type[resnum]]->
678           class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle);
679
680         ch_in_bundle=0;
681         for(j=0;j<vi->channels;j++)
682           if(info->chmuxlist[j]==i)
683             couple_bundle[ch_in_bundle++]=iwork[j];
684
685         _residue_P[ci->residue_type[resnum]]->
686           forward(opb,vb,b->residue[resnum],
687                   couple_bundle,zerobundle,ch_in_bundle,classifications,i);
688       }
689
690       /* ok, done encoding.  Next protopacket. */
691     }
692
693     free(couple_bundle);
694     free(zerobundle);
695   }
696
697 #if 0
698   seq++;
699   total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;
700 #endif
701   free(nonzero);
702   free(local_ampmax);
703   return(0);
704 }
705
706 static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
707   vorbis_dsp_state     *vd=vb->vd;
708   vorbis_info          *vi=vd->vi;
709   codec_setup_info     *ci=vi->codec_setup;
710   private_state        *b=vd->backend_state;
711   vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
712
713   int                   i,j;
714   long                  n=vb->pcmend=ci->blocksizes[vb->W];
715
716   float **pcmbundle=malloc(sizeof(*pcmbundle)*vi->channels);
717   int    *zerobundle=malloc(sizeof(*zerobundle)*vi->channels);
718
719   int   *nonzero  =malloc(sizeof(*nonzero)*vi->channels);
720   void **floormemo=malloc(sizeof(*floormemo)*vi->channels);
721
722   /* recover the spectral envelope; store it in the PCM vector for now */
723   for(i=0;i<vi->channels;i++){
724     int submap=info->chmuxlist[i];
725     floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
726       inverse1(vb,b->flr[info->floorsubmap[submap]]);
727     if(floormemo[i])
728       nonzero[i]=1;
729     else
730       nonzero[i]=0;
731     memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
732   }
733
734   /* channel coupling can 'dirty' the nonzero listing */
735   for(i=0;i<info->coupling_steps;i++){
736     if(nonzero[info->coupling_mag[i]] ||
737        nonzero[info->coupling_ang[i]]){
738       nonzero[info->coupling_mag[i]]=1;
739       nonzero[info->coupling_ang[i]]=1;
740     }
741   }
742
743   /* recover the residue into our working vectors */
744   for(i=0;i<info->submaps;i++){
745     int ch_in_bundle=0;
746     for(j=0;j<vi->channels;j++){
747       if(info->chmuxlist[j]==i){
748         if(nonzero[j])
749           zerobundle[ch_in_bundle]=1;
750         else
751           zerobundle[ch_in_bundle]=0;
752         pcmbundle[ch_in_bundle++]=vb->pcm[j];
753       }
754     }
755
756     _residue_P[ci->residue_type[info->residuesubmap[i]]]->
757       inverse(vb,b->residue[info->residuesubmap[i]],
758               pcmbundle,zerobundle,ch_in_bundle);
759   }
760
761   /* channel coupling */
762   for(i=info->coupling_steps-1;i>=0;i--){
763     float *pcmM=vb->pcm[info->coupling_mag[i]];
764     float *pcmA=vb->pcm[info->coupling_ang[i]];
765
766     for(j=0;j<n/2;j++){
767       float mag=pcmM[j];
768       float ang=pcmA[j];
769
770       if(mag>0)
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       else
779         if(ang>0){
780           pcmM[j]=mag;
781           pcmA[j]=mag+ang;
782         }else{
783           pcmA[j]=mag;
784           pcmM[j]=mag-ang;
785         }
786     }
787   }
788
789   /* compute and apply spectral envelope */
790   for(i=0;i<vi->channels;i++){
791     float *pcm=vb->pcm[i];
792     int submap=info->chmuxlist[i];
793     _floor_P[ci->floor_type[info->floorsubmap[submap]]]->
794       inverse2(vb,b->flr[info->floorsubmap[submap]],
795                floormemo[i],pcm);
796   }
797
798   /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
799   /* only MDCT right now.... */
800   for(i=0;i<vi->channels;i++){
801     float *pcm=vb->pcm[i];
802     mdct_backward(b->transform[vb->W][0],pcm,pcm);
803   }
804
805   /* all done! */
806   free(pcmbundle);
807   free(zerobundle);
808   free(nonzero);
809   free(floormemo);
810   return(0);
811 }
812
813 /* export hooks */
814 const vorbis_func_mapping mapping0_exportbundle={
815   &mapping0_pack,
816   &mapping0_unpack,
817   &mapping0_free_info,
818   &mapping0_forward,
819   &mapping0_inverse
820 };