From 32e228d1ca60d479025f5c10479ac866208e11ae Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 27 Aug 2008 22:27:30 +0000 Subject: merged in relevant changes from the v0-40 pd-extended release branch svn path=/trunk/externals/creb/; revision=10266 --- modules/bwin~.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 modules/bwin~.c (limited to 'modules/bwin~.c') diff --git a/modules/bwin~.c b/modules/bwin~.c new file mode 100644 index 0000000..90a9e2a --- /dev/null +++ b/modules/bwin~.c @@ -0,0 +1,171 @@ +/* + * window.c - window generation abstraction + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program 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 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "m_pd.h" +#include +#include + + +static t_class *window_class; + +typedef struct _window +{ + t_object x_obj; + t_float x_f; + t_float *x_window; + t_int x_size; + t_symbol *x_type; + t_float x_typearg; + +} t_window; + +static t_int *window_perform(t_int *w) +{ + t_window *x = (t_window *)(w[1]); + t_float *in = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + t_float *window = x->x_window; + int n = (int)(w[4]); + while (n--) + { + *out++ = (*in++) * (*window++); + } + return (w+5); +} + +static void window_size(t_window *x, t_int n) +{ + if (x->x_size != n){ + if (x->x_window) free(x->x_window); + x->x_window = malloc(sizeof(float)*n); + x->x_size = n; + } +} + + +static void window_type(t_window *x, t_symbol *s, t_float f) +{ + int i; + float a = 0; + float a_inc = 2 * M_PI / (float)(x->x_size); + if (!s) s = gensym("hamming"); + if (s == gensym("hamming")){ + for (i=0; ix_size; i++){ + float c = cos(a); + x->x_window[i] = (0.54 - 0.46 * c); + a += a_inc; + } + } + else if (s == gensym("hann")){ + for (i=0; ix_size; i++){ + float c = cos(a); + x->x_window[i] = (0.5 - 0.5 * c); + a += a_inc; + } + } + else if (s == gensym("hann/hamming")){ + for (i=0; ix_size; i++) { + float c = cos(a); + x->x_window[i] = (0.5 - 0.5 * c) / (0.54 - 0.46 * c); + a += a_inc; + } + } + else if (s == gensym("bfft_pink")){ + x->x_window[0] = 1.0f; //DC + x->x_window[1] = 1.0f / sqrt((double)(x->x_size>>1)); //NY + for (i=2; ix_size; i+=2) { + double freq = (double)(i>>1); + float amp = sqrt(1.0 / freq); + x->x_window[i] = amp; + x->x_window[i+1] = amp; + } + } + else if (s == gensym("bfft_blue")){ + x->x_window[0] = 1.0f; //DC + x->x_window[1] = sqrt((double)(x->x_size>>1)); //NY + for (i=2; ix_size; i+=2) { + double freq = (double)(i>>1); + float amp = sqrt(freq); + x->x_window[i] = amp; + x->x_window[i+1] = amp; + } + } + else if (s == gensym("bfft_db/octave")){ + float power = f/6.0; + x->x_window[0] = 1.0f; //DC + x->x_window[1] = pow((double)(x->x_size>>1), power); //NY + for (i=2; ix_size; i+=2) { + double freq = (double)(i>>1); + float amp = pow(freq, power); + x->x_window[i] = amp; + x->x_window[i+1] = amp; + } + } + + + /* default is no window */ + else{ + post("bwin~: unknown window type, using rectangular"); + for (i=0; ix_size; i++) x->x_window[i] = 1.0f; + } + + x->x_type = s; + x->x_typearg = f; + +} + +static void window_dsp(t_window *x, t_signal **sp) +{ + int n = sp[0]->s_n; + if (x->x_size != n){ + window_size(x, n); + window_type(x, x->x_type, x->x_typearg); + } + + dsp_add(window_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, n); +} + +static void window_free(t_window *x) +{ + free(x->x_window); +} + + +static void *window_new(t_symbol *s) +{ + t_window *x = (t_window *)pd_new(window_class); + outlet_new(&x->x_obj, &s_signal); + x->x_window = 0; + window_size(x, 64); + window_type(x, s, 0); + return (x); +} + +void bwin_tilde_setup(void) +{ + window_class = class_new(gensym("bwin~"), + (t_newmethod)window_new, (t_method)window_free, + sizeof(t_window), 0, A_DEFSYMBOL, A_NULL); + CLASS_MAINSIGNALIN(window_class, t_window, x_f); + class_addmethod(window_class, (t_method)window_dsp, + gensym("dsp"), A_NULL); + class_addmethod(window_class, (t_method)window_type, + gensym("type"), A_SYMBOL, A_DEFFLOAT, A_NULL); +} + -- cgit v1.2.1