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
39static 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
47static 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 */
91static 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
158static long seq=0;
159static ogg_int64_t total=0;
160static 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
230static int mapping0_forward(vorbis_block *vb){
231 vorbis_dsp_state *vd=vb->vd;
232 vorbis_info *vi=vd->vi;
233 codec_setup_info *ci=vi->codec_setup;
234 private_state *b=vb->vd->backend_state;
235 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
236 int n=vb->pcmend;
237 int i,j,k;
238
239 int *nonzero = alloca(sizeof(*nonzero)*vi->channels);
240 float **gmdct = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct));
241 int **iwork = _vorbis_block_alloc(vb,vi->channels*sizeof(*iwork));
242 int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts));
243
244 float global_ampmax=vbi->ampmax;
245 float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels);
246 int blocktype=vbi->blocktype;
247
248 int modenumber=vb->W;
249 vorbis_info_mapping0 *info=ci->map_param[modenumber];
250 vorbis_look_psy *psy_look=b->psy+blocktype+(vb->W?2:0);
251
252 vb->mode=modenumber;
253
254 for(i=0;i<vi->channels;i++){
255 float scale=4.f/n;
256 float scale_dB;
257
258 float *pcm =vb->pcm[i];
259 float *logfft =pcm;
260
261 iwork[i]=_vorbis_block_alloc(vb,n/2*sizeof(**iwork));
262 gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
263
264 scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original
265 todB estimation used on IEEE 754
266 compliant machines had a bug that
267 returned dB values about a third
268 of a decibel too high. The bug
269 was harmless because tunings
270 implicitly took that into
271 account. However, fixing the bug
272 in the estimator requires
273 changing all the tunings as well.
274 For now, it's easier to sync
275 things back up here, and
276 recalibrate the tunings in the
277 next major model upgrade. */
278
279#if 0
280 if(vi->channels==2){
281 if(i==0)
282 _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2);
283 else
284 _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2);
285 }else{
286 _analysis_output("pcm",seq,pcm,n,0,0,total-n/2);
287 }
288#endif
289
290 /* window the PCM data */
291 _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
292
293#if 0
294 if(vi->channels==2){
295 if(i==0)
296 _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2);
297 else
298 _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2);
299 }else{
300 _analysis_output("windowed",seq,pcm,n,0,0,total-n/2);
301 }
302#endif
303
304 /* transform the PCM data */
305 /* only MDCT right now.... */
306 mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]);
307
308 /* FFT yields more accurate tonal estimation (not phase sensitive) */
309 drft_forward(&b->fft_look[vb->W],pcm);
310 logfft[0]=scale_dB+todB(pcm) + .345; /* + .345 is a hack; the
311 original todB estimation used on
312 IEEE 754 compliant machines had a
313 bug that returned dB values about
314 a third of a decibel too high.
315 The bug was harmless because
316 tunings implicitly took that into
317 account. However, fixing the bug
318 in the estimator requires
319 changing all the tunings as well.
320 For now, it's easier to sync
321 things back up here, and
322 recalibrate the tunings in the
323 next major model upgrade. */
324 local_ampmax[i]=logfft[0];
325 for(j=1;j<n-1;j+=2){
326 float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1];
327 temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp) + .345; /* +
328 .345 is a hack; the original todB
329 estimation used on IEEE 754
330 compliant machines had a bug that
331 returned dB values about a third
332 of a decibel too high. The bug
333 was harmless because tunings
334 implicitly took that into
335 account. However, fixing the bug
336 in the estimator requires
337 changing all the tunings as well.
338 For now, it's easier to sync
339 things back up here, and
340 recalibrate the tunings in the
341 next major model upgrade. */
342 if(temp>local_ampmax[i])local_ampmax[i]=temp;
343 }
344
345 if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
346 if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
347
348#if 0
349 if(vi->channels==2){
350 if(i==0){
351 _analysis_output("fftL",seq,logfft,n/2,1,0,0);
352 }else{
353 _analysis_output("fftR",seq,logfft,n/2,1,0,0);
354 }
355 }else{
356 _analysis_output("fft",seq,logfft,n/2,1,0,0);
357 }
358#endif
359
360 }
361
362 {
363 float *noise = _vorbis_block_alloc(vb,n/2*sizeof(*noise));
364 float *tone = _vorbis_block_alloc(vb,n/2*sizeof(*tone));
365
366 for(i=0;i<vi->channels;i++){
367 /* the encoder setup assumes that all the modes used by any
368 specific bitrate tweaking use the same floor */
369
370 int submap=info->chmuxlist[i];
371
372 /* the following makes things clearer to *me* anyway */
373 float *mdct =gmdct[i];
374 float *logfft =vb->pcm[i];
375
376 float *logmdct =logfft+n/2;
377 float *logmask =logfft;
378
379 vb->mode=modenumber;
380
381 floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts));
382 memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS);
383
384 for(j=0;j<n/2;j++)
385 logmdct[j]=todB(mdct+j) + .345; /* + .345 is a hack; the original
386 todB estimation used on IEEE 754
387 compliant machines had a bug that
388 returned dB values about a third
389 of a decibel too high. The bug
390 was harmless because tunings
391 implicitly took that into
392 account. However, fixing the bug
393 in the estimator requires
394 changing all the tunings as well.
395 For now, it's easier to sync
396 things back up here, and
397 recalibrate the tunings in the
398 next major model upgrade. */
399
400#if 0
401 if(vi->channels==2){
402 if(i==0)
403 _analysis_output("mdctL",seq,logmdct,n/2,1,0,0);
404 else
405 _analysis_output("mdctR",seq,logmdct,n/2,1,0,0);
406 }else{
407 _analysis_output("mdct",seq,logmdct,n/2,1,0,0);
408 }
409#endif
410
411 /* first step; noise masking. Not only does 'noise masking'
412 give us curves from which we can decide how much resolution
413 to give noise parts of the spectrum, it also implicitly hands
414 us a tonality estimate (the larger the value in the
415 'noise_depth' vector, the more tonal that area is) */
416
417 _vp_noisemask(psy_look,
418 logmdct,
419 noise); /* noise does not have by-frequency offset
420 bias applied yet */
421#if 0
422 if(vi->channels==2){
423 if(i==0)
424 _analysis_output("noiseL",seq,noise,n/2,1,0,0);
425 else
426 _analysis_output("noiseR",seq,noise,n/2,1,0,0);
427 }else{
428 _analysis_output("noise",seq,noise,n/2,1,0,0);
429 }
430#endif
431
432 /* second step: 'all the other crap'; all the stuff that isn't
433 computed/fit for bitrate management goes in the second psy
434 vector. This includes tone masking, peak limiting and ATH */
435
436 _vp_tonemask(psy_look,
437 logfft,
438 tone,
439 global_ampmax,
440 local_ampmax[i]);
441
442#if 0
443 if(vi->channels==2){
444 if(i==0)
445 _analysis_output("toneL",seq,tone,n/2,1,0,0);
446 else
447 _analysis_output("toneR",seq,tone,n/2,1,0,0);
448 }else{
449 _analysis_output("tone",seq,tone,n/2,1,0,0);
450 }
451#endif
452
453 /* third step; we offset the noise vectors, overlay tone
454 masking. We then do a floor1-specific line fit. If we're
455 performing bitrate management, the line fit is performed
456 multiple times for up/down tweakage on demand. */
457
458#if 0
459 {
460 float aotuv[psy_look->n];
461#endif
462
463 _vp_offset_and_mix(psy_look,
464 noise,
465 tone,
466 1,
467 logmask,
468 mdct,
469 logmdct);
470
471#if 0
472 if(vi->channels==2){
473 if(i==0)
474 _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0);
475 else
476 _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0);
477 }else{
478 _analysis_output("aotuvM1",seq,aotuv,psy_look->n,1,1,0);
479 }
480 }
481#endif
482
483
484#if 0
485 if(vi->channels==2){
486 if(i==0)
487 _analysis_output("mask1L",seq,logmask,n/2,1,0,0);
488 else
489 _analysis_output("mask1R",seq,logmask,n/2,1,0,0);
490 }else{
491 _analysis_output("mask1",seq,logmask,n/2,1,0,0);
492 }
493#endif
494
495 /* this algorithm is hardwired to floor 1 for now; abort out if
496 we're *not* floor1. This won't happen unless someone has
497 broken the encode setup lib. Guard it anyway. */
498 if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1);
499
500 floor_posts[i][PACKETBLOBS/2]=
501 floor1_fit(vb,b->flr[info->floorsubmap[submap]],
502 logmdct,
503 logmask);
504
505 /* are we managing bitrate? If so, perform two more fits for
506 later rate tweaking (fits represent hi/lo) */
507 if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){
508 /* higher rate by way of lower noise curve */
509
510 _vp_offset_and_mix(psy_look,
511 noise,
512 tone,
513 2,
514 logmask,
515 mdct,
516 logmdct);
517
518#if 0
519 if(vi->channels==2){
520 if(i==0)
521 _analysis_output("mask2L",seq,logmask,n/2,1,0,0);
522 else
523 _analysis_output("mask2R",seq,logmask,n/2,1,0,0);
524 }else{
525 _analysis_output("mask2",seq,logmask,n/2,1,0,0);
526 }
527#endif
528
529 floor_posts[i][PACKETBLOBS-1]=
530 floor1_fit(vb,b->flr[info->floorsubmap[submap]],
531 logmdct,
532 logmask);
533
534 /* lower rate by way of higher noise curve */
535 _vp_offset_and_mix(psy_look,
536 noise,
537 tone,
538 0,
539 logmask,
540 mdct,
541 logmdct);
542
543#if 0
544 if(vi->channels==2){
545 if(i==0)
546 _analysis_output("mask0L",seq,logmask,n/2,1,0,0);
547 else
548 _analysis_output("mask0R",seq,logmask,n/2,1,0,0);
549 }else{
550 _analysis_output("mask0",seq,logmask,n/2,1,0,0);
551 }
552#endif
553
554 floor_posts[i][0]=
555 floor1_fit(vb,b->flr[info->floorsubmap[submap]],
556 logmdct,
557 logmask);
558
559 /* we also interpolate a range of intermediate curves for
560 intermediate rates */
561 for(k=1;k<PACKETBLOBS/2;k++)
562 floor_posts[i][k]=
563 floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
564 floor_posts[i][0],
565 floor_posts[i][PACKETBLOBS/2],
566 k*65536/(PACKETBLOBS/2));
567 for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++)
568 floor_posts[i][k]=
569 floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
570 floor_posts[i][PACKETBLOBS/2],
571 floor_posts[i][PACKETBLOBS-1],
572 (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2));
573 }
574 }
575 }
576 vbi->ampmax=global_ampmax;
577
578 /*
579 the next phases are performed once for vbr-only and PACKETBLOB
580 times for bitrate managed modes.
581
582 1) encode actual mode being used
583 2) encode the floor for each channel, compute coded mask curve/res
584 3) normalize and couple.
585 4) encode residue
586 5) save packet bytes to the packetblob vector
587
588 */
589
590 /* iterate over the many masking curve fits we've created */
591
592 {
593 int **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels);
594 int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
595
596 for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
597 k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
598 k++){
599 oggpack_buffer *opb=vbi->packetblob[k];
600
601 /* start out our new packet blob with packet type and mode */
602 /* Encode the packet type */
603 oggpack_write(opb,0,1);
604 /* Encode the modenumber */
605 /* Encode frame mode, pre,post windowsize, then dispatch */
606 oggpack_write(opb,modenumber,b->modebits);
607 if(vb->W){
608 oggpack_write(opb,vb->lW,1);
609 oggpack_write(opb,vb->nW,1);
610 }
611
612 /* encode floor, compute masking curve, sep out residue */
613 for(i=0;i<vi->channels;i++){
614 int submap=info->chmuxlist[i];
615 int *ilogmask=iwork[i];
616
617 nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]],
618 floor_posts[i][k],
619 ilogmask);
620#if 0
621 {
622 char buf[80];
623 sprintf(buf,"maskI%c%d",i?'R':'L',k);
624 float work[n/2];
625 for(j=0;j<n/2;j++)
626 work[j]=FLOOR1_fromdB_LOOKUP[iwork[i][j]];
627 _analysis_output(buf,seq,work,n/2,1,1,0);
628 }
629#endif
630 }
631
632 /* our iteration is now based on masking curve, not prequant and
633 coupling. Only one prequant/coupling step */
634
635 /* quantize/couple */
636 /* incomplete implementation that assumes the tree is all depth
637 one, or no tree at all */
638 _vp_couple_quantize_normalize(k,
639 &ci->psy_g_param,
640 psy_look,
641 info,
642 gmdct,
643 iwork,
644 nonzero,
645 ci->psy_g_param.sliding_lowpass[vb->W][k],
646 vi->channels);
647
648#if 0
649 for(i=0;i<vi->channels;i++){
650 char buf[80];
651 sprintf(buf,"res%c%d",i?'R':'L',k);
652 float work[n/2];
653 for(j=0;j<n/2;j++)
654 work[j]=iwork[i][j];
655 _analysis_output(buf,seq,work,n/2,1,0,0);
656 }
657#endif
658
659 /* classify and encode by submap */
660 for(i=0;i<info->submaps;i++){
661 int ch_in_bundle=0;
662 long **classifications;
663 int resnum=info->residuesubmap[i];
664
665 for(j=0;j<vi->channels;j++){
666 if(info->chmuxlist[j]==i){
667 zerobundle[ch_in_bundle]=0;
668 if(nonzero[j])zerobundle[ch_in_bundle]=1;
669 couple_bundle[ch_in_bundle++]=iwork[j];
670 }
671 }
672
673 classifications=_residue_P[ci->residue_type[resnum]]->
674 class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle);
675
676 ch_in_bundle=0;
677 for(j=0;j<vi->channels;j++)
678 if(info->chmuxlist[j]==i)
679 couple_bundle[ch_in_bundle++]=iwork[j];
680
681 _residue_P[ci->residue_type[resnum]]->
682 forward(opb,vb,b->residue[resnum],
683 couple_bundle,zerobundle,ch_in_bundle,classifications,i);
684 }
685
686 /* ok, done encoding. Next protopacket. */
687 }
688
689 }
690
691#if 0
692 seq++;
693 total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;
694#endif
695 return(0);
696}
697
698static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
699 vorbis_dsp_state *vd=vb->vd;
700 vorbis_info *vi=vd->vi;
701 codec_setup_info *ci=vi->codec_setup;
702 private_state *b=vd->backend_state;
703 vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
704
705 int i,j;
706 long n=vb->pcmend=ci->blocksizes[vb->W];
707
708 float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels);
709 int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
710
711 int *nonzero =alloca(sizeof(*nonzero)*vi->channels);
712 void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
713
714 /* recover the spectral envelope; store it in the PCM vector for now */
715 for(i=0;i<vi->channels;i++){
716 int submap=info->chmuxlist[i];
717 floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
718 inverse1(vb,b->flr[info->floorsubmap[submap]]);
719 if(floormemo[i])
720 nonzero[i]=1;
721 else
722 nonzero[i]=0;
723 memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
724 }
725
726 /* channel coupling can 'dirty' the nonzero listing */
727 for(i=0;i<info->coupling_steps;i++){
728 if(nonzero[info->coupling_mag[i]] ||
729 nonzero[info->coupling_ang[i]]){
730 nonzero[info->coupling_mag[i]]=1;
731 nonzero[info->coupling_ang[i]]=1;
732 }
733 }
734
735 /* recover the residue into our working vectors */
736 for(i=0;i<info->submaps;i++){
737 int ch_in_bundle=0;
738 for(j=0;j<vi->channels;j++){
739 if(info->chmuxlist[j]==i){
740 if(nonzero[j])
741 zerobundle[ch_in_bundle]=1;
742 else
743 zerobundle[ch_in_bundle]=0;
744 pcmbundle[ch_in_bundle++]=vb->pcm[j];
745 }
746 }
747
748 _residue_P[ci->residue_type[info->residuesubmap[i]]]->
749 inverse(vb,b->residue[info->residuesubmap[i]],
750 pcmbundle,zerobundle,ch_in_bundle);
751 }
752
753 /* channel coupling */
754 for(i=info->coupling_steps-1;i>=0;i--){
755 float *pcmM=vb->pcm[info->coupling_mag[i]];
756 float *pcmA=vb->pcm[info->coupling_ang[i]];
757
758 for(j=0;j<n/2;j++){
759 float mag=pcmM[j];
760 float ang=pcmA[j];
761
762 if(mag>0)
763 if(ang>0){
764 pcmM[j]=mag;
765 pcmA[j]=mag-ang;
766 }else{
767 pcmA[j]=mag;
768 pcmM[j]=mag+ang;
769 }
770 else
771 if(ang>0){
772 pcmM[j]=mag;
773 pcmA[j]=mag+ang;
774 }else{
775 pcmA[j]=mag;
776 pcmM[j]=mag-ang;
777 }
778 }
779 }
780
781 /* compute and apply spectral envelope */
782 for(i=0;i<vi->channels;i++){
783 float *pcm=vb->pcm[i];
784 int submap=info->chmuxlist[i];
785 _floor_P[ci->floor_type[info->floorsubmap[submap]]]->
786 inverse2(vb,b->flr[info->floorsubmap[submap]],
787 floormemo[i],pcm);
788 }
789
790 /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
791 /* only MDCT right now.... */
792 for(i=0;i<vi->channels;i++){
793 float *pcm=vb->pcm[i];
794 mdct_backward(b->transform[vb->W][0],pcm,pcm);
795 }
796
797 /* all done! */
798 return(0);
799}
800
801/* export hooks */
802const vorbis_func_mapping mapping0_exportbundle={
803 &mapping0_pack,
804 &mapping0_unpack,
805 &mapping0_free_info,
806 &mapping0_forward,
807 &mapping0_inverse
808};
809