diff options
author | Monty <xiphmont@xiph.org> | 2001-05-23 02:15:24 +0000 |
---|---|---|
committer | Monty <xiphmont@xiph.org> | 2001-05-23 02:15:24 +0000 |
commit | 4d3fa2bbba45ab1ca6bf4074e8bc8e68de6f6236 (patch) | |
tree | 3f1e82724d4a624db35114a56474864a18b46cc4 | |
parent | f87d0cf5d034f283b9c6d3fa516d412562ac6aaa (diff) | |
download | libvorbis-git-4d3fa2bbba45ab1ca6bf4074e8bc8e68de6f6236.tar.gz |
floor 1 fixes, residue 1 implementation (like res 0 just unintereleaved)
Not production ready; there are ATH and masking curve changes to make
to fit floor 1, and no mode is tuned for it.
Monty
svn path=/branches/monty-branch-20010404/vorbis/; revision=1452
-rw-r--r-- | lib/codebook.c | 39 | ||||
-rw-r--r-- | lib/codebook.h | 161 | ||||
-rw-r--r-- | lib/floor1.c | 217 | ||||
-rw-r--r-- | lib/masking.h | 243 | ||||
-rw-r--r-- | lib/modes/mode_A.h | 8 | ||||
-rw-r--r-- | lib/psy.c | 200 | ||||
-rw-r--r-- | lib/psy.h | 7 | ||||
-rw-r--r-- | lib/res0.c | 151 | ||||
-rw-r--r-- | lib/scales.h | 4 |
9 files changed, 764 insertions, 266 deletions
diff --git a/lib/codebook.c b/lib/codebook.c index 7487448f..070e8b4e 100644 --- a/lib/codebook.c +++ b/lib/codebook.c @@ -11,7 +11,7 @@ ******************************************************************** function: basic codebook pack/unpack/code/decode operations - last mod: $Id: codebook.c,v 1.23.4.1 2001/05/11 22:07:49 xiphmont Exp $ + last mod: $Id: codebook.c,v 1.23.4.2 2001/05/23 02:15:21 xiphmont Exp $ ********************************************************************/ @@ -416,6 +416,43 @@ long s_vorbis_book_decodevs(codebook *book,float *a,oggpack_buffer *b, return(0); } +long s_vorbis_book_decodev(codebook *book,float *a,oggpack_buffer *b, + int partsize,int addmul){ + int i,j,entry; + float *t; + + switch(addmul){ + case -1: + for(i=0;i<partsize;){ + entry = vorbis_book_decode(book,b); + if(entry==-1)return(-1); + t = book->valuelist+entry*book->dim; + for (j=0;j<book->dim;) + a[i++]=t[j++]; + } + break; + case 0: + for(i=0;i<partsize;){ + entry = vorbis_book_decode(book,b); + if(entry==-1)return(-1); + t = book->valuelist+entry*book->dim; + for (j=0;j<book->dim;) + a[i++]+=t[j++]; + } + break; + case 1: + for(i=0;i<partsize;){ + entry = vorbis_book_decode(book,b); + if(entry==-1)return(-1); + t = book->valuelist+entry*book->dim; + for (j=0;j<book->dim;) + a[i++]*=t[j++]; + } + break; + } + return(0); +} + #ifdef _V_SELFTEST /* Simple enough; pack a few candidate codebooks, unpack them. Code a diff --git a/lib/codebook.h b/lib/codebook.h new file mode 100644 index 00000000..b6ce81b8 --- /dev/null +++ b/lib/codebook.h @@ -0,0 +1,161 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + + ******************************************************************** + + function: basic shared codebook operations + last mod: $Id: codebook.h,v 1.5.4.1 2001/05/23 02:15:21 xiphmont Exp $ + + ********************************************************************/ + +#ifndef _V_CODEBOOK_H_ +#define _V_CODEBOOK_H_ + +#include "ogg/ogg.h" + +/* This structure encapsulates huffman and VQ style encoding books; it + doesn't do anything specific to either. + + valuelist/quantlist are nonNULL (and q_* significant) only if + there's entry->value mapping to be done. + + If encode-side mapping must be done (and thus the entry needs to be + hunted), the auxiliary encode pointer will point to a decision + tree. This is true of both VQ and huffman, but is mostly useful + with VQ. + +*/ + +typedef struct static_codebook{ + long dim; /* codebook dimensions (elements per vector) */ + long entries; /* codebook entries */ + long *lengthlist; /* codeword lengths in bits */ + + /* mapping ***************************************************************/ + int maptype; /* 0=none + 1=implicitly populated values from map column + 2=listed arbitrary values */ + + /* The below does a linear, single monotonic sequence mapping. */ + long q_min; /* packed 32 bit float; quant value 0 maps to minval */ + long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */ + int q_quant; /* bits: 0 < quant <= 16 */ + int q_sequencep; /* bitflag */ + + long *quantlist; /* map == 1: (int)(entries^(1/dim)) element column map + map == 2: list of dim*entries quantized entry vals + */ + + /* encode helpers ********************************************************/ + struct encode_aux_nearestmatch *nearest_tree; + struct encode_aux_threshmatch *thresh_tree; + struct encode_aux_pigeonhole *pigeon_tree; + + int allocedp; +} static_codebook; + +/* this structures an arbitrary trained book to quickly find the + nearest cell match */ +typedef struct encode_aux_nearestmatch{ + /* pre-calculated partitioning tree */ + long *ptr0; + long *ptr1; + + long *p; /* decision points (each is an entry) */ + long *q; /* decision points (each is an entry) */ + long aux; /* number of tree entries */ + long alloc; +} encode_aux_nearestmatch; + +/* assumes a maptype of 1; encode side only, so that's OK */ +typedef struct encode_aux_threshmatch{ + float *quantthresh; + long *quantmap; + int quantvals; + int threshvals; +} encode_aux_threshmatch; + +typedef struct encode_aux_pigeonhole{ + float min; + float del; + + int mapentries; + int quantvals; + long *pigeonmap; + + long fittotal; + long *fitlist; + long *fitmap; + long *fitlength; +} encode_aux_pigeonhole; + +typedef struct decode_aux{ + long *tab; + int *tabl; + int tabn; + + long *ptr0; + long *ptr1; + long aux; /* number of tree entries */ +} decode_aux; + +typedef struct codebook{ + long dim; /* codebook dimensions (elements per vector) */ + long entries; /* codebook entries */ + const static_codebook *c; + + float *valuelist; /* list of dim*entries actual entry values */ + long *codelist; /* list of bitstream codewords for each entry */ + struct decode_aux *decode_tree; + + long zeroentry; +} codebook; + +extern void vorbis_staticbook_clear(static_codebook *b); +extern void vorbis_staticbook_destroy(static_codebook *b); +extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source); +extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source); +extern void vorbis_book_clear(codebook *b); + +extern float *_book_unquantize(const static_codebook *b); +extern float *_book_logdist(const static_codebook *b,float *vals); +extern float _float32_unpack(long val); +extern long _float32_pack(float val); +extern int _best(codebook *book, float *a, int step); +extern int _ilog(unsigned int v); +extern long _book_maptype1_quantvals(const static_codebook *b); + +extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul); +extern long vorbis_book_codeword(codebook *book,int entry); +extern long vorbis_book_codelen(codebook *book,int entry); + + + +extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b); +extern int vorbis_staticbook_unpack(oggpack_buffer *b,static_codebook *c); + +extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b); +extern int vorbis_book_errorv(codebook *book, float *a); +extern int vorbis_book_encodev(codebook *book, int best,float *a, + oggpack_buffer *b); +extern int vorbis_book_encodevs(codebook *book, float *a, oggpack_buffer *b, + int step,int stagetype); + +extern long vorbis_book_decode(codebook *book, oggpack_buffer *b); +extern long vorbis_book_decodevs(codebook *book, float *a, oggpack_buffer *b, + int step,int stagetype); +extern long s_vorbis_book_decodevs(codebook *book, float *a, oggpack_buffer *b, + int step,int stagetype); +extern long s_vorbis_book_decodev(codebook *book, float *a, oggpack_buffer *b, + int partsize,int stagetype); + + + +#endif diff --git a/lib/floor1.c b/lib/floor1.c index 27a7e90e..291ddf55 100644 --- a/lib/floor1.c +++ b/lib/floor1.c @@ -11,7 +11,7 @@ ******************************************************************** function: floor backend 1 implementation - last mod: $Id: floor1.c,v 1.1.2.6 2001/05/13 22:40:24 xiphmont Exp $ + last mod: $Id: floor1.c,v 1.1.2.7 2001/05/23 02:15:21 xiphmont Exp $ ********************************************************************/ @@ -28,11 +28,8 @@ #include <stdio.h> -#define VORBIS_IEEE_FLOAT32 - #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */ - typedef struct { int sorted_index[VIF_POSIT+2]; int forward_index[VIF_POSIT+2]; @@ -70,29 +67,6 @@ typedef struct lsfit_acc{ long edgey1; } lsfit_acc; -static void vorbis_msecheck(vorbis_look_floor1 *look, - const float *flr,const float *mdct, - const float *out,int n){ - float fn=22050./n; - float lastbark=toBARK(0); - float att=look->vi->twofitatten; - int i; - float count=0; - float mse=0; - for(i=0;i<n;i++){ - float bark=toBARK((i+1)*fn); - if(mdct[i]+att>=flr[i]){ - float imse=(todB(out+i)-flr[i]); - imse*=imse; - mse+=imse*(bark-lastbark); - count+=(bark-lastbark); - } - lastbark=bark; - } - - if(count)look->mse+=mse/count; -} - /***********************************************/ static vorbis_info_floor *floor1_copy_info (vorbis_info_floor *i){ @@ -307,88 +281,27 @@ static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,vorbis_info_mode *mi, } static int render_point(int x0,int x1,int y0,int y1,int x){ - int dy=y1-y0; - int adx=x1-x0; - int ady=abs(dy); - int err=ady*(x-x0); - - int off=err/adx; - if(dy<0)return(y0-off); - return(y0+off); + y0&=0x7fff; /* mask off flag */ + y1&=0x7fff; + + { + int dy=y1-y0; + int adx=x1-x0; + int ady=abs(dy); + int err=ady*(x-x0); + + int off=err/adx; + if(dy<0)return(y0-off); + return(y0+off); + } } -static int FLOOR_quantdB_LOOKUP[560]={ - 1023, 1021, 1019, 1018, 1016, 1014, 1012, 1010, - 1008, 1007, 1005, 1003, 1001, 999, 997, 996, - 994, 992, 990, 988, 986, 985, 983, 981, - 979, 977, 975, 974, 972, 970, 968, 966, - 964, 963, 961, 959, 957, 955, 954, 952, - 950, 948, 946, 944, 943, 941, 939, 937, - 935, 933, 932, 930, 928, 926, 924, 922, - 921, 919, 917, 915, 913, 911, 910, 908, - 906, 904, 902, 900, 899, 897, 895, 893, - 891, 890, 888, 886, 884, 882, 880, 879, - 877, 875, 873, 871, 869, 868, 866, 864, - 862, 860, 858, 857, 855, 853, 851, 849, - 847, 846, 844, 842, 840, 838, 836, 835, - 833, 831, 829, 827, 826, 824, 822, 820, - 818, 816, 815, 813, 811, 809, 807, 805, - 804, 802, 800, 798, 796, 794, 793, 791, - 789, 787, 785, 783, 782, 780, 778, 776, - 774, 772, 771, 769, 767, 765, 763, 762, - 760, 758, 756, 754, 752, 751, 749, 747, - 745, 743, 741, 740, 738, 736, 734, 732, - 730, 729, 727, 725, 723, 721, 719, 718, - 716, 714, 712, 710, 708, 707, 705, 703, - 701, 699, 698, 696, 694, 692, 690, 688, - 687, 685, 683, 681, 679, 677, 676, 674, - 672, 670, 668, 666, 665, 663, 661, 659, - 657, 655, 654, 652, 650, 648, 646, 644, - 643, 641, 639, 637, 635, 634, 632, 630, - 628, 626, 624, 623, 621, 619, 617, 615, - 613, 612, 610, 608, 606, 604, 602, 601, - 599, 597, 595, 593, 591, 590, 588, 586, - 584, 582, 580, 579, 577, 575, 573, 571, - 570, 568, 566, 564, 562, 560, 559, 557, - 555, 553, 551, 549, 548, 546, 544, 542, - 540, 538, 537, 535, 533, 531, 529, 527, - 526, 524, 522, 520, 518, 516, 515, 513, - 511, 509, 507, 506, 504, 502, 500, 498, - 496, 495, 493, 491, 489, 487, 485, 484, - 482, 480, 478, 476, 474, 473, 471, 469, - 467, 465, 463, 462, 460, 458, 456, 454, - 452, 451, 449, 447, 445, 443, 442, 440, - 438, 436, 434, 432, 431, 429, 427, 425, - 423, 421, 420, 418, 416, 414, 412, 410, - 409, 407, 405, 403, 401, 399, 398, 396, - 394, 392, 390, 388, 387, 385, 383, 381, - 379, 378, 376, 374, 372, 370, 368, 367, - 365, 363, 361, 359, 357, 356, 354, 352, - 350, 348, 346, 345, 343, 341, 339, 337, - 335, 334, 332, 330, 328, 326, 324, 323, - 321, 319, 317, 315, 314, 312, 310, 308, - 306, 304, 303, 301, 299, 297, 295, 293, - 292, 290, 288, 286, 284, 282, 281, 279, - 277, 275, 273, 271, 270, 268, 266, 264, - 262, 260, 259, 257, 255, 253, 251, 250, - 248, 246, 244, 242, 240, 239, 237, 235, - 233, 231, 229, 228, 226, 224, 222, 220, - 218, 217, 215, 213, 211, 209, 207, 206, - 204, 202, 200, 198, 196, 195, 193, 191, - 189, 187, 186, 184, 182, 180, 178, 176, - 175, 173, 171, 169, 167, 165, 164, 162, - 160, 158, 156, 154, 153, 151, 149, 147, - 145, 143, 142, 140, 138, 136, 134, 132, - 131, 129, 127, 125, 123, 122, 120, 118, - 116, 114, 112, 111, 109, 107, 105, 103, - 101, 100, 98, 96, 94, 92, 90, 89, - 87, 85, 83, 81, 79, 78, 76, 74, - 72, 70, 68, 67, 65, 63, 61, 59, - 58, 56, 54, 52, 50, 48, 47, 45, - 43, 41, 39, 37, 36, 34, 32, 30, - 28, 26, 25, 23, 21, 19, 17, 15, - 14, 12, 10, 8, 6, 4, 3, 1, -}; +static int vorbis_dBquant(const float *x){ + int i= *x*7.3142857f+1023.5f; + if(i>1023)return(1023); + if(i<0)return(0); + return i; +} static float FLOOR_fromdB_LOOKUP[256]={ 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, @@ -457,23 +370,6 @@ static float FLOOR_fromdB_LOOKUP[256]={ 0.82788260F, 0.88168307F, 0.9389798F, 1.F, }; -#ifdef VORBIS_IEEE_FLOAT32 -static int vorbis_floor1_dBquant(const float *x){ - float temp=*x-256.f; - ogg_uint32_t *i=(ogg_uint32_t *)(&temp); - if(*i<(ogg_uint32_t)0xc3800000)return(1023); - if(*i>(ogg_uint32_t)0xc3c5e000)return(0); - return FLOOR_quantdB_LOOKUP[(*i-0xc3800000)>>13]; -} -#else -static int vorbis_floor1_dBquant(const float *x){ - int i= ((*x)+140.)/140.*1024.+.5; - if(i>1023)return(1023); - if(i<0)return(0); - return i; -} -#endif - static void render_line(int x0,int x1,int y0,int y1,float *d){ int dy=y1-y0; int adx=x1-x0; @@ -504,7 +400,7 @@ static int accumulate_fit(const float *flr,const float *mdct, int x0, int x1,lsfit_acc *a, int n,vorbis_info_floor1 *info){ long i; - int quantized=vorbis_floor1_dBquant(flr); + int quantized=vorbis_dBquant(flr); long xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0; @@ -515,7 +411,7 @@ static int accumulate_fit(const float *flr,const float *mdct, if(x1>n)x1=n; for(i=x0;i<x1;i++){ - int quantized=vorbis_floor1_dBquant(flr+i); + int quantized=vorbis_dBquant(flr+i); if(quantized){ if(mdct[i]+info->twofitatten>=flr[i]){ xa += i; @@ -563,7 +459,7 @@ static int accumulate_fit(const float *flr,const float *mdct, a->edgey1=-200; if(x1<n){ - int quantized=vorbis_floor1_dBquant(flr+i); + int quantized=vorbis_dBquant(flr+i); a->edgey1=quantized; } return(a->n); @@ -653,7 +549,7 @@ static int inspect_error(int x0,int x1,int y0,int y1,const float *mask, int x=x0; int y=y0; int err=0; - int val=vorbis_floor1_dBquant(mask+x); + int val=vorbis_dBquant(mask+x); int mse=0; int n=0; @@ -677,7 +573,7 @@ static int inspect_error(int x0,int x1,int y0,int y1,const float *mask, } if(mdct[x]+info->twofitatten>=mask[x]){ - val=vorbis_floor1_dBquant(mask+x); + val=vorbis_dBquant(mask+x); if(val){ if(y+info->maxover<val)return(1); if(y-info->maxunder>val)return(1); @@ -1058,13 +954,15 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in, int ly=fit_valueA[0]*info->mult; for(j=1;j<posts;j++){ int current=look->forward_index[j]; - int hy=fit_valueA[current]*info->mult; - hx=info->postlist[current]; - - render_line(lx,hx,ly,hy,codedflr); - - lx=hx; - ly=hy; + if(fit_valueB[current]>0){ + int hy=fit_valueA[current]*info->mult; + hx=info->postlist[current]; + + render_line(lx,hx,ly,hy,codedflr); + + lx=hx; + ly=hy; + } } for(j=hx;j<look->n;j++)codedflr[j]=codedflr[j-1]; /* be certain */ @@ -1083,8 +981,6 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in, } - vorbis_msecheck(look,logmask,logmdct,codedflr,n); - }else{ oggpack_write(&vb->opb,0,1); memset(codedflr,0,n*sizeof(float)); @@ -1151,21 +1047,26 @@ static int floor1_inverse(vorbis_block *vb,vorbis_look_floor *in,float *out){ int room=(hiroom<loroom?hiroom:loroom)<<1; int val=fit_value[i]; - if(val>=room){ - if(hiroom>loroom){ - val = val-loroom; - }else{ + if(val){ + if(val>=room){ + if(hiroom>loroom){ + val = val-loroom; + }else{ val = -1-(val-hiroom); - } - }else{ - if(val&1){ - val= -((val+1)>>1); + } }else{ - val>>=1; + if(val&1){ + val= -((val+1)>>1); + }else{ + val>>=1; + } } - } - fit_value[i]=val+predicted; + fit_value[i]=val+predicted; + }else{ + fit_value[i]=predicted|0x8000; + } + } /* render the lines */ @@ -1175,13 +1076,17 @@ static int floor1_inverse(vorbis_block *vb,vorbis_look_floor *in,float *out){ int ly=fit_value[0]*info->mult; for(j=1;j<look->posts;j++){ int current=look->forward_index[j]; - int hy=fit_value[current]*info->mult; - hx=info->postlist[current]; - - render_line(lx,hx,ly,hy,out); - - lx=hx; - ly=hy; + int hy=fit_value[current]&0x7fff; + if(hy==fit_value[current]){ + + hy*=info->mult; + hx=info->postlist[current]; + + render_line(lx,hx,ly,hy,out); + + lx=hx; + ly=hy; + } } for(j=hx;j<n;j++)out[j]=out[j-1]; /* be certain */ } diff --git a/lib/masking.h b/lib/masking.h new file mode 100644 index 00000000..b9c7bc94 --- /dev/null +++ b/lib/masking.h @@ -0,0 +1,243 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the XIPHOPHORUS Company http://www.xiph.org/ * + + ******************************************************************** + + function: masking curve data for psychoacoustics + last mod: $Id: masking.h,v 1.13.4.1 2001/05/23 02:15:21 xiphmont Exp $ + + ********************************************************************/ + +#ifndef _V_MASKING_H_ +#define _V_MASKING_H_ + +/* Not really an ATH, more a bottom curve to limit LSP dynamic range */ +float ATH_Bark_dB[]={ + 15, 15, 15, 15, 11, 10, 8, 7, 7, 7, + 6, 2, 0, 0, -3, -5, -6, -6, -4.5f, 2.5f, + 10, 15, 20, 30, 40, 50, 60}; + +/* The below masking curves are straight from the R. Ehmer + (J. Acoustical Society of America) papers ca 1958-59. I modified + them slightly as Ehmer does not correct for the Absolute Threshold + of Hearing, and the low dB portions of the curves are thus highly + suspect. */ + +/* Let's all do the Trek thing and just call them 'Ehmer curves' ;-) + Note these are octaves, not Bark scale. */ + +#define EHMER_OFFSET 16 +#define EHMER_MAX 56 + +float tone_125_40dB_SL[EHMER_MAX]={ + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 18, 16, 14, 12, 11, 9, 7, 5, 3, 2, 0, -2, -4, -6, -8, + -10, -12, -14, -16, -18, -20, -23, -25, -28,-30,-34,-37,-40,-44,-48,-52, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_125_60dB_SL[EHMER_MAX]={ + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 38, 36, 34, 32, 31, 29, 27, 25, 23, 22, 20, 18, 16, 14, 12, + 10, 8, 6, 4, 2, 0, -3, -5, -8,-10,-14,-17,-20,-24,-28,-32, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_125_80dB_SL[EHMER_MAX]={ + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 58, 56, 54, 52, 51, 49, 47, 45, 43, 42, 40, 38, 36, 34, 32, + 30, 28, 26, 24, 22, 20, 17, 15, 12, 10, 6, 3, 0, -4, -8,-12, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_125_100dB_SL[EHMER_MAX]={ + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 77, 75, 74, 73, 72, 71, 70, 69, 68, 67, 65, 64, 63, 62, 60, + 58, 57, 55, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 31, 29, + 27, 24, 22, 20, 18, 15, 13, 11}; + +float tone_250_40dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -19, -13, -7, -1, 4, 9, 15, 20, + 22, 23, 22, 19, 18, 18, 16, 13, 9, 7, 3, 1, -1, -3, -6, -8, + -10, -13, -16, -19, -21, -24, -28, -32, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_250_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900, -10, -5, 1, 7, 13, 19, 25, 30, 33, + 36, 39, 38, 37, 38, 39, 39, 40, 38, 36, 35, 34, 33, 31, 29, 28, + 28, 28, 25, 20, 14, 10, 5, 0, -5,-10,-15,-20,-25,-30,-35,-40, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_250_80dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900, -10, 10, 17, 24, 30, 37, 41, 48, 49, + 50, 53, 54, 53, 53, 54, 55, 57, 57, 57, 58, 59, 60, 58, 57, 58, + 59, 58, 57, 54, 52, 50, 49, 47, 46, 47, 46, 44, 43, 42, 41, 40, + 38, 32, 27, 22, 17, 11, 6, 0}; +/* no data, just interpolated from 80 */ +float tone_250_100dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900, -10, 15, 25, 34, 40, 50, 56, 60, 70, + 70, 73, 74, 73, 73, 74, 75, 77, 77, 77, 78, 79, 80, 78, 77, 78, + 79, 78, 77, 74, 72, 70, 69, 67, 66, 67, 66, 64, 63, 62, 61, 60, + 58, 52, 47, 42, 37, 31, 26, 20}; + +float tone_500_40dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900, -40, -26, -20, -14, -8, -2, 4, 10, 17, + 23, 16, 12, 9, 6, 3, 0, -3, -7, -10, -13, -16, -20, -23, -26, -30, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_500_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -18, -12, -6, 0, 6, 13, 20, 30, + 39, 34, 31, 29, 29, 27, 24, 21, 18, 16, 13, 8, 6, 3, 1, -1, + -5, -2, -5, -8, -12, -15, -18, -22, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_500_80dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -22,-16,-10, 0, 10, 20, 32, 43, + 53, 52, 52, 50, 49, 50, 52, 55, 55, 54, 51, 49, 46, 44, 44, 42, + 38, 34, 32, 29, 29, 28, 25, 23, 20, 16, 10, 7, 4, 2, -1, -4, + -7, -10, -15, -20, -25, -30, -35, -40}; +float tone_500_100dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900, -10, -7, 2, 10, 19, 27, 35, 55, 56, + 62, 61, 60, 58, 57, 57, 59, 63, 65, 66, 62, 60, 57, 57, 58, 58, + 57, 56, 56, 56, 57, 57, 56, 57, 57, 54, 47, 41, 37, 28, 21, 16, + 10, 3, -3, -8, -13, -18, -23, -28}; + +float tone_1000_40dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -55, -40, -30, -20, -10, 0, 9, 20, + 27, 20, 13, 14, 13, 5, -1, -6, -11, -20, -30,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_1000_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900, -43, -33,-23,-13, -3, 7, 17, 25, 37, + 42, 33, 25, 25, 23, 18, 13, 9, 4, -1, -7,-13,-18, -23, -28, -33, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_1000_80dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900, -35, -25,-14, -4, 6, 16, 27, 33, 50, + 59, 57, 47, 41, 40, 43, 47, 48, 47, 42, 39, 37, 37, 36, 35, 32, + 30, 27, 21, 15, 5, -2, -10, -18, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_1000_100dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900, -40, -30, -20,-10, 0, 10, 23, 33, 45, 60, + 70, 72, 55, 49, 43, 40, 44, 54, 59, 58, 49, 43, 52, 57, 57, 58, + 58, 54, 49, 47, 42, 39, 33, 28, 20, 15, 5, 0, -5,-15,-20,-25, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float tone_2000_40dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, -3, 5, 12, 20, + 24, 21, 14, 5, -5, -15, -25, -35, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_2000_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, -2, 8, 19, 31, + 38, 34, 24, 17, 14, 13, 11, 7, 3, -2, -6, -10, -14, -20, -26, -32, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_2000_80dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, -2, 13, 28, 40, + 51, 51, 43, 35, 28, 29, 35, 37, 37, 35, 31, 28, 25, 22, 19, 15, + 11, 8, 6, 2, -6, -14, -22, -30, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_2000_100dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -10, 6, 25, 42, 60, + 66, 60, 53, 43, 35, 31, 34, 47, 58, 51, 43, 45, 54, 59, 59, 56, + 54, 51, 40, 29, 20, 11, 2, -8, -17, -26, -35,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float tone_4000_40dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, 0, 3, 10, 18, + 24, 21, 14, 5, -5, -15, -25, -35, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float tone_4000_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, -2, 8, 19, 31, + 38, 33, 28, 23, 19, 14, 11, 8, 3, -2, -7, -12, -17, -22, -27, -37, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float tone_4000_80dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -60, -50, -40, -29, -12, 5, 19, 37, + 51, 49, 40, 35, 36, 36, 36, 33, 32, 24, 18, 8, -3, -12, -20, -29, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float tone_4000_100dB_SL[EHMER_MAX]={ + -20, -12, -8, -4, 0, 4, 8, 11, 15, 22, 26, 28, 32, 36, 43, 52, + 62, 59, 50, 48, 50, 50, 45, 36, 45, 30, 20, 10, 0, -10, -19, -28, + -37,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + + +float tone_8000_40dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, 0, 3, 10, 18, + 24, 21, 14, 5, 0, 0, 5, 10, 15, 25, 30, 45, 50, 55, 60, 65, + 70, 75, 80, 85, 90, 95, 100, 100, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; +float tone_8000_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900, -10, -21, -18, -14, -10, 0, 3, 15, 30, + 43, 40, 36, 35, 36, 38, 41, 43, 45, 47, 50, 55, 60, 65, 70, 75, + 80, 85, 90, 95, 100, 100, 100, 100, -900,-900,-900,-900,-900,-900,-900,-900, + -900,-900,-900,-900,-900,-900,-900,-900}; +float tone_8000_80dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900,-900,-900, -10, -1, 2, 6, 10, 13, 19, 25, 35, + 63, 55, 50, 48, 46, 45, 45, 50, 55, 65, 75, 80, 85, 90, 95, 100, + 100, 100, 100, 100,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, + -900,-900,-900,-900,-900,-900,-900,-900}; +float tone_8000_100dB_SL[EHMER_MAX]={ + -18, -12, -7, -3, 0, 2, 6, 9, 12, 19, 22, 21, 19, 21, 40, 40, + 80, 60, 35, 25, 15, 5, 5, 5, 25, 30, 35, 43, 50, 55, 60, 65, + 70, 75, 80, 85, 90, 95, 100, 100, -900,-900,-900,-900,-900,-900,-900,-900, + -900,-900,-900,-900,-900,-900,-900,-900}; + +#if 0 /* not used for the time being */ +float noise_500_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900,-900, -20, -11, -2, 7, 16, 25, 34, 43, 52, 61, 66, + 69, 68, 58, 50, 44, 38, 32, 28, 25, 24, 20, 18, 17, 12, 10, 8, + 5, 0, -5, -8, -12, -15, -18, -22, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float noise_500_80dB_SL[EHMER_MAX]={ +-900,-900,-900, -20, -10, -1, 8, 17, 26, 35, 44, 53, 62, 70, 79, 83, + 85, 85, 81, 77, 74, 71, 68, 63, 61, 59, 56, 55, 54, 52, 48, 47, + 45, 46, 45, 43, 40, 37, 33, 32, 35, 32, 30, 29, 20, 10, 0, -10, + -20, -30,-900,-900,-900,-900,-900,-900}; + +float noise_1000_60dB_SL[EHMER_MAX]={ +-900,-900,-900,-900, -24, -15, -6, 3, 12, 21, 28, 34, 40, 48, 57, 60, + 61, 56, 54, 45, 36, 27, 21, 19, 17, 13, 10, 0, -10, -20, -20,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float noise_1000_80dB_SL[EHMER_MAX]={ +-900, -26, -17, -8, 1, 10, 19, 28, 37, 41, 46, 51, 58, 68, 74, 81, + 80, 81, 70, 66, 58, 61, 59, 55, 54, 53, 52, 49, 48, 42, 38, 38, + 39, 34, 30, 27, 20, 10, 0, -10, -20, -30,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float noise_2000_60dB_SL[EHMER_MAX]={ +-900,-900,-900, -34, -25, -16, -7, 2, 11, 18, 23, 30, 35, 42, 51, 58, + 58, 57, 50, 40,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float noise_2000_80dB_SL[EHMER_MAX]={ +-900, -26, -17, -8, 1, 10, 19, 28, 33, 38, 43, 48, 53, 62, 70, 77, + 77, 75, 70, 67, 68, 66, 62, 61, 60, 59, 52, 47, 39, 35, 34, 35, + 35, 33, 30, 27, 20, 10, 0, -10, -20, -30,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float noise_4000_60dB_SL[EHMER_MAX]={ +-900,-900,-900, -34, -25, -16, -7, 2, 11, 20, 25, 31, 37, 45, 56, 62, + 64, 61,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +float noise_4000_80dB_SL[EHMER_MAX]={ +-900, -26, -17, -8, 1, 10, 19, 26, 33, 39, 45, 50, 55, 65, 75, 82, + 84, 81, 78, 72, 70, 69, 66, 61, 50, 48, 46, 40, 35, 30, 25, 20, + 15, 10, 5, 0, -10, -20, -30,-900, -900,-900,-900,-900,-900,-900,-900,-900, +-900,-900,-900,-900,-900,-900,-900,-900}; + +#endif +#endif + + diff --git a/lib/modes/mode_A.h b/lib/modes/mode_A.h index d69ba681..da4ff583 100644 --- a/lib/modes/mode_A.h +++ b/lib/modes/mode_A.h @@ -11,7 +11,7 @@ ******************************************************************** function: predefined encoding modes - last mod: $Id: mode_A.h,v 1.14.4.4 2001/05/13 22:40:25 xiphmont Exp $ + last mod: $Id: mode_A.h,v 1.14.4.5 2001/05/23 02:15:24 xiphmont Exp $ ********************************************************************/ @@ -132,6 +132,7 @@ static vorbis_info_psy _psy_set_A0={ .5f, /* high window */ 5, 5, + 10, {.000f, 0.f,/*63*/ .000f, 0.f,/*88*/ .000f, 0.f,/*125*/ @@ -221,6 +222,7 @@ static vorbis_info_psy _psy_set_A={ .5f, /* high window */ 25, 25, + 40, {.000f, 0.f, /*63*/ .000f, 0.f, /*88*/ .000f, 0.f, /*125*/ @@ -299,7 +301,7 @@ static vorbis_info_floor1 _floor_set1A={10, 60,30,600, 20,8,1,18., - 20,768}; + 20,600}; static vorbis_info_residue0 _residue_set0A={0,96,16,6,25, {0,1,1,1,1,1}, @@ -342,7 +344,7 @@ codec_setup_info info_A={ /* floors */ {1,1},{&_floor_set0A,&_floor_set1A}, /* residue */ - {0,0},{&_residue_set0A,&_residue_set1A}, + {1,1},{&_residue_set0A,&_residue_set1A}, /* books */ {&_huff_book_line0_class0, /* 0 */ &_huff_book_line0_class1, @@ -11,7 +11,7 @@ ******************************************************************** function: psychoacoustics not including preecho - last mod: $Id: psy.c,v 1.44.4.3 2001/05/11 22:07:50 xiphmont Exp $ + last mod: $Id: psy.c,v 1.44.4.4 2001/05/23 02:15:21 xiphmont Exp $ ********************************************************************/ @@ -178,7 +178,7 @@ static void setup_curve(float **c, } void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){ - long i,j; + long i,j,lo=0,hi=0; long maxoc; memset(p,0,sizeof(vorbis_look_psy)); @@ -192,21 +192,31 @@ void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){ p->ath=_ogg_malloc(n*sizeof(float)); p->octave=_ogg_malloc(n*sizeof(long)); - p->bark=_ogg_malloc(n*sizeof(float)); + p->bark=_ogg_malloc(n*sizeof(unsigned long)); p->vi=vi; p->n=n; /* set up the lookups for a given blocksize and sample rate */ /* Vorbis max sample rate is currently limited by 26 Bark (54kHz) */ set_curve(ATH_Bark_dB, p->ath,n,rate); - for(i=0;i<n;i++) - p->bark[i]=toBARK(rate/(2*n)*i); + for(i=0;i<n;i++){ + float bark=toBARK(rate/(2*n)*i); + + for(;lo+vi->noisewindowlomin<i && + toBARK(rate/(2*n)*lo)<=(bark-vi->noisewindowlo);lo++); + + for(;hi<n && (hi<i+vi->noisewindowhimin || + toBARK(rate/(2*n)*hi)<=(bark+vi->noisewindowhi));hi++); + + p->bark[i]=((hi+1)<<16)+(lo+1); + + } for(i=0;i<n;i++) p->octave[i]=toOC((i*.5f+.25f)*rate/n)*(1<<(p->shiftoc+1))+.5f; p->tonecurves=_ogg_malloc(P_BANDS*sizeof(float **)); - p->noisemedian=_ogg_malloc(n*sizeof(float)); + p->noisemedian=_ogg_malloc(n*sizeof(int)); p->noiseoffset=_ogg_malloc(n*sizeof(float)); p->peakatt=_ogg_malloc(P_BANDS*sizeof(float *)); for(i=0;i<P_BANDS;i++){ @@ -296,12 +306,13 @@ void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){ inthalfoc=(int)halfoc; del=halfoc-inthalfoc; - p->noisemedian[i]= - p->vi->noisemedian[inthalfoc*2]*(1.-del) + - p->vi->noisemedian[inthalfoc*2+2]*del; + p->noisemedian[i]=rint( + (p->vi->noisemedian[inthalfoc*2]*(1.-del) + + p->vi->noisemedian[inthalfoc*2+2]*del)*1024.f); p->noiseoffset[i]= p->vi->noisemedian[inthalfoc*2+1]*(1.-del) + - p->vi->noisemedian[inthalfoc*2+3]*del; + p->vi->noisemedian[inthalfoc*2+3]*del - + 140.f; } /*_analysis_output("mediancurve",0,p->noisemedian,n,0,0);*/ } @@ -331,21 +342,23 @@ void _vp_psy_clear(vorbis_look_psy *p){ /* octave/(8*eighth_octave_lines) x scale and dB y scale */ static void seed_curve(float *seed, - float **curves, - float amp, - int oc,int n,int linesper,float dBoffset){ - int i; - long seedptr; - float *posts,*curve; + const float **curves, + float amp, + int oc, int n, + int linesper,float dBoffset){ + int i,post1; + int seedptr; + const float *posts,*curve; int choice=(int)((amp+dBoffset)*.1f); choice=max(choice,0); choice=min(choice,P_LEVELS-1); posts=curves[choice]; curve=posts+2; + post1=(int)posts[1]; seedptr=oc+(posts[0]-16)*linesper-(linesper>>1); - for(i=posts[0];i<posts[1];i++){ + for(i=posts[0];i<post1;i++){ if(seedptr>0){ float lin=amp+curve[i]; if(seed[seedptr]<lin)seed[seedptr]=lin; @@ -356,7 +369,7 @@ static void seed_curve(float *seed, } static void seed_peak(float *seed, - float *att, + const float *att, float amp, int oc, int linesper, @@ -374,10 +387,10 @@ static void seed_peak(float *seed, } static void seed_loop(vorbis_look_psy *p, - float ***curves, - float **att, - float *f, - float *flr, + const float ***curves, + const float **att, + const float *f, + const float *flr, float *minseed, float *maxseed, float specmax){ @@ -531,75 +544,103 @@ static void max_seeds(vorbis_look_psy *p,float *minseed,float *maxseed, } -/* quarter-dB bins */ -#define BIN(x) ((int)((x)*negFour)) -#define BINdB(x) ((x)*negQuarter) -#define BINCOUNT (200*4) +/* set to match vorbis_quantdblook.h */ +#define BINCOUNT 280 #define LASTBIN (BINCOUNT-1) -static void bark_noise_median(long n,float *b,float *f,float *noise, - float lowidth,float hiwidth, - int lomin,int himin, - float *thresh,float *off){ - long i=0,lo=0,hi=0; - float bi,threshi; - long median=LASTBIN; - float negFour = -4.0f; - float negQuarter = -0.25f; - - /* these are really integral values, but we store them in floats to - avoid excessive float/int conversions, which GCC and MSVC are - farily poor at optimizing. */ +static int psy_dBquant(const float *x){ + int i= *x*2.f+279.5f; + if(i>279)return(279); + if(i<0)return(0); + return i; +} - float radix[BINCOUNT]; - float countabove=0; - float countbelow=0; - memset(radix,0,sizeof(radix)); +static void bark_noise_median(int n,const long *b,const float *f, + float *noise, + float lowidth,float hiwidth, + int lomin,int himin, + const int *thresh,const float *off, + int fixed){ + int i=0,lo=-1,hi=-1,fixedc=0; + int median=LASTBIN>>1; + + int barkradix[BINCOUNT]; + int barkcountbelow=0; + + int fixedradix[BINCOUNT]; + int fixedcountbelow=0; + + memset(barkradix,0,sizeof(barkradix)); + memset(fixedradix,0,sizeof(fixedradix)); + + /* bootstrap the fixed window case seperately */ + for(i=0;i<(fixed>>1);i++){ + int bin=psy_dBquant(f+i); + fixedradix[bin]++; + fixedc++; + if(bin<=median) + fixedcountbelow++; + } for(i=0;i<n;i++){ /* find new lo/hi */ - bi=b[i]+hiwidth; - for(;hi<n && (hi<i+himin || b[hi]<=bi);hi++){ - int bin=BIN(f[hi]); - if(bin>LASTBIN)bin=LASTBIN; - if(bin<0)bin=0; - radix[bin]++; - if(bin<median) - countabove++; - else - countbelow++; + int bi=b[i]>>16; + for(;hi<bi;hi++){ + int bin=psy_dBquant(f+hi); + barkradix[bin]++; + if(bin<=median) + barkcountbelow++; } - bi=b[i]-lowidth; - for(;lo<i && lo+lomin<i && b[lo]<=bi;lo++){ - int bin=BIN(f[lo]); - if(bin>LASTBIN)bin=LASTBIN; - if(bin<0)bin=0; - radix[bin]--; - if(bin<median) - countabove--; - else - countbelow--; + bi=b[i]&0xffff; + for(;lo<bi;lo++){ + int bin=psy_dBquant(f+lo); + barkradix[bin]--; + if(bin<=median) + barkcountbelow--; + } + + bi=i+(fixed>>1); + if(bi<n){ + int bin=psy_dBquant(f+bi); + fixedradix[bin]++; + fixedc++; + if(bin<=median) + fixedcountbelow++; + } + + bi-=fixed; + if(bi>=0){ + int bin=psy_dBquant(f+bi); + fixedradix[bin]--; + fixedc--; + if(bin<=median) + fixedcountbelow--; } /* move the median if needed */ - if(countabove+countbelow){ - threshi = thresh[i]*(countabove+countbelow); + { + int bark_th = (thresh[i]*(hi-lo)+512)/1024; + int fixed_th = (thresh[i]*(fixedc)+512)/1024; - while(threshi>countbelow && median>0){ - median--; - countabove-=radix[median]; - countbelow+=radix[median]; + while(bark_th>=barkcountbelow && + fixed_th>=fixedcountbelow /* && median<LASTBIN by rep invariant */ + ){ + median++; + barkcountbelow+=barkradix[median]; + fixedcountbelow+=fixedradix[median]; } - while(threshi<(countbelow-radix[median]) && - median<LASTBIN){ - countabove+=radix[median]; - countbelow-=radix[median]; - median++; + while(bark_th<barkcountbelow || + fixed_th<fixedcountbelow /* && median>=0 by rep invariant */ + ){ + barkcountbelow-=barkradix[median]; + fixedcountbelow-=fixedradix[median]; + median--; } } - noise[i]=BINdB(median)+off[i]; + + noise[i]= (median+1)*.5f+off[i]; } } @@ -630,12 +671,13 @@ float _vp_compute_mask(vorbis_look_psy *p, p->vi->noisewindowlomin, p->vi->noisewindowhimin, p->noisemedian, - p->noiseoffset); + p->noiseoffset, + p->vi->noisewindowfixed); /* suppress any noise curve > specmax+p->vi->noisemaxsupp */ for(i=0;i<n;i++) if(mask[i]>specmax+p->vi->noisemaxsupp) mask[i]=specmax+p->vi->noisemaxsupp; - /*_analysis_output("noise",seq,flr,n,0,0);*/ + _analysis_output("noise",seq,mask,n,0,0); }else{ for(i=0;i<n;i++)mask[i]=NEGINF; } @@ -657,7 +699,9 @@ float _vp_compute_mask(vorbis_look_psy *p, /* XXX apply decay to the fft here */ - seed_loop(p,p->tonecurves,p->peakatt,fft,mask,minseed,maxseed,specmax); + seed_loop(p, + (const float ***)p->tonecurves, + (const float **)p->peakatt,fft,mask,minseed,maxseed,specmax); bound_loop(p,mdct,maxseed,mask,p->vi->bound_att_dB); max_seeds(p,minseed,maxseed,mask); @@ -11,7 +11,7 @@ ******************************************************************** function: random psychoacoustics (not including preecho) - last mod: $Id: psy.h,v 1.19.4.2 2001/05/11 22:07:50 xiphmont Exp $ + last mod: $Id: psy.h,v 1.19.4.3 2001/05/23 02:15:21 xiphmont Exp $ ********************************************************************/ @@ -52,6 +52,7 @@ typedef struct vorbis_info_psy{ float noisewindowhi; int noisewindowlomin; int noisewindowhimin; + int noisewindowfixed; float noisemedian[P_BANDS*2]; float max_curve_dB; @@ -65,12 +66,12 @@ typedef struct { float ***tonecurves; float **peakatt; - float *noisemedian; + int *noisemedian; float *noiseoffset; float *ath; long *octave; /* in n.ocshift format */ - float *bark; + unsigned long *bark; long firstoc; long shiftoc; @@ -7,11 +7,11 @@ * * * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * * by the XIPHOPHORUS Company http://www.xiph.org/ * - + * * ******************************************************************** function: residue backend 0 and 1 implementation - last mod: $Id: res0.c,v 1.26.4.1 2001/05/11 22:07:50 xiphmont Exp $ + last mod: $Id: res0.c,v 1.26.4.2 2001/05/23 02:15:22 xiphmont Exp $ ********************************************************************/ @@ -170,8 +170,8 @@ vorbis_look_residue *res0_look (vorbis_dsp_state *vd,vorbis_info_mode *vm, /* does not guard against invalid settings; eg, a subn of 16 and a subgroup request of 32. Max subn of 128 */ -static int _testhack(float *vec,int n,vorbis_look_residue0 *look, - int auxparts,int auxpartnum){ +static int _interleaved_testhack(float *vec,int n,vorbis_look_residue0 *look, + int auxparts,int auxpartnum){ vorbis_info_residue0 *info=look->info; int i,j=0; float max,localmax=0.f; @@ -191,9 +191,9 @@ static int _testhack(float *vec,int n,vorbis_look_residue0 *look, while(1){ entropy[j]=localmax; n>>=1; + if(!n)break; j++; - if(n<=0)break; for(i=0;i<n;i++){ temp[i]+=temp[i+n]; } @@ -211,6 +211,71 @@ static int _testhack(float *vec,int n,vorbis_look_residue0 *look, return(i); } +static int _testhack(float *vec,int n,vorbis_look_residue0 *look, + int auxparts,int auxpartnum){ + vorbis_info_residue0 *info=look->info; + int i,j=0; + float max,localmax=0.f; + float temp[128]; + float entropy[8]; + + /* setup */ + for(i=0;i<n;i++)temp[i]=fabs(vec[i]); + + /* handle case subgrp==1 outside */ + for(i=0;i<n;i++) + if(temp[i]>localmax)localmax=temp[i]; + max=localmax; + + for(i=0;i<n;i++)temp[i]=rint(temp[i]); + + while(n){ + entropy[j]=localmax; + n>>=1; + j++; + if(!n)break; + for(i=0;i<n;i++){ + temp[i]=temp[i*2]+temp[i*2+1]; + } + localmax=0.f; + for(i=0;i<n;i++) + if(temp[i]>localmax)localmax=temp[i]; + } + + for(i=0;i<auxparts-1;i++) + if(auxpartnum<info->blimit[i] && + entropy[info->subgrp[i]]<=info->entmax[i] && + max<=info->ampmax[i]) + break; + + return(i); +} + +static int _interleaved_encodepart(oggpack_buffer *opb,float *vec, int n, + int stages, codebook **books,int mode, + int part){ + int i,j=0,bits=0; + if(stages){ + int dim=books[j]->dim; + int step=n/dim; + for(i=0;i<step;i++){ + int entry=vorbis_book_besterror(books[j],vec+i,step,0); +#ifdef TRAIN_RESENT + { + char buf[80]; + FILE *f; + sprintf(buf,"res0_%da%d_%d.vqd",mode,j,part); + f=fopen(buf,"a"); + fprintf(f,"%d\n",entry); + fclose(f); + } +#endif + bits+=vorbis_book_encode(books[j],entry,opb); + } + } + return(bits); +} + static int _encodepart(oggpack_buffer *opb,float *vec, int n, int stages, codebook **books,int mode,int part){ int i,j=0,bits=0; @@ -218,7 +283,7 @@ static int _encodepart(oggpack_buffer *opb,float *vec, int n, int dim=books[j]->dim; int step=n/dim; for(i=0;i<step;i++){ - int entry=vorbis_book_besterror(books[j],vec+i,step,0); + int entry=vorbis_book_besterror(books[j],vec+i*dim,1,0); #ifdef TRAIN_RESENT { char buf[80]; @@ -235,14 +300,15 @@ static int _encodepart(oggpack_buffer *opb,float *vec, int n, return(bits); } -static int _decodepart(oggpack_buffer *opb,float *work,float *vec, int n, - int stages, codebook **books){ +/* doesn;t yet deal with cascading */ +static int _interleaved_decodepart(oggpack_buffer *opb,float *work, + float *vec, int n, + int stages, codebook **books){ int i; memset(work,0,sizeof(float)*n); if(stages){ - int dim=books[0]->dim; - int step=n/dim; + int step=n/books[0]->dim; if(s_vorbis_book_decodevs(books[0],work,opb,step,0)==-1) return(-1); } @@ -253,8 +319,29 @@ static int _decodepart(oggpack_buffer *opb,float *work,float *vec, int n, return(0); } -int res0_forward(vorbis_block *vb,vorbis_look_residue *vl, - float **in,int ch){ +static int _decodepart(oggpack_buffer *opb,float *work, + float *vec, int n, + int stages, codebook **books){ + int i; + + memset(work,0,sizeof(float)*n); + if(stages){ + if(s_vorbis_book_decodev(books[0],work,opb,n,0)==-1) + return(-1); + } + + for(i=0;i<n;i++) + vec[i]*=work[i]; + + return(0); +} + +static int _01forward(vorbis_block *vb,vorbis_look_residue *vl, + float **in,int ch, + int (*classify)(float *,int,vorbis_look_residue0 *, + int,int), + int (*encode)(oggpack_buffer *,float *,int,int, + codebook **,int,int)){ long i,j,k,l; vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; vorbis_info_residue0 *info=look->info; @@ -288,12 +375,13 @@ int res0_forward(vorbis_block *vb,vorbis_look_residue *vl, for(i=info->begin,l=0;i<info->end;i+=samples_per_partition,l++){ for(j=0;j<ch;j++) - /* do the partition decision based on the number of 'bits' - needed to encode the block */ + /* do the partition decision based on the 'entropy' + int the block */ partword[j][l]= - _testhack(in[j]+i,samples_per_partition,look,possible_partitions,l); + classify(in[j]+i,samples_per_partition,look,possible_partitions,l); } + /* we code the partition words for each channel, then the residual words for a partition per channel until we've written all the residual words for that partition word. Then write the next @@ -312,9 +400,9 @@ int res0_forward(vorbis_block *vb,vorbis_look_residue *vl, for(k=0;k<partitions_per_word;k++,l++,i+=samples_per_partition) for(j=0;j<ch;j++){ /*resbits[partword[j][l]]+=*/ - resbitsT+=_encodepart(&vb->opb,in[j]+i,samples_per_partition, - info->secondstages[partword[j][l]], - look->partbooks[partword[j][l]],look->map,partword[j][l]); + resbitsT+=encode(&vb->opb,in[j]+i,samples_per_partition, + info->secondstages[partword[j][l]], + look->partbooks[partword[j][l]],look->map,partword[j][l]); resvals[partword[j][l]]+=samples_per_partition; } @@ -332,7 +420,10 @@ int res0_forward(vorbis_block *vb,vorbis_look_residue *vl, } /* a truncated packet here just means 'stop working'; it's not an error */ -int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){ +static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, + float **in,int ch, + int (*decodepart)(oggpack_buffer *,float *,float *, + int,int,codebook **)){ long i,j,k,l,transend=vb->pcmend/2; vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; vorbis_info_residue0 *info=look->info; @@ -361,13 +452,13 @@ int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){ if(partword[j]==NULL)goto errout; } - /* now we decode interleaved residual values for the partitions */ + /* now we decode residual values for the partitions */ for(k=0;k<partitions_per_word;k++,l++,i+=samples_per_partition) for(j=0;j<ch;j++){ int part=partword[j][k]; - if(_decodepart(&vb->opb,work,in[j]+i,samples_per_partition, - info->secondstages[part], - look->partbooks[part])==-1)goto eopbreak; + if(decodepart(&vb->opb,work,in[j]+i,samples_per_partition, + info->secondstages[part], + look->partbooks[part])==-1)goto eopbreak; } } @@ -385,10 +476,24 @@ int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){ return(0); } +/* residue 0 and 1 are just slight variants of one another. 0 is + interleaved, 1 is not */ +int res0_forward(vorbis_block *vb,vorbis_look_residue *vl, + float **in,int ch){ + return(_01forward(vb,vl,in,ch,_interleaved_testhack,_interleaved_encodepart)); +} + +int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){ + return(_01inverse(vb,vl,in,ch,_interleaved_decodepart)); +} + int res1_forward(vorbis_block *vb,vorbis_look_residue *vl, float **in,int ch){ + return(_01forward(vb,vl,in,ch,_testhack,_encodepart)); } + int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,float **in,int ch){ + return(_01inverse(vb,vl,in,ch,_decodepart)); } vorbis_func_residue residue0_exportbundle={ diff --git a/lib/scales.h b/lib/scales.h index 84d8083b..2e28776b 100644 --- a/lib/scales.h +++ b/lib/scales.h @@ -11,7 +11,7 @@ ******************************************************************** function: linear scale -> dB, Bark and Mel scales - last mod: $Id: scales.h,v 1.15.4.2 2001/05/13 22:40:24 xiphmont Exp $ + last mod: $Id: scales.h,v 1.15.4.3 2001/05/23 02:15:22 xiphmont Exp $ ********************************************************************/ @@ -90,7 +90,7 @@ static float todB_LOOKUP[256]={ 49.187850f, 50.102999f, 50.930853f, 51.686624f }; -static float todB(float *x){ +static float todB(const float *x){ ogg_int32_t *i=(ogg_int32_t *)x; ogg_int32_t temp=((*i&0x7fffffff)-0x33cfffff)>>20; if(temp<0)return -400.f; |