[PD] convolution stuff

J. Scott Hildebrand jshildebrand at ucdavis.edu
Mon Sep 9 21:58:56 CEST 2002


       i think this is really close to working, but i need a little bit of
help figuring some things out. marius schebella is responsible for the
majority of the pd patch and it seems to be working pretty well. my
external overlap~.c basically just takes the filters from a .bin file and
sends them out to be used in the convolution. before i had

  outlet_new(&x->x_obj, &s_signal);
  outlet_new(&x->x_obj, &s_signal);

but then i changed them to &s_float because pd didn't like me sending
signal outputs to an array. anyway i again have a seg fault but i've
narrowed it down to my external so if anybody can help me out, i think
that this convolution patch will be useful for a lot of people. you can
use any wav file you want, and if you'd like the hrir.bin with all of the
2500 different filters that my external uses, let me know and i'll email
it to you. it's only 2MB.

                                     thanks,

                                                  scott



--------------------------------------------------------------------

	"640K ought to be enough for anybody." -- Bill Gates, 1981

--------------------------------------------------------------------
-------------- next part --------------
#N canvas 697 212 552 475 10;
#X text 2 174 any input signal you want -->;
#N canvas 16 502 667 475 fft-convolution 1;
#N canvas 20 100 450 300 graph1 0;
#X graph graph1 0 -1 511 1 100 160 612 20;
#X array array1 512 float 1;
#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0;
#X pop;
#X restore 556 83 graph;
#X obj 71 147 tabreceive~ array1;
#X text 89 65 overlap of 2 means that after 128 samples another routine
is started and at the outlet added...;
#X text 551 199 don't worry \, the display is only renewed maybe every
second \, but the content actually changes every 128 samples (2.8 ms)
;
#X obj 71 176 rfft~;
#X obj 71 431 outlet~;
#X obj 71 237 *~;
#X obj 96 237 *~;
#X obj 230 178 rfft~;
#X obj 230 239 *~;
#X obj 255 239 *~;
#X obj 230 147 tabreceive~ filter;
#X obj 71 377 rifft~;
#X text 313 243 convolution;
#X text 317 314 normalize;
#N canvas 729 80 450 300 graph2 0;
#X graph graph2 0 -1 511 1 100 160 612 20;
#X array filter 512 float 1;
#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.328571 -0.321429 -0.314286
-0.307143 -0.3 -0.295238 -0.290476 -0.285714 -0.280952 -0.27619 -0.271429
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -0.671429 -0.642857 -0.628571
-0.6 -0.557143 -0.5 -0.471429 -0.428571 -0.371429 -0.314286 -0.285714
-0.271429 -0.271429 -0.257143 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0.0857143 0.0714286 0.0571429 0.0428571 0.0285714 0 -0.0285714 -0.0571429
-0.1 -0.142857 -0.171429 -0.192857 -0.214286 -0.235714 -0.257143 -0.3
-0.342857 -0.385714 -0.428571 -0.442857 -0.457143 -0.471429 -0.485714
-0.514286 -0.542857 -0.571429 -0.585714 -0.585714 -0.614286 -0.628571
-0.628571 -0.628571 -0.628571 -0.628571 -0.628571 -0.614286 -0.6 -0.592857
-0.585714 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
#X pop;
#X restore 555 294 graph;
#X obj 71 270 -~;
#X obj 230 271 +~;
#X obj 101 35 block~ 512 2;
#X obj 71 319 /~ 65536;
#X obj 230 315 /~ 65536;
#X connect 1 0 4 0;
#X connect 4 0 6 0;
#X connect 4 0 10 1;
#X connect 4 1 7 0;
#X connect 4 1 9 1;
#X connect 6 0 16 0;
#X connect 7 0 16 1;
#X connect 8 0 9 0;
#X connect 8 0 6 1;
#X connect 8 1 10 0;
#X connect 8 1 7 1;
#X connect 9 0 17 0;
#X connect 10 0 17 1;
#X connect 11 0 8 0;
#X connect 12 0 5 0;
#X connect 16 0 19 0;
#X connect 17 0 20 0;
#X connect 19 0 12 0;
#X connect 20 0 12 1;
#X restore 235 294 pd fft-convolution;
#X obj 289 366 dac~;
#N canvas 4 20 450 300 graph3 0;
#X restore 475 -91 graph;
#X msg 674 94 \; filterarray const 0;
#X obj 67 343 tabwrite~ input;
#X obj 235 326 tabwrite~ output;
#N canvas 0 0 450 300 graph4 0;
#X restore 556 220 graph;
#N canvas 8 40 450 300 graph4 0;
#X restore 556 326 graph;
#X msg 48 237 bang;
#X obj 67 293 delwrite~ calctime 10;
#X obj 67 316 delread~ calctime 3;
#X text 85 235 compare input with output signal;
#X text 359 294 <-- filter;
#X msg 290 -1 open archim20.WAV;
#X msg 205 31 0;
#X msg 246 31 1;
#X obj 255 112 readsf~;
#X obj 242 -28 t b b;
#X obj 191 -57 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1
-1;
#N canvas 12 23 668 378 split_in_256_sample_slices 1;
#X obj 55 -26 inlet~;
#X obj 55 13 tabsend~ array1;
#X obj 71 279 tabsend~ filter;
#X text 182 278 the same with the filter;
#X obj 191 -26 block~ 256;
#X text 34 52 sends portions of 256 samples to "array1" (which is located
in "pd fft-convolution");
#X text 33 95 array1 is 512 samples long \, so the rest stays 0;
#X obj 71 254 tabreceive~ filterarray;
#X obj 189 142 hsl 128 15 1 25 0 0 empty empty empty 20 8 0 8 -260818
-1 -1 4100 1;
#X obj 189 175 hsl 128 15 1 50 0 0 empty empty empty 20 8 0 8 -44926
-1 -1 4000 1;
#X obj 87 214 overlap~;
#X text 330 140 azimuth;
#X text 330 173 elevation;
#X graph graph4 0 -1 255 1 521 221 777 81;
#X array filterarray 256 float 1;
#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
#X pop;
#X connect 0 0 1 0;
#X connect 7 0 2 0;
#X connect 8 0 10 2;
#X connect 9 0 10 3;
#X restore 221 173 pd split_in_256_sample_slices;
#X graph graph6 0 -1 63 1 85 542 285 402;
#X array input 64 float 1;
#A 0 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714 0.0285714
0.0285714 0.0142857 0 0 -0.0142857 -0.0142857 -0.0142857 -0.0142857
-0.0142857 -0.0142857 0 0 0.0142857 0.0142857 0.0142857 0.0285714 0.0285714
0.0285714 0.0285714 0.0285714 0.0428571 0.0428571 0.0428571 0.0428571
0.0428571 0.0428571 0.0428571 0.0428571 0.0428571 0.0428571 0.0428571
0.0428571 0.0428571 0.0428571 0.0428571 0.0428571 0.0428571 0.0428571
0.0428571 0.0428571 0.0428571 0.0428571 0.0428571 0.0428571 0.0285714
0.0285714 0.0285714 0.0285714 0.0428571 0.0571429 0.0571429 0.0571429
0.0571429 0.0714286 0.0714286 0.0714286 0.1;
#X pop;
#X graph graph7 0 -1 63 1 351 541 551 401;
#X array output 64 float 1;
#A 0 0.114286 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1
0.1 0.1 0.1 0.1 0.1 0.1 0.0857143 0.0857143 0.0857143 0.0714286 0.0714286
0.0714286 0.0714286 0.0714286 0.0714286 0.0714286 0.0714286 0.0714286
0.0714286 0.0714286 0.0714286 0.0857143 0.0857143 0.0857143 0.1 0.1
0.1 0.114286 0.114286 0.114286 0.114286 0.114286 0.114286 0.114286
0.114286 0.114286 0.114286 0.114286 0.114286 0.114286 0.114286 0.128571
0.128571 0.128571 0.142857 0.157143 0.171429 0.171429 0.157143;
#X pop;
#X connect 1 0 6 0;
#X connect 1 0 2 0;
#X connect 9 0 5 0;
#X connect 9 0 6 0;
#X connect 11 0 5 0;
#X connect 14 0 17 0;
#X connect 15 0 17 0;
#X connect 16 0 17 0;
#X connect 17 0 20 0;
#X connect 17 0 10 0;
#X connect 18 0 16 0;
#X connect 18 1 14 0;
#X connect 19 0 18 0;
-------------- next part --------------
#include "m_pd.h"
#include <stdio.h>

