Commit d572b651 authored by Monty Montgomery's avatar Monty Montgomery

Begin adding common window function storage

Finish the job begun long ago of renaming the 'Reverberation
Suppressor' to 'Deverber' (a much better name I'm sure you all agree).

Begin work on proper centralized mute handling



git-svn-id: https://svn.xiph.org/trunk/postfish@7875 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 886ed02b
......@@ -10,7 +10,7 @@ ADD_DEF= -DUGLY_IEEE754_FLOAT32_HACK=1 -maltivec -mcpu=7400
# use the below for x86 and most other platforms where 'float' is 32 bit IEEE754
#ADD_DEF= -DUGLY_IEEE754_FLOAT32_HACK=1
ADD_DEF= -DUGLY_IEEE754_FLOAT32_HACK=1 -march=athlon-mp
# use the below for anything without IEE754 floats (eg, VAX)
......@@ -28,15 +28,15 @@ MANDIR=$(PREFIX)/man
SRC = main.c mainpanel.c multibar.c readout.c input.c output.c clippanel.c \
declip.c reconstruct.c multicompand.c windowbutton.c subpanel.c \
feedback.c freq.c eq.c eqpanel.c compandpanel.c subband.c lpc.c \
bessel.c suppresspanel.c suppress.c singlecomp.c singlepanel.c \
bessel.c deverbpanel.c deverb.c singlecomp.c singlepanel.c \
limit.c limitpanel.c mute.c mixpanel.c mix.c reverb.c reverbpanel.c \
outpanel.c config.c
outpanel.c config.c window.c
OBJ = main.o mainpanel.o multibar.o readout.o input.o output.o clippanel.o \
declip.o reconstruct.o multicompand.o windowbutton.o subpanel.o \
feedback.o freq.o eq.o eqpanel.o compandpanel.o subband.o lpc.o \
bessel.o suppresspanel.o suppress.o singlecomp.o singlepanel.o \
bessel.o deverbpanel.o deverb.o singlecomp.o singlepanel.o \
limit.o limitpanel.o mute.o mixpanel.o mix.o reverb.o reverbpanel.o \
outpanel.o config.o
outpanel.o config.o window.o
GCF = -DETCDIR=\\\"$(ETCDIR)\\\" `pkg-config --cflags gtk+-2.0` -DG_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED
all:
......@@ -76,7 +76,7 @@ endif
target: $(OBJ) postfish-wisdomrc
./touch-version
$(LD) $(OBJ) $(CFLAGS) -o postfish $(LIBS) `pkg-config --libs gtk+-2.0` -lpthread -lfftw3f -lm
$(LD) $(OBJ) $(CFLAGS) -o postfish $(LIBS) `pkg-config --libs gtk+-2.0` -lpthread -lfftw3f -lm #/home/xiphmont/electric-fence-2.1.4/libefence.a
install: target
$(INSTALL) -d -m 0755 $(BINDIR)
......
......@@ -26,19 +26,19 @@
#include <fftw3.h>
#include "subband.h"
#include "bessel.h"
#include "suppress.h"
#include "deverb.h"
/* (since this one is kinda unique) The Reverberation Suppressor....
/* (since this one is kinda unique) The Deverberation Filter....
Reverberation in a measurably live environment displays
log amplitude decay with time (linear decay when plotted on a dB
scale).
In its simplest form, the suppressor follows actual RMS amplitude
In its simplest form, the deverber follows actual RMS amplitude
attacks but chooses a slower-than-actual decay, then expands
according to the dB distance between the slow and actual decay.
Thus, the suppressor can be used to 'dry out' a very 'wet'
Thus, the deverber can be used to 'dry out' a very 'wet'
reverberative track. */
extern int input_size;
......@@ -51,23 +51,23 @@ typedef struct {
iir_filter smooth;
iir_filter release;
iir_state *iirS[suppress_freqs];
iir_state *iirR[suppress_freqs];
iir_state *iirS[deverb_freqs];
iir_state *iirR[deverb_freqs];
float prevratio[suppress_freqs];
float prevratio[deverb_freqs];
} suppress_state;
} deverb_state;
suppress_settings suppress_channel_set;
static suppress_state channel_state;
deverb_settings deverb_channel_set;
static deverb_state channel_state;
static subband_window sw;
void suppress_reset(){
void deverb_reset(){
int i,j;
subband_reset(&channel_state.ss);
for(i=0;i<suppress_freqs;i++){
for(i=0;i<deverb_freqs;i++){
for(j=0;j<input_ch;j++){
memset(&channel_state.iirS[i][j],0,sizeof(iir_state));
memset(&channel_state.iirR[i][j],0,sizeof(iir_state));
......@@ -96,17 +96,17 @@ static void filter_set(subband_state *ss,
filter->ms=msec;
}
int suppress_load(void){
int deverb_load(void){
int i;
int qblocksize=input_size/16;
memset(&channel_state,0,sizeof(channel_state));
suppress_channel_set.active=calloc(input_ch,sizeof(*suppress_channel_set.active));
deverb_channel_set.active=calloc(input_ch,sizeof(*deverb_channel_set.active));
subband_load(&channel_state.ss,suppress_freqs,qblocksize,input_ch);
subband_load_freqs(&channel_state.ss,&sw,suppress_freq_list,suppress_freqs);
subband_load(&channel_state.ss,deverb_freqs,qblocksize,input_ch);
subband_load_freqs(&channel_state.ss,&sw,deverb_freq_list,deverb_freqs);
for(i=0;i<suppress_freqs;i++){
for(i=0;i<deverb_freqs;i++){
channel_state.iirS[i]=calloc(input_ch,sizeof(iir_state));
channel_state.iirR[i]=calloc(input_ch,sizeof(iir_state));
}
......@@ -134,8 +134,8 @@ static void _analysis(char *base,int seq, float *data, int n,int dB,
}
static void suppress_work_helper(void *vs, suppress_settings *sset){
suppress_state *sss=(suppress_state *)vs;
static void deverb_work_helper(void *vs, deverb_settings *sset){
deverb_state *sss=(deverb_state *)vs;
subband_state *ss=&sss->ss;
int i,j,k,l;
float smoothms=sset->smooth*.1;
......@@ -150,7 +150,7 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){
ahead=impulse_ahead2(smooth->alpha);
for(i=0;i<suppress_freqs;i++){
for(i=0;i<deverb_freqs;i++){
int firstlink=0;
float fast[input_size];
float slow[input_size];
......@@ -192,7 +192,7 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){
compute_iir_symmetric_freefall2(fast, input_size, &sss->iirS[i][j],
smooth);
memcpy(slow,fast,sizeof(slow));
compute_iir_freefall1(slow, input_size, &sss->iirR[i][j],
compute_iir_only_freefall1(slow, input_size, &sss->iirR[i][j],
release);
//_analysis("fast",i,fast,input_size,1,offset);
......@@ -248,11 +248,11 @@ static void suppress_work_helper(void *vs, suppress_settings *sset){
offset+=input_size;
}
static void suppress_work_channel(void *vs){
suppress_work_helper(vs,&suppress_channel_set);
static void deverb_work_channel(void *vs){
deverb_work_helper(vs,&deverb_channel_set);
}
time_linkage *suppress_read_channel(time_linkage *in){
time_linkage *deverb_read_channel(time_linkage *in){
int visible[input_ch];
int active [input_ch];
subband_window *w[input_ch];
......@@ -260,10 +260,10 @@ time_linkage *suppress_read_channel(time_linkage *in){
for(i=0;i<input_ch;i++){
visible[i]=0;
active[i]=suppress_channel_set.active[i];
active[i]=deverb_channel_set.active[i];
w[i]=&sw;
}
return subband_read(in, &channel_state.ss, w, visible, active,
suppress_work_channel, &channel_state);
deverb_work_channel, &channel_state);
}
......@@ -23,17 +23,17 @@
#include "postfish.h"
#define suppress_freqs 8
static const float suppress_freq_list[suppress_freqs+1]={
#define deverb_freqs 8
static const float deverb_freq_list[deverb_freqs+1]={
125,250,500,1000,2000,4000,8000,16000,9e10
};
static char * const suppress_freq_labels[suppress_freqs]={
static char * const deverb_freq_labels[deverb_freqs]={
"125","250","500","1k","2k","4k","8k","16k"
};
typedef struct {
sig_atomic_t ratio[suppress_freqs];
sig_atomic_t ratio[deverb_freqs];
sig_atomic_t smooth;
sig_atomic_t trigger;
sig_atomic_t release;
......@@ -41,11 +41,11 @@ typedef struct {
sig_atomic_t *active;
sig_atomic_t panel_visible;
} suppress_settings;
} deverb_settings;
extern void suppress_reset();
extern int suppress_load(void);
extern time_linkage *suppress_read_channel(time_linkage *in);
extern void deverb_reset();
extern int deverb_load(void);
extern time_linkage *deverb_read_channel(time_linkage *in);
extern suppress_settings suppress_channel_set;
extern deverb_settings deverb_channel_set;
......@@ -29,14 +29,14 @@
#include "mainpanel.h"
#include "subpanel.h"
#include "feedback.h"
#include "suppress.h"
#include "suppresspanel.h"
#include "deverb.h"
#include "deverbpanel.h"
#include "config.h"
typedef struct {
GtkWidget *cslider;
Readout *readoutc;
struct suppress_panel_state *sp;
struct deverb_panel_state *sp;
sig_atomic_t *v;
int number;
} tbar;
......@@ -49,45 +49,45 @@ typedef struct{
sig_atomic_t *v1;
} callback_arg_rv2;
typedef struct suppress_panel_state{
typedef struct deverb_panel_state{
subpanel_generic *panel;
GtkWidget *link;
callback_arg_rv2 timing;
tbar bars[suppress_freqs];
} suppress_panel_state;
tbar bars[deverb_freqs];
} deverb_panel_state;
static suppress_panel_state *channel_panel;
static deverb_panel_state *channel_panel;
void suppresspanel_state_to_config(int bank){
config_set_vector("suppresspanel_active",bank,0,0,0,input_ch,suppress_channel_set.active);
config_set_vector("suppresspanel_ratio",bank,0,0,0,suppress_freqs,suppress_channel_set.ratio);
config_set_integer("suppresspanel_set",bank,0,0,0,0,suppress_channel_set.linkp);
config_set_integer("suppresspanel_set",bank,0,0,0,1,suppress_channel_set.smooth);
config_set_integer("suppresspanel_set",bank,0,0,0,3,suppress_channel_set.release);
void deverbpanel_state_to_config(int bank){
config_set_vector("deverbpanel_active",bank,0,0,0,input_ch,deverb_channel_set.active);
config_set_vector("deverbpanel_ratio",bank,0,0,0,deverb_freqs,deverb_channel_set.ratio);
config_set_integer("deverbpanel_set",bank,0,0,0,0,deverb_channel_set.linkp);
config_set_integer("deverbpanel_set",bank,0,0,0,1,deverb_channel_set.smooth);
config_set_integer("deverbpanel_set",bank,0,0,0,3,deverb_channel_set.release);
}
void suppresspanel_state_from_config(int bank){
void deverbpanel_state_from_config(int bank){
int i;
config_get_vector("suppresspanel_active",bank,0,0,0,input_ch,suppress_channel_set.active);
config_get_vector("deverbpanel_active",bank,0,0,0,input_ch,deverb_channel_set.active);
for(i=0;i<input_ch;i++)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(channel_panel->panel->subpanel_activebutton[i]),
suppress_channel_set.active[i]);
deverb_channel_set.active[i]);
config_get_vector("suppresspanel_ratio",bank,0,0,0,suppress_freqs,suppress_channel_set.ratio);
for(i=0;i<suppress_freqs;i++)
config_get_vector("deverbpanel_ratio",bank,0,0,0,deverb_freqs,deverb_channel_set.ratio);
for(i=0;i<deverb_freqs;i++)
multibar_thumb_set(MULTIBAR(channel_panel->bars[i].cslider),
1000./suppress_channel_set.ratio[i],0);
1000./deverb_channel_set.ratio[i],0);
config_get_sigat("suppresspanel_set",bank,0,0,0,0,&suppress_channel_set.linkp);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(channel_panel->link),suppress_channel_set.linkp);
config_get_sigat("deverbpanel_set",bank,0,0,0,0,&deverb_channel_set.linkp);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(channel_panel->link),deverb_channel_set.linkp);
config_get_sigat("suppresspanel_set",bank,0,0,0,1,&suppress_channel_set.smooth);
multibar_thumb_set(MULTIBAR(channel_panel->timing.s),suppress_channel_set.smooth*.1,0);
config_get_sigat("deverbpanel_set",bank,0,0,0,1,&deverb_channel_set.smooth);
multibar_thumb_set(MULTIBAR(channel_panel->timing.s),deverb_channel_set.smooth*.1,0);
config_get_sigat("suppresspanel_set",bank,0,0,0,3,&suppress_channel_set.release);
multibar_thumb_set(MULTIBAR(channel_panel->timing.s),suppress_channel_set.release*.1,1);
config_get_sigat("deverbpanel_set",bank,0,0,0,3,&deverb_channel_set.release);
multibar_thumb_set(MULTIBAR(channel_panel->timing.s),deverb_channel_set.release*.1,1);
}
static void compand_change(GtkWidget *w,gpointer in){
......@@ -137,14 +137,14 @@ static void timing_change(GtkWidget *w,gpointer in){
*ca->v1=rint(release*10.);
}
static void suppress_link(GtkToggleButton *b,gpointer in){
static void deverb_link(GtkToggleButton *b,gpointer in){
int mode=gtk_toggle_button_get_active(b);
*((sig_atomic_t *)in)=mode;
}
static suppress_panel_state *suppresspanel_create_helper(postfish_mainpanel *mp,
static deverb_panel_state *deverbpanel_create_helper(postfish_mainpanel *mp,
subpanel_generic *panel,
suppress_settings *sset){
deverb_settings *sset){
int i;
float compand_levels[5]={1,1.5,2,3,5};
char *compand_labels[5]={"","1.5","2","3","5"};
......@@ -152,17 +152,17 @@ static suppress_panel_state *suppresspanel_create_helper(postfish_mainpanel *mp,
float timing_levels[5]={1, 10, 100, 1000, 10000};
char *timing_labels[5]={"","10ms"," 100ms","1s","10s"};
GtkWidget *table=gtk_table_new(suppress_freqs+4,4,0);
GtkWidget *timinglabel=gtk_label_new("suppressor filter timing");
GtkWidget *table=gtk_table_new(deverb_freqs+4,4,0);
GtkWidget *timinglabel=gtk_label_new("deverberator filter timing");
GtkWidget *releaselabel=gtk_label_new("release");
GtkWidget *smoothlabel=gtk_label_new("smooth");
GtkWidget *compandlabel=gtk_label_new("suppression depth");
GtkWidget *compandlabel=gtk_label_new("deverb depth");
GtkWidget *linkbutton=
gtk_check_button_new_with_mnemonic("_link channels into single image");
GtkWidget *linkbox=gtk_hbox_new(0,0);
suppress_panel_state *ps=calloc(1,sizeof(suppress_panel_state));
deverb_panel_state *ps=calloc(1,sizeof(deverb_panel_state));
ps->panel=panel;
gtk_container_add(GTK_CONTAINER(panel->subpanel_box),table);
......@@ -186,8 +186,8 @@ static suppress_panel_state *suppresspanel_create_helper(postfish_mainpanel *mp,
GTK_EXPAND|GTK_FILL,
0,5);
if(input_ch>1)
gtk_table_attach(GTK_TABLE(table),linkbox,0,4,suppress_freqs+3,
suppress_freqs+4,GTK_FILL|GTK_EXPAND,0,0,10);
gtk_table_attach(GTK_TABLE(table),linkbox,0,4,deverb_freqs+3,
deverb_freqs+4,GTK_FILL|GTK_EXPAND,0,0,10);
gtk_table_set_row_spacing(GTK_TABLE(table),1,5);
......@@ -201,7 +201,7 @@ static suppress_panel_state *suppresspanel_create_helper(postfish_mainpanel *mp,
gtk_widget_set_name(compandlabel,"framelabel");
g_signal_connect (G_OBJECT (linkbutton), "clicked",
G_CALLBACK (suppress_link), &sset->linkp);
G_CALLBACK (deverb_link), &sset->linkp);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linkbutton),1);
ps->link=linkbutton;
......@@ -232,8 +232,8 @@ static suppress_panel_state *suppresspanel_create_helper(postfish_mainpanel *mp,
/* threshold controls */
for(i=0;i<suppress_freqs;i++){
GtkWidget *label=gtk_label_new(suppress_freq_labels[i]);
for(i=0;i<deverb_freqs;i++){
GtkWidget *label=gtk_label_new(deverb_freq_labels[i]);
gtk_widget_set_name(label,"scalemarker");
ps->bars[i].readoutc=READOUT(readout_new("1.55:1"));
......@@ -260,15 +260,15 @@ static suppress_panel_state *suppresspanel_create_helper(postfish_mainpanel *mp,
return ps;
}
void suppresspanel_create_channel(postfish_mainpanel *mp,
void deverbpanel_create_channel(postfish_mainpanel *mp,
GtkWidget **windowbutton,
GtkWidget **activebutton){
subpanel_generic *panel=subpanel_create(mp,windowbutton[0],activebutton,
suppress_channel_set.active,
&suppress_channel_set.panel_visible,
deverb_channel_set.active,
&deverb_channel_set.panel_visible,
"De_verberation filter",0,
0,input_ch);
channel_panel=suppresspanel_create_helper(mp,panel,&suppress_channel_set);
channel_panel=deverbpanel_create_helper(mp,panel,&deverb_channel_set);
}
......@@ -21,9 +21,9 @@
*
*/
extern void suppresspanel_create_channel(postfish_mainpanel *mp,
extern void deverbpanel_create_channel(postfish_mainpanel *mp,
GtkWidget **windowbutton,
GtkWidget **activebutton);
extern void suppresspanel_state_to_config(int bank);
extern void suppresspanel_state_from_config(int bank);
extern void deverbpanel_state_to_config(int bank);
extern void deverbpanel_state_from_config(int bank);
......@@ -37,7 +37,7 @@
#include "output.h"
#include "declip.h"
#include "eq.h"
#include "suppress.h"
#include "deverb.h"
#include "multicompand.h"
#include "singlecomp.h"
#include "limit.h"
......@@ -336,7 +336,7 @@ int main(int argc, char **argv){
/* set up filter chains */
if(declip_load())exit(1);
if(eq_load(OUTPUT_CHANNELS))exit(1);
if(suppress_load())exit(1);
if(deverb_load())exit(1);
if(multicompand_load(OUTPUT_CHANNELS))exit(1);
if(singlecomp_load(OUTPUT_CHANNELS))exit(1);
if(limit_load(OUTPUT_CHANNELS))exit(1);
......
......@@ -64,7 +64,7 @@ static void mainpanel_state_to_config(int bank){
clippanel_state_to_config(bank);
compandpanel_state_to_config(bank);
singlepanel_state_to_config(bank);
suppresspanel_state_to_config(bank);
deverbpanel_state_to_config(bank);
eqpanel_state_to_config(bank);
reverbpanel_state_to_config(bank);
limitpanel_state_to_config(bank);
......@@ -99,7 +99,7 @@ static void mainpanel_state_from_config(int bank){
clippanel_state_from_config(bank);
compandpanel_state_from_config(bank);
singlepanel_state_from_config(bank);
suppresspanel_state_from_config(bank);
deverbpanel_state_from_config(bank);
eqpanel_state_from_config(bank);
reverbpanel_state_from_config(bank);
limitpanel_state_from_config(bank);
......@@ -1060,7 +1060,7 @@ void mainpanel_create(postfish_mainpanel *panel,char **chlabels){
}
mainpanel_chentry(panel,channeltable,"_Declip ",0,clippanel_create,0);
mainpanel_chentry(panel,channeltable,"De_verb ",1,suppresspanel_create_channel,0);
mainpanel_chentry(panel,channeltable,"De_verb ",1,deverbpanel_create_channel,0);
mainpanel_chentry(panel,channeltable,"_Multicomp ",2,0,compandpanel_create_channel);
mainpanel_chentry(panel,channeltable,"_Singlecomp ",3,0,singlepanel_create_channel);
mainpanel_chentry(panel,channeltable,"_EQ ",4,0,eqpanel_create_channel);
......
......@@ -30,7 +30,7 @@ typedef struct postfish_mainpanel postfish_mainpanel;
#include "eqpanel.h"
#include "compandpanel.h"
#include "singlepanel.h"
#include "suppresspanel.h"
#include "deverbpanel.h"
#include "limitpanel.h"
#include "mixpanel.h"
#include "reverbpanel.h"
......
......@@ -25,11 +25,24 @@
#include "postfish.h"
#include "mix.h"
#include "mute.h"
#include "window.h"
extern int input_ch;
extern sig_atomic_t *mixpanel_active;
typedef struct {
u_int32_t active_prev;
int active_ch;
int init_state;
float *leftwindow;
} mute_state;
static mute_state channel_state;
int mute_load(void){
memset(&channel_state,0,sizeof(channel_state));
channel_state.active_ch=input_ch;
channel_state.leftwindow=window_get(1,input_size);
return 0;
}
......@@ -38,13 +51,45 @@ int mute_channel_muted(u_int32_t active,int i){
}
time_linkage *mute_read(time_linkage *in){
u_int32_t val=0;
int i;
u_int32_t preval=0,retval=0;
int i,j;
if(!channel_state.init_state)
channel_state.active_prev=in->active;
/* the mute module is responsible for smoothly ramping audio levels
to/from zero and unity upon mute state change */
for(i=0;i<input_ch;i++)
if(mixpanel_active[i])
val|= (1<<i);
preval|= (1<<i);
/* the mute module is responsible for smoothly ramping audio levels
to/from zero and unity upon mute state change */
for(i=0;i<input_ch;i++){
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++)
x[j]*=channel_state.leftwindow[j];
}
}else{
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];
}
}
}
in->active=val;
in->active=retval;
channel_state.active_prev=preval;
return(in);
}
......@@ -32,7 +32,7 @@
#include "eq.h"
#include "multicompand.h"
#include "singlecomp.h"
#include "suppress.h"
#include "deverb.h"
#include "limit.h"
#include "mute.h"
#include "mix.h"
......@@ -67,7 +67,7 @@ void pipeline_reset(){
eq_reset(); /* clear any persistent lapping state */
multicompand_reset(); /* clear any persistent lapping state */
singlecomp_reset(); /* clear any persistent lapping state */
suppress_reset(); /* clear any persistent lapping state */
deverb_reset(); /* clear any persistent lapping state */
limit_reset(); /* clear any persistent lapping state */
output_reset(); /* clear any persistent lapping state */
mix_reset();
......@@ -833,7 +833,7 @@ void *playback_thread(void *dummy){
result|=link->samples;
link=declip_read(link);
result|=link->samples;
link=suppress_read_channel(link);
link=deverb_read_channel(link);
result|=link->samples;
link=multicompand_read_channel(link);
result|=link->samples;
......
......@@ -50,6 +50,20 @@
#include <signal.h>
#include <fcntl.h>
#if 0
extern void ef_free(void * address);
extern void *ef_realloc(void * oldBuffer, size_t newSize);
extern void *ef_malloc(size_t size);
extern void *ef_calloc(size_t nelem, size_t elsize);
extern void *ef_valloc (size_t size);
#define free ef_free
#define realloc ef_realloc
#define malloc ef_malloc
#define calloc ef_calloc
#define valloc ef_valloc
#endif
#define OUTPUT_CHANNELS 8 // UI code assumes this is <=8
#define MAX_INPUT_CHANNELS 32 // engine code requires <= 32
......
#define VERSION "$Id$ "
/* DO NOT EDIT: Automated versioning hack [Thu Sep 16 00:53:42 EDT 2004] */
/* DO NOT EDIT: Automated versioning hack [Sat Sep 25 00:44:50 EDT 2004] */
/*
*
* postfish
*
* Copyright (C) 2002-2004 Monty and Xiph.Org
*
* Postfish is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* Postfish is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
#include "postfish.h"
#include "window.h"
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,
2048,4096,8192,16384,32768,65536 */
/* type is one of 0==sin(x),
1==sin(x)^2,
2==sin(sin(x)^2),
3==sin(sin(x)^2)^2 */
/* returns quarter-cycle (left half) n+1 samples of a window from 0. to 1. */
static int ilog(long x){
int ret=-1;
while(x>0){
x>>=1;
ret++;
}
return ret;
}
float *window_get(int type,int n){
int bits=ilog(n),i;
if((1<<bits)!=n)return 0;
if(bits<0)return 0;
if(bits>=17)return 0;
if(type<0)return 0;
if(type>3)return 0;
if(!window_func)
window_func=calloc(4,sizeof(*window_func));
if(!window_func[type])
window_func[type]=calloc(17,sizeof(**window_func));
if(!window_func[type][bits]){
window_func[type][bits]=malloc((n+1)*sizeof(***window_func));
for(i=0;i<n+1;i++)window_func[type][bits][i]=sin(M_PIl*.5*i/n);
if(type>0)
for(i=0;i<n+1;i++)window_func[type][bits][i]*=
window_func[type][bits][i];
if(type>1)
for(i=0;i<n+1;i++)window_func[type][bits][i]=
sin(window_func[type][bits][i]*M_PIl*.5);
if(type>2)
for(i=0;i<n+1;i++)window_func[type][bits][i]*=
window_func[type][bits][i];
}
return window_func[type][bits];
}
/*
*
* postfish
*
* Copyright (C) 2002-2004 Monty and Xiph.Org
*
* Postfish is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* Postfish is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Postfish; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
*/
extern float *window_get(int type,int n);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment