[xiph-cvs] cvs commit: vorbis/lib block.c codec_internal.h envelope.c envelope.h iir.c iir.h
Monty
xiphmont at xiph.org
Thu Feb 15 11:05:47 PST 2001
xiphmont 01/02/15 11:05:46
Modified: lib block.c codec_internal.h envelope.c envelope.h
iir.c iir.h
Log:
Some new preecho code; split energy threshholding up into a few bands.
Monty
Revision Changes Path
1.45 +2 -2 vorbis/lib/block.c
Index: block.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/block.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- block.c 2001/02/02 03:51:55 1.44
+++ block.c 2001/02/15 19:05:45 1.45
@@ -11,7 +11,7 @@
********************************************************************
function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.44 2001/02/02 03:51:55 xiphmont Exp $
+ last mod: $Id: block.c,v 1.45 2001/02/15 19:05:45 xiphmont Exp $
Handle windowing, overlap-add, etc of the PCM vectors. This is made
more amusing by Vorbis' current two allowed block sizes.
@@ -493,7 +493,7 @@
largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]/4;
else
/* min boundary; nW large, next small */
- largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]*3/4;
+ largebound=v->centerW+ci->blocksizes[1]/2+ci->blocksizes[0]/2;
bp=_ve_envelope_search(v,largebound);
if(bp==-1)return(0); /* not enough data currently to search for a
1.6 +3 -3 vorbis/lib/codec_internal.h
Index: codec_internal.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/codec_internal.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- codec_internal.h 2001/02/02 03:51:56 1.5
+++ codec_internal.h 2001/02/15 19:05:45 1.6
@@ -11,7 +11,7 @@
********************************************************************
function: libvorbis codec headers
- last mod: $Id: codec_internal.h,v 1.5 2001/02/02 03:51:56 xiphmont Exp $
+ last mod: $Id: codec_internal.h,v 1.6 2001/02/15 19:05:45 xiphmont Exp $
********************************************************************/
@@ -110,8 +110,8 @@
/* for block long/sort tuning; encode only */
int envelopesa;
- float preecho_thresh;
- float postecho_thresh;
+ float preecho_thresh[4];
+ float postecho_thresh[4];
float preecho_minenergy;
float ampmax_att_per_sec;
1.32 +113 -133 vorbis/lib/envelope.c
Index: envelope.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/envelope.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- envelope.c 2001/02/02 03:51:56 1.31
+++ envelope.c 2001/02/15 19:05:45 1.32
@@ -11,7 +11,7 @@
********************************************************************
function: PCM data envelope analysis and manipulation
- last mod: $Id: envelope.c,v 1.31 2001/02/02 03:51:56 xiphmont Exp $
+ last mod: $Id: envelope.c,v 1.32 2001/02/15 19:05:45 xiphmont Exp $
Preecho calculation.
@@ -30,66 +30,58 @@
#include "envelope.h"
#include "misc.h"
-/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher
- Command line: /www/usr/fisher/helpers/mkfilter -Ch \
- -6.0000000000e+00 -Bp -o 5 -a 1.3605442177e-01 3.1746031746e-01 -l */
-
-#if 0
-static int cheb_bandpass_stages=10;
-static float cheb_bandpass_gain=5.589612458e+01f;
-static float cheb_bandpass_B[]={-1.f,0.f,5.f,0.f,-10.f,0.f,
- 10.f,0.f,-5.f,0.f,1f};
-static float cheb_bandpass_A[]={
- -0.1917409386f,
- 0.0078657069f,
- -0.7126903444f,
- 0.0266343467f,
- -1.4047174730f,
- 0.0466964232f,
- -1.9032773429f,
- 0.0451493360f,
- -1.4471447397f,
- 0.0303413711f};
-#endif
-
-/* 4kHz Chebyshev highpass */
-static int cheb_highpass_stages=10;
-static float cheb_highpass_gain= 1.314337427e+01f;
-/* z^-stage, z^-stage+1... */
-static float cheb_highpass_B[]={1.f,-10.f,45.f,-120.f,210.f,
- -252.f,210.f,-120.f,45.f,-10.f,1.f};
-static float cheb_highpass_A[]={
- -0.1013448254f,
- 0.4524819695f,
- -1.3268091670f,
- 3.2875726855f,
- -7.2782468961f,
- 13.0298867474f,
- -17.6698599469f,
- 17.2757670409f,
- -11.6207967046f,
- 4.8672119675f};
-
-#if 0
-/* 6kHz Chebyshev highpass */
-static int cheb_highpass_stages=10;
-static float cheb_highpass_gain= 5.291963434e+01f;
-/* z^-stage, z^-stage+1... */
-static float cheb_highpass_B[]={1.f,-10.f,45.f,-120.f,210.f,
- -252.f,210.f,-120.f,45.f,-10.f,1.f};
-static float cheb_highpass_A[]={
- -0.1247628029f,
- 0.1334086523f,
- -0.3997715614f,
- 0.3213011089f,
- -1.1131924119f,
- 1.7692446626f,
- -3.6241199038f,
- 4.1950871291f,
- -4.2771757867f,
- 2.3920318913f};
-#endif
+/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher */
+
+
+static int cheb_highpass_stages=6;
+static float cheb_highpass_B[]={1.f,-6.f,15.f,-20.f,15.f,-6.f,1.f};
+
+static int cheb_bandpass_stages=6;
+static float cheb_bandpass_B[]={-1.f,0.f,3.f,0.f,-3.f,0.f,1.f};
+
+
+/* 10kHz Chebyshev highpass */
+static float cheb_highpass10k_gain= 54.34519586f;
+static float cheb_highpass10k_A[]={
+ -0.2064797169f,
+ -0.5609713214f,
+ -1.1352465327f,
+ -1.4495555418f,
+ -1.7938140760f,
+ -0.9473564683f};
+
+/* 6kHz-10kHz Chebyshev bandpass */
+static float cheb_bandpass6k_gain=113.4643935f;
+static float cheb_bandpass6k_A[]={
+ -0.5712621337f,
+ 1.5626130710f,
+ -3.3348854983f,
+ 4.0471340821f,
+ -4.0051680331f,
+ 2.2786325610f};
+
+/* 3kHz-6kHz Chebyshev bandpass */
+static float cheb_bandpass3k_gain= 248.8359377f;
+static float cheb_bandpass3k_A[]={
+ -0.6564230022f,
+ 3.3747911257f,
+ -8.0098635981f,
+ 11.0040876874f,
+ -9.2250963484f,
+ 4.4760355389f};
+
+/* 1.5kHz-3kHz Chebyshev bandpass */
+static float cheb_bandpass1k_gain= 1798.537183f;
+static float cheb_bandpass1k_A[]={
+ -0.8097527363f,
+ 4.7725742682f,
+ -11.9800219408f,
+ 16.3770336223f,
+ -12.8553129536f,
+ 5.4948074309f};
+
+
void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){
codec_setup_info *ci=vi->codec_setup;
int ch=vi->channels;
@@ -97,31 +89,35 @@
int i;
e->winlength=window;
e->minenergy=fromdB(ci->preecho_minenergy);
- e->iir=_ogg_calloc(ch,sizeof(IIR_state));
- e->filtered=_ogg_calloc(ch,sizeof(float *));
+ e->iir=_ogg_calloc(ch*4,sizeof(IIR_state));
+ e->filtered=_ogg_calloc(ch*4,sizeof(float *));
e->ch=ch;
e->storage=128;
- for(i=0;i<ch;i++){
- IIR_init(e->iir+i,cheb_highpass_stages,cheb_highpass_gain,
- cheb_highpass_A,cheb_highpass_B);
+ for(i=0;i<ch*4;i+=4){
+
+ IIR_init(e->iir+i,cheb_highpass_stages,cheb_highpass10k_gain,
+ cheb_highpass10k_A,cheb_highpass_B);
+ IIR_init(e->iir+i+1,cheb_bandpass_stages,cheb_bandpass6k_gain,
+ cheb_bandpass6k_A,cheb_bandpass_B);
+ IIR_init(e->iir+i+2,cheb_bandpass_stages,cheb_bandpass3k_gain,
+ cheb_bandpass3k_A,cheb_bandpass_B);
+ IIR_init(e->iir+i+3,cheb_bandpass_stages,cheb_bandpass1k_gain,
+ cheb_bandpass1k_A,cheb_bandpass_B);
+
e->filtered[i]=_ogg_calloc(e->storage,sizeof(float));
+ e->filtered[i+1]=_ogg_calloc(e->storage,sizeof(float));
+ e->filtered[i+2]=_ogg_calloc(e->storage,sizeof(float));
+ e->filtered[i+3]=_ogg_calloc(e->storage,sizeof(float));
}
- drft_init(&e->drft,window);
- e->window=_ogg_malloc(e->winlength*sizeof(float));
- /* We just use a straight sin(x) window for this */
- for(i=0;i<e->winlength;i++)
- e->window[i]=sin((i+.5)/e->winlength*M_PI);
}
void _ve_envelope_clear(envelope_lookup *e){
int i;
- for(i=0;i<e->ch;i++){
+ for(i=0;i<e->ch*4;i++){
IIR_clear((e->iir+i));
_ogg_free(e->filtered[i]);
}
- drft_clear(&e->drft);
- _ogg_free(e->window);
_ogg_free(e->filtered);
_ogg_free(e->iir);
memset(e,0,sizeof(envelope_lookup));
@@ -156,52 +152,58 @@
return(B-A);
}
-static float _ve_ampi(envelope_lookup *ve,float *pre){
- long n=ve->winlength;
-
- long i;
-
- /* we want to have a 'minimum bar' for energy, else we're just
- basing blocks on quantization noise that outweighs the signal
- itself (for low power signals) */
-
- float min=ve->minenergy;
- float A=min*min*n;
-
- for(i=0;i<n;i++){
- A+=pre[i]*pre[i];
- }
-
- A=todB(A);
- return(A);
-}
-
long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){
vorbis_info *vi=v->vi;
codec_setup_info *ci=vi->codec_setup;
envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve;
- long i,j,k;
+ long i,j,k,l;
float *work=alloca(sizeof(float)*ve->winlength*2);
+ static int seq=0;
/* make sure we have enough storage to match the PCM */
if(v->pcm_storage>ve->storage){
ve->storage=v->pcm_storage;
- for(i=0;i<ve->ch;i++)
+ for(i=0;i<ve->ch*4;i++)
ve->filtered[i]=_ogg_realloc(ve->filtered[i],ve->storage*sizeof(float));
}
/* catch up the highpass to match the pcm */
for(i=0;i<ve->ch;i++){
- float *filtered=ve->filtered[i];
float *pcm=v->pcm[i];
- IIR_state *iir=ve->iir+i;
+ float *filtered0=ve->filtered[i*4];
+ float *filtered1=ve->filtered[i*4+1];
+ float *filtered2=ve->filtered[i*4+2];
+ float *filtered3=ve->filtered[i*4+3];
+ IIR_state *iir0=ve->iir+i*4;
+ IIR_state *iir1=ve->iir+i*4+1;
+ IIR_state *iir2=ve->iir+i*4+2;
+ IIR_state *iir3=ve->iir+i*4+3;
int flag=1;
for(j=ve->current;j<v->pcm_current;j++){
- filtered[j]=IIR_filter(iir,pcm[j]);
+ filtered0[j]=IIR_filter(iir0,pcm[j]);
+ filtered1[j]=IIR_filter(iir1,pcm[j]);
+ filtered2[j]=IIR_filter(iir2,pcm[j]);
+ filtered3[j]=IIR_filter(iir3,pcm[j]);
if(pcm[j])flag=0;
}
- if(flag && ve->current+64<v->pcm_current)IIR_reset(iir);
+ if(flag && ve->current+64<v->pcm_current){
+ IIR_reset(iir0);
+ IIR_reset(iir1);
+ IIR_reset(iir2);
+ IIR_reset(iir3);
+ }
+
+ _analysis_output("pcm",seq,pcm+v->centerW,v->pcm_current-v->centerW,0,0);
+ _analysis_output("f0",seq,filtered0+v->centerW,v->pcm_current-v->centerW,
+ 0,0);
+ _analysis_output("f1",seq,filtered1+v->centerW,v->pcm_current-v->centerW,
+ 0,0);
+ _analysis_output("f2",seq,filtered2+v->centerW,v->pcm_current-v->centerW,
+ 0,0);
+ _analysis_output("f3",seq++,filtered3+v->centerW,v->pcm_current-v->centerW,
+ 0,0);
+
}
ve->current=v->pcm_current;
@@ -215,44 +217,22 @@
while(j+ve->winlength<=v->pcm_current){
for(i=0;i<ve->ch;i++){
- float *filtered=ve->filtered[i]+j;
- float m=_ve_deltai(ve,filtered-ve->winlength,filtered);
-
- if(m>ci->preecho_thresh){
- /*granulepos++;*/
- return(0);
- }
- if(m<ci->postecho_thresh){
- /*granulepos++;*/
- return(0);
- }
- /*granulepos++;*/
- }
-
- /* look also for preecho in coupled channel pairs with the center
- subtracted out (A-B) */
- for(i=1;i<ve->ch;i+=2){
- float *filteredA=ve->filtered[i-1]+j-ve->winlength;
- float *filteredB=ve->filtered[i]+j-ve->winlength;
- float m;
-
- for(k=0;k<ve->winlength*2;k++)
- work[k]=filteredA[k]-filteredB[k];
-
- m=_ve_deltai(ve,work,work+ve->winlength);
+ for(k=0;k<4;k++){
+ float *filtered=ve->filtered[i*4+k]+j;
+ float m=_ve_deltai(ve,filtered-ve->winlength,filtered);
- if(m>ci->preecho_thresh){
+ if(m>ci->preecho_thresh[k]){
+ /*granulepos++;*/
+ return(0);
+ }
+ if(m<ci->postecho_thresh[k]){
+ /*granulepos++;*/
+ return(0);
+ }
/*granulepos++;*/
- return(0);
}
- if(m<ci->postecho_thresh){
- /*granulepos++;*/
- return(0);
- }
- /*granulepos++;*/
}
-
j+=min(ci->blocksizes[0],ve->winlength)/2;
if(j>=searchpoint){
@@ -265,7 +245,7 @@
void _ve_envelope_shift(envelope_lookup *e,long shift){
int i;
- for(i=0;i<e->ch;i++)
+ for(i=0;i<e->ch*4;i++)
memmove(e->filtered[i],e->filtered[i]+shift,(e->current-shift)*
sizeof(float));
e->current-=shift;
1.13 +2 -3 vorbis/lib/envelope.h
Index: envelope.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/envelope.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- envelope.h 2001/02/02 03:51:56 1.12
+++ envelope.h 2001/02/15 19:05:45 1.13
@@ -11,7 +11,7 @@
********************************************************************
function: PCM data envelope analysis and manipulation
- last mod: $Id: envelope.h,v 1.12 2001/02/02 03:51:56 xiphmont Exp $
+ last mod: $Id: envelope.h,v 1.13 2001/02/15 19:05:45 xiphmont Exp $
********************************************************************/
@@ -31,11 +31,10 @@
IIR_state *iir;
float **filtered;
+
long storage;
long current;
- drft_lookup drft;
- float *window;
} envelope_lookup;
extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi);
1.8 +3 -3 vorbis/lib/iir.c
Index: iir.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/iir.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- iir.c 2001/02/02 03:51:56 1.7
+++ iir.c 2001/02/15 19:05:45 1.8
@@ -11,7 +11,7 @@
********************************************************************
function: Direct Form I, II IIR filters, plus some specializations
- last mod: $Id: iir.c,v 1.7 2001/02/02 03:51:56 xiphmont Exp $
+ last mod: $Id: iir.c,v 1.8 2001/02/15 19:05:45 xiphmont Exp $
********************************************************************/
@@ -69,8 +69,8 @@
}
/* this assumes the symmetrical structure of the feed-forward stage of
- a Chebyshev bandpass to save multiplies */
-float IIR_filter_ChebBand(IIR_state *s,float in){
+ a typical bandpass to save multiplies */
+float IIR_filter_Band(IIR_state *s,float in){
int stages=s->stages,i;
float newA;
float newB=0;
1.6 +2 -2 vorbis/lib/iir.h
Index: iir.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/iir.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- iir.h 2001/02/02 03:51:56 1.5
+++ iir.h 2001/02/15 19:05:45 1.6
@@ -11,7 +11,7 @@
********************************************************************
function: Direct Form I, II IIR filters, plus some specializations
- last mod: $Id: iir.h,v 1.5 2001/02/02 03:51:56 xiphmont Exp $
+ last mod: $Id: iir.h,v 1.6 2001/02/15 19:05:45 xiphmont Exp $
********************************************************************/
@@ -30,7 +30,7 @@
extern void IIR_init(IIR_state *s,int stages,float gain, float *A, float *B);
extern void IIR_clear(IIR_state *s);
extern float IIR_filter(IIR_state *s,float in);
-extern float IIR_filter_ChebBand(IIR_state *s,float in);
+extern float IIR_filter_Band(IIR_state *s,float in);
extern void IIR_reset(IIR_state *s);
#endif
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list