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
*/