vorbis_mapping0.c (28765B)
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 39 static 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 47 static 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 */ 91 static 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 158 static long seq=0; 159 static ogg_int64_t total=0; 160 static 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 230 static 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 698 static 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 */ 802 const vorbis_func_mapping mapping0_exportbundle={ 803 &mapping0_pack, 804 &mapping0_unpack, 805 &mapping0_free_info, 806 &mapping0_forward, 807 &mapping0_inverse 808 };