static float bhrir_l[25][50][256];
static float bhrir_r[25][50][256];


static void readfile(void)
{
t_int az, el, i;
	
FILE *fid;
fid = fopen("hrir.bin", "r");               
for(az=0; az<=24; az++)
{
   for(el=0; el<=49; el++)  /*takes from hrir.bin all hrtfs and arrays them*/
   {                                          
	   fread(bhrir_l[az][el], sizeof(float), 200, fid);
           	for(i=200; i<=255; i++){bhrir_l[az][el][i]=0;}  /*adds 56 zeroes*/
	   fread(bhrir_r[az][el], sizeof(float), 200, fid);
           	for(i=200; i<=255; i++){bhrir_r[az][el][i]=0;}

   }
}

}




static t_class *overlap_tilde_class;

typedef struct _overlap_tilde {
  t_object  x_obj;
  t_sample f_overlap;
  t_sample f;
  t_int apple;
  t_float secondfloat;
  t_float firstfloat;
} t_overlap_tilde;

t_int *overlap_tilde_perform(t_int *w)
{
  t_overlap_tilde *x = (t_overlap_tilde *)(w[1]);
  t_float  *in1 =    (t_float *)(w[2]);
  t_float  *in2 =    (t_float *)(w[3]);
  t_float  *out1 =    (t_float *)(w[4]);
  t_float  *out2 =    (t_float *)(w[5]);

  int         n =           (int)(w[6]);

  int         i;
 
  t_int     read;
  t_int     azi;
  t_int     ele;
  t_int	    readpos;

      azi = (x->firstfloat - 1);
      ele = (x->secondfloat - 1);

	
   for(readpos=0; readpos<256; readpos++)
   {
	   *(out2++) = bhrir_l[azi][ele][readpos];
	   *(out1++) = bhrir_r[azi][ele][readpos];
   }


	   
  return (w+7);
} // endperform

