[xiph-commits] r7884 - trunk/postfish
xiphmont at motherfish-iii.xiph.org
xiphmont at motherfish-iii.xiph.org
Sun Sep 26 23:30:09 PDT 2004
Author: xiphmont
Date: 2004-09-26 23:30:08 -0700 (Sun, 26 Sep 2004)
New Revision: 7884
Modified:
trunk/postfish/declip.c
trunk/postfish/mute.c
trunk/postfish/version.h
trunk/postfish/window.c
Log:
repair bug in new window infrastructure
convert declipper to new windowing
eliminate minor mute/unmute transition bug in declipper
Modified: trunk/postfish/declip.c
===================================================================
--- trunk/postfish/declip.c 2004-09-27 06:04:27 UTC (rev 7883)
+++ trunk/postfish/declip.c 2004-09-27 06:30:08 UTC (rev 7884)
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <fftw3.h>
#include "reconstruct.h"
+#include "window.h"
#include "feedback.h"
extern int input_rate;
@@ -42,7 +43,11 @@
static int blocksize=0;
static int lopad=0,hipad=0;
static u_int32_t *widthlookup=0;
-static float *window=0;
+
+static float *leftwindow=0;
+static float *rightwindow=0;
+static int left=0;
+static int right=0;
static float width=.5;
static float **lap;
static float **cache;
@@ -105,24 +110,35 @@
return 1;
}
-static void setup_window(int left,int right){
- int max=(left<right?right:left);
+static void apply_window(float *out,float *data,int sq){
int i,j;
+ int half=max(left,right);
- for(i=0;i<max-left;i++)
- window[i]=0;
+ for(i=0;i<half-left;i++)
+ out[i]=0;
- for(j=0;j<left;i++,j++)
- window[i]=sin( M_PIl*j/(left*2) );
+ if(sq){
+ for(j=0;i<half;i++,j++)
+ out[i]=data[i]*leftwindow[j]*leftwindow[j];
+ for(j=0;j<right;i++,j++)
+ out[i]=data[i]*rightwindow[right-j]*rightwindow[right-j];
+ }else{
+ for(j=0;i<half;i++,j++)
+ out[i]=data[i]*leftwindow[j];
+ for(j=0;j<right;i++,j++)
+ out[i]=data[i]*rightwindow[right-j];
+ }
- for(j=right;j<right*2;i++,j++)
- window[i]=sin( M_PIl*j/(right*2) );
+ for(;i<half*2;i++)
+ out[i]=0;
+}
- for(;i<max*2;i++)
- window[i]=0;
+static void setup_window(int lleft,int lright){
+ left=lleft;
+ right=lright;
- for(i=0;i<max*2;i++) window[i]*=window[i];
- for(i=0;i<max*2;i++) window[i]=sin(window[i]*M_PIl*.5);
+ leftwindow=window_get(2,left);
+ rightwindow=window_get(2,right);
}
static void setup_blocksize(int newblocksize){
@@ -169,8 +185,6 @@
for(i=0;i<input_ch;i++)
lap[i]=malloc(input_size*sizeof(**lap));
- window=malloc(input_size*2*sizeof(*window));
-
{
/* alloc for largest possible blocksize */
int blocksize=input_size*2;
@@ -268,7 +282,7 @@
if(count){
for(i=0;i<blocksize/2;i++)flag[i]=0.;
for(i=blocksize*3/2;i<blocksize*2;i++)flag[i]=0.;
- for(i=0;i<blocksize;i++)work[i+blocksize/2]*=window[i];
+ apply_window(work+blocksize/2,work+blocksize/2,0);
fftwf_execute(fftwf_weight);
sliding_bark_average(freq,blocksize*2,width);
@@ -277,9 +291,9 @@
reconstruct(work,freq,flag,epsilon,iterbound);
- for(i=0;i<blocksize;i++)work[i+blocksize/2]*=window[i];
+ apply_window(work+blocksize/2,work+blocksize/2,0);
}else
- for(i=0;i<blocksize;i++)work[i+blocksize/2]*=window[i]*window[i];
+ apply_window(work+blocksize/2,work+blocksize/2,1);
}
@@ -390,7 +404,7 @@
}
/* the gap piece is also special in that it may need to deal with
- a transition to/from mute and/or a transition to/from bypass */
+ a transition to/from bypass */
for(i=0;i<input_ch;i++){
int channel_active=declip_active[i];
@@ -402,157 +416,132 @@
if(fabs(l[j])>peak[i])peak[i]=fabs(l[j]);
}
- if( mute_channel_muted(in->active,i) &&
- mute_channel_muted(cache_active,i)){
- /* Cache: Muted=True , Bypass=X
- Input: Muted=True , Bypass=X */
+ if(mute_channel_muted(cache_active,i)){
+
/* we may need cache for a later transition, so keep it up to date */
float *temp=cache[i];
cache[i]=in->data[i];
in->data[i]=temp;
-
+
+ /* zero the lap */
+ if(!mute_channel_muted(in->active,i))
+ memset(lap[i],0,sizeof(*lap[i])*input_size);
+
}else{
- if(mute_channel_muted(cache_active,i)){
- if(channel_active){
- /* Cache: Muted=True , Bypass=X
- Input: Muted=False, Bypass=False */
+
+ active|=(1<<i); /* audible output in out.data[i] */
+
+ if(mute_channel_muted(in->active,i)){
+ if(declip_prev_active[i]){
+ /* Cache: Muted=False, Bypass=False
+ Input: Muted=True, Bypass=X */
- /* rotate cache */
+ /* transition to mute, so lap is finished output. Rotate all */
float *temp=cache[i];
cache[i]=in->data[i];
in->data[i]=temp;
- /* zero the lap */
- memset(lap[i],0,sizeof(*lap[i])*blocksize/2);
-
+
+ temp=out.data[i];
+ out.data[i]=lap[i];
+ lap[i]=temp;
}else{
- /* Cache: Muted=True , Bypass=X
- Input: Muted=False, Bypass=True */
-
- /* silence->bypass; transition must happen in the current outblock */
- active|=(1<<i); /* audible output in out.data[i] */
- memset(out.data[i],0,sizeof(*out.data[i])*input_size);
- for(j=input_size-blocksize/2,k=0;j<input_size;j++,k++)
- out.data[i][j]=cache[i][j]*window[k]*window[k];
-
- float *temp=cache[i];
+ /* Cache: Muted=False, Bypass=True
+ Input: Muted=True, Bypass=X */
+
+ /* rotate in/cache/out, transition out */
+ float *temp=out.data[i];
+ out.data[i]=cache[i];
cache[i]=in->data[i];
in->data[i]=temp;
+
}
}else{
- active|=(1<<i); /* audible output in out.data[i] */
-
- if(mute_channel_muted(in->active,i)){
- if(declip_prev_active[i]){
- /* Cache: Muted=False, Bypass=False
- Input: Muted=True, Bypass=X */
-
- /* transition to mute, so lap is finished output. Rotate all */
- float *temp=cache[i];
+ if(!declip_prev_active[i]){
+ if(!channel_active){
+ /* Cache: Muted=False, Bypass=True
+ Input: Muted=False, Bypass=True */
+
+ /* all bypass! rotate in/cache/out */
+ float *temp=out.data[i];
+ out.data[i]=cache[i];
cache[i]=in->data[i];
in->data[i]=temp;
-
- temp=out.data[i];
- out.data[i]=lap[i];
- lap[i]=temp;
}else{
/* Cache: Muted=False, Bypass=True
- Input: Muted=True, Bypass=X */
+ Input: Muted=False, Bypass=False */
- /* rotate in/cache/out, transition out */
+ /* transition the lap; right window to left of in */
+ for(j=0;j<right;j++)
+ lap[i][j]=in->data[i][j]*
+ rightwindow[right-j]*rightwindow[right-j];
+
+ /* all rotate in/cache/out */
float *temp=out.data[i];
out.data[i]=cache[i];
cache[i]=in->data[i];
in->data[i]=temp;
- for(j=input_size-blocksize/2,k=0;j<input_size;j++,k++){
- float w=(1.-window[k]);
- out.data[i][j]*=w*w;
- }
}
}else{
- if(!declip_prev_active[i]){
- if(!channel_active){
- /* Cache: Muted=False, Bypass=True
- Input: Muted=False, Bypass=True */
-
- /* all bypass! rotate in/cache/out */
- float *temp=out.data[i];
- out.data[i]=cache[i];
- cache[i]=in->data[i];
- in->data[i]=temp;
- }else{
- /* Cache: Muted=False, Bypass=True
- Input: Muted=False, Bypass=False */
-
- /* transition the lap */
- for(j=0,k=blocksize/2;j<blocksize/2;j++,k++)
- lap[i][j]=in->data[i][j]*window[k]*window[k];
+ if(!channel_active){
+ /* Cache: Muted=False, Bypass=False
+ Input: Muted=False, Bypass=True */
- /* all rotate in/cache/out */
- float *temp=out.data[i];
- out.data[i]=cache[i];
- cache[i]=in->data[i];
- in->data[i]=temp;
- }
+ /* finish off lap, then rotate all */
+ /* left window to end of cache */
+ for(j=input_size-left,k=0;j<input_size;j++,k++)
+ lap[i][j]+=cache[i][j]*leftwindow[k]*leftwindow[k];
+ float *temp=cache[i];
+ cache[i]=in->data[i];
+ in->data[i]=temp;
+
+ temp=out.data[i];
+ out.data[i]=lap[i];
+ lap[i]=temp;
}else{
- if(!channel_active){
- /* Cache: Muted=False, Bypass=False
- Input: Muted=False, Bypass=True */
-
- /* finish off lap, then rotate all */
- for(j=input_size-blocksize/2,k=0;j<input_size;j++,k++)
- lap[i][j]+=cache[i][j]*window[k]*window[k];
- float *temp=cache[i];
- cache[i]=in->data[i];
- in->data[i]=temp;
-
- temp=out.data[i];
- out.data[i]=lap[i];
- lap[i]=temp;
- }else{
- /* Cache: Muted=False, Bypass=False
- Input: Muted=False, Bypass=False */
-
- /* nominal case; the only one involving declipping the gap */
- memset(work,0,sizeof(*work)*blocksize/2);
- memcpy(work+blocksize/2,cache[i]+input_size-blocksize/2,sizeof(*work)*blocksize/2);
- memcpy(work+blocksize,in->data[i],sizeof(*work)*blocksize/2);
- memset(work+blocksize+blocksize/2,0,sizeof(*work)*blocksize/2);
-
- declip(blocksize,local_trigger[i],local_convergence,local_iterations,
- total+i,count+i);
-
- /* finish lap from last frame */
- {
- float *llap=lap[i]+input_size-blocksize/2;
- float *lwork=work+blocksize/2;
- for(j=0;j<blocksize/2;j++)
- llap[j]+=lwork[j];
- }
- /* rotate buffers */
- float *temp=out.data[i];
- out.data[i]=lap[i];
- lap[i]=temp;
-
- temp=in->data[i];
- in->data[i]=cache[i];
- cache[i]=temp;
-
- /* begin lap for this frame */
- memcpy(lap[i],work+blocksize,sizeof(*work)*blocksize/2);
+ /* Cache: Muted=False, Bypass=False
+ Input: Muted=False, Bypass=False */
+
+ /* nominal case; the only one involving declipping the gap */
+ memset(work,0,sizeof(*work)*blocksize/2);
+ memcpy(work+blocksize/2,cache[i]+input_size-blocksize/2,sizeof(*work)*blocksize/2);
+ memcpy(work+blocksize,in->data[i],sizeof(*work)*blocksize/2);
+ memset(work+blocksize+blocksize/2,0,sizeof(*work)*blocksize/2);
+
+ declip(blocksize,local_trigger[i],local_convergence,local_iterations,
+ total+i,count+i);
+
+ /* finish lap from last frame */
+ {
+ float *llap=lap[i]+input_size-blocksize/2;
+ float *lwork=work+blocksize/2;
+ for(j=0;j<blocksize/2;j++)
+ llap[j]+=lwork[j];
}
+ /* rotate buffers */
+ float *temp=out.data[i];
+ out.data[i]=lap[i];
+ lap[i]=temp;
+
+ temp=in->data[i];
+ in->data[i]=cache[i];
+ cache[i]=temp;
+
+ /* begin lap for this frame */
+ memcpy(lap[i],work+blocksize,sizeof(*work)*blocksize/2);
}
}
}
}
+
declip_prev_active[i]=channel_active;
}
-
+
/* also rotate metadata */
out.samples=cache_samples;
cache_samples=in->samples;
cache_active=in->active;
-
+
/* finish transition to new blocksize (if a change is in progress) */
if(next_blocksize != orig_blocksize){
if(next_blocksize <= orig_blocksize) setup_blocksize(next_blocksize);
Modified: trunk/postfish/mute.c
===================================================================
--- trunk/postfish/mute.c 2004-09-27 06:04:27 UTC (rev 7883)
+++ trunk/postfish/mute.c 2004-09-27 06:30:08 UTC (rev 7884)
@@ -70,7 +70,7 @@
float *x=in->data[i];
if(mixpanel_active[i]){
retval|= (1<<i);
-
+
if(mute_channel_muted(channel_state.active_prev,i)){
/* mute->active */
for(j=0;j<input_size;j++)
@@ -81,6 +81,7 @@
if(!mute_channel_muted(channel_state.active_prev,i)){
/* active->mute; ramp to zero and temporarily keep this
channel active for this frame while ramping */
+
retval|= (1<<i);
for(j=0;j<input_size;j++)
x[j]*=channel_state.leftwindow[input_size-j];
@@ -91,5 +92,6 @@
in->active=retval;
channel_state.active_prev=preval;
+ channel_state.init_state=1;
return(in);
}
Modified: trunk/postfish/version.h
===================================================================
--- trunk/postfish/version.h 2004-09-27 06:04:27 UTC (rev 7883)
+++ trunk/postfish/version.h 2004-09-27 06:30:08 UTC (rev 7884)
@@ -1,2 +1,2 @@
#define VERSION "$Id$ "
-/* DO NOT EDIT: Automated versioning hack [Sat Sep 25 01:06:02 EDT 2004] */
+/* DO NOT EDIT: Automated versioning hack [Mon Sep 27 02:46:29 EDT 2004] */
Modified: trunk/postfish/window.c
===================================================================
--- trunk/postfish/window.c 2004-09-27 06:04:27 UTC (rev 7883)
+++ trunk/postfish/window.c 2004-09-27 06:30:08 UTC (rev 7884)
@@ -24,6 +24,7 @@
#include "postfish.h"
#include "window.h"
+static pthread_mutex_t window_mutex=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static float ***window_func=0; /* sin(), sin()^2, sin(sin()^2),sin(sin^2)^2
1,2,4,8,16,32,64,128,256,512,1024,
@@ -54,6 +55,7 @@
if(type<0)return 0;
if(type>3)return 0;
+ pthread_mutex_lock(&window_mutex);
if(!window_func)
window_func=calloc(4,sizeof(*window_func));
@@ -74,5 +76,6 @@
window_func[type][bits][i];
}
+ pthread_mutex_unlock(&window_mutex);
return window_func[type][bits];
}
More information about the commits
mailing list