From a63b9787cf2a0c188d6e923bcd033c1e3c23a424 Mon Sep 17 00:00:00 2001 From: musil Date: Thu, 30 Nov 2006 14:57:40 +0000 Subject: initial commit changed float to t_float -fno-strict-aliasing #pragma obsolete help-*.pd to *-help.pd svn path=/trunk/externals/iem/iem_roomsim/; revision=6544 --- src/cart2del_damp_2d.c | 388 +++++++++++++++++++ src/cart2del_damp_3d.c | 582 +++++++++++++++++++++++++++++ src/early_reflections_2d.c | 536 +++++++++++++++++++++++++++ src/early_reflections_3d.c | 902 +++++++++++++++++++++++++++++++++++++++++++++ src/iem_roomsim.c | 34 ++ src/iem_roomsim.dsp | 85 +++++ src/iem_roomsim.dsw | 29 ++ src/iemlib.h | 102 +++++ src/makefile | 50 +++ src/makefile_linux | 50 +++ src/makefile_win | 41 +++ 11 files changed, 2799 insertions(+) create mode 100644 src/cart2del_damp_2d.c create mode 100644 src/cart2del_damp_3d.c create mode 100644 src/early_reflections_2d.c create mode 100644 src/early_reflections_3d.c create mode 100644 src/iem_roomsim.c create mode 100644 src/iem_roomsim.dsp create mode 100644 src/iem_roomsim.dsw create mode 100644 src/iemlib.h create mode 100644 src/makefile create mode 100644 src/makefile_linux create mode 100644 src/makefile_win (limited to 'src') diff --git a/src/cart2del_damp_2d.c b/src/cart2del_damp_2d.c new file mode 100644 index 0000000..a092e73 --- /dev/null +++ b/src/cart2del_damp_2d.c @@ -0,0 +1,388 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_roomsim written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2006 */ + +#include "m_pd.h" +#include "iemlib.h" +#include + + +/* -------------------------- cart2del_damp_2d ------------------------------ */ +/* +** pos. x-Richtung Nase +** pos. y-Richtung Linke Hand +** pos. z-Richtung Scheitel +** Kartesischer Koordinaten-Ursprung liegt in der Mitte des Raums am Boden + + aenderungen: src-index von 1 .. n auf 0 .. (n-1) + aenderungen: azimuth von rad auf degree +*/ + +/* +Reihenfolge der bundle-sektoren: index phi: + + + 1 0 + 2 45 + 3 90 + 4 135 + 5 180 + 6 225 + 7 270 + 8 315 + + 1. und 2. reflexionen: + + + +x + 5 + 9 1 11 ++y 6 2 0 4 8 + 12 3 10 + 7 + +*/ + + + +typedef struct _cart2del_damp_2d +{ + t_object x_obj; + t_symbol *x_s_direct; + t_symbol *x_s_early1; + t_symbol *x_s_early2; + t_symbol *x_s_del; + t_symbol *x_s_damp; + t_symbol *x_s_index_phi; + t_float x_room_x; + t_float x_room_y; + t_float x_head_x; + t_float x_head_y; + t_float x_src_x; + t_float x_src_y; + t_float x_r_ambi; + t_float x_speed; + t_float x_180_over_pi; + void *x_clock; +} t_cart2del_damp_2d; + +static t_class *cart2del_damp_2d_class; + +static t_float cart2del_damp_2d_calc_radius(t_floatarg r_ambi, t_floatarg dx, t_floatarg dy) +{ + t_float r = (t_float)sqrt(dx*dx + dy*dy); + + if(r < r_ambi) + return(r_ambi); + else + return(r); +} + +static t_float cart2del_damp_2d_calc_azimuth(t_floatarg x_180_over_pi, t_floatarg dx, t_floatarg dy)/*changes*/ +{ + if(dx == 0.0f) + { + if(dy < 0.0f) + return(270.0f); + else + return(90.0f); + } + else if(dx < 0.0f) + { + return(180.0f + x_180_over_pi * (t_float)atan(dy / dx)); + } + else + { + if(dy < 0.0f) + return(360.0f + x_180_over_pi * (t_float)atan(dy / dx)); + else + return(x_180_over_pi * (t_float)atan(dy / dx)); + } +} + +static void cart2del_damp_2d_doit(t_cart2del_damp_2d *x) +{ + t_float diff_x, diff_y; + t_float sum_x, sum_y; + t_float lx, wy; + t_float x0, y0; + t_float xp1, yp1; + t_float xn1, yn1; + t_float xp2, yp2; + t_float xn2, yn2; + t_float m2ms = 1000.0f / x->x_speed; + t_float x_180_over_pi=x->x_180_over_pi; + t_float r_ambi = x->x_r_ambi; + t_float rad[20]; + t_atom at[20]; + + lx = x->x_room_x; + wy = x->x_room_y; + + diff_x = x->x_src_x - x->x_head_x; + diff_y = x->x_src_y - x->x_head_y; + sum_x = x->x_src_x + x->x_head_x; + sum_y = x->x_src_y + x->x_head_y; + + x0 = diff_x; + y0 = diff_y; + xp1 = lx - sum_x; + yp1 = wy - sum_y; + xn1 = -lx - sum_x; + yn1 = -wy - sum_y; + xp2 = 2.0f*lx + diff_x; + yp2 = 2.0f*wy + diff_y; + xn2 = -2.0f*lx + diff_x; + yn2 = -2.0f*wy + diff_y; + + rad[0] = cart2del_damp_2d_calc_radius(r_ambi, x0, y0); + rad[1] = cart2del_damp_2d_calc_radius(r_ambi, xp1, y0); + rad[2] = cart2del_damp_2d_calc_radius(r_ambi, x0, yp1); + rad[3] = cart2del_damp_2d_calc_radius(r_ambi, xn1, y0); + rad[4] = cart2del_damp_2d_calc_radius(r_ambi, x0, yn1); + rad[5] = cart2del_damp_2d_calc_radius(r_ambi, xp2, y0); + rad[6] = cart2del_damp_2d_calc_radius(r_ambi, x0, yp2); + rad[7] = cart2del_damp_2d_calc_radius(r_ambi, xn2, y0); + rad[8] = cart2del_damp_2d_calc_radius(r_ambi, x0, yn2); + rad[9] = cart2del_damp_2d_calc_radius(r_ambi, xp1, yp1); + rad[10] = cart2del_damp_2d_calc_radius(r_ambi, xn1, yn1); + rad[11] = cart2del_damp_2d_calc_radius(r_ambi, xp1, yn1); + rad[12] = cart2del_damp_2d_calc_radius(r_ambi, xn1, yp1); + + /* delay-reihenfolge: 0, + +1x, +1y, -1x, -1y + +2x, +2y, -2x, -2y + +1x+1y, -1x-1y + +1x-1y, -1x+1y + */ + + SETSYMBOL(at, x->x_s_del); + + SETFLOAT(at+1, rad[0] * m2ms); + outlet_anything(x->x_obj.ob_outlet, x->x_s_direct, 2, at); + + SETFLOAT(at+1, rad[1] *m2ms); + SETFLOAT(at+2, rad[2] *m2ms); + SETFLOAT(at+3, rad[3] *m2ms); + SETFLOAT(at+4, rad[4] *m2ms); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 5, at); + + SETFLOAT(at+1, rad[5] *m2ms); + SETFLOAT(at+2, rad[6] *m2ms); + SETFLOAT(at+3, rad[7] *m2ms); + SETFLOAT(at+4, rad[8] *m2ms); + SETFLOAT(at+5, rad[9] *m2ms); + SETFLOAT(at+6, rad[10] *m2ms); + SETFLOAT(at+7, rad[11] *m2ms); + SETFLOAT(at+8, rad[12] *m2ms); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 9, at); + + + /* daempfungs-reihenfolge: + 0, + +1x, +1y, -1x, -1y + +2x, +2y, -2x, -2y + +1x+1y, -1x-1y + +1x-1y, -1x+1y + */ + + SETSYMBOL(at, x->x_s_damp); + + SETFLOAT(at+1, r_ambi / rad[0]); + outlet_anything(x->x_obj.ob_outlet, x->x_s_direct, 2, at); + + SETFLOAT(at+1, r_ambi / rad[1]); + SETFLOAT(at+2, r_ambi / rad[2]); + SETFLOAT(at+3, r_ambi / rad[3]); + SETFLOAT(at+4, r_ambi / rad[4]); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 5, at); + + SETFLOAT(at+1, r_ambi / rad[5]); + SETFLOAT(at+2, r_ambi / rad[6]); + SETFLOAT(at+3, r_ambi / rad[7]); + SETFLOAT(at+4, r_ambi / rad[8]); + SETFLOAT(at+5, r_ambi / rad[9]); + SETFLOAT(at+6, r_ambi / rad[10]); + SETFLOAT(at+7, r_ambi / rad[11]); + SETFLOAT(at+8, r_ambi / rad[12]); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 9, at); + + + /* encoder-winkel-reihenfolge: index delta phi + 0, + +1x, +1y, -1x, -1y + +2x, +2y, -2x, -2y + +1x+1y, -1x-1y + +1x-1y, -1x+1y + */ + + SETSYMBOL(at, x->x_s_index_phi); + + SETFLOAT(at+1, 1.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, x0, y0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_direct, 3, at); + + + SETFLOAT(at+1, 1.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, xp1, y0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 3, at); + + SETFLOAT(at+1, 2.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, x0, yp1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 3, at); + + SETFLOAT(at+1, 3.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, xn1, y0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 3, at); + + SETFLOAT(at+1, 4.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, x0, yn1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 3, at); + + + SETFLOAT(at+1, 1.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, xp2, y0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 3, at); + + SETFLOAT(at+1, 2.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, x0, yp2)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 3, at); + + SETFLOAT(at+1, 3.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, xn2, y0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 3, at); + + SETFLOAT(at+1, 4.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, x0, yn2)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 3, at); + + SETFLOAT(at+1, 5.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, xp1, yp1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 3, at); + + SETFLOAT(at+1, 6.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, xn1, yn1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 3, at); + + SETFLOAT(at+1, 7.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, xp1, yn1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 3, at); + + SETFLOAT(at+1, 8.0f); + SETFLOAT(at+2, cart2del_damp_2d_calc_azimuth(x_180_over_pi, xn1, yp1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 3, at); +} + +static void cart2del_damp_2d_src_xy(t_cart2del_damp_2d *x, t_symbol *s, int argc, t_atom *argv) +{ + if((argc >= 2)&&IS_A_FLOAT(argv, 0)&&IS_A_FLOAT(argv, 1)) + { + t_float xr2=0.5f*x->x_room_x, yr2=0.5f*x->x_room_y; + + x->x_src_x = atom_getfloat(argv++); + x->x_src_y = atom_getfloat(argv); + if(x->x_src_x > xr2) + x->x_src_x = xr2; + if(x->x_src_x < -xr2) + x->x_src_x = -xr2; + if(x->x_src_y > yr2) + x->x_src_y = yr2; + if(x->x_src_y < -yr2) + x->x_src_y = -yr2; + clock_delay(x->x_clock, 0.0f); + } +} + +static void cart2del_damp_2d_head_xy(t_cart2del_damp_2d *x, t_symbol *s, int argc, t_atom *argv) +{ + if((argc >= 2)&&IS_A_FLOAT(argv, 0)&&IS_A_FLOAT(argv, 1)) + { + t_float xr2=0.5f*x->x_room_x, yr2=0.5f*x->x_room_y; + + x->x_head_x = atom_getfloat(argv++); + x->x_head_y = atom_getfloat(argv); + if(x->x_head_x > xr2) + x->x_head_x = xr2; + if(x->x_head_x < -xr2) + x->x_head_x = -xr2; + if(x->x_head_y > yr2) + x->x_head_y = yr2; + if(x->x_head_y < -yr2) + x->x_head_y = -yr2; + clock_delay(x->x_clock, 0.0f); + } +} + +static void cart2del_damp_2d_room_dim(t_cart2del_damp_2d *x, t_symbol *s, int argc, t_atom *argv) +{ + if((argc >= 2)&&IS_A_FLOAT(argv, 0)&&IS_A_FLOAT(argv, 1)) + { + x->x_room_x = atom_getfloat(argv++); + x->x_room_y = atom_getfloat(argv); + if(x->x_room_x < 0.5f) + x->x_room_x = 0.5f; + if(x->x_room_y < 0.5f) + x->x_room_y = 0.5f; + clock_delay(x->x_clock, 0.0f); + } +} + +static void cart2del_damp_2d_r_ambi(t_cart2del_damp_2d *x, t_floatarg r_ambi) +{ + if(r_ambi < 0.1f) + r_ambi = 0.1f; + x->x_r_ambi = r_ambi; + clock_delay(x->x_clock, 0.0f); +} + +static void cart2del_damp_2d_sonic_speed(t_cart2del_damp_2d *x, t_floatarg speed) +{ + if(speed < 10.0f) + speed = 10.0f; + if(speed > 2000.0f) + speed = 2000.0f; + x->x_speed = speed; + clock_delay(x->x_clock, 0.0f); +} + +static void cart2del_damp_2d_free(t_cart2del_damp_2d *x) +{ + clock_free(x->x_clock); +} + +static void *cart2del_damp_2d_new(t_symbol *s, int argc, t_atom *argv) +{ + t_cart2del_damp_2d *x = (t_cart2del_damp_2d *)pd_new(cart2del_damp_2d_class); + + x->x_room_x = 12.0f; + x->x_room_y = 8.0f; + x->x_head_x = 0.0f; + x->x_head_y = 0.0f; + x->x_src_x = 3.0f; + x->x_src_y = 0.5f; + x->x_r_ambi = 1.4f; + x->x_speed = 340.0f; + x->x_s_direct = gensym("direct"); + x->x_s_early1 = gensym("early1"); + x->x_s_early2 = gensym("early2"); + x->x_s_damp = gensym("damp"); + x->x_s_del = gensym("del"); + x->x_s_index_phi = gensym("index_phi"); + outlet_new(&x->x_obj, &s_list); + x->x_clock = clock_new(x, (t_method)cart2del_damp_2d_doit); + x->x_180_over_pi = (t_float)(180.0 / (4.0 * atan(1.0))); + return (x); +} + +void cart2del_damp_2d_setup(void) +{ + cart2del_damp_2d_class = class_new(gensym("cart2del_damp_2d"), (t_newmethod)cart2del_damp_2d_new, (t_method)cart2del_damp_2d_free, + sizeof(t_cart2del_damp_2d), 0, A_GIMME, 0); + class_addmethod(cart2del_damp_2d_class, (t_method)cart2del_damp_2d_src_xy, gensym("src_xy"), A_GIMME, 0); + class_addmethod(cart2del_damp_2d_class, (t_method)cart2del_damp_2d_head_xy, gensym("head_xy"), A_GIMME, 0); + class_addmethod(cart2del_damp_2d_class, (t_method)cart2del_damp_2d_room_dim, gensym("room_dim"), A_GIMME, 0); + class_addmethod(cart2del_damp_2d_class, (t_method)cart2del_damp_2d_sonic_speed, gensym("sonic_speed"), A_FLOAT, 0); + class_addmethod(cart2del_damp_2d_class, (t_method)cart2del_damp_2d_r_ambi, gensym("r_ambi"), A_FLOAT, 0); + class_sethelpsymbol(cart2del_damp_2d_class, gensym("iemhelp2/cart2del_damp_2d-help")); +} diff --git a/src/cart2del_damp_3d.c b/src/cart2del_damp_3d.c new file mode 100644 index 0000000..9612aea --- /dev/null +++ b/src/cart2del_damp_3d.c @@ -0,0 +1,582 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_roomsim written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2006 */ + + +#include "m_pd.h" +#include "iemlib.h" +#include + + +/* -------------------------- cart2del_damp_3d ------------------------------ */ +/* +** pos. x-Richtung Nase +** pos. y-Richtung Linke Hand +** pos. z-Richtung Scheitel +** Kartesischer Koordinaten-Ursprung liegt in der Mitte des Raums am Boden +*/ + +/* +Reihenfolge der bundle-sektoren: index delta phi: + + 1 90 0 + 2 45 45 + 3 45 135 + 4 45 225 + 5 45 315 + 6 0 0 + 7 0 45 + 8 0 90 + 9 0 135 + 10 0 180 + 11 0 225 + 12 0 270 + 13 0 315 + 14 -45 45 + 15 -45 135 + 16 -45 225 + 17 -45 315 + + + top + + + +x + + + +y 9 + + + + +x + + 15 + +y 23 3 14 + 24 + + + +x + 8 + 22 2 13 + +y 10 4 0 1 7 + 16 5 19 + 11 + + +x + + 21 + +y 17 6 20 + 18 + + +x + + + +y 12 + + + +*/ + + + +typedef struct _cart2del_damp_3d +{ + t_object x_obj; + t_symbol *x_s_direct; + t_symbol *x_s_early1; + t_symbol *x_s_early2; + t_symbol *x_s_del; + t_symbol *x_s_damp; + t_symbol *x_s_index_theta_phi; + t_float x_room_x; + t_float x_room_y; + t_float x_room_z; + t_float x_head_x; + t_float x_head_y; + t_float x_head_z; + t_float x_src_x; + t_float x_src_y; + t_float x_src_z; + t_float x_r_ambi; + t_float x_speed; + t_float x_180_over_pi; + void *x_clock; +} t_cart2del_damp_3d; + +static t_class *cart2del_damp_3d_class; + +static t_float cart2del_damp_3d_calc_radius(t_floatarg r_ambi, t_floatarg dx, t_floatarg dy, t_floatarg dz) +{ + t_float r = (t_float)sqrt(dx*dx + dy*dy + dz*dz); + + if(r < r_ambi) + return(r_ambi); + else + return(r); +} + +static t_float cart2del_damp_3d_calc_azimuth(t_floatarg x_180_over_pi, t_floatarg dx, t_floatarg dy, t_floatarg dz) +{ + if(dx == 0.0f) + { + if(dy < 0.0f) + return(270.0f); + else + return(90.0f); + } + else if(dx < 0.0f) + { + return(180.0f + x_180_over_pi * (t_float)atan(dy / dx)); + } + else + { + if(dy < 0.0f) + return(360.0f + x_180_over_pi * (t_float)atan(dy / dx)); + else + return(x_180_over_pi * (t_float)atan(dy / dx)); + } +} + +static t_float cart2del_damp_3d_calc_elevation(t_floatarg x_180_over_pi, t_floatarg dx, t_floatarg dy, t_floatarg dz) +{ + t_float dxy = sqrt(dx*dx + dy*dy); + + if(dxy == 0.0f) + { + if(dz < 0.0f) + return(-90.0f); + else + return(90.0f); + } + else + { + return(x_180_over_pi * (t_float)atan(dz / dxy)); + } +} + +static void cart2del_damp_3d_doit(t_cart2del_damp_3d *x) +{ + t_float diff_x, diff_y, diff_z; + t_float sum_x, sum_y, sum_z; + t_float lx, wy, hz; + t_float x0, y0, z0; + t_float xp1, yp1, zp1; + t_float xn1, yn1, zn1; + t_float xp2, yp2, zp2; + t_float xn2, yn2, zn2; + t_float m2ms = 1000.0f / x->x_speed; + t_float x_180_over_pi=x->x_180_over_pi; + t_float r_ambi = x->x_r_ambi; + t_float rad[30]; + t_atom at[30]; + + lx = x->x_room_x; + wy = x->x_room_y; + hz = x->x_room_z; + + diff_x = x->x_src_x - x->x_head_x; + diff_y = x->x_src_y - x->x_head_y; + diff_z = x->x_src_z - x->x_head_z; + sum_x = x->x_src_x + x->x_head_x; + sum_y = x->x_src_y + x->x_head_y; + sum_z = x->x_src_z + x->x_head_z - hz; + + x0 = diff_x; + y0 = diff_y; + z0 = diff_z; + xp1 = lx - sum_x; + yp1 = wy - sum_y; + zp1 = hz - sum_z; + xn1 = -lx - sum_x; + yn1 = -wy - sum_y; + zn1 = -hz - sum_z; + xp2 = 2.0f*lx + diff_x; + yp2 = 2.0f*wy + diff_y; + zp2 = 2.0f*hz + diff_z; + xn2 = -2.0f*lx + diff_x; + yn2 = -2.0f*wy + diff_y; + zn2 = -2.0f*hz + diff_z; + + rad[0] = cart2del_damp_3d_calc_radius(r_ambi, x0, y0, z0); + rad[1] = cart2del_damp_3d_calc_radius(r_ambi, xp1, y0, z0); + rad[2] = cart2del_damp_3d_calc_radius(r_ambi, x0, yp1, z0); + rad[3] = cart2del_damp_3d_calc_radius(r_ambi, x0, y0, zp1); + rad[4] = cart2del_damp_3d_calc_radius(r_ambi, xn1, y0, z0); + rad[5] = cart2del_damp_3d_calc_radius(r_ambi, x0, yn1, z0); + rad[6] = cart2del_damp_3d_calc_radius(r_ambi, x0, y0, zn1); + rad[7] = cart2del_damp_3d_calc_radius(r_ambi, xp2, y0, z0); + rad[8] = cart2del_damp_3d_calc_radius(r_ambi, x0, yp2, z0); + rad[9] = cart2del_damp_3d_calc_radius(r_ambi, x0, y0, zp2); + rad[10] = cart2del_damp_3d_calc_radius(r_ambi, xn2, y0, z0); + rad[11] = cart2del_damp_3d_calc_radius(r_ambi, x0, yn2, z0); + rad[12] = cart2del_damp_3d_calc_radius(r_ambi, x0, y0, zn2); + rad[13] = cart2del_damp_3d_calc_radius(r_ambi, xp1, yp1, z0); + rad[14] = cart2del_damp_3d_calc_radius(r_ambi, xp1, y0, zp1); + rad[15] = cart2del_damp_3d_calc_radius(r_ambi, x0, yp1, zp1); + rad[16] = cart2del_damp_3d_calc_radius(r_ambi, xn1, yn1, z0); + rad[17] = cart2del_damp_3d_calc_radius(r_ambi, xn1, y0, zn1); + rad[18] = cart2del_damp_3d_calc_radius(r_ambi, x0, yn1, zn1); + rad[19] = cart2del_damp_3d_calc_radius(r_ambi, xp1, yn1, z0); + rad[20] = cart2del_damp_3d_calc_radius(r_ambi, xp1, y0, zn1); + rad[21] = cart2del_damp_3d_calc_radius(r_ambi, x0, yp1, zn1); + rad[22] = cart2del_damp_3d_calc_radius(r_ambi, xn1, yp1, z0); + rad[23] = cart2del_damp_3d_calc_radius(r_ambi, xn1, y0, zp1); + rad[24] = cart2del_damp_3d_calc_radius(r_ambi, x0, yn1, zp1); + + /* delay-reihenfolge: 0 auslassen, + +1x, +1y, +1z, -1x, -1y, -1z + +2x, +2y, +2z, -2x, -2y, -2z + +1x+1y, +1x+1z, +1y+1z + -1x-1y, -1x-1z, -1y-1z + +1x-1y, +1x-1z, +1y-1z + -1x+1y, -1x+1z, -1y+1z + */ + + SETSYMBOL(at, x->x_s_del); + + SETFLOAT(at+1, rad[0] * m2ms); + outlet_anything(x->x_obj.ob_outlet, x->x_s_direct, 2, at); + + SETFLOAT(at+1, rad[1] *m2ms); + SETFLOAT(at+2, rad[2] *m2ms); + SETFLOAT(at+3, rad[3] *m2ms); + SETFLOAT(at+4, rad[4] *m2ms); + SETFLOAT(at+5, rad[5] *m2ms); + SETFLOAT(at+6, rad[6] *m2ms); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 7, at); + + SETFLOAT(at+1, rad[7] *m2ms); + SETFLOAT(at+2, rad[8] *m2ms); + SETFLOAT(at+3, rad[9] *m2ms); + SETFLOAT(at+4, rad[10] *m2ms); + SETFLOAT(at+5, rad[11] *m2ms); + SETFLOAT(at+6, rad[12] *m2ms); + SETFLOAT(at+7, rad[13] *m2ms); + SETFLOAT(at+8, rad[14] *m2ms); + SETFLOAT(at+9, rad[15] *m2ms); + SETFLOAT(at+10, rad[16] *m2ms); + SETFLOAT(at+11, rad[17] *m2ms); + SETFLOAT(at+12, rad[18] *m2ms); + SETFLOAT(at+13, rad[19] *m2ms); + SETFLOAT(at+14, rad[20] *m2ms); + SETFLOAT(at+15, rad[21] *m2ms); + SETFLOAT(at+16, rad[22] *m2ms); + SETFLOAT(at+17, rad[23] *m2ms); + SETFLOAT(at+18, rad[24] *m2ms); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 19, at); + + + /* daempfungs-reihenfolge: + 0, + +1x, +1y, +1z, -1x, -1y, -1z + + +2x, +2y, +2z, -2x, -2y, -2z + +1x+1y, +1x+1z, +1y+1z + -1x-1y, -1x-1z, -1y-1z + +1x-1y, +1x-1z, +1y-1z + -1x+1y, -1x+1z, -1y+1z + */ + + SETSYMBOL(at, x->x_s_damp); + + SETFLOAT(at+1, r_ambi / rad[0]); + outlet_anything(x->x_obj.ob_outlet, x->x_s_direct, 2, at); + + SETFLOAT(at+1, r_ambi / rad[1]); + SETFLOAT(at+2, r_ambi / rad[2]); + SETFLOAT(at+3, r_ambi / rad[3]); + SETFLOAT(at+4, r_ambi / rad[4]); + SETFLOAT(at+5, r_ambi / rad[5]); + SETFLOAT(at+6, r_ambi / rad[6]); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 7, at); + + SETFLOAT(at+1, r_ambi / rad[7]); + SETFLOAT(at+2, r_ambi / rad[8]); + SETFLOAT(at+3, r_ambi / rad[9]); + SETFLOAT(at+4, r_ambi / rad[10]); + SETFLOAT(at+5, r_ambi / rad[11]); + SETFLOAT(at+6, r_ambi / rad[12]); + SETFLOAT(at+7, r_ambi / rad[13]); + SETFLOAT(at+8, r_ambi / rad[14]); + SETFLOAT(at+9, r_ambi / rad[15]); + SETFLOAT(at+10, r_ambi / rad[16]); + SETFLOAT(at+11, r_ambi / rad[17]); + SETFLOAT(at+12, r_ambi / rad[18]); + SETFLOAT(at+13, r_ambi / rad[19]); + SETFLOAT(at+14, r_ambi / rad[20]); + SETFLOAT(at+15, r_ambi / rad[21]); + SETFLOAT(at+16, r_ambi / rad[22]); + SETFLOAT(at+17, r_ambi / rad[23]); + SETFLOAT(at+18, r_ambi / rad[24]); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 19, at); + + + /* encoder-winkel-reihenfolge: index delta phi + 0, + +1x, +1y, +1z, -1x, -1y, -1z + +2x, +2y, +2z, -2x, -2y, -2z + +1x+1y, +1x+1z, +1y+1z + -1x-1y, -1x-1z, -1y-1z + +1x-1y, +1x-1z, +1y-1z + -1x+1y, -1x+1z, -1y+1z + */ + + SETSYMBOL(at, x->x_s_index_theta_phi); + + SETFLOAT(at+1, 1.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, y0, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, y0, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_direct, 4, at); + + + SETFLOAT(at+1, 1.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xp1, y0, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xp1, y0, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 4, at); + + SETFLOAT(at+1, 2.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, yp1, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, yp1, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 4, at); + + SETFLOAT(at+1, 3.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, y0, zp1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, y0, zp1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 4, at); + + SETFLOAT(at+1, 4.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xn1, y0, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xn1, y0, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 4, at); + + SETFLOAT(at+1, 5.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, yn1, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, yn1, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 4, at); + + SETFLOAT(at+1, 6.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, y0, zn1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, y0, zn1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early1, 4, at); + + + SETFLOAT(at+1, 1.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xp2, y0, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xp2, y0, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 2.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, yp2, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, yp2, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 3.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, y0, zp2)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, y0, zp2)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 4.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xn2, y0, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xn2, y0, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 5.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, yn2, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, yn2, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 6.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, y0, zn2)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, y0, zn2)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 7.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xp1, yp1, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xp1, yp1, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 8.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xp1, y0, zp1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xp1, y0, zp1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 9.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, yp1, zp1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, yp1, zp1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 10.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xn1, yn1, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xn1, yn1, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 11.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xn1, y0, zn1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xn1, y0, zn1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 12.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, yn1, zn1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, yn1, zn1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 13.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xp1, yn1, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xp1, yn1, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 14.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xp1, y0, zn1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xp1, y0, zn1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 15.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, yp1, zn1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, yp1, zn1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 16.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xn1, yp1, z0)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xn1, yp1, z0)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 17.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, xn1, y0, zp1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, xn1, y0, zp1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); + + SETFLOAT(at+1, 18.0f); + SETFLOAT(at+2, cart2del_damp_3d_calc_elevation(x_180_over_pi, x0, yn1, zp1)); + SETFLOAT(at+3, cart2del_damp_3d_calc_azimuth(x_180_over_pi, x0, yn1, zp1)); + outlet_anything(x->x_obj.ob_outlet, x->x_s_early2, 4, at); +} + +static void cart2del_damp_3d_src_xyz(t_cart2del_damp_3d *x, t_symbol *s, int argc, t_atom *argv) +{ + if((argc >= 3)&&IS_A_FLOAT(argv, 0)&&IS_A_FLOAT(argv, 1)&&IS_A_FLOAT(argv, 2)) + { + t_float xr2=0.5f*x->x_room_x, yr2=0.5f*x->x_room_y; + + x->x_src_x = atom_getfloat(argv++); + x->x_src_y = atom_getfloat(argv++); + x->x_src_z = atom_getfloat(argv); + if(x->x_src_x > xr2) + x->x_src_x = xr2; + if(x->x_src_x < -xr2) + x->x_src_x = -xr2; + if(x->x_src_y > yr2) + x->x_src_y = yr2; + if(x->x_src_y < -yr2) + x->x_src_y = -yr2; + if(x->x_src_z > x->x_room_z) + x->x_src_z = x->x_room_z; + if(x->x_src_z < 0.0f) + x->x_src_z = 0.0f; + clock_delay(x->x_clock, 0.0f); + } +} + +static void cart2del_damp_3d_head_xyz(t_cart2del_damp_3d *x, t_symbol *s, int argc, t_atom *argv) +{ + if((argc >= 3)&&IS_A_FLOAT(argv, 0)&&IS_A_FLOAT(argv, 1)&&IS_A_FLOAT(argv, 2)) + { + t_float xr2=0.5f*x->x_room_x, yr2=0.5f*x->x_room_y; + + x->x_head_x = atom_getfloat(argv++); + x->x_head_y = atom_getfloat(argv++); + x->x_head_z = atom_getfloat(argv); + if(x->x_head_x > xr2) + x->x_head_x = xr2; + if(x->x_head_x < -xr2) + x->x_head_x = -xr2; + if(x->x_head_y > yr2) + x->x_head_y = yr2; + if(x->x_head_y < -yr2) + x->x_head_y = -yr2; + if(x->x_head_z > x->x_room_z) + x->x_head_z = x->x_room_z; + if(x->x_head_z < 0.0f) + x->x_head_z = 0.0f; + clock_delay(x->x_clock, 0.0f); + } +} + +static void cart2del_damp_3d_room_dim(t_cart2del_damp_3d *x, t_symbol *s, int argc, t_atom *argv) +{ + if((argc >= 3)&&IS_A_FLOAT(argv, 0)&&IS_A_FLOAT(argv, 1)&&IS_A_FLOAT(argv, 2)) + { + x->x_room_x = atom_getfloat(argv++); + x->x_room_y = atom_getfloat(argv++); + x->x_room_z = atom_getfloat(argv); + if(x->x_room_x < 0.5f) + x->x_room_x = 0.5f; + if(x->x_room_y < 0.5f) + x->x_room_y = 0.5f; + if(x->x_room_z < 0.5f) + x->x_room_z = 0.5f; + clock_delay(x->x_clock, 0.0f); + } +} + +static void cart2del_damp_3d_r_ambi(t_cart2del_damp_3d *x, t_floatarg r_ambi) +{ + if(r_ambi < 0.1f) + r_ambi = 0.1f; + x->x_r_ambi = r_ambi; + clock_delay(x->x_clock, 0.0f); +} + +static void cart2del_damp_3d_sonic_speed(t_cart2del_damp_3d *x, t_floatarg speed) +{ + if(speed < 10.0f) + speed = 10.0f; + if(speed > 2000.0f) + speed = 2000.0f; + x->x_speed = speed; + clock_delay(x->x_clock, 0.0f); +} + +static void cart2del_damp_3d_free(t_cart2del_damp_3d *x) +{ + clock_free(x->x_clock); +} + +static void *cart2del_damp_3d_new(t_symbol *s, int argc, t_atom *argv) +{ + t_cart2del_damp_3d *x = (t_cart2del_damp_3d *)pd_new(cart2del_damp_3d_class); + + x->x_room_x = 12.0f; + x->x_room_y = 8.0f; + x->x_room_z = 4.0f; + x->x_head_x = 0.0f; + x->x_head_y = 0.0f; + x->x_head_z = 1.7f; + x->x_src_x = 3.0f; + x->x_src_y = 0.5f; + x->x_src_z = 2.5f; + x->x_r_ambi = 1.4f; + x->x_speed = 340.0f; + x->x_s_direct = gensym("direct"); + x->x_s_early1 = gensym("early1"); + x->x_s_early2 = gensym("early2"); + x->x_s_del = gensym("del"); + x->x_s_damp = gensym("damp"); + x->x_s_index_theta_phi = gensym("index_theta_phi"); + outlet_new(&x->x_obj, &s_list); + x->x_clock = clock_new(x, (t_method)cart2del_damp_3d_doit); + x->x_180_over_pi = (t_float)(180.0 / (4.0 * atan(1.0))); + return (x); +} + +void cart2del_damp_3d_setup(void) +{ + cart2del_damp_3d_class = class_new(gensym("cart2del_damp_3d"), (t_newmethod)cart2del_damp_3d_new, (t_method)cart2del_damp_3d_free, + sizeof(t_cart2del_damp_3d), 0, A_GIMME, 0); + class_addmethod(cart2del_damp_3d_class, (t_method)cart2del_damp_3d_src_xyz, gensym("src_xyz"), A_GIMME, 0); + class_addmethod(cart2del_damp_3d_class, (t_method)cart2del_damp_3d_head_xyz, gensym("head_xyz"), A_GIMME, 0); + class_addmethod(cart2del_damp_3d_class, (t_method)cart2del_damp_3d_room_dim, gensym("room_dim"), A_GIMME, 0); + class_addmethod(cart2del_damp_3d_class, (t_method)cart2del_damp_3d_sonic_speed, gensym("sonic_speed"), A_FLOAT, 0); + class_addmethod(cart2del_damp_3d_class, (t_method)cart2del_damp_3d_r_ambi, gensym("r_ambi"), A_FLOAT, 0); + class_sethelpsymbol(cart2del_damp_3d_class, gensym("iemhelp2/cart2del_damp_3d-help")); +} diff --git a/src/early_reflections_2d.c b/src/early_reflections_2d.c new file mode 100644 index 0000000..438db82 --- /dev/null +++ b/src/early_reflections_2d.c @@ -0,0 +1,536 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_roomsim written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2006 */ + +#include "m_pd.h" +#include "iemlib.h" +#include + +/* -------------------------- early_reflections_2d ------------------------------ */ +/* +** pos. x-Richtung Nase +** pos. y-Richtung Linke Hand +** pos. z-Richtung Scheitel +** Kartesischer Koordinaten-Ursprung liegt in der Mitte des Raums am Boden + + aenderungen: src-index von 1 .. n auf 0 .. (n-1) + aenderungen: azimuth von rad auf degree +*/ + +/* +Reihenfolge der bundle-sektoren: index phi: + + + 1 0 + 2 45 + 3 90 + 4 135 + 5 180 + 6 225 + 7 270 + 8 315 + + 1. und 2. reflexionen: + + + +x + 5 + 9 1 11 + +y 6 2 0 4 8 + 12 3 10 + 7 + +*/ + + + +typedef struct _early_reflections_2d +{ + t_object x_obj; + t_atom x_para_at[27]; + void *x_direct_out; + void *x_early_out; + void *x_rev_out; + t_symbol *x_s_del0; + t_symbol *x_s_del1; + t_symbol *x_s_del2; + t_symbol *x_s_damp; + t_symbol *x_s_index_phi; + t_symbol *x_s_bundle; + t_float x_azimuth_denominator; + t_float x_azimuth_offset; + t_float x_room_x; + t_float x_room_y; + t_float x_head_x; + t_float x_head_y; + int x_n_src; + int x_bundle; + t_float x_src_x[30]; + t_float x_src_y[30]; + t_float x_r_ambi; + t_float x_speed; + t_float x_180_over_pi; +} t_early_reflections_2d; + +static t_class *early_reflections_2d_class; + +static t_float early_reflections_2d_calc_radius(t_floatarg r_ambi, t_floatarg dx, t_floatarg dy) +{ + t_float r = (t_float)sqrt(dx*dx + dy*dy); + + if(r < r_ambi) + return(r_ambi); + else + return(r); +} + +static t_float early_reflections_2d_calc_azimuth(t_floatarg x_180_over_pi, t_floatarg dx, t_floatarg dy)/*changes*/ +{ + if(dx == 0.0f) + { + if(dy < 0.0f) + return(270.0f); + else + return(90.0f); + } + else if(dx < 0.0f) + { + return(180.0f + x_180_over_pi * (t_float)atan(dy / dx)); + } + else + { + if(dy < 0.0f) + return(360.0f + x_180_over_pi * (t_float)atan(dy / dx)); + else + return(x_180_over_pi * (t_float)atan(dy / dx)); + } +} + +static t_float early_reflections_2d_calc_bundle_index(t_floatarg phi)/*changes*/ +{ + phi += 22.5f; + if(phi >= 360.0f) + phi -= 360.0f; + + if(phi <= 180.0f) + { + if(phi <= 90.0f) + { + if(phi <= 45.0f)/* 0 .. 45 */ + return(1.0f); + else + return(2.0f); + } + else + { + if(phi <= 135.0f) + return(3.0f); + else + return(4.0f); + } + } + else + { + if(phi <= 270.0f) + { + if(phi <= 225.0f) + return(5.0f); + else + return(6.0f); + } + else + { + if(phi <= 315.0f)/* 270 .. 315 */ + return(7.0f); + else + return(8.0f);/* 315 .. 360 */ + } + } +} + +static void early_reflections_2d_doit(t_early_reflections_2d *x) +{ + t_atom *at; + t_float diff_x, diff_y; + t_float sum_x, sum_y; + t_float lx, wy; + t_float x0, y0; + t_float xp1, yp1; + t_float xn1, yn1; + t_float xp2, yp2; + t_float xn2, yn2; + t_float m2ms = 1000.0f / x->x_speed; + t_float x_180_over_pi=x->x_180_over_pi; + t_float r_ambi = x->x_r_ambi; + t_float phi[50]; + t_float rad[50]; + int n_src=x->x_n_src; + int i; + + lx = x->x_room_x; + wy = x->x_room_y; + + SETFLOAT(x->x_para_at, early_reflections_2d_calc_radius(r_ambi, lx, wy)*m2ms); + outlet_anything(x->x_rev_out, x->x_s_del0, 1, x->x_para_at); + + for(i=0; ix_src_x[i] - x->x_head_x; + diff_y = x->x_src_y[i] - x->x_head_y; + sum_x = x->x_src_x[i] + x->x_head_x; + sum_y = x->x_src_y[i] + x->x_head_y; + + x0 = diff_x; + y0 = diff_y; + xp1 = lx - sum_x; + yp1 = wy - sum_y; + xn1 = -lx - sum_x; + yn1 = -wy - sum_y; + xp2 = 2.0f*lx + diff_x; + yp2 = 2.0f*wy + diff_y; + xn2 = -2.0f*lx + diff_x; + yn2 = -2.0f*wy + diff_y; + + rad[0] = early_reflections_2d_calc_radius(r_ambi, x0, y0); + rad[1] = early_reflections_2d_calc_radius(r_ambi, xp1, y0); + rad[2] = early_reflections_2d_calc_radius(r_ambi, x0, yp1); + rad[3] = early_reflections_2d_calc_radius(r_ambi, xn1, y0); + rad[4] = early_reflections_2d_calc_radius(r_ambi, x0, yn1); + rad[5] = early_reflections_2d_calc_radius(r_ambi, xp2, y0); + rad[6] = early_reflections_2d_calc_radius(r_ambi, x0, yp2); + rad[7] = early_reflections_2d_calc_radius(r_ambi, xn2, y0); + rad[8] = early_reflections_2d_calc_radius(r_ambi, x0, yn2); + rad[9] = early_reflections_2d_calc_radius(r_ambi, xp1, yp1); + rad[10] = early_reflections_2d_calc_radius(r_ambi, xn1, yn1); + rad[11] = early_reflections_2d_calc_radius(r_ambi, xp1, yn1); + rad[12] = early_reflections_2d_calc_radius(r_ambi, xn1, yp1); + + /* delay-reihenfolge: 0, + +1x, +1y, -1x, -1y + +2x, +2y, -2x, -2y + +1x+1y, -1x-1y + +1x-1y, -1x+1y + */ + + at = x->x_para_at; + SETFLOAT(at, (t_float)(i+1));/*changes*/ + at++; + SETFLOAT(at, rad[0] * m2ms); + outlet_anything(x->x_direct_out, x->x_s_del0, 2, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, rad[1] *m2ms); + at++; + SETFLOAT(at, rad[2] *m2ms); + at++; + SETFLOAT(at, rad[3] *m2ms); + at++; + SETFLOAT(at, rad[4] *m2ms); + outlet_anything(x->x_early_out, x->x_s_del1, 5, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, rad[5] *m2ms); + at++; + SETFLOAT(at, rad[6] *m2ms); + at++; + SETFLOAT(at, rad[7] *m2ms); + at++; + SETFLOAT(at, rad[8] *m2ms); + at++; + SETFLOAT(at, rad[9] *m2ms); + at++; + SETFLOAT(at, rad[10] *m2ms); + at++; + SETFLOAT(at, rad[11] *m2ms); + at++; + SETFLOAT(at, rad[12] *m2ms); + outlet_anything(x->x_early_out, x->x_s_del2, 9, x->x_para_at); + + + /* daempfungs-reihenfolge: + 0, + +1x, +1y, -1x, -1y + +2x, +2y, -2x, -2y + +1x+1y, -1x-1y + +1x-1y, -1x+1y + */ + + at = x->x_para_at+1; + SETFLOAT(at, r_ambi / rad[0]); + outlet_anything(x->x_direct_out, x->x_s_damp, 2, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, r_ambi / rad[1]); + at++; + SETFLOAT(at, r_ambi / rad[2]); + at++; + SETFLOAT(at, r_ambi / rad[3]); + at++; + SETFLOAT(at, r_ambi / rad[4]); + at++; + SETFLOAT(at, r_ambi / rad[5]); + at++; + SETFLOAT(at, r_ambi / rad[6]); + at++; + SETFLOAT(at, r_ambi / rad[7]); + at++; + SETFLOAT(at, r_ambi / rad[8]); + at++; + SETFLOAT(at, r_ambi / rad[9]); + at++; + SETFLOAT(at, r_ambi / rad[10]); + at++; + SETFLOAT(at, r_ambi / rad[11]); + at++; + SETFLOAT(at, r_ambi / rad[12]); + + outlet_anything(x->x_early_out, x->x_s_damp, 13, x->x_para_at); + + + /* encoder-winkel-reihenfolge: index delta phi + 0, + +1x, +1y, -1x, -1y + +2x, +2y, -2x, -2y + +1x+1y, -1x-1y + +1x-1y, -1x+1y + */ + + at = x->x_para_at+1; + SETFLOAT(at, early_reflections_2d_calc_azimuth(x_180_over_pi, x0, y0)); + + outlet_anything(x->x_direct_out, x->x_s_index_phi, 2, x->x_para_at); + + /* encoder-winkel-reihenfolge: bundle + 0, + +1x, +1y, -1x, -1y + +2x, +2y, -2x, -2y + +1x+1y, -1x-1y + +1x-1y, -1x+1y + */ + + phi[0] = early_reflections_2d_calc_azimuth(x_180_over_pi, xp1, y0); + phi[1] = early_reflections_2d_calc_azimuth(x_180_over_pi, x0, yp1); + phi[2] = early_reflections_2d_calc_azimuth(x_180_over_pi, xn1, y0); + phi[3] = early_reflections_2d_calc_azimuth(x_180_over_pi, x0, yn1); + phi[4] = early_reflections_2d_calc_azimuth(x_180_over_pi, xp2, y0); + phi[5] = early_reflections_2d_calc_azimuth(x_180_over_pi, x0, yp2); + phi[6] = early_reflections_2d_calc_azimuth(x_180_over_pi, xn2, y0); + phi[7] = early_reflections_2d_calc_azimuth(x_180_over_pi, x0, yn2); + phi[8] = early_reflections_2d_calc_azimuth(x_180_over_pi, xp1, yp1); + phi[9] = early_reflections_2d_calc_azimuth(x_180_over_pi, xn1, yn1); + phi[10] = early_reflections_2d_calc_azimuth(x_180_over_pi, xp1, yn1); + phi[11] = early_reflections_2d_calc_azimuth(x_180_over_pi, xn1, yp1); + + if(x->x_bundle) + { + at = x->x_para_at+1; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[0])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[1])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[2])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[3])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[4])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[5])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[6])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[7])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[8])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[9])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[10])); + at++; + SETFLOAT(at, early_reflections_2d_calc_bundle_index(phi[11])); + + outlet_anything(x->x_early_out, x->x_s_bundle, 13, x->x_para_at); + } + + at = x->x_para_at+1; + SETFLOAT(at, 1.0f); + at++; + SETFLOAT(at, phi[0]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 2.0f); + at++; + SETFLOAT(at, phi[1]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 3.0f); + at++; + SETFLOAT(at, phi[2]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 4.0f); + at++; + SETFLOAT(at, phi[3]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 5.0f); + at++; + SETFLOAT(at, phi[4]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 6.0f); + at++; + SETFLOAT(at, phi[5]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 7.0f); + at++; + SETFLOAT(at, phi[6]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 8.0f); + at++; + SETFLOAT(at, phi[7]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 9.0f); + at++; + SETFLOAT(at, phi[8]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 10.0f); + at++; + SETFLOAT(at, phi[9]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 11.0f); + at++; + SETFLOAT(at, phi[10]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 12.0f); + at++; + SETFLOAT(at, phi[11]); + outlet_anything(x->x_early_out, x->x_s_index_phi, 3, x->x_para_at); + } +} + +static void early_reflections_2d_dump_para(t_early_reflections_2d *x) +{ + int i, n=x->x_n_src; + + post("*******************************************************************************"); + post("room-dimensions: L_x = %.3f, W_y = %.3f", x->x_room_x, x->x_room_y); + post("hear-position: x_hear = %.3f, y_hear = %.3f", x->x_head_x, x->x_head_y); + for(i=0; ix_src_x[i], i+1, x->x_src_y[i]); + post("ambisonic-radius: %f", x->x_r_ambi); + post("sonic-speed: %.3f", x->x_speed); + post("order of outputs: direct early rev"); + post("*******************************************************************************"); +} + +static void early_reflections_2d_para(t_early_reflections_2d *x, t_symbol *s, int argc, t_atom *argv) +{ + int i, n=x->x_n_src*2 + 5;/* r_ambi + 2*room + 2*head */ + + if(argc != n) + { + post("early_reflections_2d ERROR: para needs 1 r_ambi + 2*room + 2*head +n*2*src"); + return; + } + + x->x_r_ambi = atom_getfloat(argv++); + x->x_room_x = atom_getfloat(argv++); + x->x_room_y = atom_getfloat(argv++); + x->x_head_x = atom_getfloat(argv++); + x->x_head_y = atom_getfloat(argv++); + n = x->x_n_src; + for(i=0; ix_src_x[i] = atom_getfloat(argv++); + x->x_src_y[i] = atom_getfloat(argv++); + } + early_reflections_2d_doit(x); +} + +static void early_reflections_2d_sonic_speed(t_early_reflections_2d *x, t_floatarg speed) +{ + if(speed < 300.0f) + speed = 300.0f; + if(speed > 400.0f) + speed = 400.0f; + x->x_speed = speed; +} + +static void early_reflections_2d_bundle(t_early_reflections_2d *x, t_floatarg bundle) +{ + if(bundle == 0.0f) + x->x_bundle = 0; + else + x->x_bundle = 1; +} + +static void early_reflections_2d_free(t_early_reflections_2d *x) +{ +} + +static void *early_reflections_2d_new(t_floatarg fn_src) +{ + int i, n; + t_early_reflections_2d *x = (t_early_reflections_2d *)pd_new(early_reflections_2d_class); + + n = (int)fn_src; + if(n < 1) + n = 1; + if(n > 30) + n = 30; + x->x_n_src = n; + x->x_room_x = 12.0f; + x->x_room_y = 8.0f; + x->x_head_x = 0.0f; + x->x_head_y = 0.0f; + for(i=0; ix_src_x[i] = 3.0f; + x->x_src_y[i] = 0.5f; + } + x->x_r_ambi = 1.4f; + x->x_speed = 340.0f; + + x->x_s_del0 = gensym("del0"); + x->x_s_del1 = gensym("del1"); + x->x_s_del2 = gensym("del2"); + x->x_s_damp = gensym("damp"); + x->x_s_index_phi = gensym("index_phi"); + x->x_s_bundle = gensym("bundle"); + x->x_direct_out = outlet_new(&x->x_obj, &s_list); + x->x_early_out = outlet_new(&x->x_obj, &s_list); + x->x_rev_out = outlet_new(&x->x_obj, &s_list); + x->x_180_over_pi = (t_float)(180.0 / (4.0 * atan(1.0))); + x->x_bundle = 0; + return (x); +} + +void early_reflections_2d_setup(void) +{ + early_reflections_2d_class = class_new(gensym("early_reflections_2d"), (t_newmethod)early_reflections_2d_new, (t_method)early_reflections_2d_free, + sizeof(t_early_reflections_2d), 0, A_DEFFLOAT, 0); + class_addmethod(early_reflections_2d_class, (t_method)early_reflections_2d_para, gensym("para"), A_GIMME, 0); + class_addmethod(early_reflections_2d_class, (t_method)early_reflections_2d_sonic_speed, gensym("sonic_speed"), A_FLOAT, 0); + class_addmethod(early_reflections_2d_class, (t_method)early_reflections_2d_bundle, gensym("bundle"), A_FLOAT, 0); + class_addmethod(early_reflections_2d_class, (t_method)early_reflections_2d_dump_para, gensym("dump_para"), 0); + class_sethelpsymbol(early_reflections_2d_class, gensym("iemhelp2/early_reflections_2d-help")); +} diff --git a/src/early_reflections_3d.c b/src/early_reflections_3d.c new file mode 100644 index 0000000..a55f908 --- /dev/null +++ b/src/early_reflections_3d.c @@ -0,0 +1,902 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_roomsim written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2006 */ + +#include "m_pd.h" +#include "iemlib.h" +#include + + +/* -------------------------- early_reflections_3d ------------------------------ */ +/* +** pos. x-Richtung Nase +** pos. y-Richtung Linke Hand +** pos. z-Richtung Scheitel +** Kartesischer Koordinaten-Ursprung liegt in der Mitte des Raums am Boden +*/ + +/* +Reihenfolge der bundle-sektoren: index delta phi: + + 1 90 0 + 2 45 45 + 3 45 135 + 4 45 225 + 5 45 315 + 6 0 0 + 7 0 45 + 8 0 90 + 9 0 135 + 10 0 180 + 11 0 225 + 12 0 270 + 13 0 315 + 14 -45 45 + 15 -45 135 + 16 -45 225 + 17 -45 315 + + + top + + + +x + + + +y 9 + + + + +x + + 15 + +y 23 3 14 + 24 + + + +x + 8 + 22 2 13 + +y 10 4 0 1 7 + 16 5 19 + 11 + + +x + + 21 + +y 17 6 20 + 18 + + +x + + + +y 12 + + + +*/ + +typedef struct _early_reflections_3d +{ + t_object x_obj; + t_atom x_para_at[27]; + void *x_direct_out; + void *x_early_out; + void *x_rev_out; + t_symbol *x_s_del0; + t_symbol *x_s_del1; + t_symbol *x_s_del2; + t_symbol *x_s_damp; + t_symbol *x_s_index_delta_phi; + t_symbol *x_s_bundle; + t_float x_room_x; + t_float x_room_y; + t_float x_room_z; + t_float x_head_x; + t_float x_head_y; + t_float x_head_z; + int x_n_src; + int x_bundle; + t_float x_src_x[30]; + t_float x_src_y[30]; + t_float x_src_z[30]; + t_float x_r_ambi; + t_float x_speed; + t_float x_180_over_pi; +} t_early_reflections_3d; + +static t_class *early_reflections_3d_class; + +static t_float early_reflections_3d_calc_radius(t_floatarg r_ambi, t_floatarg dx, t_floatarg dy, t_floatarg dz) +{ + t_float r = (t_float)sqrt(dx*dx + dy*dy + dz*dz); + + if(r < r_ambi) + return(r_ambi); + else + return(r); +} + +static t_float early_reflections_3d_calc_azimuth(t_floatarg x_180_over_pi, t_floatarg dx, t_floatarg dy, t_floatarg dz) +{ + if(dx == 0.0f) + { + if(dy < 0.0f) + return(270.0f); + else + return(90.0f); + } + else if(dx < 0.0f) + { + return(180.0f + x_180_over_pi * (t_float)atan(dy / dx)); + } + else + { + if(dy < 0.0f) + return(360.0f + x_180_over_pi * (t_float)atan(dy / dx)); + else + return(x_180_over_pi * (t_float)atan(dy / dx)); + } +} + +static t_float early_reflections_3d_calc_elevation(t_floatarg x_180_over_pi, t_floatarg dx, t_floatarg dy, t_floatarg dz)/*changes*/ +{ + t_float dxy = sqrt(dx*dx + dy*dy); + + if(dxy == 0.0f) + { + if(dz < 0.0f) + return(-90.0f); + else + return(90.0f); + } + else + { + return(x_180_over_pi * (t_float)atan(dz / dxy)); + } +} + +static t_float early_reflections_3d_calc_bundle_index(t_floatarg delta, t_floatarg phi)/*changes*/ +{ + if(delta > 67.5f) + return(1.0f); + else if(delta > 22.5f) + { + if(phi <= 180.0f) + { + if(phi <= 90.0f) + return(2.0f); + else + return(3.0f); + } + else + { + if(phi <= 270.0f) + return(4.0f); + else + return(5.0f); + } + } + else if(delta > -22.5f) + { + phi += 22.5f; + if(phi >= 360.0f) + phi -= 360.0f; + + if(phi <= 180.0f) + { + if(phi <= 90.0f) + { + if(phi <= 45.0f)/* 0 .. 45 */ + return(6.0f); + else + return(7.0f); + } + else + { + if(phi <= 135.0f) + return(8.0f); + else + return(9.0f); + } + } + else + { + if(phi <= 270.0f) + { + if(phi <= 225.0f) + return(10.0f); + else + return(11.0f); + } + else + { + if(phi <= 315.0f)/* 270 .. 315 */ + return(12.0f); + else + return(13.0f);/* 315 .. 360 */ + } + } + } + else + { + if(phi <= 180.0f) + { + if(phi <= 90.0f) + return(14.0f); + else + return(15.0f); + } + else + { + if(phi <= 270.0f) + return(16.0f); + else + return(17.0f); + } + } +} + +static void early_reflections_3d_doit(t_early_reflections_3d *x) +{ + t_atom *at; + t_float diff_x, diff_y, diff_z; + t_float sum_x, sum_y, sum_z; + t_float lx, wy, hz; + t_float x0, y0, z0; + t_float xp1, yp1, zp1; + t_float xn1, yn1, zn1; + t_float xp2, yp2, zp2; + t_float xn2, yn2, zn2; + t_float m2ms = 1000.0f / x->x_speed; + t_float x_180_over_pi=x->x_180_over_pi; + t_float r_ambi = x->x_r_ambi; + t_float rad[50], delta[50], phi[50]; + int n_src=x->x_n_src; + int i; + /*t_float hz2 = 0.5f*x->x_room_z; + + diff_x = x->x_src_x - x->x_head_x; + diff_y = x->x_src_y - x->x_head_y; + diff_z = (x->x_src_z - hz2) - (x->x_head_z - hz2); + sum_x = x->x_src_x + x->x_head_x; + sum_y = x->x_src_y + x->x_head_y; + sum_z = (x->x_src_z - hz2) + (x->x_head_z - hz2);*/ + + lx = x->x_room_x; + wy = x->x_room_y; + hz = x->x_room_z; + + SETFLOAT(x->x_para_at, early_reflections_3d_calc_radius(r_ambi, lx, wy, hz)*m2ms); + outlet_anything(x->x_rev_out, x->x_s_del0, 1, x->x_para_at); + + for(i=0; ix_src_x[i] - x->x_head_x; + diff_y = x->x_src_y[i] - x->x_head_y; + diff_z = x->x_src_z[i] - x->x_head_z; + sum_x = x->x_src_x[i] + x->x_head_x; + sum_y = x->x_src_y[i] + x->x_head_y; + sum_z = x->x_src_z[i] + x->x_head_z - hz; + + x0 = diff_x; + y0 = diff_y; + z0 = diff_z; + xp1 = lx - sum_x; + yp1 = wy - sum_y; + zp1 = hz - sum_z; + xn1 = -lx - sum_x; + yn1 = -wy - sum_y; + zn1 = -hz - sum_z; + xp2 = 2.0f*lx + diff_x; + yp2 = 2.0f*wy + diff_y; + zp2 = 2.0f*hz + diff_z; + xn2 = -2.0f*lx + diff_x; + yn2 = -2.0f*wy + diff_y; + zn2 = -2.0f*hz + diff_z; + + rad[0] = early_reflections_3d_calc_radius(r_ambi, x0, y0, z0); + rad[1] = early_reflections_3d_calc_radius(r_ambi, xp1, y0, z0); + rad[2] = early_reflections_3d_calc_radius(r_ambi, x0, yp1, z0); + rad[3] = early_reflections_3d_calc_radius(r_ambi, x0, y0, zp1); + rad[4] = early_reflections_3d_calc_radius(r_ambi, xn1, y0, z0); + rad[5] = early_reflections_3d_calc_radius(r_ambi, x0, yn1, z0); + rad[6] = early_reflections_3d_calc_radius(r_ambi, x0, y0, zn1); + rad[7] = early_reflections_3d_calc_radius(r_ambi, xp2, y0, z0); + rad[8] = early_reflections_3d_calc_radius(r_ambi, x0, yp2, z0); + rad[9] = early_reflections_3d_calc_radius(r_ambi, x0, y0, zp2); + rad[10] = early_reflections_3d_calc_radius(r_ambi, xn2, y0, z0); + rad[11] = early_reflections_3d_calc_radius(r_ambi, x0, yn2, z0); + rad[12] = early_reflections_3d_calc_radius(r_ambi, x0, y0, zn2); + rad[13] = early_reflections_3d_calc_radius(r_ambi, xp1, yp1, z0); + rad[14] = early_reflections_3d_calc_radius(r_ambi, xp1, y0, zp1); + rad[15] = early_reflections_3d_calc_radius(r_ambi, x0, yp1, zp1); + rad[16] = early_reflections_3d_calc_radius(r_ambi, xn1, yn1, z0); + rad[17] = early_reflections_3d_calc_radius(r_ambi, xn1, y0, zn1); + rad[18] = early_reflections_3d_calc_radius(r_ambi, x0, yn1, zn1); + rad[19] = early_reflections_3d_calc_radius(r_ambi, xp1, yn1, z0); + rad[20] = early_reflections_3d_calc_radius(r_ambi, xp1, y0, zn1); + rad[21] = early_reflections_3d_calc_radius(r_ambi, x0, yp1, zn1); + rad[22] = early_reflections_3d_calc_radius(r_ambi, xn1, yp1, z0); + rad[23] = early_reflections_3d_calc_radius(r_ambi, xn1, y0, zp1); + rad[24] = early_reflections_3d_calc_radius(r_ambi, x0, yn1, zp1); + + /* delay-reihenfolge: 0 auslassen, + +1x, +1y, +1z, -1x, -1y, -1z + +2x, +2y, +2z, -2x, -2y, -2z + +1x+1y, +1x+1z, +1y+1z + -1x-1y, -1x-1z, -1y-1z + +1x-1y, +1x-1z, +1y-1z + -1x+1y, -1x+1z, -1y+1z + */ + + at = x->x_para_at; + SETFLOAT(at, (t_float)(i+1));/*changes*/ + at++; + SETFLOAT(at, rad[0] * m2ms); + outlet_anything(x->x_direct_out, x->x_s_del0, 2, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, rad[1] *m2ms); + at++; + SETFLOAT(at, rad[2] *m2ms); + at++; + SETFLOAT(at, rad[3] *m2ms); + at++; + SETFLOAT(at, rad[4] *m2ms); + at++; + SETFLOAT(at, rad[5] *m2ms); + at++; + SETFLOAT(at, rad[6] *m2ms); + outlet_anything(x->x_early_out, x->x_s_del1, 7, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, rad[7] *m2ms); + at++; + SETFLOAT(at, rad[8] *m2ms); + at++; + SETFLOAT(at, rad[9] *m2ms); + at++; + SETFLOAT(at, rad[10] *m2ms); + at++; + SETFLOAT(at, rad[11] *m2ms); + at++; + SETFLOAT(at, rad[12] *m2ms); + at++; + SETFLOAT(at, rad[13] *m2ms); + at++; + SETFLOAT(at, rad[14] *m2ms); + at++; + SETFLOAT(at, rad[15] *m2ms); + at++; + SETFLOAT(at, rad[16] *m2ms); + at++; + SETFLOAT(at, rad[17] *m2ms); + at++; + SETFLOAT(at, rad[18] *m2ms); + at++; + SETFLOAT(at, rad[19] *m2ms); + at++; + SETFLOAT(at, rad[20] *m2ms); + at++; + SETFLOAT(at, rad[21] *m2ms); + at++; + SETFLOAT(at, rad[22] *m2ms); + at++; + SETFLOAT(at, rad[23] *m2ms); + at++; + SETFLOAT(at, rad[24] *m2ms); + outlet_anything(x->x_early_out, x->x_s_del2, 19, x->x_para_at); + + + /* daempfungs-reihenfolge: + 0, + +1x, +1y, +1z, -1x, -1y, -1z + + +2x, +2y, +2z, -2x, -2y, -2z + +1x+1y, +1x+1z, +1y+1z + -1x-1y, -1x-1z, -1y-1z + +1x-1y, +1x-1z, +1y-1z + -1x+1y, -1x+1z, -1y+1z + */ + + at = x->x_para_at+1; + SETFLOAT(at, r_ambi / rad[0]); + outlet_anything(x->x_direct_out, x->x_s_damp, 2, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, r_ambi / rad[1]); + at++; + SETFLOAT(at, r_ambi / rad[2]); + at++; + SETFLOAT(at, r_ambi / rad[3]); + at++; + SETFLOAT(at, r_ambi / rad[4]); + at++; + SETFLOAT(at, r_ambi / rad[5]); + at++; + SETFLOAT(at, r_ambi / rad[6]); + at++; + + SETFLOAT(at, r_ambi / rad[7]); + at++; + SETFLOAT(at, r_ambi / rad[8]); + at++; + SETFLOAT(at, r_ambi / rad[9]); + at++; + + SETFLOAT(at, r_ambi / rad[10]); + at++; + SETFLOAT(at, r_ambi / rad[11]); + at++; + SETFLOAT(at, r_ambi / rad[12]); + at++; + + SETFLOAT(at, r_ambi / rad[13]); + at++; + SETFLOAT(at, r_ambi / rad[14]); + at++; + SETFLOAT(at, r_ambi / rad[15]); + at++; + + SETFLOAT(at, r_ambi / rad[16]); + at++; + SETFLOAT(at, r_ambi / rad[17]); + at++; + SETFLOAT(at, r_ambi / rad[18]); + at++; + + SETFLOAT(at, r_ambi / rad[19]); + at++; + SETFLOAT(at, r_ambi / rad[20]); + at++; + SETFLOAT(at, r_ambi / rad[21]); + at++; + + SETFLOAT(at, r_ambi / rad[22]); + at++; + SETFLOAT(at, r_ambi / rad[23]); + at++; + SETFLOAT(at, r_ambi / rad[24]); + + outlet_anything(x->x_early_out, x->x_s_damp, 25, x->x_para_at); + + + /* encoder-winkel-reihenfolge: index delta phi + 0, + +1x, +1y, +1z, -1x, -1y, -1z + +2x, +2y, +2z, -2x, -2y, -2z + +1x+1y, +1x+1z, +1y+1z + -1x-1y, -1x-1z, -1y-1z + +1x-1y, +1x-1z, +1y-1z + -1x+1y, -1x+1z, -1y+1z + */ + + at = x->x_para_at+1; + SETFLOAT(at, early_reflections_3d_calc_elevation(x_180_over_pi, x0, y0, z0)); + at++; + SETFLOAT(at, early_reflections_3d_calc_azimuth(x_180_over_pi, x0, y0, z0)); + + outlet_anything(x->x_direct_out, x->x_s_index_delta_phi, 3, x->x_para_at); + + /* encoder-winkel-reihenfolge: bundle + 0, + +1x, +1y, +1z, -1x, -1y, -1z + +2x, +2y, +2z, -2x, -2y, -2z + +1x+1y, +1x+1z, +1y+1z + -1x-1y, -1x-1z, -1y-1z + +1x-1y, +1x-1z, +1y-1z + -1x+1y, -1x+1z, -1y+1z + */ + + delta[0] = early_reflections_3d_calc_elevation(x_180_over_pi, xp1, y0, z0); + phi[0] = early_reflections_3d_calc_azimuth(x_180_over_pi, xp1, y0, z0); + delta[1] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, yp1, z0); + phi[1] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, yp1, z0); + delta[2] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, y0, zp1); + phi[2] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, y0, zp1); + delta[3] = early_reflections_3d_calc_elevation(x_180_over_pi, xn1, y0, z0); + phi[3] = early_reflections_3d_calc_azimuth(x_180_over_pi, xn1, y0, z0); + delta[4] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, yn1, z0); + phi[4] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, yn1, z0); + delta[5] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, y0, zn1); + phi[5] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, y0, zn1); + delta[6] = early_reflections_3d_calc_elevation(x_180_over_pi, xp2, y0, z0); + phi[6] = early_reflections_3d_calc_azimuth(x_180_over_pi, xp2, y0, z0); + delta[7] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, yp2, z0); + phi[7] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, yp2, z0); + delta[8] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, y0, zp2); + phi[8] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, y0, zp2); + delta[9] = early_reflections_3d_calc_elevation(x_180_over_pi, xn2, y0, z0); + phi[9] = early_reflections_3d_calc_azimuth(x_180_over_pi, xn2, y0, z0); + delta[10] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, yn2, z0); + phi[10] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, yn2, z0); + delta[11] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, y0, zn2); + phi[11] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, y0, zn2); + delta[12] = early_reflections_3d_calc_elevation(x_180_over_pi, xp1, yp1, z0); + phi[12] = early_reflections_3d_calc_azimuth(x_180_over_pi, xp1, yp1, z0); + delta[13] = early_reflections_3d_calc_elevation(x_180_over_pi, xp1, y0, zp1); + phi[13] = early_reflections_3d_calc_azimuth(x_180_over_pi, xp1, y0, zp1); + delta[14] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, yp1, zp1); + phi[14] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, yp1, zp1); + delta[15] = early_reflections_3d_calc_elevation(x_180_over_pi, xn1, yn1, z0); + phi[15] = early_reflections_3d_calc_azimuth(x_180_over_pi, xn1, yn1, z0); + delta[16] = early_reflections_3d_calc_elevation(x_180_over_pi, xn1, y0, zn1); + phi[16] = early_reflections_3d_calc_azimuth(x_180_over_pi, xn1, y0, zn1); + delta[17] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, yn1, zn1); + phi[17] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, yn1, zn1); + delta[18] = early_reflections_3d_calc_elevation(x_180_over_pi, xp1, yn1, z0); + phi[18] = early_reflections_3d_calc_azimuth(x_180_over_pi, xp1, yn1, z0); + delta[19] = early_reflections_3d_calc_elevation(x_180_over_pi, xp1, y0, zn1); + phi[19] = early_reflections_3d_calc_azimuth(x_180_over_pi, xp1, y0, zn1); + delta[20] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, yp1, zn1); + phi[20] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, yp1, zn1); + delta[21] = early_reflections_3d_calc_elevation(x_180_over_pi, xn1, yp1, z0); + phi[21] = early_reflections_3d_calc_azimuth(x_180_over_pi, xn1, yp1, z0); + delta[22] = early_reflections_3d_calc_elevation(x_180_over_pi, xn1, y0, zp1); + phi[22] = early_reflections_3d_calc_azimuth(x_180_over_pi, xn1, y0, zp1); + delta[23] = early_reflections_3d_calc_elevation(x_180_over_pi, x0, yn1, zp1); + phi[23] = early_reflections_3d_calc_azimuth(x_180_over_pi, x0, yn1, zp1); + + if(x->x_bundle) + { + at = x->x_para_at+1; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[0], phi[0])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[1], phi[1])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[2], phi[2])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[3], phi[3])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[4], phi[4])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[5], phi[5])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[6], phi[6])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[7], phi[7])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[8], phi[8])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[9], phi[9])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[10], phi[10])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[11], phi[11])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[12], phi[12])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[13], phi[13])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[14], phi[14])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[15], phi[15])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[16], phi[16])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[17], phi[17])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[18], phi[18])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[19], phi[19])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[20], phi[20])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[21], phi[21])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[22], phi[22])); + at++; + SETFLOAT(at, early_reflections_3d_calc_bundle_index(delta[23], phi[23])); + outlet_anything(x->x_early_out, x->x_s_bundle, 25, x->x_para_at); + } + + at = x->x_para_at+1; + SETFLOAT(at, 1.0f); + at++; + SETFLOAT(at, delta[0]); + at++; + SETFLOAT(at, phi[0]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 2.0f); + at++; + SETFLOAT(at, delta[1]); + at++; + SETFLOAT(at, phi[1]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 3.0f); + at++; + SETFLOAT(at, delta[2]); + at++; + SETFLOAT(at, phi[2]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 4.0f); + at++; + SETFLOAT(at, delta[3]); + at++; + SETFLOAT(at, phi[3]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 5.0f); + at++; + SETFLOAT(at, delta[4]); + at++; + SETFLOAT(at, phi[4]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 6.0f); + at++; + SETFLOAT(at, delta[5]); + at++; + SETFLOAT(at, phi[5]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 7.0f); + at++; + SETFLOAT(at, delta[6]); + at++; + SETFLOAT(at, phi[6]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 8.0f); + at++; + SETFLOAT(at, delta[7]); + at++; + SETFLOAT(at, phi[7]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 9.0f); + at++; + SETFLOAT(at, delta[8]); + at++; + SETFLOAT(at, phi[8]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 10.0f); + at++; + SETFLOAT(at, delta[9]); + at++; + SETFLOAT(at, phi[9]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 11.0f); + at++; + SETFLOAT(at, delta[10]); + at++; + SETFLOAT(at, phi[10]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 12.0f); + at++; + SETFLOAT(at, delta[11]); + at++; + SETFLOAT(at, phi[11]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 13.0f); + at++; + SETFLOAT(at, delta[12]); + at++; + SETFLOAT(at, phi[12]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 14.0f); + at++; + SETFLOAT(at, delta[13]); + at++; + SETFLOAT(at, phi[13]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 15.0f); + at++; + SETFLOAT(at, delta[14]); + at++; + SETFLOAT(at, phi[14]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 16.0f); + at++; + SETFLOAT(at, delta[15]); + at++; + SETFLOAT(at, phi[15]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 17.0f); + at++; + SETFLOAT(at, delta[16]); + at++; + SETFLOAT(at, phi[16]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 18.0f); + at++; + SETFLOAT(at, delta[17]); + at++; + SETFLOAT(at, phi[17]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 19.0f); + at++; + SETFLOAT(at, delta[18]); + at++; + SETFLOAT(at, phi[18]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 20.0f); + at++; + SETFLOAT(at, delta[19]); + at++; + SETFLOAT(at, phi[19]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 21.0f); + at++; + SETFLOAT(at, delta[20]); + at++; + SETFLOAT(at, phi[20]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 22.0f); + at++; + SETFLOAT(at, delta[21]); + at++; + SETFLOAT(at, phi[21]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 23.0f); + at++; + SETFLOAT(at, delta[22]); + at++; + SETFLOAT(at, phi[22]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + + at = x->x_para_at+1; + SETFLOAT(at, 24.0f); + at++; + SETFLOAT(at, delta[23]); + at++; + SETFLOAT(at, phi[23]); + outlet_anything(x->x_early_out, x->x_s_index_delta_phi, 4, x->x_para_at); + } +} + +static void early_reflections_3d_dump_para(t_early_reflections_3d *x) +{ + int i, n=x->x_n_src; + + post("*******************************************************************************"); + post("room-dimensions: L_x = %.3f, W_y = %.3f, H_z = %.3f", x->x_room_x, x->x_room_y, x->x_room_z); + post("hear-position: x_hear = %.3f, y_hear = %.3f, z_hear = %.3f", x->x_head_x, x->x_head_y, x->x_head_z); + for(i=0; ix_src_x[i], i+1, x->x_src_y[i], i+1, x->x_src_z[i], i+1); + post("ambisonic-radius: %f", x->x_r_ambi); + post("sonic-speed: %.3f", x->x_speed); + post("order of outputs: direct early rev"); + post("*******************************************************************************"); +} + +static void early_reflections_3d_para(t_early_reflections_3d *x, t_symbol *s, int argc, t_atom *argv) +{ + int i, n=x->x_n_src*3 + 7;/* r_ambi + 3*room + 3*head */ + + if(argc != n) + { + post("early_reflections_3d ERROR: para needs 1 r_ambi + 3*room + 3*head +n*3*src"); + return; + } + + x->x_r_ambi = atom_getfloat(argv++); + x->x_room_x = atom_getfloat(argv++); + x->x_room_y = atom_getfloat(argv++); + x->x_room_z = atom_getfloat(argv++); + x->x_head_x = atom_getfloat(argv++); + x->x_head_y = atom_getfloat(argv++); + x->x_head_z = atom_getfloat(argv++); + n = x->x_n_src; + for(i=0; ix_src_x[i] = atom_getfloat(argv++); + x->x_src_y[i] = atom_getfloat(argv++); + x->x_src_z[i] = atom_getfloat(argv++); + } + early_reflections_3d_doit(x); +} + +static void early_reflections_3d_sonic_speed(t_early_reflections_3d *x, t_floatarg speed) +{ + if(speed < 300.0f) + speed = 300.0f; + if(speed > 400.0f) + speed = 400.0f; + x->x_speed = speed; +} + +static void early_reflections_3d_bundle(t_early_reflections_3d *x, t_floatarg bundle) +{ + if(bundle == 0.0f) + x->x_bundle = 0; + else + x->x_bundle = 1; +} + +static void early_reflections_3d_free(t_early_reflections_3d *x) +{ +} + +static void *early_reflections_3d_new(t_floatarg fn_src) +{ + int i, n; + t_early_reflections_3d *x = (t_early_reflections_3d *)pd_new(early_reflections_3d_class); + + n = (int)fn_src; + if(n < 1) + n = 1; + if(n > 30) + n = 30; + x->x_n_src = n; + x->x_room_x = 12.0f; + x->x_room_y = 8.0f; + x->x_room_z = 4.0f; + x->x_head_x = 0.0f; + x->x_head_y = 0.0f; + x->x_head_z = 1.7f; + for(i=0; ix_src_x[i] = 3.0f; + x->x_src_y[i] = 0.5f; + x->x_src_z[i] = 2.5f; + } + x->x_r_ambi = 1.4f; + x->x_speed = 340.0f; + + x->x_s_del0 = gensym("del0"); + x->x_s_del1 = gensym("del1"); + x->x_s_del2 = gensym("del2"); + x->x_s_damp = gensym("damp"); + x->x_s_index_delta_phi = gensym("index_delta_phi"); + x->x_s_bundle = gensym("bundle"); + x->x_direct_out = outlet_new(&x->x_obj, &s_list); + x->x_early_out = outlet_new(&x->x_obj, &s_list); + x->x_rev_out = outlet_new(&x->x_obj, &s_list); + x->x_180_over_pi = (t_float)(180.0 / (4.0 * atan(1.0))); + x->x_bundle = 0; + return (x); +} + +void early_reflections_3d_setup(void) +{ + early_reflections_3d_class = class_new(gensym("early_reflections_3d"), (t_newmethod)early_reflections_3d_new, (t_method)early_reflections_3d_free, + sizeof(t_early_reflections_3d), 0, A_DEFFLOAT, 0); + class_addmethod(early_reflections_3d_class, (t_method)early_reflections_3d_para, gensym("para"), A_GIMME, 0); + class_addmethod(early_reflections_3d_class, (t_method)early_reflections_3d_sonic_speed, gensym("sonic_speed"), A_FLOAT, 0); + class_addmethod(early_reflections_3d_class, (t_method)early_reflections_3d_bundle, gensym("bundle"), A_FLOAT, 0); + class_addmethod(early_reflections_3d_class, (t_method)early_reflections_3d_dump_para, gensym("dump_para"), 0); + class_sethelpsymbol(early_reflections_3d_class, gensym("iemhelp2/early_reflections_3d-help")); +} diff --git a/src/iem_roomsim.c b/src/iem_roomsim.c new file mode 100644 index 0000000..2059d6c --- /dev/null +++ b/src/iem_roomsim.c @@ -0,0 +1,34 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_roomsim written by Thomas Musil (c) IEM KUG Graz Austria 2002 - 2006 */ + +#include "m_pd.h" +#include "iemlib.h" + +static t_class *iem_roomsim_class; + +static void *iem_roomsim_new(void) +{ + t_object *x = (t_object *)pd_new(iem_roomsim_class); + + return (x); +} + +void early_reflections_3d_setup(void); +void early_reflections_2d_setup(void); +void cart2del_damp_2d_setup(void); +void cart2del_damp_3d_setup(void); + +/* ------------------------ setup routine ------------------------- */ + +void iem_roomsim_setup(void) +{ + early_reflections_3d_setup(); + early_reflections_2d_setup(); + cart2del_damp_2d_setup(); + cart2del_damp_3d_setup(); + + post("iem_roomsim (R-1.16) library loaded! (c) Thomas Musil 05.2005"); + post(" musil%ciem.at iem KUG Graz Austria", '@'); +} diff --git a/src/iem_roomsim.dsp b/src/iem_roomsim.dsp new file mode 100644 index 0000000..83938ce --- /dev/null +++ b/src/iem_roomsim.dsp @@ -0,0 +1,85 @@ +# Microsoft Developer Studio Project File - Name="iem_roomsim" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=iem_roomsim - Win32 Debug +!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "iem_roomsim.mak". +!MESSAGE +!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "iem_roomsim.mak" CFG="iem_roomsim - Win32 Debug" +!MESSAGE +!MESSAGE Für die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "iem_roomsim - Win32 Release" (basierend auf "Win32 (x86) External Target") +!MESSAGE "iem_roomsim - Win32 Debug" (basierend auf "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "iem_roomsim - Win32 Release" + +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f makefile_win" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "makefile_win.exe" +# PROP BASE Bsc_Name "makefile_win.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "NMAKE /f makefile_win" +# PROP Rebuild_Opt "/a" +# PROP Target_File "iem_roomsim.exe" +# PROP Bsc_Name "iem_roomsim.bsc" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "iem_roomsim - Win32 Debug" + +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f makefile_win" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "makefile_win.exe" +# PROP BASE Bsc_Name "makefile_win.bsc" +# PROP BASE Target_Dir "" +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "NMAKE /f makefile_win" +# PROP Rebuild_Opt "/a" +# PROP Target_File "iem_roomsim.exe" +# PROP Bsc_Name "iem_roomsim.bsc" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "iem_roomsim - Win32 Release" +# Name "iem_roomsim - Win32 Debug" + +!IF "$(CFG)" == "iem_roomsim - Win32 Release" + +!ELSEIF "$(CFG)" == "iem_roomsim - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\makefile_win +# End Source File +# End Target +# End Project diff --git a/src/iem_roomsim.dsw b/src/iem_roomsim.dsw new file mode 100644 index 0000000..823c3cb --- /dev/null +++ b/src/iem_roomsim.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN! + +############################################################################### + +Project: "iem_roomsim"=.\iem_roomsim.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/src/iemlib.h b/src/iemlib.h new file mode 100644 index 0000000..b895ecf --- /dev/null +++ b/src/iemlib.h @@ -0,0 +1,102 @@ +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iemlib.h written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ + +#ifndef __IEMLIB_H__ +#define __IEMLIB_H__ + + +#define IS_A_POINTER(atom,index) ((atom+index)->a_type == A_POINTER) +#define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT) +#define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL) +#define IS_A_DOLLAR(atom,index) ((atom+index)->a_type == A_DOLLAR) +#define IS_A_DOLLSYM(atom,index) ((atom+index)->a_type == A_DOLLSYM) +#define IS_A_SEMI(atom,index) ((atom+index)->a_type == A_SEMI) +#define IS_A_COMMA(atom,index) ((atom+index)->a_type == A_COMMA) + + +#ifdef NT +int sys_noloadbang; +//t_symbol *iemgui_key_sym=0; +#include +#else +extern int sys_noloadbang; +//extern t_symbol *iemgui_key_sym; +#include +#endif + +#define DEFDELVS 64 +#define XTRASAMPS 4 +#define SAMPBLK 4 + + +#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */ + +/* machine-dependent definitions. These ifdefs really +should have been by CPU type and not by operating system! */ +#ifdef IRIX +/* big-endian. Most significant byte is at low address in memory */ +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#define int32 long /* a data type that has 32 bits */ +#else +#ifdef MSW +/* little-endian; most significant byte is at highest address */ +#define HIOFFSET 1 +#define LOWOFFSET 0 +#define int32 long +#else +#ifdef __FreeBSD__ +#include +#if BYTE_ORDER == LITTLE_ENDIAN +#define HIOFFSET 1 +#define LOWOFFSET 0 +#else +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#endif /* BYTE_ORDER */ +#include +#define int32 int32_t +#endif +#ifdef __linux__ + +#include + +#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN) +#error No byte order defined +#endif + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define HIOFFSET 1 +#define LOWOFFSET 0 +#else +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#endif /* __BYTE_ORDER */ + +#include +#define int32 int32_t + +#else +#ifdef __APPLE__ +#define HIOFFSET 0 /* word offset to find MSB */ +#define LOWOFFSET 1 /* word offset to find LSB */ +#define int32 int /* a data type that has 32 bits */ + +#endif /* __APPLE__ */ +#endif /* __linux__ */ +#endif /* MSW */ +#endif /* SGI */ + +union tabfudge +{ + double tf_d; + int32 tf_i[2]; +}; + +#define IEM_DENORMAL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \ +(((*(unsigned int*)&(f))&0x60000000)==0x60000000)) +/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */ + +#endif diff --git a/src/makefile b/src/makefile new file mode 100644 index 0000000..9efcae6 --- /dev/null +++ b/src/makefile @@ -0,0 +1,50 @@ +current: all + +.SUFFIXES: .pd_linux + +INCLUDE = -I. -I/usr/local/src/pd/src + +LDFLAGS = -export-dynamic -shared +LIB = -ldl -lm -lpthread + +#select either the DBG and OPT compiler flags below: + +CFLAGS = -DPD -DUNIX -W -Werror -Wno-unused \ + -Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer -fno-strict-aliasing \ + -DDL_OPEN + +SYSTEM = $(shell uname -m) + +# the sources + +SRC = early_reflections_3d.c \ + early_reflections_2d.c \ + cart2del_damp_2d.c \ + cart2del_damp_3d.c \ + iem_roomsim.c + +TARGET = iem_roomsim.pd_linux + + +OBJ = $(SRC:.c=.o) + +# +# ------------------ targets ------------------------------------ +# + +clean: + rm ..\$(TARGET) + rm *.o + +all: $(OBJ) + @echo :: $(OBJ) + $(LD) $(LDFLAGS) -o $(TARGET) *.o $(LIB) + strip --strip-unneeded $(TARGET) + mv $(TARGET) .. + +$(OBJ) : %.o : %.c + $(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c + + + + diff --git a/src/makefile_linux b/src/makefile_linux new file mode 100644 index 0000000..9efcae6 --- /dev/null +++ b/src/makefile_linux @@ -0,0 +1,50 @@ +current: all + +.SUFFIXES: .pd_linux + +INCLUDE = -I. -I/usr/local/src/pd/src + +LDFLAGS = -export-dynamic -shared +LIB = -ldl -lm -lpthread + +#select either the DBG and OPT compiler flags below: + +CFLAGS = -DPD -DUNIX -W -Werror -Wno-unused \ + -Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer -fno-strict-aliasing \ + -DDL_OPEN + +SYSTEM = $(shell uname -m) + +# the sources + +SRC = early_reflections_3d.c \ + early_reflections_2d.c \ + cart2del_damp_2d.c \ + cart2del_damp_3d.c \ + iem_roomsim.c + +TARGET = iem_roomsim.pd_linux + + +OBJ = $(SRC:.c=.o) + +# +# ------------------ targets ------------------------------------ +# + +clean: + rm ..\$(TARGET) + rm *.o + +all: $(OBJ) + @echo :: $(OBJ) + $(LD) $(LDFLAGS) -o $(TARGET) *.o $(LIB) + strip --strip-unneeded $(TARGET) + mv $(TARGET) .. + +$(OBJ) : %.o : %.c + $(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c + + + + diff --git a/src/makefile_win b/src/makefile_win new file mode 100644 index 0000000..3167d6c --- /dev/null +++ b/src/makefile_win @@ -0,0 +1,41 @@ + +all: ..\iem_roomsim.dll + +VIS_CPP_PATH = "C:\Programme\Microsoft Visual Studio\Vc98" + +PD_INST_PATH = "C:\Programme\pd-0.39-2" + +PD_WIN_INCLUDE_PATH = /I. /I$(PD_INST_PATH)\src /I$(VIS_CPP_PATH)\include + +PD_WIN_C_FLAGS = /nologo /W3 /WX /DMSW /DNT /DPD /DWIN32 /DWINDOWS /Ox -DPA_LITTLE_ENDIAN + +PD_WIN_L_FLAGS = /nologo + +PD_WIN_LIB = /NODEFAULTLIB:libc /NODEFAULTLIB:oldnames /NODEFAULTLIB:kernel /NODEFAULTLIB:uuid \ + $(VIS_CPP_PATH)\lib\libc.lib \ + $(VIS_CPP_PATH)\lib\oldnames.lib \ + $(VIS_CPP_PATH)\lib\kernel32.lib \ + $(VIS_CPP_PATH)\lib\wsock32.lib \ + $(VIS_CPP_PATH)\lib\winmm.lib \ + $(PD_INST_PATH)\bin\pthreadVC.lib \ + $(PD_INST_PATH)\bin\pd.lib + + +SRC = early_reflections_3d.c \ + early_reflections_2d.c \ + cart2del_damp_2d.c \ + cart2del_damp_3d.c \ + iem_roomsim.c + + +OBJ = $(SRC:.c=.obj) + +.c.obj: + cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c + +..\iem_roomsim.dll: $(OBJ) + link $(PD_WIN_L_FLAGS) /dll /export:iem_roomsim_setup \ + /out:..\iem_roomsim.dll $(OBJ) $(PD_WIN_LIB) + +clean: + del *.obj -- cgit v1.2.1