void overlap_tilde_dsp(t_overlap_tilde *x, t_signal **sp)
{
  dsp_add(overlap_tilde_perform, 6, x,
          sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n);
}


static void overlap_first(t_overlap_tilde *x, t_floatarg f)
{
	x->firstfloat = f;
	post("firstfloat is: %f", x->firstfloat);
}

static void overlap_bound(t_overlap_tilde *x, t_floatarg f)
{
	x->secondfloat = f;
	post("secondfloat is: %f", x->secondfloat);
}


void *overlap_tilde_new(t_floatarg f)
{
  t_overlap_tilde *x = (t_overlap_tilde *)pd_new(overlap_tilde_class);

  x->f_overlap = f;
  
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("first"));
  inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("bound"));
  outlet_new(&x->x_obj, &s_float);

  outlet_new(&x->x_obj, &s_float);	/* second outlet for stereo */


  
  return (void *)x;
}

void overlap_tilde_setup(void) {
  overlap_tilde_class = class_new(gensym("overlap~"),
        (t_newmethod)overlap_tilde_new,
        0, sizeof(t_overlap_tilde),
        CLASS_DEFAULT, 
        A_DEFFLOAT, 0);

  class_addmethod(overlap_tilde_class,(t_method)overlap_tilde_dsp, gensym("dsp"), 0);
  class_addmethod(overlap_tilde_class, (t_method)overlap_first, gensym("first"), A_FLOAT, 0);	
  class_addmethod(overlap_tilde_class, (t_method)overlap_bound, gensym("bound"), A_FLOAT, 0);
  CLASS_MAINSIGNALIN(overlap_tilde_class, t_overlap_tilde, f);
}



More information about the Pd-list mailing list