summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2001-05-23 02:15:24 +0000
committerMonty <xiphmont@xiph.org>2001-05-23 02:15:24 +0000
commit4d3fa2bbba45ab1ca6bf4074e8bc8e68de6f6236 (patch)
tree3f1e82724d4a624db35114a56474864a18b46cc4
parentf87d0cf5d034f283b9c6d3fa516d412562ac6aaa (diff)
downloadlibvorbis-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.c39
-rw-r--r--lib/codebook.h161
-rw-r--r--lib/floor1.c217
-rw-r--r--lib/masking.h243
-rw-r--r--lib/modes/mode_A.h8
-rw-r--r--lib/psy.c200
-rw-r--r--lib/psy.h7
-rw-r--r--lib/res0.c151
-rw-r--r--lib/scales.h4
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,
diff --git a/lib/psy.c b/lib/psy.c
index f08b70b9..082db21f 100644
--- a/lib/psy.c
+++ b/lib/psy.c
@@ -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);
diff --git a/lib/psy.h b/lib/psy.h
index 3e8fdaf2..59a3dd22 100644
--- a/lib/psy.h
+++ b/lib/psy.h
@@ -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;
diff --git a/lib/res0.c b/lib/res0.c
index 5eb36146..9cc6699d 100644
--- a/lib/res0.c
+++ b/lib/res0.c
@@ -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;