Bug 436663. Work around ATSUI crasher caused by long Hebrew sequence. r=roc, sr=vlad
[wine-gecko.git] / media / libvorbis / lib / vorbis_mapping0.c
blob8e5a468624cf1db3269ac10f4bf84688e8c242ba
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-2007 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function: channel mapping 0 implementation
14 last mod: $Id: mapping0.c 13293 2007-07-24 00:09:47Z xiphmont $
16 ********************************************************************/
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"
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.
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 */
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);
48 static int ilog(unsigned int v){
49 int ret=0;
50 if(v)--v;
51 while(v){
52 ret++;
53 v>>=1;
55 return(ret);
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;
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. */
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);
76 if(info->coupling_steps>0){
77 oggpack_write(opb,1,1);
78 oggpack_write(opb,info->coupling_steps-1,8);
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));
84 }else
85 oggpack_write(opb,0,1);
87 oggpack_write(opb,0,2); /* 2,3:reserved */
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);
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);
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));
108 if(oggpack_read(opb,1))
109 info->submaps=oggpack_read(opb,4)+1;
110 else
111 info->submaps=1;
113 if(oggpack_read(opb,1)){
114 info->coupling_steps=oggpack_read(opb,8)+1;
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));
120 if(testM<0 ||
121 testA<0 ||
122 testM==testA ||
123 testM>=vi->channels ||
124 testA>=vi->channels) goto err_out;
129 if(oggpack_read(opb,2)>0)goto err_out; /* 2,3:reserved */
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;
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;
145 return info;
147 err_out:
148 mapping0_free_info(info);
149 return(NULL);
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"
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,
230 #endif
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(oggpack_buffer *opb,vorbis_block *vb,
239 vorbis_look_floor *look,
240 int *post,int *ilogmask);
243 static int mapping0_forward(vorbis_block *vb){
244 vorbis_dsp_state *vd=vb->vd;
245 vorbis_info *vi=vd->vi;
246 codec_setup_info *ci=vi->codec_setup;
247 private_state *b=vb->vd->backend_state;
248 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
249 int n=vb->pcmend;
250 int i,j,k;
252 int *nonzero = alloca(sizeof(*nonzero)*vi->channels);
253 float **gmdct = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct));
254 int **ilogmaskch= _vorbis_block_alloc(vb,vi->channels*sizeof(*ilogmaskch));
255 int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts));
257 float global_ampmax=vbi->ampmax;
258 float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels);
259 int blocktype=vbi->blocktype;
261 int modenumber=vb->W;
262 vorbis_info_mapping0 *info=ci->map_param[modenumber];
263 vorbis_look_psy *psy_look=
264 b->psy+blocktype+(vb->W?2:0);
266 vb->mode=modenumber;
268 for(i=0;i<vi->channels;i++){
269 float scale=4.f/n;
270 float scale_dB;
272 float *pcm =vb->pcm[i];
273 float *logfft =pcm;
275 gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
277 scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original
278 todB estimation used on IEEE 754
279 compliant machines had a bug that
280 returned dB values about a third
281 of a decibel too high. The bug
282 was harmless because tunings
283 implicitly took that into
284 account. However, fixing the bug
285 in the estimator requires
286 changing all the tunings as well.
287 For now, it's easier to sync
288 things back up here, and
289 recalibrate the tunings in the
290 next major model upgrade. */
292 #if 0
293 if(vi->channels==2)
294 if(i==0)
295 _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2);
296 else
297 _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2);
298 #endif
300 /* window the PCM data */
301 _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
303 #if 0
304 if(vi->channels==2)
305 if(i==0)
306 _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2);
307 else
308 _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2);
309 #endif
311 /* transform the PCM data */
312 /* only MDCT right now.... */
313 mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]);
315 /* FFT yields more accurate tonal estimation (not phase sensitive) */
316 drft_forward(&b->fft_look[vb->W],pcm);
317 logfft[0]=scale_dB+todB(pcm) + .345; /* + .345 is a hack; the
318 original todB estimation used on
319 IEEE 754 compliant machines had a
320 bug that returned dB values about
321 a third of a decibel too high.
322 The bug was harmless because
323 tunings implicitly took that into
324 account. However, fixing the bug
325 in the estimator requires
326 changing all the tunings as well.
327 For now, it's easier to sync
328 things back up here, and
329 recalibrate the tunings in the
330 next major model upgrade. */
331 local_ampmax[i]=logfft[0];
332 for(j=1;j<n-1;j+=2){
333 float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1];
334 temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp) + .345; /* +
335 .345 is a hack; the original todB
336 estimation used on IEEE 754
337 compliant machines had a bug that
338 returned dB values about a third
339 of a decibel too high. The bug
340 was harmless because tunings
341 implicitly took that into
342 account. However, fixing the bug
343 in the estimator requires
344 changing all the tunings as well.
345 For now, it's easier to sync
346 things back up here, and
347 recalibrate the tunings in the
348 next major model upgrade. */
349 if(temp>local_ampmax[i])local_ampmax[i]=temp;
352 if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
353 if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
355 #if 0
356 if(vi->channels==2){
357 if(i==0){
358 _analysis_output("fftL",seq,logfft,n/2,1,0,0);
359 }else{
360 _analysis_output("fftR",seq,logfft,n/2,1,0,0);
363 #endif
368 float *noise = _vorbis_block_alloc(vb,n/2*sizeof(*noise));
369 float *tone = _vorbis_block_alloc(vb,n/2*sizeof(*tone));
371 for(i=0;i<vi->channels;i++){
372 /* the encoder setup assumes that all the modes used by any
373 specific bitrate tweaking use the same floor */
375 int submap=info->chmuxlist[i];
377 /* the following makes things clearer to *me* anyway */
378 float *mdct =gmdct[i];
379 float *logfft =vb->pcm[i];
381 float *logmdct =logfft+n/2;
382 float *logmask =logfft;
384 vb->mode=modenumber;
386 floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts));
387 memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS);
389 for(j=0;j<n/2;j++)
390 logmdct[j]=todB(mdct+j) + .345; /* + .345 is a hack; the original
391 todB estimation used on IEEE 754
392 compliant machines had a bug that
393 returned dB values about a third
394 of a decibel too high. The bug
395 was harmless because tunings
396 implicitly took that into
397 account. However, fixing the bug
398 in the estimator requires
399 changing all the tunings as well.
400 For now, it's easier to sync
401 things back up here, and
402 recalibrate the tunings in the
403 next major model upgrade. */
405 #if 0
406 if(vi->channels==2){
407 if(i==0)
408 _analysis_output("mdctL",seq,logmdct,n/2,1,0,0);
409 else
410 _analysis_output("mdctR",seq,logmdct,n/2,1,0,0);
411 }else{
412 _analysis_output("mdct",seq,logmdct,n/2,1,0,0);
414 #endif
416 /* first step; noise masking. Not only does 'noise masking'
417 give us curves from which we can decide how much resolution
418 to give noise parts of the spectrum, it also implicitly hands
419 us a tonality estimate (the larger the value in the
420 'noise_depth' vector, the more tonal that area is) */
422 _vp_noisemask(psy_look,
423 logmdct,
424 noise); /* noise does not have by-frequency offset
425 bias applied yet */
426 #if 0
427 if(vi->channels==2){
428 if(i==0)
429 _analysis_output("noiseL",seq,noise,n/2,1,0,0);
430 else
431 _analysis_output("noiseR",seq,noise,n/2,1,0,0);
433 #endif
435 /* second step: 'all the other crap'; all the stuff that isn't
436 computed/fit for bitrate management goes in the second psy
437 vector. This includes tone masking, peak limiting and ATH */
439 _vp_tonemask(psy_look,
440 logfft,
441 tone,
442 global_ampmax,
443 local_ampmax[i]);
445 #if 0
446 if(vi->channels==2){
447 if(i==0)
448 _analysis_output("toneL",seq,tone,n/2,1,0,0);
449 else
450 _analysis_output("toneR",seq,tone,n/2,1,0,0);
452 #endif
454 /* third step; we offset the noise vectors, overlay tone
455 masking. We then do a floor1-specific line fit. If we're
456 performing bitrate management, the line fit is performed
457 multiple times for up/down tweakage on demand. */
459 #if 0
461 float aotuv[psy_look->n];
462 #endif
464 _vp_offset_and_mix(psy_look,
465 noise,
466 tone,
468 logmask,
469 mdct,
470 logmdct);
472 #if 0
473 if(vi->channels==2){
474 if(i==0)
475 _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0);
476 else
477 _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0);
480 #endif
483 #if 0
484 if(vi->channels==2){
485 if(i==0)
486 _analysis_output("mask1L",seq,logmask,n/2,1,0,0);
487 else
488 _analysis_output("mask1R",seq,logmask,n/2,1,0,0);
490 #endif
492 /* this algorithm is hardwired to floor 1 for now; abort out if
493 we're *not* floor1. This won't happen unless someone has
494 broken the encode setup lib. Guard it anyway. */
495 if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1);
497 floor_posts[i][PACKETBLOBS/2]=
498 floor1_fit(vb,b->flr[info->floorsubmap[submap]],
499 logmdct,
500 logmask);
502 /* are we managing bitrate? If so, perform two more fits for
503 later rate tweaking (fits represent hi/lo) */
504 if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){
505 /* higher rate by way of lower noise curve */
507 _vp_offset_and_mix(psy_look,
508 noise,
509 tone,
511 logmask,
512 mdct,
513 logmdct);
515 #if 0
516 if(vi->channels==2){
517 if(i==0)
518 _analysis_output("mask2L",seq,logmask,n/2,1,0,0);
519 else
520 _analysis_output("mask2R",seq,logmask,n/2,1,0,0);
522 #endif
524 floor_posts[i][PACKETBLOBS-1]=
525 floor1_fit(vb,b->flr[info->floorsubmap[submap]],
526 logmdct,
527 logmask);
529 /* lower rate by way of higher noise curve */
530 _vp_offset_and_mix(psy_look,
531 noise,
532 tone,
534 logmask,
535 mdct,
536 logmdct);
538 #if 0
539 if(vi->channels==2)
540 if(i==0)
541 _analysis_output("mask0L",seq,logmask,n/2,1,0,0);
542 else
543 _analysis_output("mask0R",seq,logmask,n/2,1,0,0);
544 #endif
546 floor_posts[i][0]=
547 floor1_fit(vb,b->flr[info->floorsubmap[submap]],
548 logmdct,
549 logmask);
551 /* we also interpolate a range of intermediate curves for
552 intermediate rates */
553 for(k=1;k<PACKETBLOBS/2;k++)
554 floor_posts[i][k]=
555 floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
556 floor_posts[i][0],
557 floor_posts[i][PACKETBLOBS/2],
558 k*65536/(PACKETBLOBS/2));
559 for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++)
560 floor_posts[i][k]=
561 floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
562 floor_posts[i][PACKETBLOBS/2],
563 floor_posts[i][PACKETBLOBS-1],
564 (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2));
568 vbi->ampmax=global_ampmax;
571 the next phases are performed once for vbr-only and PACKETBLOB
572 times for bitrate managed modes.
574 1) encode actual mode being used
575 2) encode the floor for each channel, compute coded mask curve/res
576 3) normalize and couple.
577 4) encode residue
578 5) save packet bytes to the packetblob vector
582 /* iterate over the many masking curve fits we've created */
585 float **res_bundle=alloca(sizeof(*res_bundle)*vi->channels);
586 float **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels);
587 int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
588 int **sortindex=alloca(sizeof(*sortindex)*vi->channels);
589 float **mag_memo;
590 int **mag_sort;
592 if(info->coupling_steps){
593 mag_memo=_vp_quantize_couple_memo(vb,
594 &ci->psy_g_param,
595 psy_look,
596 info,
597 gmdct);
599 mag_sort=_vp_quantize_couple_sort(vb,
600 psy_look,
601 info,
602 mag_memo);
604 hf_reduction(&ci->psy_g_param,
605 psy_look,
606 info,
607 mag_memo);
610 memset(sortindex,0,sizeof(*sortindex)*vi->channels);
611 if(psy_look->vi->normal_channel_p){
612 for(i=0;i<vi->channels;i++){
613 float *mdct =gmdct[i];
614 sortindex[i]=alloca(sizeof(**sortindex)*n/2);
615 _vp_noise_normalize_sort(psy_look,mdct,sortindex[i]);
619 for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
620 k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
621 k++){
622 oggpack_buffer *opb=vbi->packetblob[k];
624 /* start out our new packet blob with packet type and mode */
625 /* Encode the packet type */
626 oggpack_write(opb,0,1);
627 /* Encode the modenumber */
628 /* Encode frame mode, pre,post windowsize, then dispatch */
629 oggpack_write(opb,modenumber,b->modebits);
630 if(vb->W){
631 oggpack_write(opb,vb->lW,1);
632 oggpack_write(opb,vb->nW,1);
635 /* encode floor, compute masking curve, sep out residue */
636 for(i=0;i<vi->channels;i++){
637 int submap=info->chmuxlist[i];
638 float *mdct =gmdct[i];
639 float *res =vb->pcm[i];
640 int *ilogmask=ilogmaskch[i]=
641 _vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
643 nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]],
644 floor_posts[i][k],
645 ilogmask);
646 #if 0
648 char buf[80];
649 sprintf(buf,"maskI%c%d",i?'R':'L',k);
650 float work[n/2];
651 for(j=0;j<n/2;j++)
652 work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]];
653 _analysis_output(buf,seq,work,n/2,1,1,0);
655 #endif
656 _vp_remove_floor(psy_look,
657 mdct,
658 ilogmask,
659 res,
660 ci->psy_g_param.sliding_lowpass[vb->W][k]);
662 _vp_noise_normalize(psy_look,res,res+n/2,sortindex[i]);
665 #if 0
667 char buf[80];
668 float work[n/2];
669 for(j=0;j<n/2;j++)
670 work[j]=FLOOR1_fromdB_LOOKUP[ilogmask[j]]*(res+n/2)[j];
671 sprintf(buf,"resI%c%d",i?'R':'L',k);
672 _analysis_output(buf,seq,work,n/2,1,1,0);
675 #endif
678 /* our iteration is now based on masking curve, not prequant and
679 coupling. Only one prequant/coupling step */
681 /* quantize/couple */
682 /* incomplete implementation that assumes the tree is all depth
683 one, or no tree at all */
684 if(info->coupling_steps){
685 _vp_couple(k,
686 &ci->psy_g_param,
687 psy_look,
688 info,
689 vb->pcm,
690 mag_memo,
691 mag_sort,
692 ilogmaskch,
693 nonzero,
694 ci->psy_g_param.sliding_lowpass[vb->W][k]);
697 /* classify and encode by submap */
698 for(i=0;i<info->submaps;i++){
699 int ch_in_bundle=0;
700 long **classifications;
701 int resnum=info->residuesubmap[i];
703 for(j=0;j<vi->channels;j++){
704 if(info->chmuxlist[j]==i){
705 zerobundle[ch_in_bundle]=0;
706 if(nonzero[j])zerobundle[ch_in_bundle]=1;
707 res_bundle[ch_in_bundle]=vb->pcm[j];
708 couple_bundle[ch_in_bundle++]=vb->pcm[j]+n/2;
712 classifications=_residue_P[ci->residue_type[resnum]]->
713 class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle);
715 _residue_P[ci->residue_type[resnum]]->
716 forward(opb,vb,b->residue[resnum],
717 couple_bundle,NULL,zerobundle,ch_in_bundle,classifications);
720 /* ok, done encoding. Next protopacket. */
725 #if 0
726 seq++;
727 total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;
728 #endif
729 return(0);
732 static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
733 vorbis_dsp_state *vd=vb->vd;
734 vorbis_info *vi=vd->vi;
735 codec_setup_info *ci=vi->codec_setup;
736 private_state *b=vd->backend_state;
737 vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
738 int hs=ci->halfrate_flag;
740 int i,j;
741 long n=vb->pcmend=ci->blocksizes[vb->W];
743 float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels);
744 int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
746 int *nonzero =alloca(sizeof(*nonzero)*vi->channels);
747 void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
749 /* recover the spectral envelope; store it in the PCM vector for now */
750 for(i=0;i<vi->channels;i++){
751 int submap=info->chmuxlist[i];
752 floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
753 inverse1(vb,b->flr[info->floorsubmap[submap]]);
754 if(floormemo[i])
755 nonzero[i]=1;
756 else
757 nonzero[i]=0;
758 memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
761 /* channel coupling can 'dirty' the nonzero listing */
762 for(i=0;i<info->coupling_steps;i++){
763 if(nonzero[info->coupling_mag[i]] ||
764 nonzero[info->coupling_ang[i]]){
765 nonzero[info->coupling_mag[i]]=1;
766 nonzero[info->coupling_ang[i]]=1;
770 /* recover the residue into our working vectors */
771 for(i=0;i<info->submaps;i++){
772 int ch_in_bundle=0;
773 for(j=0;j<vi->channels;j++){
774 if(info->chmuxlist[j]==i){
775 if(nonzero[j])
776 zerobundle[ch_in_bundle]=1;
777 else
778 zerobundle[ch_in_bundle]=0;
779 pcmbundle[ch_in_bundle++]=vb->pcm[j];
783 _residue_P[ci->residue_type[info->residuesubmap[i]]]->
784 inverse(vb,b->residue[info->residuesubmap[i]],
785 pcmbundle,zerobundle,ch_in_bundle);
788 /* channel coupling */
789 for(i=info->coupling_steps-1;i>=0;i--){
790 float *pcmM=vb->pcm[info->coupling_mag[i]];
791 float *pcmA=vb->pcm[info->coupling_ang[i]];
793 for(j=0;j<n/2;j++){
794 float mag=pcmM[j];
795 float ang=pcmA[j];
797 if(mag>0)
798 if(ang>0){
799 pcmM[j]=mag;
800 pcmA[j]=mag-ang;
801 }else{
802 pcmA[j]=mag;
803 pcmM[j]=mag+ang;
805 else
806 if(ang>0){
807 pcmM[j]=mag;
808 pcmA[j]=mag+ang;
809 }else{
810 pcmA[j]=mag;
811 pcmM[j]=mag-ang;
816 /* compute and apply spectral envelope */
817 for(i=0;i<vi->channels;i++){
818 float *pcm=vb->pcm[i];
819 int submap=info->chmuxlist[i];
820 _floor_P[ci->floor_type[info->floorsubmap[submap]]]->
821 inverse2(vb,b->flr[info->floorsubmap[submap]],
822 floormemo[i],pcm);
825 /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
826 /* only MDCT right now.... */
827 for(i=0;i<vi->channels;i++){
828 float *pcm=vb->pcm[i];
829 mdct_backward(b->transform[vb->W][0],pcm,pcm);
832 /* all done! */
833 return(0);
836 /* export hooks */
837 vorbis_func_mapping mapping0_exportbundle={
838 &mapping0_pack,
839 &mapping0_unpack,
840 &mapping0_free_info,
841 &mapping0_forward,
842 &mapping0_inverse