mapping0.c - vx32 - Local 9vx git repository for patches.
(HTM) git clone git://r-36.net/vx32
(DIR) Log
(DIR) Files
(DIR) Refs
---
mapping0.c (23521B)
---
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 1919 2005-07-24 14:18:04Z baford $
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 private_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 &ci->psy_g_param,
517 psy_look,
518 info,
519 gmdct);
520
521 mag_sort=_vp_quantize_couple_sort(vb,
522 psy_look,
523 info,
524 mag_memo);
525 }
526
527 memset(sortindex,0,sizeof(*sortindex)*vi->channels);
528 if(psy_look->vi->normal_channel_p){
529 for(i=0;i<vi->channels;i++){
530 float *mdct =gmdct[i];
531 sortindex[i]=alloca(sizeof(**sortindex)*n/2);
532 _vp_noise_normalize_sort(psy_look,mdct,sortindex[i]);
533 }
534 }
535
536 for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
537 k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
538 k++){
539
540 /* start out our new packet blob with packet type and mode */
541 /* Encode the packet type */
542 oggpack_write(&vb->opb,0,1);
543 /* Encode the modenumber */
544 /* Encode frame mode, pre,post windowsize, then dispatch */
545 oggpack_write(&vb->opb,modenumber,b->modebits);
546 if(vb->W){
547 oggpack_write(&vb->opb,vb->lW,1);
548 oggpack_write(&vb->opb,vb->nW,1);
549 }
550
551 /* encode floor, compute masking curve, sep out residue */
552 for(i=0;i<vi->channels;i++){
553 int submap=info->chmuxlist[i];
554 float *mdct =gmdct[i];
555 float *res =vb->pcm[i];
556 int *ilogmask=ilogmaskch[i]=
557 _vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
558
559 nonzero[i]=floor1_encode(vb,b->flr[info->floorsubmap[submap]],
560 floor_posts[i][k],
561 ilogmask);
562 #if 0
563 {
564 char buf[80];
565 sprintf(buf,"maskI%c%d",i?'R':'L',k);
566 float work[n/2];
567 for(j=0;j<n/2;j++)
568 work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]];
569 _analysis_output(buf,seq,work,n/2,1,1,0);
570 }
571 #endif
572 _vp_remove_floor(psy_look,
573 mdct,
574 ilogmask,
575 res,
576 ci->psy_g_param.sliding_lowpass[vb->W][k]);
577
578 _vp_noise_normalize(psy_look,res,res+n/2,sortindex[i]);
579
580
581 #if 0
582 {
583 char buf[80];
584 float work[n/2];
585 for(j=0;j<n/2;j++)
586 work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]]*(res+n/2)[j];
587 sprintf(buf,"resI%c%d",i?'R':'L',k);
588 _analysis_output(buf,seq,work,n/2,1,1,0);
589
590 }
591 #endif
592 }
593
594 /* our iteration is now based on masking curve, not prequant and
595 coupling. Only one prequant/coupling step */
596
597 /* quantize/couple */
598 /* incomplete implementation that assumes the tree is all depth
599 one, or no tree at all */
600 if(info->coupling_steps){
601 _vp_couple(k,
602 &ci->psy_g_param,
603 psy_look,
604 info,
605 vb->pcm,
606 mag_memo,
607 mag_sort,
608 ilogmaskch,
609 nonzero,
610 ci->psy_g_param.sliding_lowpass[vb->W][k]);
611 }
612
613 /* classify and encode by submap */
614 for(i=0;i<info->submaps;i++){
615 int ch_in_bundle=0;
616 long **classifications;
617 int resnum=info->residuesubmap[i];
618
619 for(j=0;j<vi->channels;j++){
620 if(info->chmuxlist[j]==i){
621 zerobundle[ch_in_bundle]=0;
622 if(nonzero[j])zerobundle[ch_in_bundle]=1;
623 res_bundle[ch_in_bundle]=vb->pcm[j];
624 couple_bundle[ch_in_bundle++]=vb->pcm[j]+n/2;
625 }
626 }
627
628 classifications=_residue_P[ci->residue_type[resnum]]->
629 class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle);
630
631 _residue_P[ci->residue_type[resnum]]->
632 forward(vb,b->residue[resnum],
633 couple_bundle,NULL,zerobundle,ch_in_bundle,classifications);
634 }
635
636 /* ok, done encoding. Mark this protopacket and prepare next. */
637 oggpack_writealign(&vb->opb);
638 vbi->packetblob_markers[k]=oggpack_bytes(&vb->opb);
639
640 }
641
642 }
643
644 #if 0
645 seq++;
646 total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;
647 #endif
648 return(0);
649 }
650
651 static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
652 vorbis_dsp_state *vd=vb->vd;
653 vorbis_info *vi=vd->vi;
654 codec_setup_info *ci=vi->codec_setup;
655 private_state *b=vd->backend_state;
656 vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
657 int hs=ci->halfrate_flag;
658
659 int i,j;
660 long n=vb->pcmend=ci->blocksizes[vb->W];
661
662 float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels);
663 int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
664
665 int *nonzero =alloca(sizeof(*nonzero)*vi->channels);
666 void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
667
668 /* recover the spectral envelope; store it in the PCM vector for now */
669 for(i=0;i<vi->channels;i++){
670 int submap=info->chmuxlist[i];
671 floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
672 inverse1(vb,b->flr[info->floorsubmap[submap]]);
673 if(floormemo[i])
674 nonzero[i]=1;
675 else
676 nonzero[i]=0;
677 memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
678 }
679
680 /* channel coupling can 'dirty' the nonzero listing */
681 for(i=0;i<info->coupling_steps;i++){
682 if(nonzero[info->coupling_mag[i]] ||
683 nonzero[info->coupling_ang[i]]){
684 nonzero[info->coupling_mag[i]]=1;
685 nonzero[info->coupling_ang[i]]=1;
686 }
687 }
688
689 /* recover the residue into our working vectors */
690 for(i=0;i<info->submaps;i++){
691 int ch_in_bundle=0;
692 for(j=0;j<vi->channels;j++){
693 if(info->chmuxlist[j]==i){
694 if(nonzero[j])
695 zerobundle[ch_in_bundle]=1;
696 else
697 zerobundle[ch_in_bundle]=0;
698 pcmbundle[ch_in_bundle++]=vb->pcm[j];
699 }
700 }
701
702 _residue_P[ci->residue_type[info->residuesubmap[i]]]->
703 inverse(vb,b->residue[info->residuesubmap[i]],
704 pcmbundle,zerobundle,ch_in_bundle);
705 }
706
707 /* channel coupling */
708 for(i=info->coupling_steps-1;i>=0;i--){
709 float *pcmM=vb->pcm[info->coupling_mag[i]];
710 float *pcmA=vb->pcm[info->coupling_ang[i]];
711
712 for(j=0;j<n/2;j++){
713 float mag=pcmM[j];
714 float ang=pcmA[j];
715
716 if(mag>0)
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 else
725 if(ang>0){
726 pcmM[j]=mag;
727 pcmA[j]=mag+ang;
728 }else{
729 pcmA[j]=mag;
730 pcmM[j]=mag-ang;
731 }
732 }
733 }
734
735 /* compute and apply spectral envelope */
736 for(i=0;i<vi->channels;i++){
737 float *pcm=vb->pcm[i];
738 int submap=info->chmuxlist[i];
739 _floor_P[ci->floor_type[info->floorsubmap[submap]]]->
740 inverse2(vb,b->flr[info->floorsubmap[submap]],
741 floormemo[i],pcm);
742 }
743
744 /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
745 /* only MDCT right now.... */
746 for(i=0;i<vi->channels;i++){
747 float *pcm=vb->pcm[i];
748 mdct_backward(b->transform[vb->W][0],pcm,pcm);
749 }
750
751 /* all done! */
752 return(0);
753 }
754
755 /* export hooks */
756 vorbis_func_mapping mapping0_exportbundle={
757 &mapping0_pack,
758 &mapping0_unpack,
759 &mapping0_free_info,
760 &mapping0_forward,
761 &mapping0_inverse
762 };
763