Update of /cvsroot/pure-data/externals/iem/iem_bin_ambi/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv443/src
Added Files: bin_ambi_calc_HRTF.c bin_ambi_reduced_decode.c iem_bin_ambi.c iem_bin_ambi.dsp iem_bin_ambi.dsw iem_bin_ambi.h iemlib.h Log Message: added the binaural ambisonic decoder
--- NEW FILE: iem_bin_ambi.c --- /* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
iem_bin_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
#ifdef NT #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif
#include "m_pd.h" #include "iemlib.h"
static t_class *iem_bin_ambi_class;
static void *iem_bin_ambi_new(void) { t_object *x = (t_object *)pd_new(iem_bin_ambi_class);
return (x); }
void bin_ambi_calc_HRTF_setup(void); void bin_ambi_reduced_decode_setup(void);
/* ------------------------ setup routine ------------------------- */
void iem_bin_ambi_setup(void) { bin_ambi_calc_HRTF_setup(); bin_ambi_reduced_decode_setup();
post("iem_bin_ambi (R-1.15) library loaded!"); }
--- NEW FILE: iem_bin_ambi.h --- /* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
iem_bin_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
#ifndef __IEMBINAMBI_H__ #define __IEMBINAMBI_H__
typedef struct { float real; float imag; } BIN_AMBI_COMPLEX;
#endif
--- NEW FILE: iem_bin_ambi.dsw --- (This appears to be a binary file; contents omitted.)
--- NEW FILE: iemlib.h --- /* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
iem_bin_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
#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 <io.h> #else extern int sys_noloadbang; //extern t_symbol *iemgui_key_sym; #include <unistd.h> #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 NT /* little-endian; most significant byte is at highest address */ #define HIOFFSET 1 #define LOWOFFSET 0 #define int32 long #else #ifdef __linux__
#include <endian.h>
#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 <sys/types.h> #define int32 int32_t
#endif /* __linux__ */ #endif /* NT */ #endif /* SGI */
union tabfudge { double tf_d; int32 tf_i[2]; };
#endif
--- NEW FILE: iem_bin_ambi.dsp --- # Microsoft Developer Studio Project File - Name="iem_bin_ambi" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) External Target" 0x0106
CFG=iem_bin_ambi - 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_bin_ambi.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_bin_ambi.mak" CFG="iem_bin_ambi - Win32 Debug" !MESSAGE !MESSAGE Für die Konfiguration stehen zur Auswahl: !MESSAGE !MESSAGE "iem_bin_ambi - Win32 Release" (basierend auf "Win32 (x86) External Target") !MESSAGE "iem_bin_ambi - Win32 Debug" (basierend auf "Win32 (x86) External Target") !MESSAGE
# Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath ""
!IF "$(CFG)" == "iem_bin_ambi - 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_bin_ambi.exe" # PROP Bsc_Name "iem_bin_ambi.bsc" # PROP Target_Dir ""
!ELSEIF "$(CFG)" == "iem_bin_ambi - 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_bin_ambi.exe" # PROP Bsc_Name "iem_bin_ambi.bsc" # PROP Target_Dir ""
!ENDIF
# Begin Target
# Name "iem_bin_ambi - Win32 Release" # Name "iem_bin_ambi - Win32 Debug"
!IF "$(CFG)" == "iem_bin_ambi - Win32 Release"
!ELSEIF "$(CFG)" == "iem_bin_ambi - Win32 Debug"
!ENDIF
# Begin Source File
SOURCE=.\makefile_win # End Source File # End Target # End Project
--- NEW FILE: bin_ambi_reduced_decode.c --- /* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
iem_bin_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
#ifdef NT #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif
#include "m_pd.h" #include "iemlib.h" #include "iem_bin_ambi.h" #include <math.h> #include <stdio.h> #include <string.h>
[...1209 lines suppressed...] class_addmethod(bin_ambi_reduced_decode_class, (t_method)bin_ambi_reduced_decode_decoding, gensym("decoding"), 0); class_addmethod(bin_ambi_reduced_decode_class, (t_method)bin_ambi_reduced_decode_ambi_weight, gensym("ambi_weight"), A_GIMME, 0); class_addmethod(bin_ambi_reduced_decode_class, (t_method)bin_ambi_reduced_decode_sing_range, gensym("sing_range"), A_DEFFLOAT, 0); class_sethelpsymbol(bin_ambi_reduced_decode_class, gensym("iemhelp2/help-bin_ambi_reduced_decode")); } /* Reihenfolge: n_ambi x bin_ambi_reduced_decode_ls
bin_ambi_reduced_decode_calc_pinv
n_ambi x bin_ambi_reduced_decode_load_HRIR
n_ambi x bin_ambi_reduced_decode_check_arrays
n_ambi x bin_ambi_reduced_decode_calc_reduced
bin_ambi_reduced_decode_decoding
*/
--- NEW FILE: bin_ambi_calc_HRTF.c --- /* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution.
iem_bin_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2003 */
#ifdef NT #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif
#include "m_pd.h" #include "iemlib.h" #include "iem_bin_ambi.h" #include <math.h> #include <stdio.h> #include <string.h>
/* -------------------------- bin_ambi_calc_HRTF ------------------------------ */ /* ** berechnet ein reduziertes Ambisonic-Decoder-Set in die HRTF-Spektren ** ** Inputs: ls + Liste von 3 floats: Index [1 .. 16] + Elevation [-90 .. +90 degree] + Azimut [0 .. 360 degree] ** ** Inputs: calc_inv ** ** Inputs: load_HRIR + float index1..16 ** ** Outputs: List of 2 symbols: left-HRIR-File-name + HRIR-table-name ** ** Inputs: calc_reduced ** ** "output" ... writes the HRTF into tables ** ** ** ** ** ** setzt voraus , dass die HRIR-tabele-names von LS1_L_HRIR .. LS16_L_HRIR heissen und existieren ** ** setzt voraus , dass die HRTF-tabele-names von LS1_HRTF_re .. LS16_HRTF_re heissen und existieren ** ** setzt voraus , dass die HRTF-tabele-names von LS1_HRTF_im .. LS16_HRTF_im heissen und existieren ** */
typedef struct _bin_ambi_calc_HRTF { t_object x_obj; t_atom x_at[2]; int x_n_ls; int x_fftsize; int *x_delta; int *x_phi; BIN_AMBI_COMPLEX *x_spec; BIN_AMBI_COMPLEX *x_sin_cos; float *x_beg_fade_out_hrir; float *x_beg_hrir; float **x_beg_hrtf_re; float **x_beg_hrtf_im; t_symbol **x_hrir_filename; t_symbol **x_s_hrir; t_symbol **x_s_hrtf_re; t_symbol **x_s_hrtf_im; t_symbol *x_s_fade_out_hrir; double x_pi_over_180; } t_bin_ambi_calc_HRTF;
static t_class *bin_ambi_calc_HRTF_class;
static void bin_ambi_calc_HRTF_init_cos(t_bin_ambi_calc_HRTF *x) { int i, fftsize = x->x_fftsize; float f, g; BIN_AMBI_COMPLEX *sincos = x->x_sin_cos;
g = 2.0f * 3.1415926538f / (float)fftsize; for(i=0; i<fftsize; i++) { f = g * (float)i; (*sincos).real = cos(f); (*sincos).imag = sin(f);/*change*/ sincos++; } }
static void bin_ambi_calc_HRTF_quant(t_bin_ambi_calc_HRTF *x, double *delta_deg2rad, double *phi_deg2rad, int index) { double q = 1.0; double d = *delta_deg2rad; double p = *phi_deg2rad; int i;
if(d < -40.0) d = -40.0; if(d > 90.0) d = 90.0; while(p < 0.0) p += 360.0; while(p >= 360.0) p -= 360.0;
if(d < -35.0) { *delta_deg2rad = -40.0; q = 360.0 / 56.0; } else if(d < -25.0) { *delta_deg2rad = -30.0; q = 6.0; } else if(d < -15.0) { *delta_deg2rad = -20.0; q = 5.0; } else if(d < -5.0) { *delta_deg2rad = -10.0; q = 5.0; } else if(d < 5.0) { *delta_deg2rad = 0.0; q = 5.0; } else if(d < 15.0) { *delta_deg2rad = 10.0; q = 5.0; } else if(d < 25.0) { *delta_deg2rad = 20.0; q = 5.0; } else if(d < 35.0) { *delta_deg2rad = 30.0; q = 6.0; } else if(d < 45.0) { *delta_deg2rad = 40.0; q = 360.0 / 56.0; } else if(d < 55.0) { *delta_deg2rad = 50.0; q = 8.0; } else if(d < 65.0) { *delta_deg2rad = 60.0; q = 10.0; } else if(d < 75.0) { *delta_deg2rad = 70.0; q = 15.0; } else if(d < 85.0) { *delta_deg2rad = 80.0; q = 30.0; } else { *delta_deg2rad = 90.0; q = 360.0; }
p /= q; i = (int)(p + 0.499999); p = (double)i * q; i = (int)(p + 0.499999); while(i >= 360) i -= 360; p = (double)i; *phi_deg2rad = p;
x->x_delta[index] = (int)(*delta_deg2rad); x->x_phi[index] = i;
*delta_deg2rad *= x->x_pi_over_180; *phi_deg2rad *= x->x_pi_over_180; }
static void bin_ambi_calc_HRTF_do_2d(t_bin_ambi_calc_HRTF *x, int argc, t_atom *argv) { double delta=0.0, phi; int index; int n_ls = x->x_n_ls;
if(argc < 2) { post("bin_ambi_calc_HRTF ERROR: ls-input needs 1 index and 1 angle: ls_index + phi [degree]"); return; } index = (int)atom_getint(argv++) - 1; phi = (double)atom_getfloat(argv);
if(index < 0) index = 0; if(index >= n_ls) index = n_ls - 1;
bin_ambi_calc_HRTF_quant(x, &delta, &phi, index); }
static void bin_ambi_calc_HRTF_do_3d(t_bin_ambi_calc_HRTF *x, int argc, t_atom *argv) { double delta, phi; int index; int n_ls=x->x_n_ls;
if(argc < 3) { post("bin_ambi_calc_HRTF ERROR: ls-input needs 1 index and 2 angles: ls index + delta [degree] + phi [degree]"); return; } index = (int)atom_getint(argv++) - 1; delta = atom_getfloat(argv++); phi = atom_getfloat(argv);
if(index < 0) index = 0; if(index >= n_ls) index = n_ls - 1; bin_ambi_calc_HRTF_quant(x, &delta, &phi, index); }
static void bin_ambi_calc_HRTF_ls(t_bin_ambi_calc_HRTF *x, t_symbol *s, int argc, t_atom *argv) { if(argc >= 3) bin_ambi_calc_HRTF_do_3d(x, argc, argv); else bin_ambi_calc_HRTF_do_2d(x, argc, argv); }
static void bin_ambi_calc_HRTF_check_fade_out(t_bin_ambi_calc_HRTF *x) { t_garray *a; int npoints; t_float *fadevec;
if((int)(x->x_beg_fade_out_hrir) == 0) { if (!(a = (t_garray *)pd_findbyclass(x->x_s_fade_out_hrir, garray_class))) error("%s: no such array", x->x_s_fade_out_hrir->s_name); else if (!garray_getfloatarray(a, &npoints, &fadevec)) error("%s: bad template for bin_ambi_calc_HRTF", x->x_s_fade_out_hrir->s_name); else if (npoints < x->x_fftsize) error("%s: bad array-size: %d", x->x_s_fade_out_hrir->s_name, npoints); else x->x_beg_fade_out_hrir = fadevec; } }
/* x_prod: n_ambi columns; n_ambi rows; */
static void bin_ambi_calc_HRTF_load_HRIR(t_bin_ambi_calc_HRTF *x, float findex) { int index=(int)findex - 1; int p; char buf[60];
if(index < 0) index = 0; if(index >= x->x_n_ls) index = x->x_n_ls - 1;
p = x->x_phi[index]; if(p)/*change*/ p = 360 - p; if(p < 10) sprintf(buf, "L%de00%da.wav", x->x_delta[index], p); else if(p < 100) sprintf(buf, "L%de0%da.wav", x->x_delta[index], p); else sprintf(buf, "L%de%da.wav", x->x_delta[index], p); x->x_hrir_filename[index] = gensym(buf);
SETSYMBOL(x->x_at, x->x_hrir_filename[index]); SETSYMBOL(x->x_at+1, x->x_s_hrir[index]); outlet_list(x->x_obj.ob_outlet, &s_list, 2, x->x_at); }
static void bin_ambi_calc_HRTF_check_arrays(t_bin_ambi_calc_HRTF *x, float findex) { int index=(int)findex - 1; int j, k, n; int fftsize = x->x_fftsize; int fs2=fftsize/2; t_garray *a; int npoints; t_float *vec_hrir, *vec, *vec_fade_out_hrir; t_float *vec_hrtf_re, *vec_hrtf_im; t_symbol *hrir, *hrtf_re, *hrtf_im; float decr, sum;
if(index < 0) index = 0; if(index >= x->x_n_ls) index = x->x_n_ls - 1;
hrir = x->x_s_hrir[index]; hrtf_re = x->x_s_hrtf_re[index]; hrtf_im = x->x_s_hrtf_im[index];
if (!(a = (t_garray *)pd_findbyclass(hrtf_re, garray_class))) error("%s: no such array", hrtf_re->s_name); else if (!garray_getfloatarray(a, &npoints, &vec_hrtf_re)) error("%s: bad template for bin_ambi_calc_HRTF", hrtf_re->s_name); else if (npoints < fftsize) error("%s: bad array-size: %d", hrtf_re->s_name, npoints); else if (!(a = (t_garray *)pd_findbyclass(hrtf_im, garray_class))) error("%s: no such array", hrtf_im->s_name); else if (!garray_getfloatarray(a, &npoints, &vec_hrtf_im)) error("%s: bad template for bin_ambi_calc_HRTF", hrtf_im->s_name); else if (npoints < fftsize) error("%s: bad array-size: %d", hrtf_im->s_name, npoints); else if (!(a = (t_garray *)pd_findbyclass(hrir, garray_class))) error("%s: no such array", hrir->s_name); else if (!garray_getfloatarray(a, &npoints, &vec_hrir)) error("%s: bad template for bin_ambi_calc_HRTF", hrir->s_name); else { x->x_beg_hrtf_re[index] = vec_hrtf_re; x->x_beg_hrtf_im[index] = vec_hrtf_im;
if(npoints < fftsize) { post("warning: %s-array-size: %d", hrir->s_name, npoints); } vec = x->x_beg_hrir; vec += index * fftsize; if((int)(x->x_beg_fade_out_hrir)) { vec_fade_out_hrir = x->x_beg_fade_out_hrir; for(j=0; j<fs2; j++) vec[j] = vec_hrir[j]*vec_fade_out_hrir[j]; } else { post("no HRIR-fade-out-window found"); n = fs2 * 3; n /= 4; for(j=0; j<n; j++) vec[j] = vec_hrir[j]; sum = 1.0f; decr = 4.0f / (float)fs2; for(j=n, k=0; j<fs2; j++, k++) { sum -= decr; vec[j] = vec_hrir[j] * sum; } } } }
static void bin_ambi_calc_HRTF_calc_fft(t_bin_ambi_calc_HRTF *x, float findex) { int index=(int)findex - 1; int i, j, k, w_index, w_inc, i_inc, v_index, fs1, fs2; int fftsize = x->x_fftsize; BIN_AMBI_COMPLEX old1, old2, w; BIN_AMBI_COMPLEX *sincos = x->x_sin_cos; BIN_AMBI_COMPLEX *val = x->x_spec; t_float *vec_hrir, *vec_hrtf_re, *vec_hrtf_im; int n_ls = x->x_n_ls;
if(index < 0) index = 0; if(index >= n_ls) index = n_ls - 1;
vec_hrtf_re = x->x_beg_hrtf_re[index]; vec_hrtf_im = x->x_beg_hrtf_im[index];
vec_hrir = x->x_beg_hrir; vec_hrir += index * fftsize; for(k=0; k<fftsize; k++) { val[k].real = vec_hrir[k]; val[k].imag = 0.0f; }
fs1 = fftsize - 1; fs2 = fftsize / 2; i_inc = fs2; w_inc = 1; for(i=1; i<fftsize; i<<=1) { v_index = 0; for(j=0; j<i; j++) { w_index = 0; for(k=0; k<i_inc; k++) { old1 = val[v_index]; old2 = val[v_index+i_inc]; w = sincos[w_index]; val[v_index+i_inc].real = (old1.real-old2.real)*w.real - (old1.imag-old2.imag)*w.imag; val[v_index+i_inc].imag = (old1.imag - old2.imag)*w.real + (old1.real-old2.real)*w.imag; val[v_index].real = old1.real+old2.real; val[v_index].imag = old1.imag+old2.imag; w_index += w_inc; v_index++; } v_index += i_inc; } w_inc <<= 1; i_inc >>= 1; }
j = 0; for(i=1;i<fs1;i++) { k = fs2; while(k <= j) { j = j - k; k >>= 1; } j = j + k; if(i < j) { old1 = val[j]; val[j] = val[i]; val[i] = old1; } }
vec_hrtf_re[0] = val[0].real; vec_hrtf_im[0] = 0.0f; for( i = 1; i < fs2; i++ ) { vec_hrtf_re[i] = 2.0f*val[i].real; vec_hrtf_im[i] = 2.0f*val[i].imag; } vec_hrtf_re[fs2] = 0.0f; vec_hrtf_im[fs2] = 0.0f; }
static void bin_ambi_calc_HRTF_free(t_bin_ambi_calc_HRTF *x) { freebytes(x->x_hrir_filename, x->x_n_ls * sizeof(t_symbol *)); freebytes(x->x_s_hrir, x->x_n_ls * sizeof(t_symbol *)); freebytes(x->x_s_hrtf_re, x->x_n_ls * sizeof(t_symbol *)); freebytes(x->x_s_hrtf_im, x->x_n_ls * sizeof(t_symbol *));
freebytes(x->x_delta, x->x_n_ls * sizeof(int)); freebytes(x->x_phi, x->x_n_ls * sizeof(int));
freebytes(x->x_spec, x->x_fftsize * sizeof(BIN_AMBI_COMPLEX)); freebytes(x->x_sin_cos, x->x_fftsize * sizeof(BIN_AMBI_COMPLEX));
freebytes(x->x_beg_hrir, x->x_fftsize * x->x_n_ls * sizeof(float)); freebytes(x->x_beg_hrtf_re, x->x_n_ls * sizeof(float *)); freebytes(x->x_beg_hrtf_im, x->x_n_ls * sizeof(float *)); }
/* 1.arg: t_symbol *hrir_name; 2.arg: t_symbol *hrtf_re_name; 3.arg: t_symbol *hrtf_im_name; 4.arg: t_symbol *hrir_fade_out_name; 5.arg: int ambi_order; 6.arg: int dim; 7.arg: int n_ambi; 8.arg: int fftsize; */
static void *bin_ambi_calc_HRTF_new(t_symbol *s, int argc, t_atom *argv) { t_bin_ambi_calc_HRTF *x = (t_bin_ambi_calc_HRTF *)pd_new(bin_ambi_calc_HRTF_class); char buf[400]; int i, j, fftok; int n_ls, fftsize; t_symbol *s_hrir; t_symbol *s_hrtf_re; t_symbol *s_hrtf_im;
if((argc >= 6) && IS_A_SYMBOL(argv,0) && IS_A_SYMBOL(argv,1) && IS_A_SYMBOL(argv,2) && IS_A_SYMBOL(argv,3) && IS_A_FLOAT(argv,4) && IS_A_FLOAT(argv,5)) { s_hrir = (t_symbol *)atom_getsymbolarg(0, argc, argv); s_hrtf_re = (t_symbol *)atom_getsymbolarg(1, argc, argv); s_hrtf_im = (t_symbol *)atom_getsymbolarg(2, argc, argv); x->x_s_fade_out_hrir = (t_symbol *)atom_getsymbolarg(3, argc, argv);
n_ls = (int)atom_getintarg(4, argc, argv); fftsize = (int)atom_getintarg(5, argc, argv);
if(n_ls < 1) n_ls = 1;
j = 2; fftok = 0; for(i=0; i<21; i++) { if(j == fftsize) { fftok = 1; i = 22; } j *= 2; }
if(!fftok) { post("bin_ambi_calc_HRTF-ERROR: fftsize not equal to 2 ^ n !!!"); return(0); }
x->x_n_ls = n_ls; x->x_fftsize = fftsize;
x->x_hrir_filename = (t_symbol **)getbytes(x->x_n_ls * sizeof(t_symbol *)); x->x_s_hrir = (t_symbol **)getbytes(x->x_n_ls * sizeof(t_symbol *)); x->x_s_hrtf_re = (t_symbol **)getbytes(x->x_n_ls * sizeof(t_symbol *)); x->x_s_hrtf_im = (t_symbol **)getbytes(x->x_n_ls * sizeof(t_symbol *)); for(i=0; i<n_ls; i++) { sprintf(buf, "%d%s", i+1, s_hrir->s_name); x->x_s_hrir[i] = gensym(buf);
sprintf(buf, "%d%s", i+1, s_hrtf_re->s_name); x->x_s_hrtf_re[i] = gensym(buf);
sprintf(buf, "%d%s", i+1, s_hrtf_im->s_name); x->x_s_hrtf_im[i] = gensym(buf); }
x->x_delta = (int *)getbytes(x->x_n_ls * sizeof(int)); x->x_phi = (int *)getbytes(x->x_n_ls * sizeof(int));
x->x_spec = (BIN_AMBI_COMPLEX *)getbytes(x->x_fftsize * sizeof(BIN_AMBI_COMPLEX)); x->x_sin_cos = (BIN_AMBI_COMPLEX *)getbytes(x->x_fftsize * sizeof(BIN_AMBI_COMPLEX));
x->x_beg_fade_out_hrir = (float *)0; x->x_beg_hrir = (float *)getbytes(x->x_fftsize * x->x_n_ls * sizeof(float)); x->x_beg_hrtf_re = (float **)getbytes(x->x_n_ls * sizeof(float *)); x->x_beg_hrtf_im = (float **)getbytes(x->x_n_ls * sizeof(float *));
x->x_pi_over_180 = 4.0 * atan(1.0) / 180.0;
bin_ambi_calc_HRTF_init_cos(x);
outlet_new(&x->x_obj, &s_list); return(x); } else { post("bin_ambi_calc_HRTF-ERROR: need 4 symbols + 2 floats arguments:"); post(" hrir_name + hrtf_re_name + hrtf_im_name + hrir_fade_out_name +"); post(" number_of_loudspeakers + fftsize"); return(0); } }
void bin_ambi_calc_HRTF_setup(void) { bin_ambi_calc_HRTF_class = class_new(gensym("bin_ambi_calc_HRTF"), (t_newmethod)bin_ambi_calc_HRTF_new, (t_method)bin_ambi_calc_HRTF_free, sizeof(t_bin_ambi_calc_HRTF), 0, A_GIMME, 0); class_addmethod(bin_ambi_calc_HRTF_class, (t_method)bin_ambi_calc_HRTF_ls, gensym("ls"), A_GIMME, 0); class_addmethod(bin_ambi_calc_HRTF_class, (t_method)bin_ambi_calc_HRTF_check_fade_out, gensym("check_fade_out"), 0); class_addmethod(bin_ambi_calc_HRTF_class, (t_method)bin_ambi_calc_HRTF_load_HRIR, gensym("load_HRIR"), A_FLOAT, 0); class_addmethod(bin_ambi_calc_HRTF_class, (t_method)bin_ambi_calc_HRTF_check_arrays, gensym("check_arrays"), A_FLOAT, 0); class_addmethod(bin_ambi_calc_HRTF_class, (t_method)bin_ambi_calc_HRTF_calc_fft, gensym("calc_fft"), A_FLOAT, 0); class_sethelpsymbol(bin_ambi_calc_HRTF_class, gensym("iemhelp2/help-bin_ambi_calc_HRTF")); } /* Reihenfolge: n_ls x bin_ambi_calc_HRTF_ls
bin_ambi_calc_HRTF_check_fade_out
n_ls x bin_ambi_calc_HRTF_load_HRIR
n_ls x bin_ambi_calc_HRTF_check_arrays
n_ls x bin_ambi_calc_HRTF_calc_fft
*/