Add Russian translation provided by Валерий Крувялис <valkru@mail.ru>
[xiph-mirror.git] / vorbis / lib / mapping0.c
blob8a7a04c6361a5e5a57cc1cb3d9064eb70d7bf94a
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 http://www.xiph.org/ *
10 * *
11 ********************************************************************
13 function: channel mapping 0 implementation
14 last mod: $Id$
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 void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
49 oggpack_buffer *opb){
50 int i;
51 vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm;
53 /* another 'we meant to do it this way' hack... up to beta 4, we
54 packed 4 binary zeros here to signify one submapping in use. We
55 now redefine that to mean four bitflags that indicate use of
56 deeper features; bit0:submappings, bit1:coupling,
57 bit2,3:reserved. This is backward compatable with all actual uses
58 of the beta code. */
60 if(info->submaps>1){
61 oggpack_write(opb,1,1);
62 oggpack_write(opb,info->submaps-1,4);
63 }else
64 oggpack_write(opb,0,1);
66 if(info->coupling_steps>0){
67 oggpack_write(opb,1,1);
68 oggpack_write(opb,info->coupling_steps-1,8);
70 for(i=0;i<info->coupling_steps;i++){
71 oggpack_write(opb,info->coupling_mag[i],ov_ilog(vi->channels-1));
72 oggpack_write(opb,info->coupling_ang[i],ov_ilog(vi->channels-1));
74 }else
75 oggpack_write(opb,0,1);
77 oggpack_write(opb,0,2); /* 2,3:reserved */
79 /* we don't write the channel submappings if we only have one... */
80 if(info->submaps>1){
81 for(i=0;i<vi->channels;i++)
82 oggpack_write(opb,info->chmuxlist[i],4);
84 for(i=0;i<info->submaps;i++){
85 oggpack_write(opb,0,8); /* time submap unused */
86 oggpack_write(opb,info->floorsubmap[i],8);
87 oggpack_write(opb,info->residuesubmap[i],8);
91 /* also responsible for range checking */
92 static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){
93 int i,b;
94 vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info));
95 codec_setup_info *ci=vi->codec_setup;
96 memset(info,0,sizeof(*info));
97 if(vi->channels<=0)goto err_out;
99 b=oggpack_read(opb,1);
100 if(b<0)goto err_out;
101 if(b){
102 info->submaps=oggpack_read(opb,4)+1;
103 if(info->submaps<=0)goto err_out;
104 }else
105 info->submaps=1;
107 b=oggpack_read(opb,1);
108 if(b<0)goto err_out;
109 if(b){
110 info->coupling_steps=oggpack_read(opb,8)+1;
111 if(info->coupling_steps<=0)goto err_out;
112 for(i=0;i<info->coupling_steps;i++){
113 /* vi->channels > 0 is enforced in the caller */
114 int testM=info->coupling_mag[i]=
115 oggpack_read(opb,ov_ilog(vi->channels-1));
116 int testA=info->coupling_ang[i]=
117 oggpack_read(opb,ov_ilog(vi->channels-1));
119 if(testM<0 ||
120 testA<0 ||
121 testM==testA ||
122 testM>=vi->channels ||
123 testA>=vi->channels) goto err_out;
128 if(oggpack_read(opb,2)!=0)goto err_out; /* 2,3:reserved */
130 if(info->submaps>1){
131 for(i=0;i<vi->channels;i++){
132 info->chmuxlist[i]=oggpack_read(opb,4);
133 if(info->chmuxlist[i]>=info->submaps || info->chmuxlist[i]<0)goto err_out;
136 for(i=0;i<info->submaps;i++){
137 oggpack_read(opb,8); /* time submap unused */
138 info->floorsubmap[i]=oggpack_read(opb,8);
139 if(info->floorsubmap[i]>=ci->floors || info->floorsubmap[i]<0)goto err_out;
140 info->residuesubmap[i]=oggpack_read(opb,8);
141 if(info->residuesubmap[i]>=ci->residues || info->residuesubmap[i]<0)goto err_out;
144 return info;
146 err_out:
147 mapping0_free_info(info);
148 return(NULL);
151 #include "os.h"
152 #include "lpc.h"
153 #include "lsp.h"
154 #include "envelope.h"
155 #include "mdct.h"
156 #include "psy.h"
157 #include "scales.h"
159 #if 0
160 static long seq=0;
161 static ogg_int64_t total=0;
162 static float FLOOR1_fromdB_LOOKUP[256]={
163 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
164 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
165 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
166 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
167 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
168 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
169 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
170 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
171 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
172 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
173 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
174 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
175 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
176 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
177 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
178 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
179 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
180 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
181 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
182 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
183 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
184 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
185 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
186 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
187 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
188 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
189 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
190 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
191 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
192 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
193 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
194 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
195 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
196 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
197 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
198 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
199 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
200 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
201 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
202 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
203 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
204 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
205 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
206 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
207 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
208 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
209 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
210 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
211 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
212 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
213 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
214 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
215 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
216 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
217 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
218 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
219 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
220 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
221 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
222 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
223 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
224 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
225 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
226 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
229 #endif
232 static int mapping0_forward(vorbis_block *vb){
233 vorbis_dsp_state *vd=vb->vd;
234 vorbis_info *vi=vd->vi;
235 codec_setup_info *ci=vi->codec_setup;
236 private_state *b=vb->vd->backend_state;
237 vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
238 int n=vb->pcmend;
239 int i,j,k;
241 int *nonzero = alloca(sizeof(*nonzero)*vi->channels);
242 float **gmdct = _vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct));
243 int **iwork = _vorbis_block_alloc(vb,vi->channels*sizeof(*iwork));
244 int ***floor_posts = _vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts));
246 float global_ampmax=vbi->ampmax;
247 float *local_ampmax=alloca(sizeof(*local_ampmax)*vi->channels);
248 int blocktype=vbi->blocktype;
250 int modenumber=vb->W;
251 vorbis_info_mapping0 *info=ci->map_param[modenumber];
252 vorbis_look_psy *psy_look=b->psy+blocktype+(vb->W?2:0);
254 vb->mode=modenumber;
256 for(i=0;i<vi->channels;i++){
257 float scale=4.f/n;
258 float scale_dB;
260 float *pcm =vb->pcm[i];
261 float *logfft =pcm;
263 iwork[i]=_vorbis_block_alloc(vb,n/2*sizeof(**iwork));
264 gmdct[i]=_vorbis_block_alloc(vb,n/2*sizeof(**gmdct));
266 scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original
267 todB estimation used on IEEE 754
268 compliant machines had a bug that
269 returned dB values about a third
270 of a decibel too high. The bug
271 was harmless because tunings
272 implicitly took that into
273 account. However, fixing the bug
274 in the estimator requires
275 changing all the tunings as well.
276 For now, it's easier to sync
277 things back up here, and
278 recalibrate the tunings in the
279 next major model upgrade. */
281 #if 0
282 if(vi->channels==2){
283 if(i==0)
284 _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2);
285 else
286 _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2);
287 }else{
288 _analysis_output("pcm",seq,pcm,n,0,0,total-n/2);
290 #endif
292 /* window the PCM data */
293 _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW);
295 #if 0
296 if(vi->channels==2){
297 if(i==0)
298 _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2);
299 else
300 _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2);
301 }else{
302 _analysis_output("windowed",seq,pcm,n,0,0,total-n/2);
304 #endif
306 /* transform the PCM data */
307 /* only MDCT right now.... */
308 mdct_forward(b->transform[vb->W][0],pcm,gmdct[i]);
310 /* FFT yields more accurate tonal estimation (not phase sensitive) */
311 drft_forward(&b->fft_look[vb->W],pcm);
312 logfft[0]=scale_dB+todB(pcm) + .345; /* + .345 is a hack; the
313 original todB estimation used on
314 IEEE 754 compliant machines had a
315 bug that returned dB values about
316 a third of a decibel too high.
317 The bug was harmless because
318 tunings implicitly took that into
319 account. However, fixing the bug
320 in the estimator requires
321 changing all the tunings as well.
322 For now, it's easier to sync
323 things back up here, and
324 recalibrate the tunings in the
325 next major model upgrade. */
326 local_ampmax[i]=logfft[0];
327 for(j=1;j<n-1;j+=2){
328 float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1];
329 temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp) + .345; /* +
330 .345 is a hack; the original todB
331 estimation used on IEEE 754
332 compliant machines had a bug that
333 returned dB values about a third
334 of a decibel too high. The bug
335 was harmless because tunings
336 implicitly took that into
337 account. However, fixing the bug
338 in the estimator requires
339 changing all the tunings as well.
340 For now, it's easier to sync
341 things back up here, and
342 recalibrate the tunings in the
343 next major model upgrade. */
344 if(temp>local_ampmax[i])local_ampmax[i]=temp;
347 if(local_ampmax[i]>0.f)local_ampmax[i]=0.f;
348 if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i];
350 #if 0
351 if(vi->channels==2){
352 if(i==0){
353 _analysis_output("fftL",seq,logfft,n/2,1,0,0);
354 }else{
355 _analysis_output("fftR",seq,logfft,n/2,1,0,0);
357 }else{
358 _analysis_output("fft",seq,logfft,n/2,1,0,0);
360 #endif
365 float *noise = _vorbis_block_alloc(vb,n/2*sizeof(*noise));
366 float *tone = _vorbis_block_alloc(vb,n/2*sizeof(*tone));
368 for(i=0;i<vi->channels;i++){
369 /* the encoder setup assumes that all the modes used by any
370 specific bitrate tweaking use the same floor */
372 int submap=info->chmuxlist[i];
374 /* the following makes things clearer to *me* anyway */
375 float *mdct =gmdct[i];
376 float *logfft =vb->pcm[i];
378 float *logmdct =logfft+n/2;
379 float *logmask =logfft;
381 vb->mode=modenumber;
383 floor_posts[i]=_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts));
384 memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS);
386 for(j=0;j<n/2;j++)
387 logmdct[j]=todB(mdct+j) + .345; /* + .345 is a hack; the original
388 todB estimation used on IEEE 754
389 compliant machines had a bug that
390 returned dB values about a third
391 of a decibel too high. The bug
392 was harmless because tunings
393 implicitly took that into
394 account. However, fixing the bug
395 in the estimator requires
396 changing all the tunings as well.
397 For now, it's easier to sync
398 things back up here, and
399 recalibrate the tunings in the
400 next major model upgrade. */
402 #if 0
403 if(vi->channels==2){
404 if(i==0)
405 _analysis_output("mdctL",seq,logmdct,n/2,1,0,0);
406 else
407 _analysis_output("mdctR",seq,logmdct,n/2,1,0,0);
408 }else{
409 _analysis_output("mdct",seq,logmdct,n/2,1,0,0);
411 #endif
413 /* first step; noise masking. Not only does 'noise masking'
414 give us curves from which we can decide how much resolution
415 to give noise parts of the spectrum, it also implicitly hands
416 us a tonality estimate (the larger the value in the
417 'noise_depth' vector, the more tonal that area is) */
419 _vp_noisemask(psy_look,
420 logmdct,
421 noise); /* noise does not have by-frequency offset
422 bias applied yet */
423 #if 0
424 if(vi->channels==2){
425 if(i==0)
426 _analysis_output("noiseL",seq,noise,n/2,1,0,0);
427 else
428 _analysis_output("noiseR",seq,noise,n/2,1,0,0);
429 }else{
430 _analysis_output("noise",seq,noise,n/2,1,0,0);
432 #endif
434 /* second step: 'all the other crap'; all the stuff that isn't
435 computed/fit for bitrate management goes in the second psy
436 vector. This includes tone masking, peak limiting and ATH */
438 _vp_tonemask(psy_look,
439 logfft,
440 tone,
441 global_ampmax,
442 local_ampmax[i]);
444 #if 0
445 if(vi->channels==2){
446 if(i==0)
447 _analysis_output("toneL",seq,tone,n/2,1,0,0);
448 else
449 _analysis_output("toneR",seq,tone,n/2,1,0,0);
450 }else{
451 _analysis_output("tone",seq,tone,n/2,1,0,0);
453 #endif
455 /* third step; we offset the noise vectors, overlay tone
456 masking. We then do a floor1-specific line fit. If we're
457 performing bitrate management, the line fit is performed
458 multiple times for up/down tweakage on demand. */
460 #if 0
462 float aotuv[psy_look->n];
463 #endif
465 _vp_offset_and_mix(psy_look,
466 noise,
467 tone,
469 logmask,
470 mdct,
471 logmdct);
473 #if 0
474 if(vi->channels==2){
475 if(i==0)
476 _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0);
477 else
478 _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0);
479 }else{
480 _analysis_output("aotuvM1",seq,aotuv,psy_look->n,1,1,0);
483 #endif
486 #if 0
487 if(vi->channels==2){
488 if(i==0)
489 _analysis_output("mask1L",seq,logmask,n/2,1,0,0);
490 else
491 _analysis_output("mask1R",seq,logmask,n/2,1,0,0);
492 }else{
493 _analysis_output("mask1",seq,logmask,n/2,1,0,0);
495 #endif
497 /* this algorithm is hardwired to floor 1 for now; abort out if
498 we're *not* floor1. This won't happen unless someone has
499 broken the encode setup lib. Guard it anyway. */
500 if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1);
502 floor_posts[i][PACKETBLOBS/2]=
503 floor1_fit(vb,b->flr[info->floorsubmap[submap]],
504 logmdct,
505 logmask);
507 /* are we managing bitrate? If so, perform two more fits for
508 later rate tweaking (fits represent hi/lo) */
509 if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){
510 /* higher rate by way of lower noise curve */
512 _vp_offset_and_mix(psy_look,
513 noise,
514 tone,
516 logmask,
517 mdct,
518 logmdct);
520 #if 0
521 if(vi->channels==2){
522 if(i==0)
523 _analysis_output("mask2L",seq,logmask,n/2,1,0,0);
524 else
525 _analysis_output("mask2R",seq,logmask,n/2,1,0,0);
526 }else{
527 _analysis_output("mask2",seq,logmask,n/2,1,0,0);
529 #endif
531 floor_posts[i][PACKETBLOBS-1]=
532 floor1_fit(vb,b->flr[info->floorsubmap[submap]],
533 logmdct,
534 logmask);
536 /* lower rate by way of higher noise curve */
537 _vp_offset_and_mix(psy_look,
538 noise,
539 tone,
541 logmask,
542 mdct,
543 logmdct);
545 #if 0
546 if(vi->channels==2){
547 if(i==0)
548 _analysis_output("mask0L",seq,logmask,n/2,1,0,0);
549 else
550 _analysis_output("mask0R",seq,logmask,n/2,1,0,0);
551 }else{
552 _analysis_output("mask0",seq,logmask,n/2,1,0,0);
554 #endif
556 floor_posts[i][0]=
557 floor1_fit(vb,b->flr[info->floorsubmap[submap]],
558 logmdct,
559 logmask);
561 /* we also interpolate a range of intermediate curves for
562 intermediate rates */
563 for(k=1;k<PACKETBLOBS/2;k++)
564 floor_posts[i][k]=
565 floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
566 floor_posts[i][0],
567 floor_posts[i][PACKETBLOBS/2],
568 k*65536/(PACKETBLOBS/2));
569 for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++)
570 floor_posts[i][k]=
571 floor1_interpolate_fit(vb,b->flr[info->floorsubmap[submap]],
572 floor_posts[i][PACKETBLOBS/2],
573 floor_posts[i][PACKETBLOBS-1],
574 (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2));
578 vbi->ampmax=global_ampmax;
581 the next phases are performed once for vbr-only and PACKETBLOB
582 times for bitrate managed modes.
584 1) encode actual mode being used
585 2) encode the floor for each channel, compute coded mask curve/res
586 3) normalize and couple.
587 4) encode residue
588 5) save packet bytes to the packetblob vector
592 /* iterate over the many masking curve fits we've created */
595 int **couple_bundle=alloca(sizeof(*couple_bundle)*vi->channels);
596 int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
598 for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2);
599 k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2);
600 k++){
601 oggpack_buffer *opb=vbi->packetblob[k];
603 /* start out our new packet blob with packet type and mode */
604 /* Encode the packet type */
605 oggpack_write(opb,0,1);
606 /* Encode the modenumber */
607 /* Encode frame mode, pre,post windowsize, then dispatch */
608 oggpack_write(opb,modenumber,b->modebits);
609 if(vb->W){
610 oggpack_write(opb,vb->lW,1);
611 oggpack_write(opb,vb->nW,1);
614 /* encode floor, compute masking curve, sep out residue */
615 for(i=0;i<vi->channels;i++){
616 int submap=info->chmuxlist[i];
617 int *ilogmask=iwork[i];
619 nonzero[i]=floor1_encode(opb,vb,b->flr[info->floorsubmap[submap]],
620 floor_posts[i][k],
621 ilogmask);
622 #if 0
624 char buf[80];
625 sprintf(buf,"maskI%c%d",i?'R':'L',k);
626 float work[n/2];
627 for(j=0;j<n/2;j++)
628 work[j]=FLOOR1_fromdB_LOOKUP[iwork[i][j]];
629 _analysis_output(buf,seq,work,n/2,1,1,0);
631 #endif
634 /* our iteration is now based on masking curve, not prequant and
635 coupling. Only one prequant/coupling step */
637 /* quantize/couple */
638 /* incomplete implementation that assumes the tree is all depth
639 one, or no tree at all */
640 _vp_couple_quantize_normalize(k,
641 &ci->psy_g_param,
642 psy_look,
643 info,
644 gmdct,
645 iwork,
646 nonzero,
647 ci->psy_g_param.sliding_lowpass[vb->W][k],
648 vi->channels);
650 #if 0
651 for(i=0;i<vi->channels;i++){
652 char buf[80];
653 sprintf(buf,"res%c%d",i?'R':'L',k);
654 float work[n/2];
655 for(j=0;j<n/2;j++)
656 work[j]=iwork[i][j];
657 _analysis_output(buf,seq,work,n/2,1,0,0);
659 #endif
661 /* classify and encode by submap */
662 for(i=0;i<info->submaps;i++){
663 int ch_in_bundle=0;
664 long **classifications;
665 int resnum=info->residuesubmap[i];
667 for(j=0;j<vi->channels;j++){
668 if(info->chmuxlist[j]==i){
669 zerobundle[ch_in_bundle]=0;
670 if(nonzero[j])zerobundle[ch_in_bundle]=1;
671 couple_bundle[ch_in_bundle++]=iwork[j];
675 classifications=_residue_P[ci->residue_type[resnum]]->
676 class(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle);
678 ch_in_bundle=0;
679 for(j=0;j<vi->channels;j++)
680 if(info->chmuxlist[j]==i)
681 couple_bundle[ch_in_bundle++]=iwork[j];
683 _residue_P[ci->residue_type[resnum]]->
684 forward(opb,vb,b->residue[resnum],
685 couple_bundle,zerobundle,ch_in_bundle,classifications,i);
688 /* ok, done encoding. Next protopacket. */
693 #if 0
694 seq++;
695 total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4;
696 #endif
697 return(0);
700 static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){
701 vorbis_dsp_state *vd=vb->vd;
702 vorbis_info *vi=vd->vi;
703 codec_setup_info *ci=vi->codec_setup;
704 private_state *b=vd->backend_state;
705 vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l;
707 int i,j;
708 long n=vb->pcmend=ci->blocksizes[vb->W];
710 float **pcmbundle=alloca(sizeof(*pcmbundle)*vi->channels);
711 int *zerobundle=alloca(sizeof(*zerobundle)*vi->channels);
713 int *nonzero =alloca(sizeof(*nonzero)*vi->channels);
714 void **floormemo=alloca(sizeof(*floormemo)*vi->channels);
716 /* recover the spectral envelope; store it in the PCM vector for now */
717 for(i=0;i<vi->channels;i++){
718 int submap=info->chmuxlist[i];
719 floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]->
720 inverse1(vb,b->flr[info->floorsubmap[submap]]);
721 if(floormemo[i])
722 nonzero[i]=1;
723 else
724 nonzero[i]=0;
725 memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2);
728 /* channel coupling can 'dirty' the nonzero listing */
729 for(i=0;i<info->coupling_steps;i++){
730 if(nonzero[info->coupling_mag[i]] ||
731 nonzero[info->coupling_ang[i]]){
732 nonzero[info->coupling_mag[i]]=1;
733 nonzero[info->coupling_ang[i]]=1;
737 /* recover the residue into our working vectors */
738 for(i=0;i<info->submaps;i++){
739 int ch_in_bundle=0;
740 for(j=0;j<vi->channels;j++){
741 if(info->chmuxlist[j]==i){
742 if(nonzero[j])
743 zerobundle[ch_in_bundle]=1;
744 else
745 zerobundle[ch_in_bundle]=0;
746 pcmbundle[ch_in_bundle++]=vb->pcm[j];
750 _residue_P[ci->residue_type[info->residuesubmap[i]]]->
751 inverse(vb,b->residue[info->residuesubmap[i]],
752 pcmbundle,zerobundle,ch_in_bundle);
755 /* channel coupling */
756 for(i=info->coupling_steps-1;i>=0;i--){
757 float *pcmM=vb->pcm[info->coupling_mag[i]];
758 float *pcmA=vb->pcm[info->coupling_ang[i]];
760 for(j=0;j<n/2;j++){
761 float mag=pcmM[j];
762 float ang=pcmA[j];
764 if(mag>0)
765 if(ang>0){
766 pcmM[j]=mag;
767 pcmA[j]=mag-ang;
768 }else{
769 pcmA[j]=mag;
770 pcmM[j]=mag+ang;
772 else
773 if(ang>0){
774 pcmM[j]=mag;
775 pcmA[j]=mag+ang;
776 }else{
777 pcmA[j]=mag;
778 pcmM[j]=mag-ang;
783 /* compute and apply spectral envelope */
784 for(i=0;i<vi->channels;i++){
785 float *pcm=vb->pcm[i];
786 int submap=info->chmuxlist[i];
787 _floor_P[ci->floor_type[info->floorsubmap[submap]]]->
788 inverse2(vb,b->flr[info->floorsubmap[submap]],
789 floormemo[i],pcm);
792 /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */
793 /* only MDCT right now.... */
794 for(i=0;i<vi->channels;i++){
795 float *pcm=vb->pcm[i];
796 mdct_backward(b->transform[vb->W][0],pcm,pcm);
799 /* all done! */
800 return(0);
803 /* export hooks */
804 const vorbis_func_mapping mapping0_exportbundle={
805 &mapping0_pack,
806 &mapping0_unpack,
807 &mapping0_free_info,
808 &mapping0_forward,
809 &mapping0_inverse