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