iem_ambi-0.2/0000755000175000017500000000000012163236210013343 5ustar zmoelnigzmoelnigiem_ambi-0.2/ambi_decode3-help.pd0000644000175000017500000002277712163235551017142 0ustar zmoelnigzmoelnig#N canvas 5 50 981 718 10; #X declare -stdlib extra/iem_ambi -stdlib extra/iemmatrix -stdlib extra/iemlib/iemlib2 ; #X text 27 436 1.arg: ambisonic order; #X text 794 41 -180 <= phi <= +180; #X text 494 172 input: one mul-factor for each; #X text 42 454 (1 .. 5 in case of 3 dimensional); #X text 42 445 (1 .. 12 in case of 2 dimensional); #X text 27 464 2.arg: dimension (2 or 3); #X text 78 645 IEM KUG; #X text 62 633 musil; #X text 92 633 @; #X text 98 633 iem.at; #X text 61 655 Graz \, Austria; #X text 13 622 (c) Thomas Musil 2000 - 2006; #X obj 109 347 cnv 15 126 15 empty empty empty 20 12 0 14 -260818 -66577 0; #X obj 108 368 round_zero 1e-06; #X obj 38 33 bng 35 250 50 0 empty empty empty 0 -6 0 8 -24198 -42246 -1; #X msg 246 121 ambi_weight 1 1 1 0.3904; #X msg 108 121 ambi_weight 1 1 1 1; #X msg 124 99 mirror_weight 0.7; #X msg 80 220 pht_ls \$1 \$2 \$3; #X obj 38 77 t b b b b b b b; #X msg 94 143 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; #X msg 94 177 real_ls \$1 \$2 \$3; #X msg 66 243 begin_pseudo_inverse; #X obj 108 346 ambi_decode3 3 3 13 6; #X msg 38 313 end_pseudo_inverse; #X msg 80 199 1 -45 0 \, 2 -45 90 \, 3 -45 180 \, 4 -45 270 \, 6 -90 0; #X msg 52 289 ipht_ireal_muladd \$1 \$2 \$3; #N canvas 337 146 567 517 mirror_phantom_ls_____ 0; #X msg 142 186 1 6 \$1; #X obj 102 58 inlet; #X obj 101 441 outlet; #X obj 162 59 inlet; #X obj 71 135 f; #X obj 103 135 f; #X obj 157 106 * 0.25; #X obj 214 106 * 0.5; #X msg 163 211 2 8 \$1; #X msg 40 187 1 13 \$1 \, 1 7 \$1; #X msg 61 212 2 7 \$1 \, 2 9 \$1; #X msg 179 241 3 10 \$1; #X msg 77 242 3 9 \$1 \, 3 11 \$1; #X msg 199 271 4 12 \$1; #X msg 87 271 4 11 \$1 \, 4 13 \$1; #X obj 162 81 route mirror_weight; #X obj 380 60 inlet; #X connect 0 0 2 0; #X connect 1 0 4 0; #X connect 1 0 5 0; #X connect 3 0 15 0; #X connect 4 0 9 0; #X connect 4 0 10 0; #X connect 4 0 12 0; #X connect 4 0 14 0; #X connect 5 0 0 0; #X connect 5 0 8 0; #X connect 5 0 11 0; #X connect 5 0 13 0; #X connect 6 0 4 1; #X connect 7 0 5 1; #X connect 8 0 2 0; #X connect 9 0 2 0; #X connect 10 0 2 0; #X connect 11 0 2 0; #X connect 12 0 2 0; #X connect 13 0 2 0; #X connect 14 0 2 0; #X connect 15 0 7 0; #X connect 15 0 6 0; #X restore 52 268 pd mirror_phantom_ls_____; #X text 18 9 ambi_decode3; #X text 160 14 AMBISONIC DECODING; #X text 131 40 up to 12.Order 2-dimensional; #X text 128 28 up to 5.Order 3-dimensional or; #X text 508 5 n_ao = ambisonic-order; #X text 520 42 all angles in degree; #X text 539 183 ambisonic order group to suppress the side-lobe-phenomena ; #X text 493 274 input: starts the encoding; #X text 536 285 of all (real + phantom) loudspeaker positions \,; #X text 537 309 and calculates the pseudo inverse.; #X text 540 297 multiplicates the ambi order weight; #X msg 276 230 sing_range 1e-10; #X text 799 328 mirror_weight; #X text 545 354 phantom speaker with the factor "mirror_weight" and adds; #X text 494 202 input: singularity range; #X text 537 213 when calculating the inverse of the matrix by gauss ; #X text 537 223 algorithm \, you have to divide a row by a certain number \,; #X text 537 243 outside of this range (> sing_range \, or < -sing_range). ; #X text 493 385 input: outputs only the first part of; #X text 539 398 the inverted matrix (row 1 to row n_pht_ls). The part ; #X text 541 410 with the phantom speakers \, we ignore.; #X obj 221 576 cnv 15 192 15 empty empty empty 20 12 0 14 -260818 -66577 0; #X obj 221 601 cnv 15 228 15 empty empty empty 20 12 0 14 -260818 -66577 0; #X text 537 255 Otherwise we say \, this matrix is singular.; #N canvas 152 51 413 549 real_speaker_example 0; #X obj 124 33 bng 35 250 50 0 empty empty empty 0 -6 0 8 -24198 -42246 -1; #X obj 143 217 cnv 15 120 15 empty empty empty 20 12 0 14 -260818 -66577 0; #X obj 142 261 print; #X obj 142 238 round_zero 1e-06; #X msg 161 121 real_ls \$1 \$2; #X msg 142 144 begin_pseudo_inverse; #X msg 124 167 end_pseudo_inverse; #X obj 142 216 ambi_decode3 2 2 5 0; #X obj 124 75 t b b b; #X msg 161 98 1 5 \, 2 2.5 \, 3 0 \, 4 -2.5 \, 5 -5; #X text 110 300 ambisonic system 2.order; #X text 137 313 2 dimensional; #X text 135 327 5 real speakers; #X text 100 347 arranged in a very small arc between; #X text 117 360 +5 degrees and -5 degrees; #X text 82 490 IEM KUG; #X text 66 478 musil; #X text 96 478 @; #X text 102 478 iem.at; #X text 65 500 Graz \, Austria; #X text 17 467 (c) Thomas Musil 2000 - 2006; #X connect 0 0 8 0; #X connect 3 0 2 0; #X connect 4 0 7 0; #X connect 5 0 7 0; #X connect 6 0 7 0; #X connect 7 0 3 0; #X connect 8 0 6 0; #X connect 8 1 5 0; #X connect 8 2 9 0; #X connect 9 0 4 0; #X restore 220 575 pd real_speaker_example singular; #N canvas 253 59 437 609 phantom_speaker_example 0; #X obj 79 30 bng 35 250 50 0 empty empty empty 0 -6 0 8 -24198 -42246 -1; #X obj 184 250 cnv 15 132 15 empty empty empty 20 12 0 14 -260818 -66577 0; #X obj 184 299 print; #X obj 184 274 round_zero 1e-06; #X msg 202 164 real_ls \$1 \$2; #X msg 184 187 begin_pseudo_inverse; #X msg 165 210 end_pseudo_inverse; #X obj 165 118 t b b b; #X msg 202 141 1 5 \, 2 2.5 \, 3 0 \, 4 -2.5 \, 5 -5; #X text 151 343 ambisonic system 2.order; #X text 178 356 2 dimensional; #X text 176 370 5 real speakers; #X msg 79 190 pht_ls \$1 \$2; #X obj 79 94 t f f; #X obj 79 125 + 1; #X obj 104 116 * 2.5; #X obj 104 138 + 7.5; #X obj 79 168 pack 0 0; #X obj 184 249 ambi_decode3 2 2 5 139; #X text 157 395 -5 degrees and +5 degrees; #X text 166 410 139 phantom speakers; #X text 140 382 arranged on a very small arc between; #X text 150 422 arranged on an arc between; #X text 154 436 +7.5 degrees and -7.5 degrees; #X text 86 558 IEM KUG; #X text 70 546 musil; #X text 100 546 @; #X text 106 546 iem.at; #X text 69 568 Graz \, Austria; #X text 21 535 (c) Thomas Musil 2000 - 2006; #N canvas 0 0 450 300 0..138 0; #X msg 90 142 138; #X obj 90 164 until; #X obj 90 186 i; #X obj 90 208 + 1; #X obj 90 230 t f f; #X msg 119 141 0; #X obj 63 99 t b b; #X obj 90 120 t b b; #X obj 63 72 inlet; #X obj 90 252 outlet; #X obj 180 252 outlet; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 3 0 4 0; #X connect 4 0 9 0; #X connect 4 1 2 1; #X connect 5 0 2 1; #X connect 6 0 10 0; #X connect 6 1 7 0; #X connect 7 0 0 0; #X connect 7 1 5 0; #X connect 8 0 6 0; #X restore 79 72 pd 0..138; #X connect 0 0 30 0; #X connect 3 0 2 0; #X connect 4 0 18 0; #X connect 5 0 18 0; #X connect 6 0 18 0; #X connect 7 0 6 0; #X connect 7 1 5 0; #X connect 7 2 8 0; #X connect 8 0 4 0; #X connect 12 0 18 0; #X connect 13 0 14 0; #X connect 13 1 15 0; #X connect 14 0 17 0; #X connect 15 0 16 0; #X connect 16 0 17 1; #X connect 17 0 12 0; #X connect 18 0 3 0; #X connect 30 0 13 0; #X connect 30 1 7 0; #X restore 220 600 pd phantom_speaker_example nonsingular; #X text 537 233 to achieve the identity matrix. This number has to be; #X obj 108 391 mtx_print; #X text 504 463 + n_col = (2*n_ao+1) = number of ambisonic-channels ; #X text 27 476 3.arg: number of real existing loudspeakers ; #X text 27 488 4.arg: number of virtual phantom_loudspeakers ; #X text 493 16 n_re_ls = number of real loudspeakers; #X text 493 28 n_vi_ls = number of virtual phantom loudspeakers; #X text 494 78 input: re_ls_index + phi .. 2-dimensional ; #X text 494 88 input: re_ls_index + theta + phi .. 3-dimensional ; #X text 494 118 input: vi_ls_index + phi .. 2-dimensional ; #X text 494 129 input: vi_ls_index + theta + phi .. 3-dimensional ; #X text 794 29 -90 <= theta <= +90; #X text 786 5 1 <= re_ls_index <= n_re_ls; #X text 786 16 1 <= vi_ls_index <= n_vi_ls; #X text 59 423 initial arguments:; #X text 334 18 calculates a ambisonic; #X text 358 29 decoder matrix; #X text 529 100 encodes the re_ls_index row of a matrix; #X text 525 141 encodes the (re_ls_index + vi_ls_index) row of a matrix ; #X text 532 153 we need them to achieve a nonsingular matrix; #X text 493 328 input: vi_ls_index re_ls_index ; #X text 811 443 floats :; #X text 851 503 floats :; #X text 516 513 n_row = (n_re_ls) = number of real loudspeakers ; #X text 516 453 n_row = (n_re_ls) = number of real loudspeakers ; #X text 784 523 ambisonic-channels; #X text 504 523 + n_col = (n_ao+1)*(nao+1) = number of; #X text 825 534 decoder matrix; #X text 504 474 + (2*n_ao + 1) * n_re_ls elements of the; #X text 504 534 + (n_ao+1)*(n_ao+1) * n_re_ls elements of the ; #X text 796 474 decoder matrix; #X text 490 443 output in case of 2d: (n_re_ls*(2*n_ao+1)+2) ; #X text 490 503 output in case of 3d: (n_re_ls*(n_ao+1)*(n_ao+1)+2) ; #X text 544 367 this column to the column "re_ls_index" of real speaker ; #X text 546 341 multiplies the column "vi_ls_index + n_re_ls" of; #N canvas 5 50 450 300 dependencies 0; #X text 41 49 this help-patch depends on several libraries:; #X text 90 66 iem_ambi; #X text 90 79 iemmatrix; #X obj 52 130 declare -stdlib extra/iem_ambi -stdlib extra/iemmatrix -stdlib extra/iemlib/iemlib2; #X text 91 91 iemlib2; #X restore 506 651 pd dependencies; #X connect 13 0 55 0; #X connect 14 0 19 0; #X connect 15 0 23 0; #X connect 16 0 23 0; #X connect 17 0 27 1; #X connect 18 0 23 0; #X connect 19 0 24 0; #X connect 19 1 27 0; #X connect 19 2 22 0; #X connect 19 3 25 0; #X connect 19 4 20 0; #X connect 19 5 16 0; #X connect 19 6 17 0; #X connect 20 0 21 0; #X connect 21 0 23 0; #X connect 22 0 23 0; #X connect 23 0 13 0; #X connect 24 0 23 0; #X connect 25 0 18 0; #X connect 26 0 23 0; #X connect 27 0 26 0; #X connect 39 0 23 0; iem_ambi-0.2/src/0000755000175000017500000000000012163236210014132 5ustar zmoelnigzmoelnigiem_ambi-0.2/src/makefile0000644000175000017500000000003011217735241015632 0ustar zmoelnigzmoelniginclude makefile_linux iem_ambi-0.2/src/VC9/0000755000175000017500000000000012163236207014541 5ustar zmoelnigzmoelnigiem_ambi-0.2/src/VC9/iem_ambi.vcproj0000644000175000017500000000357111603103256017531 0ustar zmoelnigzmoelnig iem_ambi-0.2/src/VC9/makefile_vc9proj0000644000175000017500000000176711603103256017723 0ustar zmoelnigzmoelnigTARGET = iem_ambi all: ..\$(TARGET).dll VIS_CPP_PATH = "C:\Program Files\Microsoft Visual Studio 9.0\VC" VIS_SDK_PATH = "C:\Program Files\Microsoft SDKs\Windows\v6.0A" PD_INST_PATH = "C:\Program Files\pd-0.43.0" 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 -D_CRT_SECURE_NO_WARNINGS PD_WIN_L_FLAGS = /nologo PD_WIN_LIB = /NODEFAULTLIB:libcmt /NODEFAULTLIB:oldnames /NODEFAULTLIB:kernel32 \ $(VIS_CPP_PATH)\lib\libcmt.lib \ $(VIS_CPP_PATH)\lib\oldnames.lib \ $(VIS_SDK_PATH)\lib\kernel32.lib \ $(PD_INST_PATH)\bin\pd.lib SRC = ambi_decode.c \ ambi_decode2.c \ ambi_decode3.c \ ambi_decode_cube.c \ ambi_encode.c \ ambi_rot.c \ iem_ambi.c OBJ = $(SRC:.c=.obj) .c.obj: cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c ..\$(TARGET).dll: $(OBJ) link $(PD_WIN_L_FLAGS) /dll /export:$(TARGET)_setup \ /out:..\$(TARGET).dll $(OBJ) $(PD_WIN_LIB) clean: del *.obj iem_ambi-0.2/src/VC9/iem_ambi.sln0000644000175000017500000000156111603103256017017 0ustar zmoelnigzmoelnig Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iem_ambi", "iem_ambi.vcproj", "{6A44952F-0D55-44EE-9032-928368583BEC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6A44952F-0D55-44EE-9032-928368583BEC}.Debug|Win32.ActiveCfg = Debug|Win32 {6A44952F-0D55-44EE-9032-928368583BEC}.Debug|Win32.Build.0 = Debug|Win32 {6A44952F-0D55-44EE-9032-928368583BEC}.Release|Win32.ActiveCfg = Release|Win32 {6A44952F-0D55-44EE-9032-928368583BEC}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal iem_ambi-0.2/src/iem_ambi.c0000644000175000017500000000167512163236107016056 0ustar zmoelnigzmoelnig/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ #include "m_pd.h" #include "iemlib.h" static t_class *iem_ambi_class; static void *iem_ambi_new(void) { t_object *x = (t_object *)pd_new(iem_ambi_class); return (x); } void ambi_encode_setup(void); void ambi_decode_setup(void); void ambi_decode2_setup(void); void ambi_decode3_setup(void); void ambi_decode_cube_setup(void); void ambi_rot_setup(void); /* ------------------------ setup routine ------------------------- */ void iem_ambi_setup(void) { ambi_encode_setup(); ambi_decode_setup(); ambi_decode2_setup(); ambi_decode3_setup(); ambi_decode_cube_setup(); ambi_rot_setup(); post("iem_ambi (R-0.2) library loaded! (c) Thomas Musil 2000-2012"); post(" musil%ciem.at iem KUG Graz Austria", '@'); } iem_ambi-0.2/src/makefile_linux0000644000175000017500000000162412163233266017064 0ustar zmoelnigzmoelnigcurrent: all .SUFFIXES: .pd_linux PDSOURCE?=/usr/local/src/pd/src PD_INCLUDE = -I. -I$(PDSOURCE) PD_LDFLAGS = -Wl,--export-dynamic -shared -fPIC LIB = -lc -lm #select either the DBG and OPT compiler flags below: PD_CFLAGS = -DPD -DUNIX \ -W -Wno-unused -Wno-parentheses -Wno-switch \ -funroll-loops -fomit-frame-pointer -fno-strict-aliasing \ -DDL_OPEN -fPIC CFLAGS="-O6" SYSTEM = $(shell uname -m) # the sources SRC = ambi_decode.c \ ambi_decode2.c \ ambi_decode3.c \ ambi_decode_cube.c \ ambi_encode.c \ ambi_rot.c \ iem_ambi.c TARGET = iem_ambi.pd_linux OBJ = $(SRC:.c=.o) # # ------------------ targets ------------------------------------ # clean: -rm -f ../$(TARGET) -rm -f *.o all: $(OBJ) @echo :: $(OBJ) $(CC) $(PD_LDFLAGS) $(LDFLAGS) -o $(TARGET) *.o $(LIB) mv $(TARGET) .. $(OBJ) : %.o : %.c $(CC) $(PD_CFLAGS) $(CFLAGS) $(PD_INCLUDE) $(INCLUDE) -c -o $*.o $*.c iem_ambi-0.2/src/iem_ambi.vcproj0000644000175000017500000000357111603103256017130 0ustar zmoelnigzmoelnig iem_ambi-0.2/src/ambi_decode2.c0000644000175000017500000004561310540330021016574 0ustar zmoelnigzmoelnig/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ #include "m_pd.h" #include "iemlib.h" #include "iem_ambi.h" #include /* -------------------------- ambi_decode2 ------------------------------ */ /* ** berechnet ein reduziertes Ambisonic-Decoder-Set in die HRTF-Spektren ** ** Inputs: ls + Liste von 3 floats: Index [1 .. 25] + Elevation [-90 .. +90 degree] + Azimut [0 .. 360 degree] ** ** Inputs: calc_inv ** ** Inputs: load_HRIR + float index1..25 ** ** 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 .. LS25_L_HRIR heissen und existieren ** ** setzt voraus , dass die HRTF-tabele-names von LS1_HRTF_re .. LS25_HRTF_re heissen und existieren ** ** setzt voraus , dass die HRTF-tabele-names von LS1_HRTF_im .. LS25_HRTF_im heissen und existieren ** */ typedef struct _ambi_decode2 { t_object x_obj; t_atom *x_at; double *x_inv_work1; double *x_inv_work2; double *x_inv_buf2; double *x_transp; double *x_ls_encode; double *x_prod; double *x_ambi_channel_weight; double x_mirror_weight; double x_sing_range; int x_n_ambi; int x_n_order; int x_n_ls; int x_n_ph_ls; int x_n_mir_ls; int x_n_dim; t_symbol *x_s_matrix; double x_sqrt3; double x_sqrt10_4; double x_sqrt15_2; double x_sqrt6_4; double x_sqrt35_8; double x_sqrt70_4; double x_sqrt5_2; double x_sqrt126_16; double x_sqrt315_8; double x_sqrt105_4; double x_pi_over_180; } t_ambi_decode2; static t_class *ambi_decode2_class; static void ambi_decode2_copy_row2buf(t_ambi_decode2 *x, int row) { int n_ambi2 = 2*x->x_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw_src=x->x_inv_work2; double *dw_dst=x->x_inv_work2; dw_src += src_row*n_ambi2; dw_dst += dst_row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int n_ambi2 = 2*n_ambi; int i, j; double *dw=x->x_inv_work2; double singrange=x->x_sing_range; int ret=-1; dw += start_row*n_ambi2 + col; j = 0; for(i=start_row; i singrange) || (*dw < -singrange)) { ret = i; i = n_ambi+1; } dw += n_ambi2; } return(ret); } static void ambi_decode2_mul1(t_ambi_decode2 *x) { double *vec1, *beg1=x->x_ls_encode; double *vec2, *beg2=x->x_ls_encode; double *inv=x->x_inv_work1; double sum; int n_ls=x->x_n_ls+2*x->x_n_mir_ls+x->x_n_ph_ls; int n_ambi=x->x_n_ambi; int i, j, k; for(k=0; kx_ls_encode; for(j=0; jx_n_ls+2*x->x_n_mir_ls+x->x_n_ph_ls; int n_ambi=x->x_n_ambi; int n_ambi2=2*n_ambi; int i, j, k; double *vec1, *beg1=x->x_transp; double *vec2, *beg2=x->x_inv_work2+n_ambi; double *vec3=x->x_prod; double *acw_vec=x->x_ambi_channel_weight; double sum; for(k=0; kx_inv_work2+n_ambi; for(j=0; jx_transp; double *straight=x->x_ls_encode; int n_ls=x->x_n_ls+2*x->x_n_mir_ls+x->x_n_ph_ls; int n_ambi=x->x_n_ambi; int i, j; for(j=0; jx_n_ambi; int n_ambi2 = 2*n_ambi; int i, j, nz; int r,c; double *src=x->x_inv_work1; double *db=x->x_inv_work2; double rcp, *dv; dv = db; for(i=0; i=0; i--) { dv = db + i*n_ambi2 + i; ambi_decode2_copy_row2buf(x, i); for(j=i-1; j>=0; j--) { dv -= n_ambi2; rcp = -(*dv); ambi_decode2_mul_buf_and_add2row(x, j, rcp); } } post("matrix_inverse nonsingular"); } static void ambi_decode2_pseudo_inverse(t_ambi_decode2 *x, t_symbol *s, int argc, t_atom *argv) { t_atom *at=x->x_at; int i, n=x->x_n_ls*x->x_n_ambi; double *dv1=x->x_prod; double *dv2=x->x_prod; double mw=x->x_mirror_weight; ambi_decode2_transp_back(x); ambi_decode2_mul1(x); ambi_decode2_inverse(x); ambi_decode2_mul2(x); at += 2; for(i=0; ix_n_mir_ls*x->x_n_ambi; dv2 += n; for(i=0; ix_obj.ob_outlet, x->x_s_matrix, x->x_n_ambi*(x->x_n_ls+x->x_n_mir_ls)+2, x->x_at); } static void ambi_decode2_encode_ls_2d(t_ambi_decode2 *x, int argc, t_atom *argv, int mode) { double phi; double *dw = x->x_transp; int index; int order=x->x_n_order; if(argc < 2) { post("ambi_decode2 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(mode == AMBI_LS_IND) { if(index >= x->x_n_ls) index = x->x_n_ls - 1; } else if(mode == AMBI_LS_MRG) { if(x->x_n_mir_ls) { if(index >= x->x_n_mir_ls) index = x->x_n_mir_ls - 1; index += x->x_n_ls; } else return; } else if(mode == AMBI_LS_MIR) { if(x->x_n_mir_ls) { if(index >= x->x_n_mir_ls) index = x->x_n_mir_ls - 1; index += x->x_n_ls; index += x->x_n_mir_ls; } else return; } else if(mode == AMBI_LS_PHT) { if(x->x_n_ph_ls) { if(index >= x->x_n_ph_ls) index = x->x_n_ph_ls - 1; index += x->x_n_ls; index += 2*x->x_n_mir_ls; } else return; } else return; phi *= x->x_pi_over_180; dw += index * x->x_n_ambi; *dw++ = 1.0; *dw++ = cos(phi); *dw++ = sin(phi); if(order >= 2) { *dw++ = cos(2.0*phi); *dw++ = sin(2.0*phi); if(order >= 3) { *dw++ = cos(3.0*phi); *dw++ = sin(3.0*phi); if(order >= 4) { *dw++ = cos(4.0*phi); *dw++ = sin(4.0*phi); if(order >= 5) { *dw++ = cos(5.0*phi); *dw++ = sin(5.0*phi); if(order >= 6) { *dw++ = cos(6.0*phi); *dw++ = sin(6.0*phi); if(order >= 7) { *dw++ = cos(7.0*phi); *dw++ = sin(7.0*phi); if(order >= 8) { *dw++ = cos(8.0*phi); *dw++ = sin(8.0*phi); if(order >= 9) { *dw++ = cos(9.0*phi); *dw++ = sin(9.0*phi); if(order >= 10) { *dw++ = cos(10.0*phi); *dw++ = sin(10.0*phi); if(order >= 11) { *dw++ = cos(11.0*phi); *dw++ = sin(11.0*phi); if(order >= 12) { *dw++ = cos(12.0*phi); *dw++ = sin(12.0*phi); } } } } } } } } } } } } static void ambi_decode2_encode_ls_3d(t_ambi_decode2 *x, int argc, t_atom *argv, int mode) { double delta, phi; double cd, sd, cd2, cd3, sd2, csd, cp, sp, cp2, sp2, cp3, sp3, cp4, sp4; double *dw = x->x_transp; int index; int order=x->x_n_order; if(argc < 3) { post("ambi_decode2 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(mode == AMBI_LS_IND) { if(index >= x->x_n_ls) index = x->x_n_ls - 1; } else if(mode == AMBI_LS_MRG) { if(x->x_n_mir_ls) { if(index >= x->x_n_mir_ls) index = x->x_n_mir_ls - 1; index += x->x_n_ls; } else return; } else if(mode == AMBI_LS_MIR) { if(x->x_n_mir_ls) { if(index >= x->x_n_mir_ls) index = x->x_n_mir_ls - 1; index += x->x_n_ls; index += x->x_n_mir_ls; } else return; } else if(mode == AMBI_LS_PHT) { if(x->x_n_ph_ls) { if(index >= x->x_n_ph_ls) index = x->x_n_ph_ls - 1; index += x->x_n_ls; index += 2*x->x_n_mir_ls; } else return; } else return; delta *= x->x_pi_over_180; phi *= x->x_pi_over_180; dw += index * x->x_n_ambi; cd = cos(delta); sd = sin(delta); cp = cos(phi); sp = sin(phi); *dw++ = 1.0; *dw++ = cd * cp; *dw++ = cd * sp; *dw++ = sd; if(order >= 2) { cp2 = cos(2.0*phi); sp2 = sin(2.0*phi); cd2 = cd * cd; sd2 = sd * sd; csd = cd * sd; *dw++ = 0.5 * x->x_sqrt3 * cd2 * cp2; *dw++ = 0.5 * x->x_sqrt3 * cd2 * sp2; *dw++ = x->x_sqrt3 * csd * cp; *dw++ = x->x_sqrt3 * csd * sp; *dw++ = 0.5 * (3.0 * sd2 - 1.0); if(order >= 3) { cp3 = cos(3.0*phi); sp3 = sin(3.0*phi); cd3 = cd2 * cd; *dw++ = x->x_sqrt10_4 * cd3 * cp3; *dw++ = x->x_sqrt10_4 * cd3 * sp3; *dw++ = x->x_sqrt15_2 * cd * csd * cp2; *dw++ = x->x_sqrt15_2 * cd * csd * sp2; *dw++ = x->x_sqrt6_4 * cd * (5.0 * sd2 - 1.0) * cp; *dw++ = x->x_sqrt6_4 * cd * (5.0 * sd2 - 1.0) * sp; *dw++ = 0.5 * sd * (5.0 * sd2 - 3.0); if(order >= 4) { cp4 = cos(4.0*phi); sp4 = sin(4.0*phi); *dw++ = x->x_sqrt35_8 * cd2 * cd2 * cp4; *dw++ = x->x_sqrt35_8 * cd2 * cd2 * sp4; *dw++ = x->x_sqrt70_4 * cd2 * csd * cp3; *dw++ = x->x_sqrt70_4 * cd2 * csd * sp3; *dw++ = 0.5 * x->x_sqrt5_2 * cd2 * (7.0 * sd2 - 1.0) * cp2; *dw++ = 0.5 * x->x_sqrt5_2 * cd2 * (7.0 * sd2 - 1.0) * sp2; *dw++ = x->x_sqrt10_4 * csd * (7.0 * sd2 - 3.0) * cp; *dw++ = x->x_sqrt10_4 * csd * (7.0 * sd2 - 3.0) * sp; *dw++ = 0.125 * (sd2 * (35.0 * sd2 - 30.0) + 3.0); if(order >= 5) { *dw++ = x->x_sqrt126_16 * cd3 * cd2 * cos(5.0*phi); *dw++ = x->x_sqrt126_16 * cd3 * cd2 * sin(5.0*phi); *dw++ = x->x_sqrt315_8 * cd3 * csd * cp4; *dw++ = x->x_sqrt315_8 * cd3 * csd * sp4; *dw++ = 0.25 * x->x_sqrt70_4 * cd3 * (9.0 * sd2 - 1.0) * cp3; *dw++ = 0.25 * x->x_sqrt70_4 * cd3 * (9.0 * sd2 - 1.0) * sp3; *dw++ = x->x_sqrt105_4 * cd * csd * (3.0 * sd2 - 1.0) * cp2; *dw++ = x->x_sqrt105_4 * cd * csd * (3.0 * sd2 - 1.0) * sp2; *dw++ = 0.25 * x->x_sqrt15_2 * cd * (sd2 * (21.0 * sd2 - 14.0) + 1.0) * cp; *dw++ = 0.25 * x->x_sqrt15_2 * cd * (sd2 * (21.0 * sd2 - 14.0) + 1.0) * sp; *dw = 0.125 * sd * (sd2 * (63.0 * sd2 - 70.0) + 15.0); } } } } } static void ambi_decode2_ind_ls(t_ambi_decode2 *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode2_encode_ls_2d(x, argc, argv, AMBI_LS_IND); else ambi_decode2_encode_ls_3d(x, argc, argv, AMBI_LS_IND); } static void ambi_decode2_mrg_ls(t_ambi_decode2 *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode2_encode_ls_2d(x, argc, argv, AMBI_LS_MRG); else ambi_decode2_encode_ls_3d(x, argc, argv, AMBI_LS_MRG); } static void ambi_decode2_mir_ls(t_ambi_decode2 *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode2_encode_ls_2d(x, argc, argv, AMBI_LS_MIR); else ambi_decode2_encode_ls_3d(x, argc, argv, AMBI_LS_MIR); } static void ambi_decode2_pht_ls(t_ambi_decode2 *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode2_encode_ls_2d(x, argc, argv, AMBI_LS_PHT); else ambi_decode2_encode_ls_3d(x, argc, argv, AMBI_LS_PHT); } static void ambi_decode2_ambi_weight(t_ambi_decode2 *x, t_symbol *s, int argc, t_atom *argv) { if(argc > x->x_n_order) { int i, k=0, n=x->x_n_order; double d; x->x_ambi_channel_weight[k] = atom_getfloat(argv++); k++; if(x->x_n_dim == 2) { for(i=1; i<=n; i++) { d = atom_getfloat(argv++); x->x_ambi_channel_weight[k] = d; k++; x->x_ambi_channel_weight[k] = d; k++; } } else { int j, m; for(i=1; i<=n; i++) { d = atom_getfloat(argv++); m = 2*i + 1; for(j=0; jx_ambi_channel_weight[k] = d; k++; } } } } else post("ambi_decode2-ERROR: ambi_weight needs %d float weights", x->x_n_order+1); } static void ambi_decode2_mirror_weight(t_ambi_decode2 *x, t_floatarg f) { x->x_mirror_weight = (double)f; } static void ambi_decode2_sing_range(t_ambi_decode2 *x, t_floatarg f) { if(f < 0.0f) x->x_sing_range = -(double)f; else x->x_sing_range = (double)f; } static void ambi_decode2_free(t_ambi_decode2 *x) { freebytes(x->x_inv_work1, x->x_n_ambi * x->x_n_ambi * sizeof(double)); freebytes(x->x_inv_work2, 2 * x->x_n_ambi * x->x_n_ambi * sizeof(double)); freebytes(x->x_inv_buf2, 2 * x->x_n_ambi * sizeof(double)); freebytes(x->x_transp, (x->x_n_ls+2*x->x_n_mir_ls+x->x_n_ph_ls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_ls_encode, (x->x_n_ls+2*x->x_n_mir_ls+x->x_n_ph_ls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_prod, (x->x_n_ls+2*x->x_n_mir_ls+x->x_n_ph_ls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_ambi_channel_weight, x->x_n_ambi * sizeof(double)); freebytes(x->x_at, ((x->x_n_ls+x->x_n_mir_ls) * x->x_n_ambi + 2) * sizeof(t_atom)); } static void *ambi_decode2_new(t_symbol *s, int argc, t_atom *argv) { t_ambi_decode2 *x = (t_ambi_decode2 *)pd_new(ambi_decode2_class); int order, dim, i; int n_ls=0;/* number of loudspeakers */ int n_mir_ls=0;/* number of mirror_loudspeakers */ int n_ph_ls=0;/* number of phantom_loudspeakers */ if((argc >= 5) && IS_A_FLOAT(argv,0) && IS_A_FLOAT(argv,1) && IS_A_FLOAT(argv,2) && IS_A_FLOAT(argv,3) && IS_A_FLOAT(argv,4)) { order = (int)atom_getint(argv++); dim = (int)atom_getint(argv++); n_ls = (int)atom_getint(argv++); n_mir_ls = (int)atom_getint(argv++); n_ph_ls = (int)atom_getint(argv); if(order < 1) order = 1; if(dim != 3) { dim = 2; if(order > 12) order = 12; x->x_n_ambi = 2*order + 1; } else { if(order > 5) order = 5; x->x_n_ambi = (order + 1)*(order + 1); } x->x_n_dim = dim; x->x_n_order = order; if(n_ls < 1) n_ls = 1; if(n_mir_ls < 0) n_mir_ls = 0; if(n_ph_ls < 0) n_ph_ls = 0; if((n_ls + 2*n_mir_ls + n_ph_ls) < x->x_n_ambi) post("ambi_decode2-WARNING: Number of Loudspeakers < Number of Ambisonic-Channels !!!!"); x->x_n_ls = n_ls; x->x_n_mir_ls = n_mir_ls; x->x_n_ph_ls = n_ph_ls; x->x_inv_work1 = (double *)getbytes(x->x_n_ambi * x->x_n_ambi * sizeof(double)); x->x_inv_work2 = (double *)getbytes(2 * x->x_n_ambi * x->x_n_ambi * sizeof(double)); x->x_inv_buf2 = (double *)getbytes(2 * x->x_n_ambi * sizeof(double)); x->x_transp = (double *)getbytes((x->x_n_ls+2*x->x_n_mir_ls+x->x_n_ph_ls) * x->x_n_ambi * sizeof(double)); x->x_ls_encode = (double *)getbytes((x->x_n_ls+2*x->x_n_mir_ls+x->x_n_ph_ls) * x->x_n_ambi * sizeof(double)); x->x_prod = (double *)getbytes((x->x_n_ls+2*x->x_n_mir_ls+x->x_n_ph_ls) * x->x_n_ambi * sizeof(double)); x->x_ambi_channel_weight = (double *)getbytes(x->x_n_ambi * sizeof(double)); x->x_at = (t_atom *)getbytes(((x->x_n_ls+x->x_n_mir_ls) * x->x_n_ambi + 2) * sizeof(t_atom)); x->x_s_matrix = gensym("matrix"); /*change*/ SETFLOAT(x->x_at, (t_float)(x->x_n_ls+x->x_n_mir_ls)); SETFLOAT(x->x_at+1, (t_float)x->x_n_ambi); x->x_mirror_weight = 0.0; x->x_sqrt3 = sqrt(3.0); x->x_sqrt5_2 = sqrt(5.0) / 2.0; x->x_sqrt6_4 = sqrt(6.0) / 4.0; x->x_sqrt10_4 = sqrt(10.0) / 4.0; x->x_sqrt15_2 = sqrt(15.0) / 2.0; x->x_sqrt35_8 = sqrt(35.0) / 8.0; x->x_sqrt70_4 = sqrt(70.0) / 4.0; x->x_sqrt126_16 = sqrt(126.0) / 16.0; x->x_sqrt315_8 = sqrt(315.0) / 8.0; x->x_sqrt105_4 = sqrt(105.0) / 4.0; x->x_pi_over_180 = 4.0 * atan(1.0) / 180.0; x->x_sing_range = 1.0e-10; for(i=0; ix_n_ambi; i++) x->x_ambi_channel_weight[i] = 1.0; outlet_new(&x->x_obj, &s_list); return (x); } else { post("ambi_decode2-ERROR: need 5 float arguments: ambi_order dimension number_of_independent_loudspeakers number_of_merged_and_mirrored_speakers number_of_canceled_phantom_speakers"); return(0); } } void ambi_decode2_setup(void) { ambi_decode2_class = class_new(gensym("ambi_decode2"), (t_newmethod)ambi_decode2_new, (t_method)ambi_decode2_free, sizeof(t_ambi_decode2), 0, A_GIMME, 0); class_addmethod(ambi_decode2_class, (t_method)ambi_decode2_ind_ls, gensym("ind_ls"), A_GIMME, 0); class_addmethod(ambi_decode2_class, (t_method)ambi_decode2_mrg_ls, gensym("mrg_ls"), A_GIMME, 0); class_addmethod(ambi_decode2_class, (t_method)ambi_decode2_mir_ls, gensym("mir_ls"), A_GIMME, 0); class_addmethod(ambi_decode2_class, (t_method)ambi_decode2_pht_ls, gensym("pht_ls"), A_GIMME, 0); class_addmethod(ambi_decode2_class, (t_method)ambi_decode2_mirror_weight, gensym("mirror_weight"), A_DEFFLOAT, 0); class_addmethod(ambi_decode2_class, (t_method)ambi_decode2_ambi_weight, gensym("ambi_weight"), A_GIMME, 0); class_addmethod(ambi_decode2_class, (t_method)ambi_decode2_sing_range, gensym("sing_range"), A_DEFFLOAT, 0); class_addmethod(ambi_decode2_class, (t_method)ambi_decode2_pseudo_inverse, gensym("pseudo_inverse"), A_GIMME, 0); // class_sethelpsymbol(ambi_decode2_class, gensym("iemhelp2/ambi_decode2-help")); } iem_ambi-0.2/src/makefile_d_ppc0000644000175000017500000000143510714614221017004 0ustar zmoelnigzmoelnigcurrent: all .SUFFIXES: .d_ppc PD_INSTALL_PATH = "/Applications/Pd.app/Contents/Resources" INCLUDE = -I. -I$(PD_INSTALL_PATH)/src CFLAGS =-DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch LFLAGS = -bundle -undefined suppress -flat_namespace # the sources SRC = ambi_decode.c \ ambi_decode2.c \ ambi_decode3.c \ ambi_decode_cube.c \ ambi_encode.c \ ambi_rot.c \ iem_ambi.c TARGET = iem_ambi.d_ppc OBJ = $(SRC:.c=.o) # # ------------------ targets ------------------------------------ # clean: rm ../$(TARGET) rm *.o all: $(OBJ) @echo :: $(OBJ) $(CC) $(LFLAGS) -o $(TARGET) *.o strip -S -x $(TARGET) mv $(TARGET) .. $(OBJ) : %.o : %.c touch $*.c $(CC) $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c iem_ambi-0.2/src/ambi_decode.c0000644000175000017500000004030110540330021016477 0ustar zmoelnigzmoelnig/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ #include "m_pd.h" #include "iemlib.h" #include /* -------------------------- ambi_decode ------------------------------ */ /* ** berechnet ein reduziertes Ambisonic-Decoder-Set in die HRTF-Spektren ** ** Inputs: ls + Liste von 3 floats: Index [1 .. 25] + Elevation [-90 .. +90 degree] + Azimut [0 .. 360 degree] ** ** Inputs: calc_inv ** ** Inputs: load_HRIR + float index1..25 ** ** 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 .. LS25_L_HRIR heissen und existieren ** ** setzt voraus , dass die HRTF-tabele-names von LS1_HRTF_re .. LS25_HRTF_re heissen und existieren ** ** setzt voraus , dass die HRTF-tabele-names von LS1_HRTF_im .. LS25_HRTF_im heissen und existieren ** */ typedef struct _ambi_decode { t_object x_obj; t_atom *x_at; double *x_inv_work1; double *x_inv_work2; double *x_inv_buf2; double *x_transp; double *x_ls_encode; double *x_prod; double *x_ambi_channel_weight; double x_sing_range; int x_n_ambi; int x_n_order; int x_n_ls; int x_n_phls; int x_n_dim; t_symbol *x_s_matrix; double x_sqrt3; double x_sqrt10_4; double x_sqrt15_2; double x_sqrt6_4; double x_sqrt35_8; double x_sqrt70_4; double x_sqrt5_2; double x_sqrt126_16; double x_sqrt315_8; double x_sqrt105_4; double x_pi_over_180; } t_ambi_decode; static t_class *ambi_decode_class; static void ambi_decode_copy_row2buf(t_ambi_decode *x, int row) { int n_ambi2 = 2*x->x_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw_src=x->x_inv_work2; double *dw_dst=x->x_inv_work2; dw_src += src_row*n_ambi2; dw_dst += dst_row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int n_ambi2 = 2*n_ambi; int i, j; double *dw=x->x_inv_work2; double singrange=x->x_sing_range; int ret=-1; dw += start_row*n_ambi2 + col; j = 0; for(i=start_row; i singrange) || (*dw < -singrange)) { ret = i; i = n_ambi+1; } dw += n_ambi2; } return(ret); } static void ambi_decode_mul1(t_ambi_decode *x) { double *vec1, *beg1=x->x_ls_encode; double *vec2, *beg2=x->x_ls_encode; double *inv=x->x_inv_work1; double sum; int n_ls=x->x_n_ls+x->x_n_phls; int n_ambi=x->x_n_ambi; int i, j, k; for(k=0; kx_ls_encode; for(j=0; jx_n_ls+x->x_n_phls; int n_ambi=x->x_n_ambi; int n_ambi2=2*n_ambi; int i, j, k; double *vec1, *beg1=x->x_transp; double *vec2, *beg2=x->x_inv_work2+n_ambi; double *vec3=x->x_prod; double *acw_vec=x->x_ambi_channel_weight; double sum; for(k=0; kx_inv_work2+n_ambi; for(j=0; jx_transp; double *straight=x->x_ls_encode; int n_ls=x->x_n_ls+x->x_n_phls; int n_ambi=x->x_n_ambi; int i, j; for(j=0; jx_n_ambi; int n_ambi2 = 2*n_ambi; int i, j, nz; int r,c; double *src=x->x_inv_work1; double *db=x->x_inv_work2; double rcp, *dv; dv = db; for(i=0; i=0; i--) { dv = db + i*n_ambi2 + i; ambi_decode_copy_row2buf(x, i); for(j=i-1; j>=0; j--) { dv -= n_ambi2; rcp = -(*dv); ambi_decode_mul_buf_and_add2row(x, j, rcp); } } post("matrix_inverse nonsingular"); } static void ambi_decode_pinv(t_ambi_decode *x) { t_atom *at=x->x_at; int i, n=x->x_n_ls*x->x_n_ambi; double *dv=x->x_prod; ambi_decode_transp_back(x); ambi_decode_mul1(x); ambi_decode_inverse(x); ambi_decode_mul2(x); at += 2; for(i=0; ix_obj.ob_outlet, x->x_s_matrix, n+2, x->x_at); } static void ambi_decode_encode_ls_2d(t_ambi_decode *x, int argc, t_atom *argv, int ls0_ph1) { double phi; double *dw = x->x_transp; int index; int n_ls=x->x_n_ls; int n_phls=x->x_n_phls; int order=x->x_n_order; if(argc < 2) { post("ambi_decode 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(ls0_ph1) { if(n_phls) { if(index >= n_phls) index = n_phls - 1; index += n_ls; } else return; } else { if(index >= n_ls) index = n_ls - 1; } phi *= x->x_pi_over_180; dw += index * x->x_n_ambi; *dw++ = 1.0; *dw++ = cos(phi); *dw++ = sin(phi); if(order >= 2) { *dw++ = cos(2.0*phi); *dw++ = sin(2.0*phi); if(order >= 3) { *dw++ = cos(3.0*phi); *dw++ = sin(3.0*phi); if(order >= 4) { *dw++ = cos(4.0*phi); *dw++ = sin(4.0*phi); if(order >= 5) { *dw++ = cos(5.0*phi); *dw++ = sin(5.0*phi); if(order >= 6) { *dw++ = cos(6.0*phi); *dw++ = sin(6.0*phi); if(order >= 7) { *dw++ = cos(7.0*phi); *dw++ = sin(7.0*phi); if(order >= 8) { *dw++ = cos(8.0*phi); *dw++ = sin(8.0*phi); if(order >= 9) { *dw++ = cos(9.0*phi); *dw++ = sin(9.0*phi); if(order >= 10) { *dw++ = cos(10.0*phi); *dw++ = sin(10.0*phi); if(order >= 11) { *dw++ = cos(11.0*phi); *dw++ = sin(11.0*phi); if(order >= 12) { *dw++ = cos(12.0*phi); *dw++ = sin(12.0*phi); } } } } } } } } } } } } static void ambi_decode_encode_ls_3d(t_ambi_decode *x, int argc, t_atom *argv, int ls0_ph1) { double delta, phi; double cd, sd, cd2, cd3, sd2, csd, cp, sp, cp2, sp2, cp3, sp3, cp4, sp4; double *dw = x->x_transp; int index; int n_ls=x->x_n_ls; int n_phls=x->x_n_phls; int order=x->x_n_order; if(argc < 3) { post("ambi_decode 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(ls0_ph1) { if(n_phls) { if(index >= n_phls) index = n_phls - 1; index += n_ls; } else return; } else { if(index >= n_ls) index = n_ls - 1; } delta *= x->x_pi_over_180; phi *= x->x_pi_over_180; dw += index * x->x_n_ambi; cd = cos(delta); sd = sin(delta); cp = cos(phi); sp = sin(phi); *dw++ = 1.0; *dw++ = cd * cp; *dw++ = cd * sp; *dw++ = sd; if(order >= 2) { cp2 = cos(2.0*phi); sp2 = sin(2.0*phi); cd2 = cd * cd; sd2 = sd * sd; csd = cd * sd; *dw++ = 0.5 * x->x_sqrt3 * cd2 * cp2; *dw++ = 0.5 * x->x_sqrt3 * cd2 * sp2; *dw++ = x->x_sqrt3 * csd * cp; *dw++ = x->x_sqrt3 * csd * sp; *dw++ = 0.5 * (3.0 * sd2 - 1.0); if(order >= 3) { cp3 = cos(3.0*phi); sp3 = sin(3.0*phi); cd3 = cd2 * cd; *dw++ = x->x_sqrt10_4 * cd3 * cp3; *dw++ = x->x_sqrt10_4 * cd3 * sp3; *dw++ = x->x_sqrt15_2 * cd * csd * cp2; *dw++ = x->x_sqrt15_2 * cd * csd * sp2; *dw++ = x->x_sqrt6_4 * cd * (5.0 * sd2 - 1.0) * cp; *dw++ = x->x_sqrt6_4 * cd * (5.0 * sd2 - 1.0) * sp; *dw++ = 0.5 * sd * (5.0 * sd2 - 3.0); if(order >= 4) { cp4 = cos(4.0*phi); sp4 = sin(4.0*phi); *dw++ = x->x_sqrt35_8 * cd2 * cd2 * cp4; *dw++ = x->x_sqrt35_8 * cd2 * cd2 * sp4; *dw++ = x->x_sqrt70_4 * cd2 * csd * cp3; *dw++ = x->x_sqrt70_4 * cd2 * csd * sp3; *dw++ = 0.5 * x->x_sqrt5_2 * cd2 * (7.0 * sd2 - 1.0) * cp2; *dw++ = 0.5 * x->x_sqrt5_2 * cd2 * (7.0 * sd2 - 1.0) * sp2; *dw++ = x->x_sqrt10_4 * csd * (7.0 * sd2 - 3.0) * cp; *dw++ = x->x_sqrt10_4 * csd * (7.0 * sd2 - 3.0) * sp; *dw++ = 0.125 * (sd2 * (35.0 * sd2 - 30.0) + 3.0); if(order >= 5) { *dw++ = x->x_sqrt126_16 * cd3 * cd2 * cos(5.0*phi); *dw++ = x->x_sqrt126_16 * cd3 * cd2 * sin(5.0*phi); *dw++ = x->x_sqrt315_8 * cd3 * csd * cp4; *dw++ = x->x_sqrt315_8 * cd3 * csd * sp4; *dw++ = 0.25 * x->x_sqrt70_4 * cd3 * (9.0 * sd2 - 1.0) * cp3; *dw++ = 0.25 * x->x_sqrt70_4 * cd3 * (9.0 * sd2 - 1.0) * sp3; *dw++ = x->x_sqrt105_4 * cd * csd * (3.0 * sd2 - 1.0) * cp2; *dw++ = x->x_sqrt105_4 * cd * csd * (3.0 * sd2 - 1.0) * sp2; *dw++ = 0.25 * x->x_sqrt15_2 * cd * (sd2 * (21.0 * sd2 - 14.0) + 1.0) * cp; *dw++ = 0.25 * x->x_sqrt15_2 * cd * (sd2 * (21.0 * sd2 - 14.0) + 1.0) * sp; *dw = 0.125 * sd * (sd2 * (63.0 * sd2 - 70.0) + 15.0); } } } } } static void ambi_decode_ls(t_ambi_decode *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode_encode_ls_2d(x, argc, argv, 0); else ambi_decode_encode_ls_3d(x, argc, argv, 0); } static void ambi_decode_phls(t_ambi_decode *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode_encode_ls_2d(x, argc, argv, 1); else ambi_decode_encode_ls_3d(x, argc, argv, 1); } static void ambi_decode_ambi_weight(t_ambi_decode *x, t_symbol *s, int argc, t_atom *argv) { if(argc > x->x_n_order) { int i, k=0, n=x->x_n_order; double d; x->x_ambi_channel_weight[k] = atom_getfloat(argv++); k++; if(x->x_n_dim == 2) { for(i=1; i<=n; i++) { d = atom_getfloat(argv++); x->x_ambi_channel_weight[k] = d; k++; x->x_ambi_channel_weight[k] = d; k++; } } else { int j, m; for(i=1; i<=n; i++) { d = atom_getfloat(argv++); m = 2*i + 1; for(j=0; jx_ambi_channel_weight[k] = d; k++; } } } } else post("ambi_decode-ERROR: ambi_weight needs %d float weights", x->x_n_order+1); } static void ambi_decode_sing_range(t_ambi_decode *x, t_floatarg f) { if(f < 0.0f) x->x_sing_range = -(double)f; else x->x_sing_range = (double)f; } static void ambi_decode_free(t_ambi_decode *x) { freebytes(x->x_inv_work1, x->x_n_ambi * x->x_n_ambi * sizeof(double)); freebytes(x->x_inv_work2, 2 * x->x_n_ambi * x->x_n_ambi * sizeof(double)); freebytes(x->x_inv_buf2, 2 * x->x_n_ambi * sizeof(double)); freebytes(x->x_transp, (x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_ls_encode, (x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_prod, (x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_ambi_channel_weight, x->x_n_ambi * sizeof(double)); freebytes(x->x_at, (x->x_n_ls * x->x_n_ambi + 2) * sizeof(t_atom)); } static void *ambi_decode_new(t_symbol *s, int argc, t_atom *argv) { t_ambi_decode *x = (t_ambi_decode *)pd_new(ambi_decode_class); int nls, order, dim, i; int nphls=0;/* phantom_loudspeaker */ if(argc < 3) { post("ambi_decode-ERROR: need following arguments: ambi_order dimension number_of_loudspeakers (number_of_phantom_speakers)"); return(0); } else { order = (int)atom_getint(argv++); dim = (int)atom_getint(argv++); nls = (int)atom_getint(argv++); if((argc > 3)&&IS_A_FLOAT(argv,0)) nphls=(int)atom_getint(argv); if(order < 1) order = 1; if(dim != 3) { dim = 2; if(order > 12) order = 12; x->x_n_ambi = 2*order + 1; } else { if(order > 5) order = 5; x->x_n_ambi = (order + 1)*(order + 1); } x->x_n_dim = dim; x->x_n_order = order; if(nls < 1) nls = 1; if(nphls < 0) nphls = 0; if(nls < x->x_n_ambi) post("ambi_decode-WARNING: Number of Loudspeakers < Number of Ambisonic-Channels !!!!"); if(nphls > nls) { post("ambi_decode-WARNING: Number of Phantom-Loudspeakers > Number of Loudspeakers !!!!"); nphls = nls; } x->x_n_ls = nls; x->x_n_phls = nphls; x->x_inv_work1 = (double *)getbytes(x->x_n_ambi * x->x_n_ambi * sizeof(double)); x->x_inv_work2 = (double *)getbytes(2 * x->x_n_ambi * x->x_n_ambi * sizeof(double)); x->x_inv_buf2 = (double *)getbytes(2 * x->x_n_ambi * sizeof(double)); x->x_transp = (double *)getbytes((x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); x->x_ls_encode = (double *)getbytes((x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); x->x_prod = (double *)getbytes((x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); x->x_ambi_channel_weight = (double *)getbytes(x->x_n_ambi * sizeof(double)); x->x_at = (t_atom *)getbytes((x->x_n_ls * x->x_n_ambi + 2) * sizeof(t_atom)); x->x_s_matrix = gensym("matrix"); /*change*/ SETFLOAT(x->x_at, (t_float)x->x_n_ls); SETFLOAT(x->x_at+1, (t_float)x->x_n_ambi); x->x_sqrt3 = sqrt(3.0); x->x_sqrt5_2 = sqrt(5.0) / 2.0; x->x_sqrt6_4 = sqrt(6.0) / 4.0; x->x_sqrt10_4 = sqrt(10.0) / 4.0; x->x_sqrt15_2 = sqrt(15.0) / 2.0; x->x_sqrt35_8 = sqrt(35.0) / 8.0; x->x_sqrt70_4 = sqrt(70.0) / 4.0; x->x_sqrt126_16 = sqrt(126.0) / 16.0; x->x_sqrt315_8 = sqrt(315.0) / 8.0; x->x_sqrt105_4 = sqrt(105.0) / 4.0; x->x_pi_over_180 = 4.0 * atan(1.0) / 180.0; x->x_sing_range = 1.0e-10; for(i=0; ix_n_ambi; i++) x->x_ambi_channel_weight[i] = 1.0; outlet_new(&x->x_obj, &s_list); return (x); } } void ambi_decode_setup(void) { ambi_decode_class = class_new(gensym("ambi_decode"), (t_newmethod)ambi_decode_new, (t_method)ambi_decode_free, sizeof(t_ambi_decode), 0, A_GIMME, 0); class_addmethod(ambi_decode_class, (t_method)ambi_decode_ls, gensym("ls"), A_GIMME, 0); class_addmethod(ambi_decode_class, (t_method)ambi_decode_phls, gensym("phls"), A_GIMME, 0); class_addmethod(ambi_decode_class, (t_method)ambi_decode_ambi_weight, gensym("ambi_weight"), A_GIMME, 0); class_addmethod(ambi_decode_class, (t_method)ambi_decode_sing_range, gensym("sing_range"), A_DEFFLOAT, 0); class_addmethod(ambi_decode_class, (t_method)ambi_decode_pinv, gensym("pinv"), 0); // class_sethelpsymbol(ambi_decode_class, gensym("iemhelp2/ambi_decode-help")); } iem_ambi-0.2/src/makefile_d_fat0000644000175000017500000000147311203037257017000 0ustar zmoelnigzmoelnigcurrent: all .SUFFIXES: .d_fat PD_INSTALL_PATH ?= "/Applications/Pd.app/Contents/Resources" INCLUDE = -I. -I$(PD_INSTALL_PATH)/src CFLAGS =-DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch LFLAGS = -bundle -undefined suppress -flat_namespace # the sources SRC = ambi_decode.c \ ambi_decode2.c \ ambi_decode3.c \ ambi_decode_cube.c \ ambi_encode.c \ ambi_rot.c \ iem_ambi.c TARGET = iem_ambi.d_fat OBJ = $(SRC:.c=.o) # # ------------------ targets ------------------------------------ # clean: rm ../$(TARGET) rm *.o all: $(OBJ) @echo :: $(OBJ) $(CC) -arch i386 -arch ppc $(LFLAGS) -o $(TARGET) *.o strip -S -x $(TARGET) mv $(TARGET) .. $(OBJ) : %.o : %.c $(CC) -arch i386 -arch ppc $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c iem_ambi-0.2/src/iem_ambi.h0000644000175000017500000000060710533535743016064 0ustar zmoelnigzmoelnig/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ #ifndef __IEMAMBI_H__ #define __IEMAMBI_H__ #define AMBI_LS_REAL 0 #define AMBI_LS_IND 0 #define AMBI_LS_MRG 1 #define AMBI_LS_MIR 2 #define AMBI_LS_PHT 3 #endif iem_ambi-0.2/src/VC6/0000755000175000017500000000000012163236207014536 5ustar zmoelnigzmoelnigiem_ambi-0.2/src/VC6/iem_ambi.dsw0000644000175000017500000000106711603103256017016 0ustar zmoelnigzmoelnigMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN! ############################################################################### Project: "iem_ambi"=.\iem_ambi.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### iem_ambi-0.2/src/VC6/iem_ambi.dsp0000644000175000017500000000476611603103256017020 0ustar zmoelnigzmoelnig# Microsoft Developer Studio Project File - Name="iem_ambi" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** NICHT BEARBEITEN ** # TARGTYPE "Win32 (x86) External Target" 0x0106 CFG=iem_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_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_ambi.mak" CFG="iem_ambi - Win32 Debug" !MESSAGE !MESSAGE Für die Konfiguration stehen zur Auswahl: !MESSAGE !MESSAGE "iem_ambi - Win32 Release" (basierend auf "Win32 (x86) External Target") !MESSAGE "iem_ambi - Win32 Debug" (basierend auf "Win32 (x86) External Target") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" !IF "$(CFG)" == "iem_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_ambi.exe" # PROP Bsc_Name "iem_ambi.bsc" # PROP Target_Dir "" !ELSEIF "$(CFG)" == "iem_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_ambi.exe" # PROP Bsc_Name "iem_ambi.bsc" # PROP Target_Dir "" !ENDIF # Begin Target # Name "iem_ambi - Win32 Release" # Name "iem_ambi - Win32 Debug" !IF "$(CFG)" == "iem_ambi - Win32 Release" !ELSEIF "$(CFG)" == "iem_ambi - Win32 Debug" !ENDIF # Begin Source File SOURCE=.\makefile_win # End Source File # End Target # End Project iem_ambi-0.2/src/VC6/makefile_win0000644000175000017500000000174711603103256017117 0ustar zmoelnigzmoelnig all: ..\iem_ambi.dll VIS_CPP_PATH = "C:\Programme\Microsoft Visual Studio\Vc98" PD_INST_PATH = "C:\Programme\pd" 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\pd.lib SRC = ambi_decode.c \ ambi_decode2.c \ ambi_decode3.c \ ambi_decode_cube.c \ ambi_encode.c \ ambi_rot.c \ iem_ambi.c OBJ = $(SRC:.c=.obj) .c.obj: cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c ..\iem_ambi.dll: $(OBJ) link $(PD_WIN_L_FLAGS) /dll /export:iem_ambi_setup \ /out:..\iem_ambi.dll $(OBJ) $(PD_WIN_LIB) clean: del *.obj iem_ambi-0.2/src/iemlib.h0000644000175000017500000000762412163234742015565 0ustar zmoelnigzmoelnig/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iemlib written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2012 */ #ifndef __IEMLIB_H__ #define __IEMLIB_H__ #define IS_A_NULL(atom,index) ((atom+index)->a_type == A_NULL) #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) #define SETNULL(atom) ((atom)->a_type = A_NULL) /* now miller's code starts : for 4 point interpolation for lookup tables for denormal floats */ #ifdef MSW 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 */ #endif /* IRIX */ #ifdef MSW /* little-endian; most significant byte is at highest address */ #define HIOFFSET 1 #define LOWOFFSET 0 #define int32 long #endif /* MSW */ #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) #include #endif #if defined(__linux__) || defined(__CYGWIN__) || defined(__GNU__) || defined(ANDROID) #include #endif #if defined(__unix__) || defined(__APPLE__) #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 #endif /* __unix__ or __APPLE__*/ union tabfudge_d { double tf_d; int32 tf_i[2]; }; union tabfudge_f { float tf_f; long tf_l; }; #if defined __i386__ || defined __x86_64__ #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 */ #else #define IEM_DENORMAL(f) 0 #endif /* on 64bit systems we cannot use garray_getfloatarray... */ #if ((defined PD_MAJOR_VERSION && defined PD_MINOR_VERSION) && (PD_MAJOR_VERSION > 0 || PD_MINOR_VERSION > 40)) # define iemarray_t t_word # define iemarray_getarray garray_getfloatwords # define iemarray_getfloat(pointer, index) (pointer[index].w_float) # define iemarray_setfloat(pointer, index, fvalue) (pointer[index].w_float = fvalue) #else # define iemarray_t t_float # define iemarray_getarray garray_getfloatarray # define iemarray_getfloat(pointer, index) (pointer[index]) # define iemarray_setfloat(pointer, index, fvalue) (pointer[index] = fvalue) #endif #endif iem_ambi-0.2/src/iem_ambi.dsw0000644000175000017500000000106711203414554016422 0ustar zmoelnigzmoelnigMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN! ############################################################################### Project: "iem_ambi"=.\iem_ambi.dsp - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### iem_ambi-0.2/src/makefile_vc9proj0000644000175000017500000000176711603103256017322 0ustar zmoelnigzmoelnigTARGET = iem_ambi all: ..\$(TARGET).dll VIS_CPP_PATH = "C:\Program Files\Microsoft Visual Studio 9.0\VC" VIS_SDK_PATH = "C:\Program Files\Microsoft SDKs\Windows\v6.0A" PD_INST_PATH = "C:\Program Files\pd-0.43.0" 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 -D_CRT_SECURE_NO_WARNINGS PD_WIN_L_FLAGS = /nologo PD_WIN_LIB = /NODEFAULTLIB:libcmt /NODEFAULTLIB:oldnames /NODEFAULTLIB:kernel32 \ $(VIS_CPP_PATH)\lib\libcmt.lib \ $(VIS_CPP_PATH)\lib\oldnames.lib \ $(VIS_SDK_PATH)\lib\kernel32.lib \ $(PD_INST_PATH)\bin\pd.lib SRC = ambi_decode.c \ ambi_decode2.c \ ambi_decode3.c \ ambi_decode_cube.c \ ambi_encode.c \ ambi_rot.c \ iem_ambi.c OBJ = $(SRC:.c=.obj) .c.obj: cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c ..\$(TARGET).dll: $(OBJ) link $(PD_WIN_L_FLAGS) /dll /export:$(TARGET)_setup \ /out:..\$(TARGET).dll $(OBJ) $(PD_WIN_LIB) clean: del *.obj iem_ambi-0.2/src/VC7/0000755000175000017500000000000012163236207014537 5ustar zmoelnigzmoelnigiem_ambi-0.2/src/VC7/iem_ambi.vcproj0000644000175000017500000000242511603103256017524 0ustar zmoelnigzmoelnig iem_ambi-0.2/src/VC7/makefile_vc7proj0000644000175000017500000000201111603103256017676 0ustar zmoelnigzmoelnigTARGET = iem_ambi all: ..\$(TARGET).dll VIS_CPP_PATH = "C:\Programme\Microsoft Visual Studio .NET 2003\Vc7" VIS_SDK_PATH = "C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK" PD_INST_PATH = "C:\Programme\pd-0.42-5" 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 -D_CRT_SECURE_NO_WARNINGS PD_WIN_L_FLAGS = /nologo PD_WIN_LIB = /NODEFAULTLIB:libcmt /NODEFAULTLIB:oldnames /NODEFAULTLIB:kernel32 \ $(VIS_CPP_PATH)\lib\libcmt.lib \ $(VIS_CPP_PATH)\lib\oldnames.lib \ $(VIS_SDK_PATH)\lib\kernel32.lib \ $(PD_INST_PATH)\bin\pd.lib SRC = ambi_decode.c \ ambi_decode2.c \ ambi_decode3.c \ ambi_decode_cube.c \ ambi_encode.c \ ambi_rot.c \ iem_ambi.c OBJ = $(SRC:.c=.obj) .c.obj: cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c ..\$(TARGET).dll: $(OBJ) link $(PD_WIN_L_FLAGS) /dll /export:$(TARGET)_setup \ /out:..\$(TARGET).dll $(OBJ) $(PD_WIN_LIB) clean: del *.obj iem_ambi-0.2/src/iem_ambi.sln0000644000175000017500000000156111603103256016416 0ustar zmoelnigzmoelnig Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iem_ambi", "iem_ambi.vcproj", "{6A44952F-0D55-44EE-9032-928368583BEC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6A44952F-0D55-44EE-9032-928368583BEC}.Debug|Win32.ActiveCfg = Debug|Win32 {6A44952F-0D55-44EE-9032-928368583BEC}.Debug|Win32.Build.0 = Debug|Win32 {6A44952F-0D55-44EE-9032-928368583BEC}.Release|Win32.ActiveCfg = Release|Win32 {6A44952F-0D55-44EE-9032-928368583BEC}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal iem_ambi-0.2/src/ambi_rot.c0000644000175000017500000013002410540330021016062 0ustar zmoelnigzmoelnig/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ #include "m_pd.h" #include "iemlib.h" #include /* -------------------------- ambi_rot ------------------------------ */ /* ambi_rot : 1. uebergabe-argument : ambisonic-ordnung 1 .. 4; input: nur z-rotation; input: mit 2 floats: nur z*y-rotation; input: mit 3 floats: z*y*x-rotation; output: je nach ordnung: 1 .. 4 -outputs mit selector "matrix" + row + col + ordnung*ordnung-coeff.; */ typedef struct _ambi_rot { t_object x_obj; t_atom *x_at2; int x_size2; t_atom *x_at3; int x_size3; void *x_out3; t_atom *x_at5; int x_size5; void *x_out5; t_atom *x_at7; int x_size7; void *x_out7; t_atom *x_at9; int x_size9; void *x_out9; t_atom *x_at11; int x_size11; void *x_out11; void *x_out13; void *x_out15; void *x_out17; void *x_out19; void *x_out21; void *x_out23; void *x_out25; t_float x_sqrt2_16; t_float x_sqrt3_2; t_float x_sqrt5_32; t_float x_sqrt6_4; t_float x_sqrt7_8; t_float x_sqrt10_4; t_float x_sqrt14_16; t_float x_sqrt15_8; t_float x_sqrt35_64; t_float x_sqrt70_32; t_float x_pi_over_180; t_symbol *x_s_matrix; int x_order; } t_ambi_rot; static t_class *ambi_rot_class; static void ambi_rot_float(t_ambi_rot *x, t_floatarg rho_z) /* = ambi_rot_z(); */ { t_float c, s, cc, ss, c2, s2, c3, s3, s4, c4, s5, c5, s6, c6, sx, cx; t_atom *at; rho_z *= x->x_pi_over_180; c = cos(rho_z); s = sin(rho_z); cc = c*c; ss = s*s; if(x->x_order >= 2) { c2 = cc - ss; s2 = 2.0f*s*c; if(x->x_order >= 3) { c3 = c*(4.0f*cc - 3.0f); s3 = s*(3.0f - 4.0f*ss); if(x->x_order >= 4) { c4 = 1.0f + 8.0f*cc*(cc - 1.0f); s4 = 2.0f*s2*c2; if(x->x_order >= 5) { c5 = c*(1.0f + 4.0f*ss*(ss - 3.0f*cc)); s5 = s*(1.0f + 4.0f*cc*(cc - 3.0f*ss)); if(x->x_order >= 6) { c6 = c3*c3 - s3*s3; s6 = 2.0f*s3*c3; if(x->x_order >= 7) { if(x->x_order >= 8) { if(x->x_order >= 9) { if(x->x_order >= 10) { if(x->x_order >= 11) { if(x->x_order >= 12) { if(x->x_order >= 13) post("ambi_rot-ERROR: do not support Ambisonic-Order greater than 12 in z-Rotation !!!"); at = x->x_at2; at += 2; cx = c6*c6 - s6*s6; sx = 2.0f*s6*c6; SETFLOAT(at, cx); at++; SETFLOAT(at, -sx); at++; SETFLOAT(at, sx); at++; SETFLOAT(at, cx); outlet_anything(x->x_out25, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; cx = cos(11.0f*rho_z); sx = sin(11.0f*rho_z); SETFLOAT(at, cx); at++; SETFLOAT(at, -sx); at++; SETFLOAT(at, sx); at++; SETFLOAT(at, cx); outlet_anything(x->x_out23, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; cx = c5*c5 - s5*s5; sx = 2.0f*s5*c5; SETFLOAT(at, cx); at++; SETFLOAT(at, -sx); at++; SETFLOAT(at, sx); at++; SETFLOAT(at, cx); outlet_anything(x->x_out21, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; cx = cos(9.0f*rho_z); sx = sin(9.0f*rho_z); SETFLOAT(at, cx); at++; SETFLOAT(at, -sx); at++; SETFLOAT(at, sx); at++; SETFLOAT(at, cx); outlet_anything(x->x_out19, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; cx = c4*c4 - s4*s4; sx = 2.0f*s4*c4; SETFLOAT(at, cx); at++; SETFLOAT(at, -sx); at++; SETFLOAT(at, sx); at++; SETFLOAT(at, cx); outlet_anything(x->x_out17, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; cx = cos(7.0f*rho_z); sx = sin(7.0f*rho_z); SETFLOAT(at, cx); at++; SETFLOAT(at, -sx); at++; SETFLOAT(at, sx); at++; SETFLOAT(at, cx); outlet_anything(x->x_out15, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; SETFLOAT(at, c6); at++; SETFLOAT(at, -s6); at++; SETFLOAT(at, s6); at++; SETFLOAT(at, c6); outlet_anything(x->x_out13, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; SETFLOAT(at, c5); at++; SETFLOAT(at, -s5); at++; SETFLOAT(at, s5); at++; SETFLOAT(at, c5); outlet_anything(x->x_out11, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; SETFLOAT(at, c4); at++; SETFLOAT(at, -s4); at++; SETFLOAT(at, s4); at++; SETFLOAT(at, c4); outlet_anything(x->x_out9, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; SETFLOAT(at, c3); at++; SETFLOAT(at, -s3); at++; SETFLOAT(at, s3); at++; SETFLOAT(at, c3); outlet_anything(x->x_out7, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; SETFLOAT(at, c2); at++; SETFLOAT(at, -s2); at++; SETFLOAT(at, s2); at++; SETFLOAT(at, c2); outlet_anything(x->x_out5, x->x_s_matrix, x->x_size2, x->x_at2); } at = x->x_at2; at += 2; SETFLOAT(at, c); at++; SETFLOAT(at, -s); at++; SETFLOAT(at, s); at++; SETFLOAT(at, c); outlet_anything(x->x_out3, x->x_s_matrix, x->x_size2, x->x_at2); } static void ambi_rot_zy(t_ambi_rot *x, t_floatarg rho_z, t_floatarg rho_y) { t_float cy, sy, ccy, ssy, c2y, s2y, c3y, s3y, c4y, s4y; t_float cz, sz, ccz, ssz, c2z, s2z, c3z, s3z, c4z, s4z; t_float r9_y[9][9]; int i; t_atom *at; rho_z *= x->x_pi_over_180; rho_y *= x->x_pi_over_180; cz = cos(rho_z); sz = sin(rho_z); ccz = cz*cz; ssz = sz*sz; cy = cos(rho_y); sy = sin(rho_y); ccy = cy*cy; ssy = sy*sy; if(x->x_order >= 2) { c2z = ccz - ssz; s2z = 2.0f*sz*cz; c2y = ccy - ssy; s2y = 2.0f*sy*cy; if(x->x_order >= 3) { c3z = cz*(4.0f*ccz - 3.0f); s3z = sz*(3.0f - 4.0f*ssz); c3y = cy*(4.0f*ccy - 3.0f); s3y = sy*(3.0f - 4.0f*ssy); if(x->x_order >= 4) { if(x->x_order >= 5) post("ambi_rot-ERROR: do not support Ambisonic-Order greater than 5 in zy-Rotation !!!"); /*y r9_11=(35 + 28*c2 + c4)/64; r9_22=(7c + c3)/8; r9_31 = x->x_sqrt2*(14*s2 + s4)/32; r9_33=(7*c2 + c4)/8; r9_42 = x->x_sqrt2*(7*s + 3*s3)/16; r9_44=(7*c + 9*c3)/16; r9_51 = x->x_sqrt7*(5 - 4*c2 - c4)/32; r9_53 = x->x_sqrt14*(2*s2 + s4)/16; r9_55=(5 + 4*c2 + 7*c4)/16; r9_62 = x->x_sqrt7*(c - c3)/8; r9_64 = x->x_sqrt14*(-s + 3*s3)/16; r9_66=(c + 7*c3)/8; r9_71 = x->x_sqrt14*(2*s2 - s4)/32; r9_73 = x->x_sqrt7*(c2 - c4)/8; r9_75 = x->x_sqrt2*(-2*s2 + 7*s4)/16; r9_77=(c2 + 7*c4)/8; r9_82 = x->x_sqrt14*(3*s - s3)/16; r9_84 = x->x_sqrt7*(3*c - 3*c3)/16; r9_86 = x->x_sqrt2*(3*s + 7*s3)/16; r9_88=(9*c + 7*c3)/16; r9_91 = x->x_sqrt35*(3 - 4*c2 + c4)/64; r9_93 = x->x_sqrt70*(2*s2 - s4)/32; r9_95 = x->x_sqrt5*(3 + 4*c2 - 7*c4)/32; r9_97 = x->x_sqrt10*(2*s2 + 7*s4)/32; r9_99=(9 + 20*c2 + 35*c4)/64; */ c4y = 1.0f + 8.0f*ccy*(ccy - 1.0f); s4y = 2.0f*s2y*c2y; c4z = 1.0f + 8.0f*ccz*(ccz - 1.0f); s4z = 2.0f*s2z*c2z; r9_y[0][0] = (35.0f + 28.0f*c2y + c4y)*0.015625f;/* -r9_31y, r9_51y, -r9_71y, r9_91y; */ r9_y[1][1] = (7.0f*cy + c3y)*0.125f;/* -r9_42y, r9_62y, -r9_82y;*/ r9_y[2][0] = x->x_sqrt2_16*(14.0f*s2y + s4y)*0.5f; r9_y[2][2] = (7.0f*c2y + c4y)*0.125f;/* -r9_53y, r9_73y, -r9_93y;*/ r9_y[3][1] = x->x_sqrt2_16*(7.0f*sy + 3.0f*s3y); r9_y[3][3] = (7.0f*cy + 9.0f*c3y)*0.0625f;/* -r9_64y, r9_84y;*/ r9_y[4][0] = x->x_sqrt7_8*(5.0f - 4.0f*c2y - c4y)*0.25f; r9_y[4][2] = x->x_sqrt14_16*(2.0f*s2y + s4y); r9_y[4][4] = (5.0f + 4.0f*c2y + 7.0f*c4y)*0.0625f;/* -r9_75y, r9_95y;*/ r9_y[5][1] = x->x_sqrt7_8*(cy - c3y); r9_y[5][3] = x->x_sqrt14_16*(3.0f*s3y - sy); r9_y[5][5] = (cy + 7.0f*c3y)*0.125f;/* -r9_86y;*/ r9_y[6][0] = x->x_sqrt14_16*(2.0f*s2y - s4y)*0.5f; r9_y[6][2] = x->x_sqrt7_8*(c2y - c4y); r9_y[6][4] = x->x_sqrt2_16*(7.0f*s4y - 2.0f*s2y); r9_y[6][6] = (c2y + 7.0f*c4y)*0.125f;/* -r9_97y;*/ r9_y[7][1] = x->x_sqrt14_16*(3.0f*sy - s3y); r9_y[7][3] = x->x_sqrt7_8*(cy - c3y)*1.5f; r9_y[7][5] = x->x_sqrt2_16*(3.0f*sy + 7.0f*s3y); r9_y[7][7] = (9.0f*cy + 7.0f*c3y)*0.0625f; r9_y[8][0] = x->x_sqrt35_64*(3.0f - 4.0f*c2y + c4y); r9_y[8][2] = x->x_sqrt70_32*(2.0f*s2y - s4y); r9_y[8][4] = x->x_sqrt5_32*(3.0f + 4.0f*c2y - 7.0f*c4y); r9_y[8][6] = x->x_sqrt10_4*(2.0f*s2y + 7.0f*s4y)*0.125f; r9_y[8][8] = (9.0f + 20.0f*c2y + 35.0f*c4y)*0.015625f; r9_y[0][2] = -r9_y[2][0]; r9_y[0][4] = r9_y[4][0]; r9_y[0][6] = -r9_y[6][0]; r9_y[0][8] = r9_y[8][0]; r9_y[1][3] = -r9_y[3][1]; r9_y[1][5] = r9_y[5][1]; r9_y[1][7] = -r9_y[7][1]; r9_y[2][4] = -r9_y[4][2]; r9_y[2][6] = r9_y[6][2]; r9_y[2][8] = -r9_y[8][2]; r9_y[3][5] = -r9_y[5][3]; r9_y[3][7] = r9_y[7][3]; r9_y[4][6] = -r9_y[6][4]; r9_y[4][8] = r9_y[8][4]; r9_y[5][7] = -r9_y[7][5]; r9_y[6][8] = -r9_y[8][6]; at = x->x_at9; at += 2; for(i=0; i<8; i+=2) { SETFLOAT(at, c4z*r9_y[0][i]); at++; SETFLOAT(at, -s4z*r9_y[1][i+1]); at++; } SETFLOAT(at, c4z*r9_y[0][8]); at++; for(i=0; i<8; i+=2) { SETFLOAT(at, c4z*r9_y[0][i]); at++; SETFLOAT(at, s4z*r9_y[1][i+1]); at++; } SETFLOAT(at, s4z*r9_y[0][8]); at++; for(i=0; i<8; i+=2) { SETFLOAT(at, c3z*r9_y[2][i]); at++; SETFLOAT(at, -s3z*r9_y[3][i+1]); at++; } SETFLOAT(at, c3z*r9_y[2][8]); at++; for(i=0; i<8; i+=2) { SETFLOAT(at, c3z*r9_y[2][i]); at++; SETFLOAT(at, s3z*r9_y[3][i+1]); at++; } SETFLOAT(at, s3z*r9_y[2][8]); at++; for(i=0; i<8; i+=2) { SETFLOAT(at, c2z*r9_y[4][i]); at++; SETFLOAT(at, -s2z*r9_y[5][i+1]); at++; } SETFLOAT(at, c2z*r9_y[4][8]); at++; for(i=0; i<8; i+=2) { SETFLOAT(at, c2z*r9_y[4][i]); at++; SETFLOAT(at, s2z*r9_y[5][i+1]); at++; } SETFLOAT(at, s2z*r9_y[4][8]); at++; for(i=0; i<8; i+=2) { SETFLOAT(at, cz*r9_y[6][i]); at++; SETFLOAT(at, -sz*r9_y[7][i+1]); at++; } SETFLOAT(at, cz*r9_y[6][8]); at++; for(i=0; i<8; i+=2) { SETFLOAT(at, cz*r9_y[6][i]); at++; SETFLOAT(at, sz*r9_y[7][i+1]); at++; } SETFLOAT(at, sz*r9_y[6][8]); at++; for(i=0; i<8; i+=2) { SETFLOAT(at, r9_y[8][i]); at++; SETFLOAT(at, 0.0f); at++; } SETFLOAT(at, r9_y[8][8]); outlet_anything(x->x_out9, x->x_s_matrix, x->x_size9, x->x_at9); } /*y r7_11=(15*c + c3)/16; r7_22=(5 + 3*c2)/8; r7_31 = x->x_sqrt6*(5*s + s3)/16; r7_33=(5*c + 3*c3)/8; r7_42 = x->x_sqrt6*(s2)/4; r7_44=(c2); r7_51 = x->x_sqrt15*(c - c3)/16; r7_53 = x->x_sqrt10*(-s + 3*s3)/16; r7_55=(c + 15*c3)/16; r7_62 = x->x_sqrt15*(1 - c2)/8; r7_64 = x->x_sqrt10*(s2)/4; r7_66=(3 + 5*c2)/8; r7_71 = x->x_sqrt10*(3*s - s3)/16; r7_73 = x->x_sqrt15*(c - c3)/8 = 2*r7_51; r7_75 = x->x_sqrt6*(s + 5*s3)/16; r7_77=(3*c + 5*c3)/8; */ r9_y[0][0] = (15.0f*cy + c3y)*0.0625f;/* -r7_31y, r7_51y, -r7_71y;*/ r9_y[1][1] = (5.0f + 3.0f*c2y)*0.125f;/* -r7_42y, r7_62y;*/ r9_y[2][0] = x->x_sqrt6_4*(5.0f*sy + s3y)*0.25f; r9_y[2][2] = (5.0f*cy + 3.0f*c3y)*0.125f;/* -r7_53y, r7_73y;*/ r9_y[3][1] = x->x_sqrt6_4*s2y; r9_y[3][3] = c2y;/* -r7_64y;*/ r9_y[6][2] = x->x_sqrt15_8*(cy - c3y); r9_y[4][0] = r9_y[6][2]*0.5f; r9_y[4][2] = x->x_sqrt10_4*(3.0f*s3y - sy)*0.25f; r9_y[4][4] = (cy + 15.0f*c3y)*0.0625f;/* -r7_75y;*/ r9_y[5][1] = x->x_sqrt15_8*(1.0f - c2y); r9_y[5][3] = x->x_sqrt10_4*s2y; r9_y[5][5] = (3.0f + 5.0f*c2y)*0.125f; r9_y[6][0] = x->x_sqrt10_4*(3.0f*sy - s3y)*0.25f; r9_y[6][4] = x->x_sqrt6_4*(sy + 5.0f*s3y)*0.25f; r9_y[6][6] = (3.0f*cy + 5.0f*c3y)*0.125f; r9_y[0][2] = -r9_y[2][0]; r9_y[0][4] = r9_y[4][0]; r9_y[0][6] = -r9_y[6][0]; r9_y[1][3] = -r9_y[3][1]; r9_y[1][5] = r9_y[5][1]; r9_y[2][4] = -r9_y[4][2]; r9_y[2][6] = r9_y[6][2]; r9_y[3][5] = -r9_y[5][3]; r9_y[4][6] = -r9_y[6][4]; at = x->x_at7; at += 2; for(i=0; i<6; i+=2) { SETFLOAT(at, c3z*r9_y[0][i]); at++; SETFLOAT(at, -s3z*r9_y[1][i+1]); at++; } SETFLOAT(at, c3z*r9_y[0][6]); at++; for(i=0; i<6; i+=2) { SETFLOAT(at, c3z*r9_y[0][i]); at++; SETFLOAT(at, s3z*r9_y[1][i+1]); at++; } SETFLOAT(at, s3z*r9_y[0][6]); at++; for(i=0; i<6; i+=2) { SETFLOAT(at, c2z*r9_y[2][i]); at++; SETFLOAT(at, -s2z*r9_y[3][i+1]); at++; } SETFLOAT(at, c2z*r9_y[2][6]); at++; for(i=0; i<6; i+=2) { SETFLOAT(at, c2z*r9_y[2][i]); at++; SETFLOAT(at, s2z*r9_y[3][i+1]); at++; } SETFLOAT(at, s2z*r9_y[2][6]); at++; for(i=0; i<6; i+=2) { SETFLOAT(at, cz*r9_y[4][i]); at++; SETFLOAT(at, -sz*r9_y[5][i+1]); at++; } SETFLOAT(at, cz*r9_y[4][6]); at++; for(i=0; i<6; i+=2) { SETFLOAT(at, cz*r9_y[4][i]); at++; SETFLOAT(at, sz*r9_y[5][i+1]); at++; } SETFLOAT(at, sz*r9_y[4][6]); at++; for(i=0; i<6; i+=2) { SETFLOAT(at, r9_y[6][i]); at++; SETFLOAT(at, 0.0f); at++; } SETFLOAT(at, r9_y[6][6]); outlet_anything(x->x_out7, x->x_s_matrix, x->x_size7, x->x_at7); } /*y r5_11=(3 + c2)/4; r5_22=(c); r5_31 = (s2)/2; r5_33=(c2); r5_42 = (s); r5_44=(c); r5_51 = x->x_sqrt3*(1 - c2)/4; r5_53 = x->x_sqrt3*(s2)/2; r5_55=(1 + 3*c2)/4; */ r9_y[0][0] = (3.0f + c2y)*0.25f;/* -r5_31y, r5_51y;*/ r9_y[1][1] = cy;/* -r5_42y;*/ r9_y[2][0] = s2y*0.5f; r9_y[2][2] = c2y;/* -r5_53y;*/ r9_y[3][1] = sy; r9_y[3][3] = cy; r9_y[4][0] = x->x_sqrt3_2*(1.0f - c2y)*0.5f; r9_y[4][2] = x->x_sqrt3_2*s2y; r9_y[4][4] = (1.0f + 3.0f*c2y)*0.25f; r9_y[0][2] = -r9_y[2][0]; r9_y[0][4] = r9_y[4][0]; r9_y[1][3] = -r9_y[3][1]; r9_y[2][4] = -r9_y[4][2]; at = x->x_at5; at += 2; for(i=0; i<4; i+=2) { SETFLOAT(at, c2z*r9_y[0][i]); at++; SETFLOAT(at, -s2z*r9_y[1][i+1]); at++; } SETFLOAT(at, c2z*r9_y[0][4]); at++; for(i=0; i<4; i+=2) { SETFLOAT(at, c2z*r9_y[0][i]); at++; SETFLOAT(at, s2z*r9_y[1][i+1]); at++; } SETFLOAT(at, s2z*r9_y[0][4]); at++; for(i=0; i<4; i+=2) { SETFLOAT(at, cz*r9_y[2][i]); at++; SETFLOAT(at, -sz*r9_y[3][i+1]); at++; } SETFLOAT(at, cz*r9_y[2][4]); at++; for(i=0; i<4; i+=2) { SETFLOAT(at, cz*r9_y[2][i]); at++; SETFLOAT(at, sz*r9_y[3][i+1]); at++; } SETFLOAT(at, sz*r9_y[2][4]); at++; for(i=0; i<4; i+=2) { SETFLOAT(at, r9_y[4][i]); at++; SETFLOAT(at, 0.0f); at++; } SETFLOAT(at, r9_y[4][4]); outlet_anything(x->x_out5, x->x_s_matrix, x->x_size5, x->x_at5); } /*y r3_11=(c); r3_22=(1); r3_31 = (s); r3_33=(c); */ r9_y[0][0] = cy;/* -r3_31y;*/ r9_y[1][1] = 1.0f; r9_y[2][0] = sy; r9_y[2][2] = cy; r9_y[0][2] = -r9_y[2][0]; at = x->x_at3; at += 2; SETFLOAT(at, cz*r9_y[0][0]); at++; SETFLOAT(at, -sz*r9_y[1][1]); at++; SETFLOAT(at, cz*r9_y[0][2]); at++; SETFLOAT(at, sz*r9_y[0][0]); at++; SETFLOAT(at, cz*r9_y[1][1]); at++; SETFLOAT(at, sz*r9_y[0][2]); at++; SETFLOAT(at, r9_y[2][0]); at++; SETFLOAT(at, 0.0f); at++; SETFLOAT(at, r9_y[2][2]); outlet_anything(x->x_out3, x->x_s_matrix, x->x_size3, x->x_at3); } static void ambi_rot_zyx(t_ambi_rot *x, t_floatarg rho_z, t_floatarg rho_y, t_floatarg rho_x) { t_float cx, sx, ccx, ssx, c2x, s2x, c3x, s3x, c4x, s4x; t_float cy, sy, ccy, ssy, c2y, s2y, c3y, s3y, c4y, s4y; t_float cz, sz, ccz, ssz, c2z, s2z, c3z, s3z, c4z, s4z; t_float r9_zy[9][9]; t_float r9_z[9][9]; t_float r9_y[9][9]; t_float r9_x[9][9]; int i, j; t_atom *at; rho_z *= x->x_pi_over_180; rho_y *= x->x_pi_over_180; rho_x *= x->x_pi_over_180; cz = cos(rho_z); sz = sin(rho_z); ccz = cz*cz; ssz = sz*sz; cy = cos(rho_y); sy = sin(rho_y); ccy = cy*cy; ssy = sy*sy; cx = cos(rho_x); sx = sin(rho_x); ccx = cx*cx; ssx = sx*sx; if(x->x_order >= 2) { c2z = ccz - ssz; s2z = 2.0f*sz*cz; c2y = ccy - ssy; s2y = 2.0f*sy*cy; c2x = ccx - ssx; s2x = 2.0f*sx*cx; if(x->x_order >= 3) { c3z = cz*(4.0f*ccz - 3.0f); s3z = sz*(3.0f - 4.0f*ssz); c3y = cy*(4.0f*ccy - 3.0f); s3y = sy*(3.0f - 4.0f*ssy); c3x = cx*(4.0f*ccx - 3.0f); s3x = sx*(3.0f - 4.0f*ssx); if(x->x_order >= 4) { if(x->x_order >= 5) post("ambi_rot-ERROR: do not support Ambisonic-Order greater than 5 in zyx-Rotation !!!"); c4z = 1.0f + 8.0f*ccz*(ccz - 1.0f); s4z = 2.0f*s2z*c2z; c4y = 1.0f + 8.0f*ccy*(ccy - 1.0f); s4y = 2.0f*s2y*c2y; c4x = 1.0f + 8.0f*ccx*(ccx - 1.0f); s4x = 2.0f*s2x*c2x; r9_z[0][0] = c4z; r9_z[0][1] = -s4z; r9_z[1][0] = s4z; r9_z[1][1] = c4z; r9_z[2][2] = c3z; r9_z[2][3] = -s3z; r9_z[3][2] = s3z; r9_z[3][3] = c3z; r9_z[4][4] = c2z; r9_z[4][5] = -s2z; r9_z[5][4] = s2z; r9_z[5][5] = c2z; r9_z[6][6] = cz; r9_z[6][7] = -sz; r9_z[7][6] = sz; r9_z[7][7] = cz; r9_z[8][8] = 1.0f; /*y r9_11=(35 + 28*c2 + c4)/64; r9_22=(7c + c3)/8; r9_31 = x->x_sqrt2*(14*s2 + s4)/32; r9_33=(7*c2 + c4)/8; r9_42 = x->x_sqrt2*(7*s + 3*s3)/16; r9_44=(7*c + 9*c3)/16; r9_51 = x->x_sqrt7*(5 - 4*c2 - c4)/32; r9_53 = x->x_sqrt14*(2*s2 + s4)/16; r9_55=(5 + 4*c2 + 7*c4)/16; r9_62 = x->x_sqrt7*(c - c3)/8; r9_64 = x->x_sqrt14*(-s + 3*s3)/16; r9_66=(c + 7*c3)/8; r9_71 = x->x_sqrt14*(2*s2 - s4)/32; r9_73 = x->x_sqrt7*(c2 - c4)/8; r9_75 = x->x_sqrt2*(-2*s2 + 7*s4)/16; r9_77=(c2 + 7*c4)/8; r9_82 = x->x_sqrt14*(3*s - s3)/16; r9_84 = x->x_sqrt7*(3*c - 3*c3)/16; r9_86 = x->x_sqrt2*(3*s + 7*s3)/16; r9_88=(9*c + 7*c3)/16; r9_91 = x->x_sqrt35*(3 - 4*c2 + c4)/64; r9_93 = x->x_sqrt70*(2*s2 - s4)/32; r9_95 = x->x_sqrt5*(3 + 4*c2 - 7*c4)/32; r9_97 = x->x_sqrt10*(2*s2 + 7*s4)/32; r9_99=(9 + 20*c2 + 35*c4)/64; */ r9_y[0][0] = (35.0f + 28.0f*c2y + c4y)*0.015625f;/* -r9_31y, r9_51y, -r9_71y, r9_91y; */ r9_y[1][1] = (7.0f*cy + c3y)*0.125f;/* -r9_42y, r9_62y, -r9_82y;*/ r9_y[2][0] = x->x_sqrt2_16*(14.0f*s2y + s4y)*0.5f; r9_y[2][2] = (7.0f*c2y + c4y)*0.125f;/* -r9_53y, r9_73y, -r9_93y;*/ r9_y[3][1] = x->x_sqrt2_16*(7.0f*sy + 3.0f*s3y); r9_y[3][3] = (7.0f*cy + 9.0f*c3y)*0.0625f;/* -r9_64y, r9_84y;*/ r9_y[4][0] = x->x_sqrt7_8*(5.0f - 4.0f*c2y - c4y)*0.25f; r9_y[4][2] = x->x_sqrt14_16*(2.0f*s2y + s4y); r9_y[4][4] = (5.0f + 4.0f*c2y + 7.0f*c4y)*0.0625f;/* -r9_75y, r9_95y;*/ r9_y[5][1] = x->x_sqrt7_8*(cy - c3y); r9_y[5][3] = x->x_sqrt14_16*(3.0f*s3y - sy); r9_y[5][5] = (cy + 7.0f*c3y)*0.125f;/* -r9_86y;*/ r9_y[6][0] = x->x_sqrt14_16*(2.0f*s2y - s4y)*0.5f; r9_y[6][2] = x->x_sqrt7_8*(c2y - c4y); r9_y[6][4] = x->x_sqrt2_16*(7.0f*s4y - 2.0f*s2y); r9_y[6][6] = (c2y + 7.0f*c4y)*0.125f;/* -r9_97y;*/ r9_y[7][1] = x->x_sqrt14_16*(3.0f*sy - s3y); r9_y[7][3] = x->x_sqrt7_8*(cy - c3y)*1.5f; r9_y[7][5] = x->x_sqrt2_16*(3.0f*sy + 7.0f*s3y); r9_y[7][7] = (9.0f*cy + 7.0f*c3y)*0.0625f; r9_y[8][0] = x->x_sqrt35_64*(3.0f - 4.0f*c2y + c4y); r9_y[8][2] = x->x_sqrt70_32*(2.0f*s2y - s4y); r9_y[8][4] = x->x_sqrt5_32*(3.0f + 4.0f*c2y - 7.0f*c4y); r9_y[8][6] = x->x_sqrt10_4*(2.0f*s2y + 7.0f*s4y)*0.125f; r9_y[8][8] = (9.0f + 20.0f*c2y + 35.0f*c4y)*0.015625f; r9_y[0][2] = -r9_y[2][0]; r9_y[0][4] = r9_y[4][0]; r9_y[0][6] = -r9_y[6][0]; r9_y[0][8] = r9_y[8][0]; r9_y[1][3] = -r9_y[3][1]; r9_y[1][5] = r9_y[5][1]; r9_y[1][7] = -r9_y[7][1]; r9_y[2][4] = -r9_y[4][2]; r9_y[2][6] = r9_y[6][2]; r9_y[2][8] = -r9_y[8][2]; r9_y[3][5] = -r9_y[5][3]; r9_y[3][7] = r9_y[7][3]; r9_y[4][6] = -r9_y[6][4]; r9_y[4][8] = r9_y[8][4]; r9_y[5][7] = -r9_y[7][5]; r9_y[6][8] = -r9_y[8][6]; /*x r9_11=(35 + 28*c2 + c4)/64; r9_22=(7c + c3)/8; r9_32 = x->x_sqrt2*(7*s + 3*s3)/16; r9_33=(7*c + 9*c3)/16; r9_41 = x->x_sqrt2*(-14*s2 - s4)/32; r9_44=(7*c2 + c4)/8; r9_51 = x->x_sqrt7*(-5 + 4*c2 + c4)/32; r9_54 = x->x_sqrt14*(2*s2 + s4)/16; r9_55=(5 + 4*c2 + 7*c4)/16; r9_62 = x->x_sqrt7*(-c + c3)/8; r9_63 = x->x_sqrt14*(s - 3*s3)/16; r9_66=(c + 7*c3)/8; r9_72 = x->x_sqrt14*(-3s + s3)/16; r9_73 = x->x_sqrt7*(-3*c + 3*c3)/16; r9_76 = x->x_sqrt2*(3*s + 7*s3)/16; r9_77=(9*c + 7*c3)/16; r9_81 = x->x_sqrt14*(2*s2 - s4)/32; r9_84 = x->x_sqrt7*(-c2 + c4)/8; r9_85 = x->x_sqrt2*(2*s2 - 7*s4)/16; r9_88=(c2 + 7*c4)/8; r9_91 = x->x_sqrt35*(3 - 4*c2 + c4)/64; r9_94 = x->x_sqrt70*(-2*s2 + s4)/32; r9_95 = x->x_sqrt5*(-3 - 4*c2 + 7*c4)/32; r9_98 = x->x_sqrt10*(2*s2 + 7*s4)/32; r9_99=(9 + 20*c2 + 35*c4)/64; */ r9_x[0][0] = (35.0f + 28.0f*c2x + c4x)*0.015625f;/* -r9_41x, r9_51x, -r9_81x, r9_91x;*/ r9_x[1][1] = (7.0f*cx + c3x)*0.125f;/* -r9_32x, r9_62x, -r9_72x;*/ r9_x[2][1] = x->x_sqrt2_16*(7.0f*sx + 3.0f*s3x); r9_x[2][2] = (7.0f*cx + 9.0f*c3x)*0.0625f;/* -r9_63x, r9_73x;*/ r9_x[3][0] = -x->x_sqrt2_16*(14.0f*s2x + s4x)*0.5f; r9_x[3][3] = (7.0f*c2x + c4x)*0.125f;/* -r9_54x, r9_84x, -r9_94x;*/ r9_x[4][0] = x->x_sqrt7_8*(4.0f*c2x + c4x - 5.0f)*0.25f; r9_x[4][3] = x->x_sqrt14_16*(2.0f*s2x + s4x); r9_x[4][4] = (5.0f + 4.0f*c2x + 7.0f*c4x)*0.0625f;/* -r9_85x, r9_95x;*/ r9_x[5][1] = x->x_sqrt7_8*(c3x - cx); r9_x[5][2] = x->x_sqrt14_16*(sx - 3.0f*s3x); r9_x[5][5] = (cx + 7.0f*c3x)*0.125f;/* -r9_76x;*/ r9_x[6][1] = x->x_sqrt14_16*(s3x - 3.0f*sx); r9_x[6][2] = x->x_sqrt7_8*(c3x - cx)*1.5f; r9_x[6][5] = x->x_sqrt2_16*(3.0f*sx + 7.0f*s3x); r9_x[6][6] = (9.0f*cx + 7.0f*c3x)*0.0625f; r9_x[7][0] = x->x_sqrt14_16*(2.0f*s2x - s4x)*0.5f; r9_x[7][3] = x->x_sqrt7_8*(c4x - c2x); r9_x[7][4] = x->x_sqrt2_16*(2.0f*s2x - 7.0f*s4x); r9_x[7][7] = (c2x + 7.0f*c4x)*0.125f;/* -r9_98x*/ r9_x[8][0] = x->x_sqrt35_64*(3.0f - 4.0f*c2x + c4x); r9_x[8][3] = x->x_sqrt70_32*(s4x - 2.0f*s2x); r9_x[8][4] = x->x_sqrt5_32*(7.0f*c4x - 3.0f - 4.0f*c2x); r9_x[8][7] = x->x_sqrt10_4*(2.0f*s2x + 7.0f*s4x)*0.125f; r9_x[8][8] = (9.0f + 20.0f*c2x + 35.0f*c4x)*0.015625f; r9_x[0][3] = -r9_x[3][0]; r9_x[0][4] = r9_x[4][0]; r9_x[0][7] = -r9_x[7][0]; r9_x[0][8] = r9_x[8][0]; r9_x[1][2] = -r9_x[2][1]; r9_x[1][5] = r9_x[5][1]; r9_x[1][6] = -r9_x[6][1]; r9_x[2][5] = -r9_x[5][2]; r9_x[2][6] = r9_x[6][2]; r9_x[3][4] = -r9_x[4][3]; r9_x[3][7] = r9_x[7][3]; r9_x[3][8] = -r9_x[8][3]; r9_x[4][7] = -r9_x[7][4]; r9_x[4][8] = r9_x[8][4]; r9_x[5][6] = -r9_x[6][5]; r9_x[7][8] = -r9_x[8][7]; for(j=0; j<8; j+=2) { for(i=0; i<8; i+=2) { r9_zy[j][i] = r9_z[j][j]*r9_y[j][i]; r9_zy[j][i+1] = r9_z[j][j+1]*r9_y[j+1][i+1]; r9_zy[j+1][i] = r9_z[j+1][j]*r9_y[j][i]; r9_zy[j+1][i+1] = r9_z[j+1][j+1]*r9_y[j+1][i+1]; } r9_zy[j][8] = r9_z[j][j]*r9_y[j][8]; r9_zy[j+1][8] = r9_z[j+1][j]*r9_y[j][8]; } for(i=0; i<=8; i+=2) { r9_zy[8][i] = r9_y[8][i]; } at = x->x_at9; at += 2; for(i=0; i<8; i++) { SETFLOAT(at, (r9_zy[i][0]*r9_x[0][0] + r9_zy[i][3]*r9_x[3][0] + r9_zy[i][4]*r9_x[4][0] + r9_zy[i][7]*r9_x[7][0] + r9_zy[i][8]*r9_x[8][0])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][1] + r9_zy[i][2]*r9_x[2][1] + r9_zy[i][5]*r9_x[5][1] + r9_zy[i][6]*r9_x[6][1])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][2] + r9_zy[i][2]*r9_x[2][2] + r9_zy[i][5]*r9_x[5][2] + r9_zy[i][6]*r9_x[6][2])); at++; SETFLOAT(at, (r9_zy[i][0]*r9_x[0][3] + r9_zy[i][3]*r9_x[3][3] + r9_zy[i][4]*r9_x[4][3] + r9_zy[i][7]*r9_x[7][3] + r9_zy[i][8]*r9_x[8][3])); at++; SETFLOAT(at, (r9_zy[i][0]*r9_x[0][4] + r9_zy[i][3]*r9_x[3][4] + r9_zy[i][4]*r9_x[4][4] + r9_zy[i][7]*r9_x[7][4] + r9_zy[i][8]*r9_x[8][4])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][5] + r9_zy[i][2]*r9_x[2][5] + r9_zy[i][5]*r9_x[5][5] + r9_zy[i][6]*r9_x[6][5])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][6] + r9_zy[i][2]*r9_x[2][6] + r9_zy[i][5]*r9_x[5][6] + r9_zy[i][6]*r9_x[6][6])); at++; SETFLOAT(at, (r9_zy[i][0]*r9_x[0][7] + r9_zy[i][3]*r9_x[3][7] + r9_zy[i][4]*r9_x[4][7] + r9_zy[i][7]*r9_x[7][7] + r9_zy[i][8]*r9_x[8][7])); at++; SETFLOAT(at, (r9_zy[i][0]*r9_x[0][8] + r9_zy[i][3]*r9_x[3][8] + r9_zy[i][4]*r9_x[4][8] + r9_zy[i][7]*r9_x[7][8] + r9_zy[i][8]*r9_x[8][8])); at++; } SETFLOAT(at, (r9_zy[8][0]*r9_x[0][0] + r9_zy[8][4]*r9_x[4][0] + r9_zy[8][8]*r9_x[8][0])); at++; SETFLOAT(at, (r9_zy[8][2]*r9_x[2][1] + r9_zy[8][6]*r9_x[6][1])); at++; SETFLOAT(at, (r9_zy[8][2]*r9_x[2][2] + r9_zy[8][6]*r9_x[6][2])); at++; SETFLOAT(at, (r9_zy[8][0]*r9_x[0][3] + r9_zy[8][4]*r9_x[4][3] + r9_zy[8][8]*r9_x[8][3])); at++; SETFLOAT(at, (r9_zy[8][0]*r9_x[0][4] + r9_zy[8][4]*r9_x[4][4] + r9_zy[8][8]*r9_x[8][4])); at++; SETFLOAT(at, (r9_zy[8][2]*r9_x[2][5] + r9_zy[8][6]*r9_x[6][5])); at++; SETFLOAT(at, (r9_zy[8][2]*r9_x[2][6] + r9_zy[8][6]*r9_x[6][6])); at++; SETFLOAT(at, (r9_zy[8][0]*r9_x[0][7] + r9_zy[8][4]*r9_x[4][7] + r9_zy[8][8]*r9_x[8][7])); at++; SETFLOAT(at, (r9_zy[8][0]*r9_x[0][8] + r9_zy[8][4]*r9_x[4][8] + r9_zy[8][8]*r9_x[8][8])); outlet_anything(x->x_out9, x->x_s_matrix, x->x_size9, x->x_at9); } r9_z[0][0] = c3z; r9_z[0][1] = -s3z; r9_z[1][0] = s3z; r9_z[1][1] = c3z; r9_z[2][2] = c2z; r9_z[2][3] = -s2z; r9_z[3][2] = s2z; r9_z[3][3] = c2z; r9_z[4][4] = cz; r9_z[4][5] = -sz; r9_z[5][4] = sz; r9_z[5][5] = cz; r9_z[6][6] = 1.0f; /*y r7_11=(15*c + c3)/16; r7_22=(5 + 3*c2)/8; r7_31 = x->x_sqrt6*(5*s + s3)/16; r7_33=(5*c + 3*c3)/8; r7_42 = x->x_sqrt6*(s2)/4; r7_44=(c2); r7_51 = x->x_sqrt15*(c - c3)/16; r7_53 = x->x_sqrt10*(-s + 3*s3)/16; r7_55=(c + 15*c3)/16; r7_62 = x->x_sqrt15*(1 - c2)/8; r7_64 = x->x_sqrt10*(s2)/4; r7_66=(3 + 5*c2)/8; r7_71 = x->x_sqrt10*(3*s - s3)/16; r7_73 = x->x_sqrt15*(c - c3)/8 = 2*r7_51; r7_75 = x->x_sqrt6*(s + 5*s3)/16; r7_77=(3*c + 5*c3)/8; */ r9_y[0][0] = (15.0f*cy + c3y)*0.0625f;/* -r7_31y, r7_51y, -r7_71y;*/ r9_y[1][1] = (5.0f + 3.0f*c2y)*0.125f;/* -r7_42y, r7_62y;*/ r9_y[2][0] = x->x_sqrt6_4*(5.0f*sy + s3y)*0.25f; r9_y[2][2] = (5.0f*cy + 3.0f*c3y)*0.125f;/* -r7_53y, r7_73y;*/ r9_y[3][1] = x->x_sqrt6_4*s2y; r9_y[3][3] = c2y;/* -r7_64y;*/ r9_y[6][2] = x->x_sqrt15_8*(cy - c3y); r9_y[4][0] = r9_y[6][2]*0.5f; r9_y[4][2] = x->x_sqrt10_4*(3.0f*s3y - sy)*0.25f; r9_y[4][4] = (cy + 15.0f*c3y)*0.0625f;/* -r7_75y;*/ r9_y[5][1] = x->x_sqrt15_8*(1.0f - c2y); r9_y[5][3] = x->x_sqrt10_4*s2y; r9_y[5][5] = (3.0f + 5.0f*c2y)*0.125f; r9_y[6][0] = x->x_sqrt10_4*(3.0f*sy - s3y)*0.25f; r9_y[6][4] = x->x_sqrt6_4*(sy + 5.0f*s3y)*0.25f; r9_y[6][6] = (3.0f*cy + 5.0f*c3y)*0.125f; r9_y[0][2] = -r9_y[2][0]; r9_y[0][4] = r9_y[4][0]; r9_y[0][6] = -r9_y[6][0]; r9_y[1][3] = -r9_y[3][1]; r9_y[1][5] = r9_y[5][1]; r9_y[2][4] = -r9_y[4][2]; r9_y[2][6] = r9_y[6][2]; r9_y[3][5] = -r9_y[5][3]; r9_y[4][6] = -r9_y[6][4]; /*x r7_11=(5 + 3*c2)/8; r7_22=(15*c + c3)/16; r7_32 = x->x_sqrt6*(5*s + s3)/16; r7_33=(5*c + 3*c3)/8; r7_41 = x->x_sqrt6*(-s2)/4; r7_44=(c2); r7_51 = x->x_sqrt15*(-1 + c2)/8; r7_54 = x->x_sqrt10*(s2)/4; r7_55=(3 + 5*c2)/8; r7_62 = x->x_sqrt15*(-c + c3)/16; r7_63 = x->x_sqrt10*(s - 3*s3)/16; r7_66=(c + 15*c3)/16; r7_72 = x->x_sqrt10*(-3*s + s3)/16; r7_73 = x->x_sqrt15*(-c + c3)/8 = 2*r7_62; r7_76 = x->x_sqrt6*(s + 5*s3)/16; r7_77=(3*c + 5*c3)/8; */ r9_x[0][0] = (5.0f + 3.0f*c2x)*0.125f;/* -r7_41, r7_51;*/ r9_x[1][1] = (15.0f*cx + c3x)*0.0625f;/* -r7_32, r7_62, -r7_72;*/ r9_x[2][1] = x->x_sqrt6_4*(5.0f*sx + s3x)*0.25f; r9_x[2][2] = (5.0f*cx + 3.0f*c3x)*0.125f;/* */ r9_x[3][0] = -x->x_sqrt6_4*s2x; r9_x[3][3] = c2x; r9_x[4][0] = x->x_sqrt15_8*(c2x - 1.0f); r9_x[4][3] = x->x_sqrt10_4*s2x; r9_x[4][4] = (3.0f + 5.0f*c2x)*0.125f; r9_x[6][2] = x->x_sqrt15_8*(c3x - cx); r9_x[5][1] = r9_x[6][2]*0.5f; r9_x[5][2] = x->x_sqrt10_4*(sx - 3.0f*s3x)*0.25f; r9_x[5][5] = (cx + 15.0f*c3x)*0.0625f; r9_x[6][1] = x->x_sqrt10_4*(s3x - 3.0f*sx)*0.25f; r9_x[6][5] = x->x_sqrt6_4*(sx + 5.0f*s3x)*0.25f; r9_x[6][6] = (3.0f*cx + 5.0f*c3x)*0.125f; r9_x[0][3] = -r9_x[3][0]; r9_x[0][4] = r9_x[4][0]; r9_x[1][2] = -r9_x[2][1]; r9_x[1][5] = r9_x[5][1]; r9_x[1][6] = -r9_x[6][1]; r9_x[2][5] = -r9_x[5][2]; r9_x[2][6] = r9_x[6][2]; r9_x[3][4] = -r9_x[4][3]; r9_x[5][6] = -r9_x[6][5]; for(j=0; j<6; j+=2) { for(i=0; i<6; i+=2) { r9_zy[j][i] = r9_z[j][j]*r9_y[j][i]; r9_zy[j][i+1] = r9_z[j][j+1]*r9_y[j+1][i+1]; r9_zy[j+1][i] = r9_z[j+1][j]*r9_y[j][i]; r9_zy[j+1][i+1] = r9_z[j+1][j+1]*r9_y[j+1][i+1]; } r9_zy[j][6] = r9_z[j][j]*r9_y[j][6]; r9_zy[j+1][6] = r9_z[j+1][j]*r9_y[j][6]; } for(i=0; i<=6; i+=2) { r9_zy[6][i] = r9_y[6][i]; } at = x->x_at7; at += 2; for(i=0; i<6; i++) { SETFLOAT(at, (r9_zy[i][0]*r9_x[0][0] + r9_zy[i][3]*r9_x[3][0] + r9_zy[i][4]*r9_x[4][0])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][1] + r9_zy[i][2]*r9_x[2][1] + r9_zy[i][5]*r9_x[5][1] + r9_zy[i][6]*r9_x[6][1])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][2] + r9_zy[i][2]*r9_x[2][2] + r9_zy[i][5]*r9_x[5][2] + r9_zy[i][6]*r9_x[6][2])); at++; SETFLOAT(at, (r9_zy[i][0]*r9_x[0][3] + r9_zy[i][3]*r9_x[3][3] + r9_zy[i][4]*r9_x[4][3])); at++; SETFLOAT(at, (r9_zy[i][0]*r9_x[0][4] + r9_zy[i][3]*r9_x[3][4] + r9_zy[i][4]*r9_x[4][4])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][5] + r9_zy[i][2]*r9_x[2][5] + r9_zy[i][5]*r9_x[5][5] + r9_zy[i][6]*r9_x[6][5])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][6] + r9_zy[i][2]*r9_x[2][6] + r9_zy[i][5]*r9_x[5][6] + r9_zy[i][6]*r9_x[6][6])); at++; } SETFLOAT(at, (r9_zy[6][0]*r9_x[0][0] + r9_zy[6][4]*r9_x[4][0])); at++; SETFLOAT(at, (r9_zy[6][2]*r9_x[2][1] + r9_zy[6][6]*r9_x[6][1])); at++; SETFLOAT(at, (r9_zy[6][2]*r9_x[2][2] + r9_zy[6][6]*r9_x[6][2])); at++; SETFLOAT(at, (r9_zy[6][0]*r9_x[0][3] + r9_zy[6][4]*r9_x[4][3])); at++; SETFLOAT(at, (r9_zy[6][0]*r9_x[0][4] + r9_zy[6][4]*r9_x[4][4])); at++; SETFLOAT(at, (r9_zy[6][2]*r9_x[2][5] + r9_zy[6][6]*r9_x[6][5])); at++; SETFLOAT(at, (r9_zy[6][2]*r9_x[2][6] + r9_zy[6][6]*r9_x[6][6])); outlet_anything(x->x_out7, x->x_s_matrix, x->x_size7, x->x_at7); } r9_z[0][0] = c2z; r9_z[0][1] = -s2z; r9_z[1][0] = s2z; r9_z[1][1] = c2z; r9_z[2][2] = cz; r9_z[2][3] = -sz; r9_z[3][2] = sz; r9_z[3][3] = cz; r9_z[4][4] = 1.0f; /*y r5_11=(3 + c2)/4; r5_22=(c); r5_31 = (s2)/2; r5_33=(c2); r5_42 = (s); r5_44=(c); r5_51 = x->x_sqrt3*(1 - c2)/4; r5_53 = x->x_sqrt3*(s2)/2; r5_55=(1 + 3*c2)/4; */ r9_y[0][0] = (3.0f + c2y)*0.25f;/* -r5_31y, r5_51y;*/ r9_y[1][1] = cy;/* -r5_42y;*/ r9_y[2][0] = s2y*0.5f; r9_y[2][2] = c2y;/* -r5_53y;*/ r9_y[3][1] = sy; r9_y[3][3] = cy; r9_y[4][0] = x->x_sqrt3_2*(1.0f - c2y)*0.5f; r9_y[4][2] = x->x_sqrt3_2*s2y; r9_y[4][4] = (1.0f + 3.0f*c2y)*0.25f; r9_y[0][2] = -r9_y[2][0]; r9_y[0][4] = r9_y[4][0]; r9_y[1][3] = -r9_y[3][1]; r9_y[2][4] = -r9_y[4][2]; /*x r5_11=(3 + c2)/4; r5_22=(c); r5_32 = (s); r5_33=(c); r5_41 = (-s2)/2; r5_44=(c2); r5_51 = x->x_sqrt3*(-1 + c2)/4; r5_54 = x->x_sqrt3*(s2)/2; r5_55=(1 + 3*c2)/4; */ r9_x[0][0] = (3.0f + c2x)*0.25f; r9_x[1][1] = cx; r9_x[2][1] = sx; r9_x[2][2] = cx; r9_x[3][0] = -0.5f*s2x; r9_x[3][3] = c2x; r9_x[4][0] = x->x_sqrt3_2*(c2x - 1.0f)*0.5f; r9_x[4][3] = x->x_sqrt3_2*s2x; r9_x[4][4] = (1.0f + 3.0f*c2x)*0.25f; r9_x[0][3] = -r9_x[3][0]; r9_x[0][4] = r9_x[4][0]; r9_x[1][2] = -r9_x[2][1]; r9_x[3][4] = -r9_x[4][3]; for(j=0; j<4; j+=2) { for(i=0; i<4; i+=2) { r9_zy[j][i] = r9_z[j][j]*r9_y[j][i]; r9_zy[j][i+1] = r9_z[j][j+1]*r9_y[j+1][i+1]; r9_zy[j+1][i] = r9_z[j+1][j]*r9_y[j][i]; r9_zy[j+1][i+1] = r9_z[j+1][j+1]*r9_y[j+1][i+1]; } r9_zy[j][4] = r9_z[j][j]*r9_y[j][4]; r9_zy[j+1][4] = r9_z[j+1][j]*r9_y[j][4]; } for(i=0; i<=4; i+=2) { r9_zy[4][i] = r9_y[4][i]; } at = x->x_at5; at += 2; for(i=0; i<4; i++) { SETFLOAT(at, (r9_zy[i][0]*r9_x[0][0] + r9_zy[i][3]*r9_x[3][0] + r9_zy[i][4]*r9_x[4][0])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][1] + r9_zy[i][2]*r9_x[2][1])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][2] + r9_zy[i][2]*r9_x[2][2])); at++; SETFLOAT(at, (r9_zy[i][0]*r9_x[0][3] + r9_zy[i][3]*r9_x[3][3] + r9_zy[i][4]*r9_x[4][3])); at++; SETFLOAT(at, (r9_zy[i][0]*r9_x[0][4] + r9_zy[i][3]*r9_x[3][4] + r9_zy[i][4]*r9_x[4][4])); at++; } SETFLOAT(at, (r9_zy[4][0]*r9_x[0][0] + r9_zy[4][4]*r9_x[4][0])); at++; SETFLOAT(at, (r9_zy[4][2]*r9_x[2][1])); at++; SETFLOAT(at, (r9_zy[4][2]*r9_x[2][2])); at++; SETFLOAT(at, (r9_zy[4][0]*r9_x[0][3] + r9_zy[4][4]*r9_x[4][3])); at++; SETFLOAT(at, (r9_zy[4][0]*r9_x[0][4] + r9_zy[4][4]*r9_x[4][4])); outlet_anything(x->x_out5, x->x_s_matrix, x->x_size5, x->x_at5); } r9_z[0][0] = cz; r9_z[0][1] = -sz; r9_z[1][0] = sz; r9_z[1][1] = cz; r9_z[2][2] = 1.0f; /*y r3_11=(c); r3_22=(1); r3_31 = (s); r3_33=(c); */ r9_y[0][0] = cy;/* -r3_31y;*/ r9_y[1][1] = 1.0f; r9_y[2][0] = sy; r9_y[2][2] = cy; r9_y[0][2] = -r9_y[2][0]; /*x r3_11=(1); r3_22=(c); r3_32 = (s); r3_33=(c); */ r9_x[0][0] = 1.0f; r9_x[1][1] = cx;/* -r3_32x;*/ r9_x[2][1] = sx; r9_x[2][2] = cx; r9_x[1][2] = -r9_x[2][1]; r9_zy[0][0] = cz*r9_y[0][0]; r9_zy[0][1] = -sz*r9_y[1][1]; r9_zy[0][2] = cz*r9_y[0][2]; r9_zy[1][0] = sz*r9_y[0][0]; r9_zy[1][1] = cz*r9_y[1][1]; r9_zy[1][2] = sz*r9_y[0][2]; r9_zy[2][0] = r9_y[2][0]; r9_zy[2][1] = 0.0f; r9_zy[2][2] = r9_y[2][2]; at = x->x_at3; at += 2; for(i=0; i<2; i++) { SETFLOAT(at, (r9_zy[i][0]*r9_x[0][0])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][1] + r9_zy[i][2]*r9_x[2][1])); at++; SETFLOAT(at, (r9_zy[i][1]*r9_x[1][2] + r9_zy[i][2]*r9_x[2][2])); at++; } SETFLOAT(at, (r9_zy[2][0]*r9_x[0][0])); at++; SETFLOAT(at, (r9_zy[2][2]*r9_x[2][1])); at++; SETFLOAT(at, (r9_zy[2][2]*r9_x[2][2])); outlet_anything(x->x_out3, x->x_s_matrix, x->x_size3, x->x_at3); } static void ambi_rot_list(t_ambi_rot *x, t_symbol *s, int argc, t_atom *argv) { if(argc == 1) ambi_rot_float(x, atom_getfloatarg(0, argc, argv));/* = ambi_rot_z(); */ else if(argc == 2) ambi_rot_zy(x, atom_getfloatarg(0, argc, argv), atom_getfloatarg(1, argc, argv)); else if(argc >= 3) ambi_rot_zyx(x, atom_getfloatarg(0, argc, argv), atom_getfloatarg(1, argc, argv), atom_getfloatarg(2, argc, argv)); } static void ambi_rot_free(t_ambi_rot *x) { if(x->x_size11) freebytes(x->x_at11, x->x_size11 * sizeof(t_atom)); if(x->x_size9) freebytes(x->x_at9, x->x_size9 * sizeof(t_atom)); if(x->x_size7) freebytes(x->x_at7, x->x_size7 * sizeof(t_atom)); if(x->x_size5) freebytes(x->x_at5, x->x_size5 * sizeof(t_atom)); if(x->x_size3) freebytes(x->x_at3, x->x_size3 * sizeof(t_atom)); if(x->x_size2) freebytes(x->x_at2, x->x_size2 * sizeof(t_atom)); } static void *ambi_rot_new(t_floatarg forder) { t_ambi_rot *x = (t_ambi_rot *)pd_new(ambi_rot_class); t_atom *at; int i=(int)forder; if(i < 1) i = 1; if(i > 12) i = 12; x->x_order = i; x->x_size2 = 2*2 + 2; x->x_at2 = (t_atom *)getbytes(x->x_size2 * sizeof(t_atom)); at = x->x_at2; SETFLOAT(at, 2.0f); at++; SETFLOAT(at, 2.0f); at++; for(i=0; i<4; i++) { SETFLOAT(at, 0.0f); at++; } x->x_size3 = 3*3 + 2; x->x_at3 = (t_atom *)getbytes(x->x_size3 * sizeof(t_atom)); at = x->x_at3; SETFLOAT(at, 3.0f); at++; SETFLOAT(at, 3.0f); at++; for(i=0; i<9; i++) { SETFLOAT(at, 0.0f); at++; } x->x_out3 = outlet_new(&x->x_obj, &s_list); if(x->x_order >= 2) { x->x_size5 = 5*5 + 2; x->x_at5 = (t_atom *)getbytes(x->x_size5 * sizeof(t_atom)); at = x->x_at5; SETFLOAT(at, 5.0f); at++; SETFLOAT(at, 5.0f); at++; for(i=0; i<25; i++) { SETFLOAT(at, 0.0f); at++; } x->x_out5 = outlet_new(&x->x_obj, &s_list); } else { x->x_size5 = 0; x->x_at5 = (t_atom *)0; } if(x->x_order >= 3) { x->x_size7 = 7*7 + 2; x->x_at7 = (t_atom *)getbytes(x->x_size7 * sizeof(t_atom)); at = x->x_at7; SETFLOAT(at, 7.0f); at++; SETFLOAT(at, 7.0f); at++; for(i=0; i<49; i++) { SETFLOAT(at, 0.0f); at++; } x->x_out7 = outlet_new(&x->x_obj, &s_list); } else { x->x_size7 = 0; x->x_at7 = (t_atom *)0; } if(x->x_order >= 4) { x->x_size9 = 9*9 + 2; x->x_at9 = (t_atom *)getbytes(x->x_size9 * sizeof(t_atom)); at = x->x_at9; SETFLOAT(at, 9.0f); at++; SETFLOAT(at, 9.0f); at++; for(i=0; i<81; i++) { SETFLOAT(at, 0.0f); at++; } x->x_out9 = outlet_new(&x->x_obj, &s_list); } else { x->x_size9 = 0; x->x_at9 = (t_atom *)0; } if(x->x_order >= 5) { x->x_size11 = 11*11 + 2; x->x_at11 = (t_atom *)getbytes(x->x_size11 * sizeof(t_atom)); at = x->x_at11; SETFLOAT(at, 11.0f); at++; SETFLOAT(at, 11.0f); at++; for(i=0; i<121; i++) { SETFLOAT(at, 0.0f); at++; } x->x_out11 = outlet_new(&x->x_obj, &s_list); } else { x->x_size11 = 0; x->x_at11 = (t_atom *)0; } if(x->x_order >= 6) x->x_out13 = outlet_new(&x->x_obj, &s_list); if(x->x_order >= 7) x->x_out15 = outlet_new(&x->x_obj, &s_list); if(x->x_order >= 8) x->x_out17 = outlet_new(&x->x_obj, &s_list); if(x->x_order >= 9) x->x_out19 = outlet_new(&x->x_obj, &s_list); if(x->x_order >= 10) x->x_out21 = outlet_new(&x->x_obj, &s_list); if(x->x_order >= 11) x->x_out23 = outlet_new(&x->x_obj, &s_list); if(x->x_order >= 12) x->x_out25 = outlet_new(&x->x_obj, &s_list); x->x_sqrt2_16 = (t_float)(sqrt(2.0) / 16.0); x->x_sqrt3_2 = (t_float)(sqrt(3.0) / 2.0); x->x_sqrt5_32 = (t_float)(sqrt(5.0) / 32.0); x->x_sqrt6_4 = (t_float)(sqrt(6.0) / 4.0); x->x_sqrt7_8 = (t_float)(sqrt(7.0) / 8.0); x->x_sqrt10_4 = (t_float)(sqrt(10.0) / 4.0); x->x_sqrt14_16 = (t_float)(sqrt(14.0) / 16.0); x->x_sqrt15_8 = (t_float)(sqrt(15.0) / 8.0); x->x_sqrt35_64 = (t_float)(sqrt(35.0) / 64.0); x->x_sqrt70_32 = (t_float)(sqrt(70.0) / 32.0); x->x_pi_over_180 = (t_float)(4.0 * atan(1.0) / 180.0); x->x_s_matrix = gensym("matrix"); return (x); } void ambi_rot_setup(void) { ambi_rot_class = class_new(gensym("ambi_rot"), (t_newmethod)ambi_rot_new, (t_method)ambi_rot_free, sizeof(t_ambi_rot), 0, A_DEFFLOAT, 0); class_addfloat(ambi_rot_class, (t_method)ambi_rot_float); class_addlist(ambi_rot_class, (t_method)ambi_rot_list); // class_sethelpsymbol(ambi_rot_class, gensym("iemhelp2/ambi_rot-help")); } iem_ambi-0.2/src/ambi_decode3.c0000644000175000017500000004225710540330021016576 0ustar zmoelnigzmoelnig/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ #include "m_pd.h" #include "iemlib.h" #include "iem_ambi.h" #include /* -------------------------- ambi_decode3 ------------------------------ */ /* */ typedef struct _ambi_decode3 { t_object x_obj; t_atom *x_at; double *x_inv_work1; double *x_inv_work2; double *x_inv_buf2; double *x_transp; double *x_ls_encode; double *x_prod; double *x_ambi_channel_weight; double x_sing_range; int x_n_ambi; int x_n_order; int x_n_real_ls; int x_n_pht_ls; int x_n_dim; t_symbol *x_s_matrix; double x_sqrt3; double x_sqrt10_4; double x_sqrt15_2; double x_sqrt6_4; double x_sqrt35_8; double x_sqrt70_4; double x_sqrt5_2; double x_sqrt126_16; double x_sqrt315_8; double x_sqrt105_4; double x_pi_over_180; } t_ambi_decode3; static t_class *ambi_decode3_class; static void ambi_decode3_copy_row2buf(t_ambi_decode3 *x, int row) { int n_ambi2 = 2*x->x_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw_src=x->x_inv_work2; double *dw_dst=x->x_inv_work2; dw_src += src_row*n_ambi2; dw_dst += dst_row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int n_ambi2 = 2*n_ambi; int i, j; double *dw=x->x_inv_work2; double singrange=x->x_sing_range; int ret=-1; dw += start_row*n_ambi2 + col; j = 0; for(i=start_row; i singrange) || (*dw < -singrange)) { ret = i; i = n_ambi+1; } dw += n_ambi2; } return(ret); } static void ambi_decode3_mul1(t_ambi_decode3 *x) { double *vec1, *beg1=x->x_ls_encode; double *vec2, *beg2=x->x_ls_encode; double *inv=x->x_inv_work1; double sum; int n_ls=x->x_n_real_ls+x->x_n_pht_ls; int n_ambi=x->x_n_ambi; int i, j, k; for(k=0; kx_ls_encode; for(j=0; jx_n_real_ls+x->x_n_pht_ls; int n_ambi=x->x_n_ambi; int n_ambi2=2*n_ambi; int i, j, k; double *vec1, *beg1=x->x_transp; double *vec2, *beg2=x->x_inv_work2+n_ambi; double *vec3=x->x_prod; double *acw_vec=x->x_ambi_channel_weight; double sum; for(k=0; kx_inv_work2+n_ambi; for(j=0; jx_transp; double *straight=x->x_ls_encode; int n_ls=x->x_n_real_ls+x->x_n_pht_ls; int n_ambi=x->x_n_ambi; int i, j; for(j=0; jx_n_ambi; int n_ambi2 = 2*n_ambi; int i, j, nz; int r,c; double *src=x->x_inv_work1; double *db=x->x_inv_work2; double rcp, *dv; dv = db; for(i=0; i=0; i--) { dv = db + i*n_ambi2 + i; ambi_decode3_copy_row2buf(x, i); for(j=i-1; j>=0; j--) { dv -= n_ambi2; rcp = -(*dv); ambi_decode3_mul_buf_and_add2row(x, j, rcp); } } post("matrix_inverse nonsingular"); } static void ambi_decode3_begin_pseudo_inverse(t_ambi_decode3 *x) { t_atom *at=x->x_at; int i, n=x->x_n_real_ls*x->x_n_ambi; double *dv1=x->x_prod; ambi_decode3_transp_back(x); ambi_decode3_mul1(x); ambi_decode3_inverse(x); ambi_decode3_mul2(x); at += 2; for(i=0; ix_at; int i, n=x->x_n_ambi; int pht_index, real_index; double mw; t_float dat1; double *dv2=x->x_prod; if(argc < 3) { post("ambi_decode3 ERROR: ipht_ireal_muladd needs 2 index and 1 mirrorweight: pht_ls_index + real_ls_index + mirror_weight_element"); return; } pht_index = (int)atom_getint(argv++) - 1; real_index = (int)atom_getint(argv++) - 1; mw = (double)atom_getfloat(argv); if(pht_index < 0) pht_index = 0; if(real_index < 0) real_index = 0; if(real_index >= x->x_n_real_ls) real_index = x->x_n_real_ls - 1; if(pht_index >= x->x_n_pht_ls) pht_index = x->x_n_pht_ls - 1; at += 2 + (real_index)*x->x_n_ambi; dv2 += (x->x_n_real_ls+pht_index)*x->x_n_ambi; for(i=0; ix_obj.ob_outlet, x->x_s_matrix, x->x_n_ambi*x->x_n_real_ls+2, x->x_at); } static void ambi_decode3_encode_ls_2d(t_ambi_decode3 *x, int argc, t_atom *argv, int mode) { double phi; double *dw = x->x_transp; int index; int order=x->x_n_order; if(argc < 2) { post("ambi_decode3 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(mode == AMBI_LS_REAL) { if(index >= x->x_n_real_ls) index = x->x_n_real_ls - 1; } else if(mode == AMBI_LS_PHT) { if(x->x_n_pht_ls) { if(index >= x->x_n_pht_ls) index = x->x_n_pht_ls - 1; index += x->x_n_real_ls; } else return; } else return; phi *= x->x_pi_over_180; dw += index * x->x_n_ambi; *dw++ = 1.0; *dw++ = cos(phi); *dw++ = sin(phi); if(order >= 2) { *dw++ = cos(2.0*phi); *dw++ = sin(2.0*phi); if(order >= 3) { *dw++ = cos(3.0*phi); *dw++ = sin(3.0*phi); if(order >= 4) { *dw++ = cos(4.0*phi); *dw++ = sin(4.0*phi); if(order >= 5) { *dw++ = cos(5.0*phi); *dw++ = sin(5.0*phi); if(order >= 6) { *dw++ = cos(6.0*phi); *dw++ = sin(6.0*phi); if(order >= 7) { *dw++ = cos(7.0*phi); *dw++ = sin(7.0*phi); if(order >= 8) { *dw++ = cos(8.0*phi); *dw++ = sin(8.0*phi); if(order >= 9) { *dw++ = cos(9.0*phi); *dw++ = sin(9.0*phi); if(order >= 10) { *dw++ = cos(10.0*phi); *dw++ = sin(10.0*phi); if(order >= 11) { *dw++ = cos(11.0*phi); *dw++ = sin(11.0*phi); if(order >= 12) { *dw++ = cos(12.0*phi); *dw++ = sin(12.0*phi); } } } } } } } } } } } } static void ambi_decode3_encode_ls_3d(t_ambi_decode3 *x, int argc, t_atom *argv, int mode) { double delta, phi; double cd, sd, cd2, cd3, sd2, csd, cp, sp, cp2, sp2, cp3, sp3, cp4, sp4; double *dw = x->x_transp; int index; int order=x->x_n_order; if(argc < 3) { post("ambi_decode3 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(mode == AMBI_LS_REAL) { if(index >= x->x_n_real_ls) index = x->x_n_real_ls - 1; } else if(mode == AMBI_LS_PHT) { if(x->x_n_pht_ls) { if(index >= x->x_n_pht_ls) index = x->x_n_pht_ls - 1; index += x->x_n_real_ls; } else return; } else return; delta *= x->x_pi_over_180; phi *= x->x_pi_over_180; dw += index * x->x_n_ambi; cd = cos(delta); sd = sin(delta); cp = cos(phi); sp = sin(phi); *dw++ = 1.0; *dw++ = cd * cp; *dw++ = cd * sp; *dw++ = sd; if(order >= 2) { cp2 = cos(2.0*phi); sp2 = sin(2.0*phi); cd2 = cd * cd; sd2 = sd * sd; csd = cd * sd; *dw++ = 0.5 * x->x_sqrt3 * cd2 * cp2; *dw++ = 0.5 * x->x_sqrt3 * cd2 * sp2; *dw++ = x->x_sqrt3 * csd * cp; *dw++ = x->x_sqrt3 * csd * sp; *dw++ = 0.5 * (3.0 * sd2 - 1.0); if(order >= 3) { cp3 = cos(3.0*phi); sp3 = sin(3.0*phi); cd3 = cd2 * cd; *dw++ = x->x_sqrt10_4 * cd3 * cp3; *dw++ = x->x_sqrt10_4 * cd3 * sp3; *dw++ = x->x_sqrt15_2 * cd * csd * cp2; *dw++ = x->x_sqrt15_2 * cd * csd * sp2; *dw++ = x->x_sqrt6_4 * cd * (5.0 * sd2 - 1.0) * cp; *dw++ = x->x_sqrt6_4 * cd * (5.0 * sd2 - 1.0) * sp; *dw++ = 0.5 * sd * (5.0 * sd2 - 3.0); if(order >= 4) { cp4 = cos(4.0*phi); sp4 = sin(4.0*phi); *dw++ = x->x_sqrt35_8 * cd2 * cd2 * cp4; *dw++ = x->x_sqrt35_8 * cd2 * cd2 * sp4; *dw++ = x->x_sqrt70_4 * cd2 * csd * cp3; *dw++ = x->x_sqrt70_4 * cd2 * csd * sp3; *dw++ = 0.5 * x->x_sqrt5_2 * cd2 * (7.0 * sd2 - 1.0) * cp2; *dw++ = 0.5 * x->x_sqrt5_2 * cd2 * (7.0 * sd2 - 1.0) * sp2; *dw++ = x->x_sqrt10_4 * csd * (7.0 * sd2 - 3.0) * cp; *dw++ = x->x_sqrt10_4 * csd * (7.0 * sd2 - 3.0) * sp; *dw++ = 0.125 * (sd2 * (35.0 * sd2 - 30.0) + 3.0); if(order >= 5) { *dw++ = x->x_sqrt126_16 * cd3 * cd2 * cos(5.0*phi); *dw++ = x->x_sqrt126_16 * cd3 * cd2 * sin(5.0*phi); *dw++ = x->x_sqrt315_8 * cd3 * csd * cp4; *dw++ = x->x_sqrt315_8 * cd3 * csd * sp4; *dw++ = 0.25 * x->x_sqrt70_4 * cd3 * (9.0 * sd2 - 1.0) * cp3; *dw++ = 0.25 * x->x_sqrt70_4 * cd3 * (9.0 * sd2 - 1.0) * sp3; *dw++ = x->x_sqrt105_4 * cd * csd * (3.0 * sd2 - 1.0) * cp2; *dw++ = x->x_sqrt105_4 * cd * csd * (3.0 * sd2 - 1.0) * sp2; *dw++ = 0.25 * x->x_sqrt15_2 * cd * (sd2 * (21.0 * sd2 - 14.0) + 1.0) * cp; *dw++ = 0.25 * x->x_sqrt15_2 * cd * (sd2 * (21.0 * sd2 - 14.0) + 1.0) * sp; *dw = 0.125 * sd * (sd2 * (63.0 * sd2 - 70.0) + 15.0); } } } } } static void ambi_decode3_real_ls(t_ambi_decode3 *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode3_encode_ls_2d(x, argc, argv, AMBI_LS_REAL); else ambi_decode3_encode_ls_3d(x, argc, argv, AMBI_LS_REAL); } static void ambi_decode3_pht_ls(t_ambi_decode3 *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode3_encode_ls_2d(x, argc, argv, AMBI_LS_PHT); else ambi_decode3_encode_ls_3d(x, argc, argv, AMBI_LS_PHT); } static void ambi_decode3_ambi_weight(t_ambi_decode3 *x, t_symbol *s, int argc, t_atom *argv) { if(argc > x->x_n_order) { int i, k=0, n=x->x_n_order; double d; x->x_ambi_channel_weight[k] = atom_getfloat(argv++); k++; if(x->x_n_dim == 2) { for(i=1; i<=n; i++) { d = atom_getfloat(argv++); x->x_ambi_channel_weight[k] = d; k++; x->x_ambi_channel_weight[k] = d; k++; } } else { int j, m; for(i=1; i<=n; i++) { d = atom_getfloat(argv++); m = 2*i + 1; for(j=0; jx_ambi_channel_weight[k] = d; k++; } } } } else post("ambi_decode3-ERROR: ambi_weight needs %d float weights", x->x_n_order+1); } static void ambi_decode3_sing_range(t_ambi_decode3 *x, t_floatarg f) { if(f < 0.0f) x->x_sing_range = -(double)f; else x->x_sing_range = (double)f; } static void ambi_decode3_free(t_ambi_decode3 *x) { freebytes(x->x_inv_work1, x->x_n_ambi * x->x_n_ambi * sizeof(double)); freebytes(x->x_inv_work2, 2 * x->x_n_ambi * x->x_n_ambi * sizeof(double)); freebytes(x->x_inv_buf2, 2 * x->x_n_ambi * sizeof(double)); freebytes(x->x_transp, (x->x_n_real_ls+x->x_n_pht_ls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_ls_encode, (x->x_n_real_ls+x->x_n_pht_ls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_prod, (x->x_n_real_ls+x->x_n_pht_ls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_ambi_channel_weight, x->x_n_ambi * sizeof(double)); freebytes(x->x_at, (x->x_n_real_ls * x->x_n_ambi + 2) * sizeof(t_atom)); } static void *ambi_decode3_new(t_symbol *s, int argc, t_atom *argv) { t_ambi_decode3 *x = (t_ambi_decode3 *)pd_new(ambi_decode3_class); int order, dim, i; int n_real_ls=0;/* number of loudspeakers */ int n_pht_ls=0;/* number of phantom_loudspeakers */ if((argc >= 4) && IS_A_FLOAT(argv,0) && IS_A_FLOAT(argv,1) && IS_A_FLOAT(argv,2) && IS_A_FLOAT(argv,3)) { order = (int)atom_getint(argv++); dim = (int)atom_getint(argv++); n_real_ls = (int)atom_getint(argv++); n_pht_ls = (int)atom_getint(argv); if(order < 1) order = 1; if(dim != 3) { dim = 2; if(order > 12) order = 12; x->x_n_ambi = 2*order + 1; } else { if(order > 5) order = 5; x->x_n_ambi = (order + 1)*(order + 1); } x->x_n_dim = dim; x->x_n_order = order; if(n_real_ls < 1) n_real_ls = 1; if(n_pht_ls < 0) n_pht_ls = 0; if((n_real_ls + n_pht_ls) < x->x_n_ambi) post("ambi_decode3-WARNING: Number of Loudspeakers < Number of Ambisonic-Channels !!!!"); x->x_n_real_ls = n_real_ls; x->x_n_pht_ls = n_pht_ls; x->x_inv_work1 = (double *)getbytes(x->x_n_ambi * x->x_n_ambi * sizeof(double)); x->x_inv_work2 = (double *)getbytes(2 * x->x_n_ambi * x->x_n_ambi * sizeof(double)); x->x_inv_buf2 = (double *)getbytes(2 * x->x_n_ambi * sizeof(double)); x->x_transp = (double *)getbytes((x->x_n_real_ls+x->x_n_pht_ls) * x->x_n_ambi * sizeof(double)); x->x_ls_encode = (double *)getbytes((x->x_n_real_ls+x->x_n_pht_ls) * x->x_n_ambi * sizeof(double)); x->x_prod = (double *)getbytes((x->x_n_real_ls+x->x_n_pht_ls) * x->x_n_ambi * sizeof(double)); x->x_ambi_channel_weight = (double *)getbytes(x->x_n_ambi * sizeof(double)); x->x_at = (t_atom *)getbytes((x->x_n_real_ls * x->x_n_ambi + 2) * sizeof(t_atom)); x->x_s_matrix = gensym("matrix"); /*change*/ SETFLOAT(x->x_at, (t_float)x->x_n_real_ls); SETFLOAT(x->x_at+1, (t_float)x->x_n_ambi); x->x_sqrt3 = sqrt(3.0); x->x_sqrt5_2 = sqrt(5.0) / 2.0; x->x_sqrt6_4 = sqrt(6.0) / 4.0; x->x_sqrt10_4 = sqrt(10.0) / 4.0; x->x_sqrt15_2 = sqrt(15.0) / 2.0; x->x_sqrt35_8 = sqrt(35.0) / 8.0; x->x_sqrt70_4 = sqrt(70.0) / 4.0; x->x_sqrt126_16 = sqrt(126.0) / 16.0; x->x_sqrt315_8 = sqrt(315.0) / 8.0; x->x_sqrt105_4 = sqrt(105.0) / 4.0; x->x_pi_over_180 = 4.0 * atan(1.0) / 180.0; x->x_sing_range = 1.0e-10; for(i=0; ix_n_ambi; i++) x->x_ambi_channel_weight[i] = 1.0; outlet_new(&x->x_obj, &s_list); return (x); } else { post("ambi_decode3-ERROR: need 4 float arguments: ambi_order dimension number_of_real_loudspeakers number_of_canceled_phantom_speakers"); return(0); } } void ambi_decode3_setup(void) { ambi_decode3_class = class_new(gensym("ambi_decode3"), (t_newmethod)ambi_decode3_new, (t_method)ambi_decode3_free, sizeof(t_ambi_decode3), 0, A_GIMME, 0); class_addmethod(ambi_decode3_class, (t_method)ambi_decode3_real_ls, gensym("real_ls"), A_GIMME, 0); class_addmethod(ambi_decode3_class, (t_method)ambi_decode3_pht_ls, gensym("pht_ls"), A_GIMME, 0); class_addmethod(ambi_decode3_class, (t_method)ambi_decode3_ambi_weight, gensym("ambi_weight"), A_GIMME, 0); class_addmethod(ambi_decode3_class, (t_method)ambi_decode3_sing_range, gensym("sing_range"), A_DEFFLOAT, 0); class_addmethod(ambi_decode3_class, (t_method)ambi_decode3_begin_pseudo_inverse, gensym("begin_pseudo_inverse"), 0); class_addmethod(ambi_decode3_class, (t_method)ambi_decode3_ipht_ireal_muladd, gensym("ipht_ireal_muladd"), A_GIMME, 0); class_addmethod(ambi_decode3_class, (t_method)ambi_decode3_end_pseudo_inverse, gensym("end_pseudo_inverse"), 0); // class_sethelpsymbol(ambi_decode3_class, gensym("iemhelp2/ambi_decode3-help")); } iem_ambi-0.2/src/iem_ambi.dsp0000644000175000017500000000476611203414554016424 0ustar zmoelnigzmoelnig# Microsoft Developer Studio Project File - Name="iem_ambi" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** NICHT BEARBEITEN ** # TARGTYPE "Win32 (x86) External Target" 0x0106 CFG=iem_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_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_ambi.mak" CFG="iem_ambi - Win32 Debug" !MESSAGE !MESSAGE Für die Konfiguration stehen zur Auswahl: !MESSAGE !MESSAGE "iem_ambi - Win32 Release" (basierend auf "Win32 (x86) External Target") !MESSAGE "iem_ambi - Win32 Debug" (basierend auf "Win32 (x86) External Target") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" !IF "$(CFG)" == "iem_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_ambi.exe" # PROP Bsc_Name "iem_ambi.bsc" # PROP Target_Dir "" !ELSEIF "$(CFG)" == "iem_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_ambi.exe" # PROP Bsc_Name "iem_ambi.bsc" # PROP Target_Dir "" !ENDIF # Begin Target # Name "iem_ambi - Win32 Release" # Name "iem_ambi - Win32 Debug" !IF "$(CFG)" == "iem_ambi - Win32 Release" !ELSEIF "$(CFG)" == "iem_ambi - Win32 Debug" !ENDIF # Begin Source File SOURCE=.\makefile_win # End Source File # End Target # End Project iem_ambi-0.2/src/ambi_encode.c0000644000175000017500000002733210540330021016522 0ustar zmoelnigzmoelnig/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ #include "m_pd.h" #include "iemlib.h" #include /* -------------------------- ambi_encode ------------------------------ */ typedef struct _ambi_encode { t_object x_obj; t_atom *x_at; int x_size; int x_size2d; int x_size3d; t_float x_sqrt3; t_float x_sqrt10_4; t_float x_sqrt15; t_float x_sqrt6_4; t_float x_sqrt35_2; t_float x_sqrt70_4; t_float x_sqrt5_2; t_float x_sqrt126_16; t_float x_sqrt315_2; t_float x_sqrt105_2; t_float x_pi_over_180; t_float *x_ambi_order_weight; int x_colrow; int x_n_order; } t_ambi_encode; static t_class *ambi_encode_class; static void ambi_encode_ambi_weight(t_ambi_encode *x, t_symbol *s, int argc, t_atom *argv) { if(argc > x->x_n_order) { int i, n=x->x_n_order; for(i=0; i<=n; i++) { x->x_ambi_order_weight[i] = atom_getfloat(argv++); } } else post("ambi_encode-ERROR: ambi_weight needs %d float weights", x->x_n_order+1); } static void ambi_encode_do_2d(t_ambi_encode *x, t_floatarg phi) { t_float c, s, cc, ss, c2, s2, c3, s3, s4, c4, s5, c5, s6, c6; t_float *awght = x->x_ambi_order_weight; t_atom *at=x->x_at; phi *= x->x_pi_over_180; c = cos(phi); s = sin(phi); cc = c*c; ss = s*s; SETFLOAT(at, (t_float)x->x_colrow); at++; SETFLOAT(at, awght[0]); at++; SETFLOAT(at, c*awght[1]); at++; SETFLOAT(at, s*awght[1]); at++; if(x->x_n_order >= 2) { c2 = cc - ss; s2 = 2.0f*s*c; SETFLOAT(at, c2*awght[2]); at++; SETFLOAT(at, s2*awght[2]); at++; if(x->x_n_order >= 3) { c3 = c*(4.0f*cc - 3.0f); s3 = s*(3.0f - 4.0f*ss); SETFLOAT(at, c3*awght[3]); at++; SETFLOAT(at, s3*awght[3]); at++; if(x->x_n_order >= 4) { c4 = 1.0f + 8.0f*cc*(cc - 1.0f); s4 = 2.0f*s2*c2; SETFLOAT(at, c4*awght[4]); at++; SETFLOAT(at, s4*awght[4]); at++; if(x->x_n_order >= 5) { c5 = c*(1.0f + 4.0f*ss*(ss - 3.0f*cc)); s5 = s*(1.0f + 4.0f*cc*(cc - 3.0f*ss)); SETFLOAT(at, c5*awght[5]); at++; SETFLOAT(at, s5*awght[5]); at++; if(x->x_n_order >= 6) { c6 = c3*c3 - s3*s3; s6 = 2.0f*s3*c3; SETFLOAT(at, c6*awght[6]); at++; SETFLOAT(at, s6*awght[6]); at++; if(x->x_n_order >= 7) { SETFLOAT(at, cos(7.0f*phi)*awght[7]); at++; SETFLOAT(at, sin(7.0f*phi)*awght[7]); at++; if(x->x_n_order >= 8) { SETFLOAT(at, (c4*c4 - s4*s4)*awght[8]); at++; SETFLOAT(at, 2.0f*s4*c4*awght[8]); at++; if(x->x_n_order >= 9) { SETFLOAT(at, cos(9.0f*phi)*awght[9]); at++; SETFLOAT(at, sin(9.0f*phi)*awght[9]); at++; if(x->x_n_order >= 10) { SETFLOAT(at, (c5*c5 - s5*s5)*awght[10]); at++; SETFLOAT(at, 2.0f*s5*c5*awght[10]); at++; if(x->x_n_order >= 11) { SETFLOAT(at, cos(11.0f*phi)*awght[11]); at++; SETFLOAT(at, sin(11.0f*phi)*awght[11]); at++; if(x->x_n_order >= 12) { SETFLOAT(at, (c6*c6 - s6*s6)*awght[12]); at++; SETFLOAT(at, 2.0f*s6*c6*awght[12]); } if(x->x_n_order >= 13) post("ambi_encode-ERROR: do not support Ambisonic-Order greater than 12 in 2d !!!"); } } } } } } } } } } } static void ambi_encode_do_3d(t_ambi_encode *x, t_symbol *s, int argc, t_atom *argv) { t_float delta, phi; t_float cd, x1, y, z, x2, y2, z2, x2my2, x2m3y2, p3x2my2, xy, xz, yz, m1p5z2, m1p7z2, m3p7z2; t_float *awght = x->x_ambi_order_weight; t_atom *at=x->x_at; delta = atom_getfloat(argv++)*x->x_pi_over_180; phi = atom_getfloat(argv)*x->x_pi_over_180; cd = cos(delta); x1 = cd * cos(phi); y = cd * sin(phi); z = sin(delta); xy = x1*y; xz = x1*z; yz = y*z; x2 = x1*x1; y2 = y*y; z2 = z*z; x2my2 = x2 - y2; x2m3y2 = x2my2 - 2.0f*y2; p3x2my2 = 2.0f*x2 + x2my2; m1p5z2 = 5.0f*z2 - 1.0f; m1p7z2 = 2.0f*z2 + m1p5z2; m3p7z2 = m1p7z2 - 2.0f; SETFLOAT(at, (t_float)x->x_colrow); at++; SETFLOAT(at, awght[0]); at++; SETFLOAT(at, x1*awght[1]); at++; SETFLOAT(at, y*awght[1]); at++; SETFLOAT(at, z*awght[1]); at++; if(x->x_n_order >= 2) { SETFLOAT(at, 0.5f*x->x_sqrt3*x2my2*awght[2]); at++; SETFLOAT(at, x->x_sqrt3*xy*awght[2]); at++; SETFLOAT(at, x->x_sqrt3*xz*awght[2]); at++; SETFLOAT(at, x->x_sqrt3*yz*awght[2]); at++; SETFLOAT(at, 0.5f*(3.0f*z2 - 1.0f)*awght[2]); at++; if(x->x_n_order >= 3) { SETFLOAT(at, x->x_sqrt10_4*x1*x2m3y2*awght[3]); at++; SETFLOAT(at, x->x_sqrt10_4*y*p3x2my2*awght[3]); at++; SETFLOAT(at, 0.5f*x->x_sqrt15*z*x2my2*awght[3]); at++; SETFLOAT(at, x->x_sqrt15*xy*z*awght[3]); at++; SETFLOAT(at, x->x_sqrt6_4*x1*m1p5z2*awght[3]); at++; SETFLOAT(at, x->x_sqrt6_4*y*m1p5z2*awght[3]); at++; SETFLOAT(at, 0.5f*z*(m1p5z2 - 2.0f)*awght[3]); at++; if(x->x_n_order >= 4) { SETFLOAT(at, 0.25f*x->x_sqrt35_2*(x2my2*x2my2 - 4.0f*x2*y2)*awght[4]); at++; SETFLOAT(at, x->x_sqrt35_2*xy*x2my2*awght[4]); at++; SETFLOAT(at, x->x_sqrt70_4*xz*x2m3y2*awght[4]); at++; SETFLOAT(at, x->x_sqrt70_4*yz*p3x2my2*awght[4]); at++; SETFLOAT(at, 0.5f*x->x_sqrt5_2*x2my2*m1p7z2*awght[4]); at++; SETFLOAT(at, x->x_sqrt5_2*xy*m1p7z2*awght[4]); at++; SETFLOAT(at, x->x_sqrt10_4*xz*m3p7z2*awght[4]); at++; SETFLOAT(at, x->x_sqrt10_4*yz*m3p7z2*awght[4]); at++; SETFLOAT(at, 0.125f*(5.0f*(z2 - 1.0f)*(m1p7z2 + 2.0f) + 8.0f)*awght[4]); at++; if(x->x_n_order >= 5) { SETFLOAT(at, x->x_sqrt126_16*x1*(x2*(x2 - 10.0f*y2) + 5.0f*y2*y2)*awght[5]); at++; SETFLOAT(at, x->x_sqrt126_16*y*(y2*(y2 - 10.0f*x2) + 5.0f*x2*x2)*awght[5]); at++; SETFLOAT(at, 0.25f*x->x_sqrt315_2*z*(y2*(y2 - 6.0f*x2) + x2*x2)*awght[5]); at++; SETFLOAT(at, x->x_sqrt315_2*xy*z*x2my2*awght[5]); at++; SETFLOAT(at, 0.25f*x->x_sqrt70_4*x1*(9.0f*z2 - 1.0f)*x2m3y2*awght[5]); at++; SETFLOAT(at, 0.25f*x->x_sqrt70_4*y*(9.0f*z2 - 1.0f)*p3x2my2*awght[5]); at++; SETFLOAT(at, 0.5f*x->x_sqrt105_2*x2my2*z*(3.0f*z2 - 1.0f)*awght[5]); at++; SETFLOAT(at, x->x_sqrt105_2*xy*z*(3.0f*z2 - 1.0f)*awght[5]); at++; SETFLOAT(at, 0.125f*x->x_sqrt15*x1*(z2*(21.0f*z2 - 14.0f) + 1.0f)*awght[5]); at++; SETFLOAT(at, 0.125f*x->x_sqrt15*y*(z2*(21.0f*z2 - 14.0f) + 1.0f)*awght[5]); at++; SETFLOAT(at, 0.125f*z*(z2*(63.0f*z2 - 70.0f) + 15.0f)*awght[5]); } if(x->x_n_order > 5) post("ambi_encode-ERROR: do not support Ambisonic-Order greater than 5 in 3d !!!"); } } } } static void ambi_encode_float(t_ambi_encode *x, t_floatarg phi) { x->x_colrow = -1; ambi_encode_do_2d(x, phi); outlet_list(x->x_obj.ob_outlet, &s_list, x->x_size2d, x->x_at+1); } static void ambi_encode_list(t_ambi_encode *x, t_symbol *s, int argc, t_atom *argv) { if(argc <= 0) { post("ambi_encode ERROR: list-input needs 2 angles: delta [rad] and phi [rad]"); return; } else if(argc == 1) { ambi_encode_float(x, atom_getfloat(argv)); } else { x->x_colrow = -1; ambi_encode_do_3d(x, &s_list, 2, argv); outlet_list(x->x_obj.ob_outlet, &s_list, x->x_size3d, x->x_at+1); } } static void ambi_encode_row(t_ambi_encode *x, t_symbol *s, int argc, t_atom *argv) { if(argc == 2) { x->x_colrow = (int)atom_getint(argv++); ambi_encode_do_2d(x, atom_getfloat(argv)); outlet_anything(x->x_obj.ob_outlet, s, x->x_size2d+1, x->x_at); } else if(argc >= 3) { x->x_colrow = (int)atom_getint(argv++); ambi_encode_do_3d(x, &s_list, 2, argv); outlet_anything(x->x_obj.ob_outlet, s, x->x_size3d+1, x->x_at); } else { post("ambi_encode-ERROR: row needs row-index + angle ( + angle)"); } } static void ambi_encode_col(t_ambi_encode *x, t_symbol *s, int argc, t_atom *argv) { if(argc == 2) { x->x_colrow = (int)atom_getint(argv++); ambi_encode_do_2d(x, atom_getfloat(argv)); outlet_anything(x->x_obj.ob_outlet, s, x->x_size2d+1, x->x_at); } else if(argc >= 3) { x->x_colrow = (int)atom_getint(argv++); ambi_encode_do_3d(x, &s_list, 2, argv); outlet_anything(x->x_obj.ob_outlet, s, x->x_size3d+1, x->x_at); } else { post("ambi_encode-ERROR: col needs col-index + angle ( + angle)"); } } static void ambi_encode_free(t_ambi_encode *x) { freebytes(x->x_ambi_order_weight, (x->x_n_order+1) * sizeof(t_float)); freebytes(x->x_at, x->x_size * sizeof(t_atom)); } static void *ambi_encode_new(t_floatarg forder) { t_ambi_encode *x = (t_ambi_encode *)pd_new(ambi_encode_class); t_atom *at; int i=(int)forder; if(i < 1) i = 1; if(i > 12) i = 12; x->x_n_order = i; x->x_size = 6*6 + 1; x->x_size2d = 2*i + 1; x->x_size3d = (i + 1)*(i + 1); x->x_sqrt3 = (t_float)(sqrt(3.0)); x->x_sqrt5_2 = (t_float)(sqrt(5.0) / 2.0); x->x_sqrt6_4 = (t_float)(sqrt(6.0) / 4.0); x->x_sqrt10_4 = (t_float)(sqrt(10.0) / 4.0); x->x_sqrt15 = (t_float)(sqrt(15.0)); x->x_sqrt35_2 = (t_float)(sqrt(35.0) / 2.0); x->x_sqrt70_4 = (t_float)(sqrt(70.0) / 4.0); x->x_sqrt126_16 = (t_float)(sqrt(126.0) / 16.0); x->x_sqrt315_2 = (t_float)(sqrt(315.0) / 2.0); x->x_sqrt105_2 = (t_float)(sqrt(105.0) / 2.0); x->x_pi_over_180 = (t_float)(4.0 * atan(1.0)/180.0); x->x_colrow = 0; x->x_ambi_order_weight = (t_float *)getbytes((x->x_n_order+1) * sizeof(t_float)); x->x_at = (t_atom *)getbytes(x->x_size * sizeof(t_atom)); at=x->x_at; SETFLOAT(at, -1.0f);/*row index*/ at++; SETFLOAT(at, 1.0f);/*W channel*/ for(i=0; i<=x->x_n_order; i++) x->x_ambi_order_weight[i] = 1.0f; outlet_new(&x->x_obj, &s_list); return (x); } void ambi_encode_setup(void) { ambi_encode_class = class_new(gensym("ambi_encode"), (t_newmethod)ambi_encode_new, (t_method)ambi_encode_free, sizeof(t_ambi_encode), 0, A_DEFFLOAT, 0); class_addlist(ambi_encode_class, (t_method)ambi_encode_list); class_addfloat(ambi_encode_class, (t_method)ambi_encode_float); class_addmethod(ambi_encode_class, (t_method)ambi_encode_row, gensym("row"), A_GIMME, 0); class_addmethod(ambi_encode_class, (t_method)ambi_encode_col, gensym("col"), A_GIMME, 0); class_addmethod(ambi_encode_class, (t_method)ambi_encode_ambi_weight, gensym("ambi_weight"), A_GIMME, 0); // class_sethelpsymbol(ambi_encode_class, gensym("iemhelp2/ambi_encode-help")); } iem_ambi-0.2/src/makefile_win0000644000175000017500000000174711203414554016523 0ustar zmoelnigzmoelnig all: ..\iem_ambi.dll VIS_CPP_PATH = "C:\Programme\Microsoft Visual Studio\Vc98" PD_INST_PATH = "C:\Programme\pd" 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\pd.lib SRC = ambi_decode.c \ ambi_decode2.c \ ambi_decode3.c \ ambi_decode_cube.c \ ambi_encode.c \ ambi_rot.c \ iem_ambi.c OBJ = $(SRC:.c=.obj) .c.obj: cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c ..\iem_ambi.dll: $(OBJ) link $(PD_WIN_L_FLAGS) /dll /export:iem_ambi_setup \ /out:..\iem_ambi.dll $(OBJ) $(PD_WIN_LIB) clean: del *.obj iem_ambi-0.2/src/makefile_darwin0000644000175000017500000000165510714614221017207 0ustar zmoelnigzmoelnigcurrent: all .SUFFIXES: .pd_darwin PD_INSTALL_PATH = "/Applications/Pd.app/Contents/Resources" INCLUDE = -I. -I$(PD_INSTALL_PATH)/src LIB = -ldl -lm -lpthread CFLAGS = -DPD -DUNIX -g -Wall -W -Werror -Wno-unused \ -Wno-parentheses -Wno-switch -O2 -fno-strict-aliasing \ $(INCLUDE) $(UCFLAGS) $(AFLAGS) \ MACOSXLINKFLAGS = -bundle -bundle_loader $(PD_INSTALL_PATH)/bin/pd SYSTEM = $(shell uname -m) # the sources SRC = ambi_decode.c \ ambi_decode2.c \ ambi_decode3.c \ ambi_decode_cube.c \ ambi_encode.c \ ambi_rot.c \ iem_ambi.c TARGET = iem_ambi.pd_darwin OBJ = $(SRC:.c=.o) # # ------------------ targets ------------------------------------ # clean: rm ../$(TARGET) rm *.o all: $(OBJ) @echo :: $(OBJ) $(CC) $(MACOSXLINKFLAGS) -o $(TARGET) *.o $(LIB) strip -S -x $(TARGET) mv $(TARGET) .. $(OBJ) : %.o : %.c touch $*.c $(CC) $(CFLAGS) -DPD $(INCLUDE) -c -o $*.o $*.c iem_ambi-0.2/src/ambi_decode_cube.c0000644000175000017500000004472610540330021017514 0ustar zmoelnigzmoelnig/* For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. iem_ambi written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006 */ #include "m_pd.h" #include "iemlib.h" #include /* -------------------------- ambi_decode_cube ------------------------------ */ /* ** berechnet ein reduziertes Ambisonic-Decoder-Set in die HRTF-Spektren ** ** Inputs: ls + Liste von 3 floats: Index [1 .. 25] + Elevation [-90 .. +90 degree] + Azimut [0 .. 360 degree] ** ** Inputs: calc_inv ** ** Inputs: load_HRIR + float index1..25 ** ** 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 .. LS25_L_HRIR heissen und existieren ** ** setzt voraus , dass die HRTF-tabele-names von LS1_HRTF_re .. LS25_HRTF_re heissen und existieren ** ** setzt voraus , dass die HRTF-tabele-names von LS1_HRTF_im .. LS25_HRTF_im heissen und existieren ** */ typedef struct _ambi_decode_cube { t_object x_obj; t_atom *x_at; double *x_inv_work1; double *x_inv_work2; double *x_inv_buf2; double *x_transp; double *x_ls_encode; double *x_prod; double *x_ambi_channel_weight; double x_mir_wght; int x_n_ambi; int x_n_order; int x_n_ls; int x_n_phls; int x_n_dim; int x_realsum_beg; int x_realsum_end; int x_mirrorsum_beg; int x_mirrorsum_end; t_symbol *x_s_matrix; double x_sqrt3; double x_sqrt10_4; double x_sqrt15_2; double x_sqrt6_4; double x_sqrt35_8; double x_sqrt70_4; double x_sqrt5_2; double x_sqrt126_16; double x_sqrt315_8; double x_sqrt105_4; double x_pi_over_180; } t_ambi_decode_cube; static t_class *ambi_decode_cube_class; static void ambi_decode_cube_copy_row2buf(t_ambi_decode_cube *x, int row) { int n_ambi2 = 2*x->x_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw_src=x->x_inv_work2; double *dw_dst=x->x_inv_work2; dw_src += src_row*n_ambi2; dw_dst += dst_row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int i; double *dw=x->x_inv_work2; double *db=x->x_inv_buf2; dw += row*n_ambi2; for(i=0; ix_n_ambi; int n_ambi2 = 2*n_ambi; int i, j; double *dw=x->x_inv_work2; int ret=-1; dw += start_row*n_ambi2 + col; j = 0; for(i=start_row; i 1.0e-10) || (*dw < -1.0e-10)) { ret = i; i = n_ambi+1; } dw += n_ambi2; } return(ret); } static void ambi_decode_cube_mul1(t_ambi_decode_cube *x) { double *vec1, *beg1=x->x_ls_encode; double *vec2, *beg2=x->x_ls_encode; double *inv=x->x_inv_work1; double sum; int n_ls=x->x_n_ls+x->x_n_phls; int n_ambi=x->x_n_ambi; int i, j, k; for(k=0; kx_ls_encode; for(j=0; jx_n_ls+x->x_n_phls; int n_ambi=x->x_n_ambi; int n_ambi2=2*n_ambi; int i, j, k; double *vec1, *beg1=x->x_transp; double *vec2, *beg2=x->x_inv_work2+n_ambi; double *vec3=x->x_prod; double *acw_vec=x->x_ambi_channel_weight; double sum; for(k=0; kx_inv_work2+n_ambi; for(j=0; jx_transp; double *straight=x->x_ls_encode; int n_ls=x->x_n_ls+x->x_n_phls; int n_ambi=x->x_n_ambi; int i, j; for(j=0; jx_n_ambi; int n_ambi2 = 2*n_ambi; int i, j, nz; int r,c; double *src=x->x_inv_work1; double *db=x->x_inv_work2; double rcp, *dv; dv = db; for(i=0; i=0; i--) { dv = db + i*n_ambi2 + i; ambi_decode_cube_copy_row2buf(x, i); for(j=i-1; j>=0; j--) { dv -= n_ambi2; rcp = -(*dv); ambi_decode_cube_mul_buf_and_add2row(x, j, rcp); } } post("matrix_inverse nonsingular"); } static void ambi_decode_cube_pinv(t_ambi_decode_cube *x) { t_atom *at=x->x_at; ambi_decode_cube_transp_back(x); ambi_decode_cube_mul1(x); ambi_decode_cube_inverse(x); ambi_decode_cube_mul2(x); if((x->x_mirrorsum_end > x->x_mirrorsum_beg)&& (x->x_realsum_end > x->x_realsum_beg)&& ((x->x_mirrorsum_end - x->x_mirrorsum_beg) == (x->x_realsum_end - x->x_realsum_beg))) { double *mir=x->x_prod+x->x_mirrorsum_beg*x->x_n_ambi; double *real=x->x_prod+x->x_realsum_beg*x->x_n_ambi; double mwght=x->x_mir_wght; int i, n=(x->x_mirrorsum_end - x->x_mirrorsum_beg)*x->x_n_ambi; // post("mirror"); for(i=0; ix_mirrorsum_beg*x->x_n_ambi; real=x->x_prod; SETFLOAT(at, (t_float)x->x_n_ambi); at++; SETFLOAT(at, (t_float)x->x_mirrorsum_beg); at++; for(i=0; ix_obj.ob_outlet, x->x_s_matrix, n+2, x->x_at); } else { int i, n=x->x_n_ls*x->x_n_ambi; double *dv=x->x_prod; // post("real"); SETFLOAT(at, (t_float)x->x_n_ambi); at++; SETFLOAT(at, (t_float)x->x_n_ls); at++; for(i=0; ix_obj.ob_outlet, x->x_s_matrix, n+2, x->x_at); } } static void ambi_decode_cube_encode_ls_2d(t_ambi_decode_cube *x, int argc, t_atom *argv, int ls0_ph1) { double phi; double *dw = x->x_transp; int index; int n_ls=x->x_n_ls; int n_phls=x->x_n_phls; int order=x->x_n_order; if(argc < 2) { post("ambi_decode_cube 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(ls0_ph1) { if(n_phls) { if(index >= n_phls) index = n_phls - 1; index += n_ls; } else return; } else { if(index >= n_ls) index = n_ls - 1; } phi *= x->x_pi_over_180; dw += index * x->x_n_ambi; *dw++ = 1.0; *dw++ = cos(phi); *dw++ = sin(phi); if(order >= 2) { *dw++ = cos(2.0*phi); *dw++ = sin(2.0*phi); if(order >= 3) { *dw++ = cos(3.0*phi); *dw++ = sin(3.0*phi); if(order >= 4) { *dw++ = cos(4.0*phi); *dw++ = sin(4.0*phi); if(order >= 5) { *dw++ = cos(5.0*phi); *dw++ = sin(5.0*phi); if(order >= 6) { *dw++ = cos(6.0*phi); *dw++ = sin(6.0*phi); if(order >= 7) { *dw++ = cos(7.0*phi); *dw++ = sin(7.0*phi); if(order >= 8) { *dw++ = cos(8.0*phi); *dw++ = sin(8.0*phi); if(order >= 9) { *dw++ = cos(9.0*phi); *dw++ = sin(9.0*phi); if(order >= 10) { *dw++ = cos(10.0*phi); *dw++ = sin(10.0*phi); if(order >= 11) { *dw++ = cos(11.0*phi); *dw++ = sin(11.0*phi); if(order >= 12) { *dw++ = cos(12.0*phi); *dw++ = sin(12.0*phi); } } } } } } } } } } } } static void ambi_decode_cube_encode_ls_3d(t_ambi_decode_cube *x, int argc, t_atom *argv, int ls0_ph1) { double delta, phi; double cd, sd, cd2, cd3, sd2, csd, cp, sp, cp2, sp2, cp3, sp3, cp4, sp4; double *dw = x->x_transp; int index; int n_ls=x->x_n_ls; int n_phls=x->x_n_phls; int order=x->x_n_order; if(argc < 3) { post("ambi_decode_cube 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(ls0_ph1) { if(n_phls) { if(index >= n_phls) index = n_phls - 1; index += n_ls; } else return; } else { if(index >= n_ls) index = n_ls - 1; } delta *= x->x_pi_over_180; phi *= x->x_pi_over_180; dw += index * x->x_n_ambi; cd = cos(delta); sd = sin(delta); cp = cos(phi); sp = sin(phi); *dw++ = 1.0; *dw++ = cd * cp; *dw++ = cd * sp; *dw++ = sd; if(order >= 2) { cp2 = cos(2.0*phi); sp2 = sin(2.0*phi); cd2 = cd * cd; sd2 = sd * sd; csd = cd * sd; *dw++ = 0.5 * x->x_sqrt3 * cd2 * cp2; *dw++ = 0.5 * x->x_sqrt3 * cd2 * sp2; *dw++ = x->x_sqrt3 * csd * cp; *dw++ = x->x_sqrt3 * csd * sp; *dw++ = 0.5 * (3.0 * sd2 - 1.0); if(order >= 3) { cp3 = cos(3.0*phi); sp3 = sin(3.0*phi); cd3 = cd2 * cd; *dw++ = x->x_sqrt10_4 * cd3 * cp3; *dw++ = x->x_sqrt10_4 * cd3 * sp3; *dw++ = x->x_sqrt15_2 * cd * csd * cp2; *dw++ = x->x_sqrt15_2 * cd * csd * sp2; *dw++ = x->x_sqrt6_4 * cd * (5.0 * sd2 - 1.0) * cp; *dw++ = x->x_sqrt6_4 * cd * (5.0 * sd2 - 1.0) * sp; *dw++ = 0.5 * sd * (5.0 * sd2 - 3.0); if(order >= 4) { cp4 = cos(4.0*phi); sp4 = sin(4.0*phi); *dw++ = x->x_sqrt35_8 * cd2 * cd2 * cp4; *dw++ = x->x_sqrt35_8 * cd2 * cd2 * sp4; *dw++ = x->x_sqrt70_4 * cd2 * csd * cp3; *dw++ = x->x_sqrt70_4 * cd2 * csd * sp3; *dw++ = 0.5 * x->x_sqrt5_2 * cd2 * (7.0 * sd2 - 1.0) * cp2; *dw++ = 0.5 * x->x_sqrt5_2 * cd2 * (7.0 * sd2 - 1.0) * sp2; *dw++ = x->x_sqrt10_4 * csd * (7.0 * sd2 - 3.0) * cp; *dw++ = x->x_sqrt10_4 * csd * (7.0 * sd2 - 3.0) * sp; *dw++ = 0.125 * (sd2 * (35.0 * sd2 - 30.0) + 3.0); if(order >= 5) { *dw++ = x->x_sqrt126_16 * cd3 * cd2 * cos(5.0*phi); *dw++ = x->x_sqrt126_16 * cd3 * cd2 * sin(5.0*phi); *dw++ = x->x_sqrt315_8 * cd3 * csd * cp4; *dw++ = x->x_sqrt315_8 * cd3 * csd * sp4; *dw++ = 0.25 * x->x_sqrt70_4 * cd3 * (9.0 * sd2 - 1.0) * cp3; *dw++ = 0.25 * x->x_sqrt70_4 * cd3 * (9.0 * sd2 - 1.0) * sp3; *dw++ = x->x_sqrt105_4 * cd * csd * (3.0 * sd2 - 1.0) * cp2; *dw++ = x->x_sqrt105_4 * cd * csd * (3.0 * sd2 - 1.0) * sp2; *dw++ = 0.25 * x->x_sqrt15_2 * cd * (sd2 * (21.0 * sd2 - 14.0) + 1.0) * cp; *dw++ = 0.25 * x->x_sqrt15_2 * cd * (sd2 * (21.0 * sd2 - 14.0) + 1.0) * sp; *dw = 0.125 * sd * (sd2 * (63.0 * sd2 - 70.0) + 15.0); } } } } } static void ambi_decode_cube_ls(t_ambi_decode_cube *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode_cube_encode_ls_2d(x, argc, argv, 0); else ambi_decode_cube_encode_ls_3d(x, argc, argv, 0); } static void ambi_decode_cube_phls(t_ambi_decode_cube *x, t_symbol *s, int argc, t_atom *argv) { if(x->x_n_dim == 2) ambi_decode_cube_encode_ls_2d(x, argc, argv, 1); else ambi_decode_cube_encode_ls_3d(x, argc, argv, 1); } static void ambi_decode_cube_ambi_weight(t_ambi_decode_cube *x, t_symbol *s, int argc, t_atom *argv) { if(argc > x->x_n_order) { int i, k=0, n=x->x_n_order; double d; x->x_ambi_channel_weight[k] = atom_getfloat(argv++); k++; if(x->x_n_dim == 2) { for(i=1; i<=n; i++) { d = atom_getfloat(argv++); x->x_ambi_channel_weight[k] = d; k++; x->x_ambi_channel_weight[k] = d; k++; } } else { int j, m; for(i=1; i<=n; i++) { d = atom_getfloat(argv++); m = 2*i + 1; for(j=0; jx_ambi_channel_weight[k] = d; k++; } } } } else post("ambi_decode_cube-ERROR: ambi_weight needs %d float weights", x->x_n_order+1); } static void ambi_decode_cube_mirror_weight(t_ambi_decode_cube *x, t_floatarg mwght) { x->x_mir_wght = mwght; } static void ambi_decode_cube_mirror_range(t_ambi_decode_cube *x, t_floatarg beg, t_floatarg end) { int b=(int)beg; int e=(int)end; if(b < 0) b = 0; if(b > x->x_n_ls) b = x->x_n_ls; if(e < 0) e = 0; if(e > x->x_n_ls) e = x->x_n_ls; x->x_mirrorsum_beg = b; x->x_mirrorsum_end = e; } static void ambi_decode_cube_real_sum_range(t_ambi_decode_cube *x, t_floatarg beg, t_floatarg end) { int b=(int)beg; int e=(int)end; if(b < 0) b = 0; if(b > x->x_n_ls) b = x->x_n_ls; if(e < 0) e = 0; if(e > x->x_n_ls) e = x->x_n_ls; x->x_realsum_beg = b; x->x_realsum_end = e; } static void ambi_decode_cube_free(t_ambi_decode_cube *x) { freebytes(x->x_inv_work1, x->x_n_ambi * x->x_n_ambi * sizeof(double)); freebytes(x->x_inv_work2, 2 * x->x_n_ambi * x->x_n_ambi * sizeof(double)); freebytes(x->x_inv_buf2, 2 * x->x_n_ambi * sizeof(double)); freebytes(x->x_transp, (x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_ls_encode, (x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_prod, (x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); freebytes(x->x_ambi_channel_weight, x->x_n_ambi * sizeof(double)); freebytes(x->x_at, (x->x_n_ls * x->x_n_ambi + 2) * sizeof(t_atom)); } static void *ambi_decode_cube_new(t_symbol *s, int argc, t_atom *argv) { t_ambi_decode_cube *x = (t_ambi_decode_cube *)pd_new(ambi_decode_cube_class); int nls, order, dim, i; int nphls=0;/* phantom_loudspeaker */ if(argc < 3) { post("ambi_decode_cube-ERROR: need following arguments: ambi_order dimension number_of_loudspeakers (number_of_phantom_speakers)"); return(0); } else { order = (int)atom_getint(argv++); dim = (int)atom_getint(argv++); nls = (int)atom_getint(argv++); if((argc > 3)&&IS_A_FLOAT(argv,0)) nphls=(int)atom_getint(argv); if(order < 1) order = 1; if(dim != 3) { dim = 2; if(order > 12) order = 12; x->x_n_ambi = 2*order + 1; } else { if(order > 5) order = 5; x->x_n_ambi = (order + 1)*(order + 1); } x->x_n_dim = dim; x->x_n_order = order; if(nls < 1) nls = 1; if(nphls < 0) nphls = 0; if(nls < x->x_n_ambi) post("ambi_decode_cube-WARNING: Number of Loudspeakers < Number of Ambisonic-Channels !!!!"); if(nphls > nls) { post("ambi_decode_cube-WARNING: Number of Phantom-Loudspeakers > Number of Loudspeakers !!!!"); nphls = nls; } x->x_n_ls = nls; x->x_n_phls = nphls; x->x_inv_work1 = (double *)getbytes(x->x_n_ambi * x->x_n_ambi * sizeof(double)); x->x_inv_work2 = (double *)getbytes(2 * x->x_n_ambi * x->x_n_ambi * sizeof(double)); x->x_inv_buf2 = (double *)getbytes(2 * x->x_n_ambi * sizeof(double)); x->x_transp = (double *)getbytes((x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); x->x_ls_encode = (double *)getbytes((x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); x->x_prod = (double *)getbytes((x->x_n_ls+x->x_n_phls) * x->x_n_ambi * sizeof(double)); x->x_ambi_channel_weight = (double *)getbytes(x->x_n_ambi * sizeof(double)); x->x_at = (t_atom *)getbytes((x->x_n_ls * x->x_n_ambi + 2) * sizeof(t_atom)); x->x_s_matrix = gensym("matrix"); /*change*/ SETFLOAT(x->x_at, (t_float)x->x_n_ls); SETFLOAT(x->x_at+1, (t_float)x->x_n_ambi); x->x_sqrt3 = sqrt(3.0); x->x_sqrt5_2 = sqrt(5.0) / 2.0; x->x_sqrt6_4 = sqrt(6.0) / 4.0; x->x_sqrt10_4 = sqrt(10.0) / 4.0; x->x_sqrt15_2 = sqrt(15.0) / 2.0; x->x_sqrt35_8 = sqrt(35.0) / 8.0; x->x_sqrt70_4 = sqrt(70.0) / 4.0; x->x_sqrt126_16 = sqrt(126.0) / 16.0; x->x_sqrt315_8 = sqrt(315.0) / 8.0; x->x_sqrt105_4 = sqrt(105.0) / 4.0; x->x_pi_over_180 = 4.0 * atan(1.0) / 180.0; x->x_mirrorsum_beg = x->x_n_ls; x->x_mirrorsum_end = x->x_n_ls; x->x_realsum_beg = 0; x->x_realsum_end = 0; for(i=0; ix_n_ambi; i++) x->x_ambi_channel_weight[i] = 1.0; x->x_mir_wght = 1.0; outlet_new(&x->x_obj, &s_list); return (x); } } void ambi_decode_cube_setup(void) { ambi_decode_cube_class = class_new(gensym("ambi_decode_cube"), (t_newmethod)ambi_decode_cube_new, (t_method)ambi_decode_cube_free, sizeof(t_ambi_decode_cube), 0, A_GIMME, 0); class_addmethod(ambi_decode_cube_class, (t_method)ambi_decode_cube_ls, gensym("ls"), A_GIMME, 0); class_addmethod(ambi_decode_cube_class, (t_method)ambi_decode_cube_phls, gensym("phls"), A_GIMME, 0); class_addmethod(ambi_decode_cube_class, (t_method)ambi_decode_cube_ambi_weight, gensym("ambi_weight"), A_GIMME, 0); class_addmethod(ambi_decode_cube_class, (t_method)ambi_decode_cube_pinv, gensym("pinv"), 0); class_addmethod(ambi_decode_cube_class, (t_method)ambi_decode_cube_mirror_weight, gensym("mirror_weight"), A_DEFFLOAT, 0); class_addmethod(ambi_decode_cube_class, (t_method)ambi_decode_cube_mirror_range, gensym("mirror_range"), A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(ambi_decode_cube_class, (t_method)ambi_decode_cube_real_sum_range, gensym("real_sum_range"), A_DEFFLOAT, A_DEFFLOAT, 0); // class_sethelpsymbol(ambi_decode_cube_class, gensym("iemhelp/ambi_decode_cube-help")); } iem_ambi-0.2/GnuGPL.txt0000644000175000017500000004311010404060147015177 0ustar zmoelnigzmoelnig GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. iem_ambi-0.2/ambi_rot-help.pd0000644000175000017500000001301612163235551016422 0ustar zmoelnigzmoelnig#N canvas 51 50 838 665 10; #X declare -stdlib extra/iem_ambi -stdlib extra/iemmatrix -stdpath extra/zexy -stdlib extra/iemlib/iemlib2; #X floatatom 50 76 6 -180 180 0 - - -; #X obj 27 76 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 126 76 6 -180 180 0 - - -; #X text 127 59 rho_y; #X text 52 59 rho_z; #X floatatom 193 76 6 -180 180 0 - - -; #X text 195 59 rho_x; #X obj 125 149 pack 0 0 0; #X obj 193 120 t b f; #X obj 126 120 t b f; #X obj 50 93 deg2rad; #X obj 126 94 deg2rad; #X obj 193 95 deg2rad; #X text 14 11 ambi_rot; #X text 128 8 AMBISONIC ROTATION; #X text 110 32 up to 12.Order 2-dimensional; #X text 107 20 up to 4.Order 3-dimensional or; #X text 615 153 o-; #X text 623 148 _____; #X text 653 153 > +y; #X text 615 146 |; #X text 615 140 |; #X text 615 134 |; #X text 615 128 |; #X text 615 124 ^; #X text 611 114 +z; #X text 603 158 +x; #X text 614 139 +; #X text 619 139 -; #X text 611 139 -; #X text 623 140 -; #X text 564 139 +rho_x <; #X text 626 139 .; #X text 627 139 .; #X text 628 139 .; #X text 629 140 .; #X text 630 140 .; #X text 631 141 .; #X text 632 142 .; #X text 633 143 .; #X text 437 148 _____; #X text 469 140 |; #X text 469 146 |; #X text 469 134 |; #X text 469 128 |; #X text 469 124 ^; #X text 465 114 +z; #X text 468 136 +; #X text 473 136 -; #X text 459 136 .; #X text 463 153 -o; #X text 412 153 +x <; #X text 480 136 > +rho_y; #X text 474 158 +y; #X text 465 136 -; #X text 461 137 -; #X text 458 136 .; #X text 457 136 .; #X text 456 137 .; #X text 455 137 .; #X text 454 138 .; #X text 453 139 .; #X text 452 140 .; #X text 308 148 _____; #X text 340 140 |; #X text 340 146 |; #X text 340 134 |; #X text 340 128 |; #X text 340 124 ^; #X text 334 153 -o; #X text 336 114 +x; #X text 283 153 +y <; #X text 345 158 +z; #X text 339 136 +; #X text 344 136 -; #X text 336 136 -; #X text 348 137 -; #X text 351 136 .; #X text 352 136 .; #X text 353 136 .; #X text 354 137 .; #X text 355 137 .; #X text 356 138 .; #X text 357 139 .; #X text 358 140 .; #X text 289 136 +rho_z <; #X text 300 60 rho_z ... rotation angle resp. z-axe; #X text 300 71 rho_y ... rotation angle resp. y-axe; #X text 300 82 rho_x ... rotation angle resp. x-axe; #X obj 82 250 cnv 15 60 15 empty empty empty 20 12 0 14 -260818 -66577 0; #X obj 151 250 cnv 15 60 15 empty empty empty 20 12 0 14 -260818 -66577 0; #X obj 81 299 mtx_mul; #X obj 150 229 pack 0 0 0; #X obj 150 189 unpack 0 0 0; #X obj 150 209 * -1; #X obj 125 169 t l l; #X obj 99 320 mtx_mul; #X obj 117 340 mtx_mul; #X obj 136 360 mtx_mul; #X obj 183 209 * -1; #X obj 217 209 * -1; #X obj 150 249 ambi_rot 4; #X obj 81 249 ambi_rot 4; #X obj 355 476 round_zero 0.0001; #X obj 355 418 round_zero 0.0001; #X obj 349 359 round_zero 0.0001; #X obj 353 299 round_zero 0.0001; #X symbolatom 473 309 0 0 0 0 - - -; #X symbolatom 473 344 0 0 0 0 - - -; #X symbolatom 474 423 0 0 0 0 - - -; #X symbolatom 474 536 0 0 0 0 - - -; #X obj 355 496 mergefilename blank; #X obj 353 321 mergefilename blank; #X obj 349 380 mergefilename blank; #X obj 355 438 mergefilename blank; #X text 380 282 1st order; #X text 383 341 2nd order; #X text 378 400 3rd order; #X text 376 456 4th order; #X text 325 6 calculates a matrix message; #X text 329 17 for each ambisonic order; #X text 233 250 1.arg.: ambisonic order; #X text 283 190 inlet: rotation angle in degree for 2-D; #X text 322 204 or a list of 3 floats in degree for 3-D:; #X text 334 216 1.) rotation angle of z-axe; #X text 334 236 3.) rotation angle of x-axe; #X text 334 226 2.) rotation angle of y-axe; #X obj 709 136 ambi_rot 4; #X obj 709 46 ambi_rot 1; #X obj 709 76 ambi_rot 2; #X obj 709 106 ambi_rot 3; #X obj 709 166 ambi_rot 5; #X obj 709 196 ambi_rot 6; #X obj 709 226 ambi_rot 7; #X obj 669 256 ambi_rot 12 ________; #X text 11 437 with "matrix" \, followed by number; #X text 11 449 of rows and columns and the >float> elements.; #X text 23 462 1.outlet is the ambisonic rotation matrix; #X text 12 474 for the components of 1.order ambisonc domain.; #X text 23 487 2.outlet is the ambisonic rotation matrix; #X text 12 499 for the components of 2.order ambisonc domain.; #X text 105 513 aso.; #X text 10 425 outlets: matrix message beginning; #X text 79 603 IEM KUG; #X text 63 591 musil; #X text 93 591 @; #X text 99 591 iem.at; #X text 62 613 Graz \, Austria; #X text 14 580 (c) Thomas Musil 2000 - 2006; #N canvas 4 50 450 300 dependencies 0; #X text 41 49 this help-patch depends on several libraries:; #X text 90 66 iem_ambi; #X text 90 79 iemmatrix; #X text 91 91 zexy; #X obj 52 130 declare -stdlib extra/iem_ambi -stdlib extra/iemmatrix -stdpath extra/zexy -stdlib extra/iemlib/iemlib2; #X restore 502 619 pd dependencies; #X connect 0 0 10 0; #X connect 1 0 0 0; #X connect 2 0 11 0; #X connect 5 0 12 0; #X connect 7 0 95 0; #X connect 8 0 7 0; #X connect 8 1 7 2; #X connect 9 0 7 0; #X connect 9 1 7 1; #X connect 10 0 7 0; #X connect 11 0 9 0; #X connect 12 0 8 0; #X connect 91 0 106 0; #X connect 92 0 101 0; #X connect 93 0 94 0; #X connect 93 1 99 0; #X connect 93 2 100 0; #X connect 94 0 92 0; #X connect 95 0 102 0; #X connect 95 1 93 0; #X connect 96 0 105 0; #X connect 97 0 104 0; #X connect 98 0 103 0; #X connect 99 0 92 1; #X connect 100 0 92 2; #X connect 101 0 91 1; #X connect 101 1 96 1; #X connect 101 2 97 1; #X connect 101 3 98 1; #X connect 102 0 91 0; #X connect 102 1 96 0; #X connect 102 2 97 0; #X connect 102 3 98 0; #X connect 103 0 111 0; #X connect 104 0 114 0; #X connect 105 0 113 0; #X connect 106 0 112 0; #X connect 111 0 110 0; #X connect 112 0 107 0; #X connect 113 0 108 0; #X connect 114 0 109 0; iem_ambi-0.2/ambi_encode-help.pd0000644000175000017500000003033412163235551017055 0ustar zmoelnigzmoelnig#N canvas 63 50 872 684 10; #X declare -stdlib extra/iem_ambi -stdlib extra/iemlib/iemlib2; #X obj 375 244 cnv 15 78 15 empty empty empty 20 12 0 14 -260818 -66577 0; #X obj 374 243 ambi_encode 2; #X obj 374 288 print; #X text 478 247 1.arg: ambisonic order; #X text 489 259 (1 .. 12 for 2 dimensional use); #X msg 461 178 col 2 \$1; #X msg 425 97 row 1 \$1; #X msg 288 211 col 3 \$1 \$2; #X obj 288 188 pack 0 0; #X obj 306 166 t b f; #X obj 374 265 round_zero 1e-06; #X obj 184 193 pack 0 0; #X obj 202 171 t b f; #X floatatom 100 161 5 -180 180 0 - - -; #X floatatom 51 162 5 -90 90 0 - - -; #X obj 82 222 pack 0 0; #X obj 100 200 t b f; #X text 102 142 phi; #X text 21 12 ambi_encode; #X text 34 291 ambisonic-order = n_ao; #X text 346 320 -> output: of (2*n_ao+1) ; #X text 346 331 -> output: of (n_ao+1)*(n_ao+1) ; #X text 387 356 -> output: + index + (2*n_ao+1) ; #X text 387 368 -> output: + index + (n_ao+1)*(n_ao+1) ; #X text 383 394 -> output: + index + (2*n_ao+1) ; #X text 383 406 -> output: + index + (n_ao+1)*(n_ao+1) ; #X text 432 424 for crossfading of 2 ambisonic-systems; #X msg 605 183 ambi_weight 1 1 1; #X msg 588 162 ambi_weight 1 1 0.3904; #X text 299 424 ambisonic-order-group; #X text 89 464 -180 <= phi <= +180; #X text 415 439 or for bluring a signal-source-direction; #X text 31 496 order of ambisonic-channels in 2d-case: W X1 Y1 X2 Y2 X3 Y3; #X text 391 496 X4 Y4 X5 Y5 ....; #X text 167 510 W := 1 \, X-term ... cos(i*phi) \, Y-term ... sin(i*phi) ; #X text 30 550 order of ambisonic-channels in 3d-case: W Z1X1 Z1Y1 Z1; #X text 358 550 Z2X2 Z2Y2 Z2X1 Z2Y1 Z2 Z3X3 Z3Y3 Z3X2 Z3Y2 Z3X1 Z3Y1 Z3 ...; #X text 166 564 W := 1 \, X-term ... cos(i*phi) \, Y-term ... sin(i*phi) \,; #X text 33 318 input: phi [degree] .. 2-dimensional; #X text 33 356 input: index + phi [degree] .. 2-dimensional; #X text 31 395 input: index + phi [degree .. 2-dimensional; #X text 31 424 input: one mul-factor for each; #X text 267 482 |0| 1 | 2 | 3 | 4 | 5 |; #X text 687 539 |; #X text 263 537 |0| 1 | 2 | 3; #X floatatom 226 142 5 -180 180 0 - - -; #X floatatom 177 143 5 -90 90 0 - - -; #X text 228 123 phi; #X floatatom 327 139 5 -180 180 0 - - -; #X floatatom 278 140 5 -90 90 0 - - -; #X text 329 120 phi; #X floatatom 370 65 5 -180 180 0 - - -; #X text 372 46 phi; #X floatatom 425 79 5 -180 180 0 - - -; #X text 427 60 phi; #X floatatom 461 160 5 -180 180 0 - - -; #X text 463 141 phi; #X text 491 272 (1 .. 5 for 3 dimensional use); #X msg 184 218 row 4 \$1 \$2; #X text 82 849 "float"-message: azimuth-angle phi [degree] -> two-dimensional ambisonic-system -> output a of (2*n_ao + 1) elements; #X text 478 850 "list"-message: 1.item elevation-angle delta [degree] \, 2.item azimuth-angle phi [degree] -> three-dimensional ambisonic-system -> output a of (n_ao + 1)^2 elements ; #X text 87 914 "row"-message: row-index of ambisonic-encoder-matrix \, azimuth-angle phi [degree] -> two-dimensional ambisonic-system -> output a "row"-message + row-index + (2*n_ao + 1) elements; #X text 480 919 "row"-message: 1.item elevation-angle delta [degree] \, 2.item azimuth-angle phi [degree] -> three-dimensional ambisonic-system -> output a of (n_ao + 1)^2 elements ; #X text 105 441 1 <= index <= nr_sources; #X text 120 6 AMBISONIC ENCODING; #X text 112 32 up to 12.Order 2-dimensional; #X text 109 20 up to 5.Order 3-dimensional or; #X text 366 8 calculates a row or column of; #X text 372 20 a ambisonic-encoder-matrix; #X obj 539 62 cnv 15 126 15 empty empty empty 20 12 0 14 -260818 -66577 0; #N canvas 283 108 628 490 3D-5.Order-example 0; #X obj 83 104 pack 0 0; #X floatatom 83 62 5 -90 90 0 - - -; #X floatatom 126 63 5 -180 180 0 - - -; #X text 49 45 -90 .. +90; #X text 152 33 phi; #X text 125 47 -180 .. +180; #X obj 101 83 t b f; #X obj 102 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 112 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 122 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 132 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 142 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 152 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 162 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 172 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 182 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 192 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 202 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 212 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 222 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 232 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 242 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 252 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 262 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 272 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 282 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 292 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 302 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 312 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 322 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 332 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 92 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 427 96 ambi_encode 4; #X floatatom 427 75 5 -180 180 0 - - -; #X text 439 38 phi; #X text 412 52 -180 .. +180; #X obj 147 259 print 3d; #X obj 427 139 print 2d; #X obj 83 258 route row; #X obj 147 237 round_zero 1e-06; #X floatatom 47 301 5 0 0 0 - - -; #X text 18 311 row-index; #X obj 427 118 round_zero 1e-06; #X text 453 317 +1; #X text 453 417 -1; #X text 456 368 0; #X obj 83 208 ambi_encode 5; #X obj 83 279 unpack 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; #X obj 342 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 352 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 362 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 372 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 382 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 392 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 402 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 412 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 422 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 432 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X obj 442 325 vsl 8 101 -1 1 0 0 empty empty empty 0 -8 0 8 -225280 -1109 -1 0 1; #X msg 265 64 ambi_weight 1 1 1 1 1 1; #X msg 265 102 ambi_weight 1 1 1 1 0 0; #X msg 265 121 ambi_weight 1 1 1 0 0 0; #X msg 265 191 ambi_weight 1 1 0 0 0 0; #X msg 265 211 ambi_weight 1 0 0 0 0 0; #X msg 265 83 ambi_weight 1 1 1 1 1 0; #X text 95 459 IEM KUG; #X text 79 447 musil; #X text 109 447 @; #X text 115 447 iem.at; #X text 78 469 Graz \, Austria; #X text 30 436 (c) Thomas Musil 2000 - 2006; #X text 68 32 theta; #X obj 83 129 list prepend row 7; #X obj 83 151 list trim; #X connect 0 0 72 0; #X connect 1 0 0 0; #X connect 2 0 6 0; #X connect 6 0 0 0; #X connect 6 1 0 1; #X connect 32 0 42 0; #X connect 33 0 32 0; #X connect 38 0 47 0; #X connect 39 0 36 0; #X connect 42 0 37 0; #X connect 46 0 38 0; #X connect 46 0 39 0; #X connect 47 0 40 0; #X connect 47 1 31 0; #X connect 47 2 7 0; #X connect 47 3 8 0; #X connect 47 4 9 0; #X connect 47 5 10 0; #X connect 47 6 11 0; #X connect 47 7 12 0; #X connect 47 8 13 0; #X connect 47 9 14 0; #X connect 47 10 15 0; #X connect 47 11 16 0; #X connect 47 12 17 0; #X connect 47 13 18 0; #X connect 47 14 19 0; #X connect 47 15 20 0; #X connect 47 16 21 0; #X connect 47 17 22 0; #X connect 47 18 23 0; #X connect 47 19 24 0; #X connect 47 20 25 0; #X connect 47 21 26 0; #X connect 47 22 27 0; #X connect 47 23 28 0; #X connect 47 24 29 0; #X connect 47 25 30 0; #X connect 47 26 48 0; #X connect 47 27 49 0; #X connect 47 28 50 0; #X connect 47 29 51 0; #X connect 47 30 52 0; #X connect 47 31 53 0; #X connect 47 32 54 0; #X connect 47 33 55 0; #X connect 47 34 56 0; #X connect 47 35 57 0; #X connect 47 36 58 0; #X connect 59 0 46 0; #X connect 60 0 46 0; #X connect 61 0 46 0; #X connect 62 0 46 0; #X connect 63 0 46 0; #X connect 64 0 46 0; #X connect 72 0 73 0; #X connect 73 0 46 0; #X restore 538 61 pd 3D-5.Order-example; #X text 90 632 IEM KUG; #X text 74 620 musil; #X text 104 620 @; #X text 110 620 iem.at; #X text 73 642 Graz \, Austria; #X text 25 609 (c) Thomas Musil 2000 - 2006; #X text 48 143 theta; #X text 174 124 theta; #X text 275 121 theta; #X text 33 331 input: theta + phi [degree] .. 3-dimensional; #X text 34 368 input: index theta + phi [degree] .. 3-dimensional ; #X text 31 407 input: index + theta + phi [degree] .. 3-dimensional ; #X text 89 452 -90 <= theta <= +90; #X text 489 564 Z-term ... cos(j*theta)*sin(k*theta); #X obj 59 72 cnv 15 204 15 empty empty empty 20 12 0 14 -260818 -66577 0; #N canvas 5 50 620 309 Definition 0; #X text 173 233 IEM KUG; #X text 157 221 musil; #X text 187 221 @; #X text 193 221 iem.at; #X text 156 243 Graz \, Austria; #X text 108 210 (c) Thomas Musil 2000 - 2006; #X text 108 154 o-; #X text 116 149 _____; #X text 108 147 |; #X text 108 141 |; #X text 108 135 |; #X text 108 129 |; #X text 108 125 ^; #X text 107 140 +; #X text 112 140 -; #X text 104 140 -; #X text 116 141 -; #X text 119 140 .; #X text 120 140 .; #X text 121 140 .; #X text 122 141 .; #X text 123 141 .; #X text 124 142 .; #X text 125 143 .; #X text 126 144 .; #X text 146 154 > +x; #X text 104 115 +y; #X text 96 159 +z; #X text 127 145 .; #X text 127 146 .; #X text 128 147 .; #X text 128 148 .; #X text 128 149 .; #X text 129 150 .; #X text 129 151 .; #X text 69 140 +phi <; #X text 278 154 o-; #X text 278 129 |; #X text 278 125 ^; #X text 290 140 .; #X text 291 140 .; #X text 292 141 .; #X text 293 141 .; #X text 294 142 .; #X text 295 143 .; #X text 296 144 .; #X text 297 145 .; #X text 297 146 .; #X text 298 147 .; #X text 298 148 .; #X text 298 149 .; #X text 299 150 .; #X text 299 151 .; #X text 266 159 +x; #X text 316 154 > +y; #X text 274 115 +z; #X text 278 135 |; #X text 278 141 |; #X text 278 147 |; #X text 288 149 _____; #X text 291 135 _; #X text 288 143 |; #X text 295 135 +theta; #X text 74 55 theta .. elevation \, geodetical pos. orientation; #X text 75 42 phi .... azimute in math. pos. orientation; #X text 373 65 theta = -90 on south pole \;; #X text 373 75 theta = 0 equator ); #X text 361 55 ( theta = +90 on north pole \;; #X text 332 42 ( counter clockwise in xy-plane ); #X text 74 67 radius . is always 1; #X text 253 23 we use the spherical coordinate system; #X text 109 23 for ambisonic encoding \,; #X restore 58 71 pd Definition of Coordinate System; #N canvas 4 50 450 300 dependencies 0; #X text 41 49 this help-patch depends on several libraries:; #X text 90 66 iem_ambi; #X obj 52 130 declare -stdlib extra/iem_ambi -stdlib extra/iemlib/iemlib2 ; #X text 89 82 iemlib2; #X restore 286 638 pd dependencies; #X connect 1 0 10 0; #X connect 5 0 1 0; #X connect 6 0 1 0; #X connect 7 0 1 0; #X connect 8 0 7 0; #X connect 9 0 8 0; #X connect 9 1 8 1; #X connect 10 0 2 0; #X connect 11 0 58 0; #X connect 12 0 11 0; #X connect 12 1 11 1; #X connect 13 0 16 0; #X connect 14 0 15 0; #X connect 15 0 1 0; #X connect 16 0 15 0; #X connect 16 1 15 1; #X connect 27 0 1 0; #X connect 28 0 1 0; #X connect 45 0 12 0; #X connect 46 0 11 0; #X connect 48 0 9 0; #X connect 49 0 8 0; #X connect 51 0 1 0; #X connect 53 0 6 0; #X connect 55 0 5 0; #X connect 58 0 1 0; iem_ambi-0.2/LICENSE.txt0000644000175000017500000000210210526617505015174 0ustar zmoelnigzmoelnigiem_ambi - dynamic library for pd; render ambisonic encoder, rotation and decoder Copyright (C) 2000-2006 Thomas MUSIL [musil_at_iem.at] IEM - Institute of Electronic Music and Acoustics, Graz Inffeldgasse 10/3, 8010 Graz, Austria http://iem.at This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details ( GnuGPL.txt ). (e.g. http://www.gnu.org/copyleft/gpl.html) You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Graz, 15 Nov. 2006 Thomas Musiliem_ambi-0.2/READ_ME.txt0000644000175000017500000000111310526617505015207 0ustar zmoelnigzmoelnigThis library extends the performance of miller puckette's pure data (pd). iem_ambi is written by Thomas Musil from IEM Graz Austria and it is compatible to miller puckette's pd-0.37-3 to pd-0.39-2. see also LICENCE.txt, GnuGPL.txt. iem_ambi contains 3 objects: "ambi_encode", "ambi_rot" and "ambi_decode3" they calculate ambisonic encoder matrices, rotation matrices and decoder matrices from 1st to 4th order in 3D, or from 1st to 12th order in 2D. ambisonic is a 3D sound spatialisation system with separated encoding and decoding. (calculation base are the spherical harmonics). iem_ambi-0.2/Ambisonic_2d_example.pd0000644000175000017500000001643512163236013017706 0ustar zmoelnigzmoelnig#N canvas 27 50 875 690 10; #X declare -stdlib extra/iem_ambi -stdlib extra/iemmatrix -stdlib extra/iemlib/iemlib1 -stdlib extra/iemlib/iemlib2; #X obj 20 44 dsp; #X obj 20 24 tgl 15 0 empty empty empty 0 -6 0 8 -260818 -1 -1 0 1 ; #X floatatom 20 83 5 0 0 0 - - -; #X floatatom 33 65 5 0 0 0 - - -; #X obj 230 88 ambi_encode 2; #X obj 469 102 mtx_*~ 5 1 100; #X obj 509 11 noise~; #X obj 509 32 rbpq2~ 1000 2 100; #X obj 225 591 mtx_print; #X obj 230 140 mtx 5 1; #X msg 230 51 col 1 \$1; #X obj 230 109 t b a; #X obj 699 118 prvu~; #X obj 700 142 vu 15 120 empty empty -1 -8 0 8 -66577 -1 0 0; #X obj 719 118 prvu~; #X obj 720 142 vu 15 120 empty empty -1 -8 0 8 -66577 -1 0 0; #X obj 739 118 prvu~; #X obj 740 142 vu 15 120 empty empty -1 -8 0 8 -66577 -1 0 0; #X obj 759 118 prvu~; #X obj 760 142 vu 15 120 empty empty -1 -8 0 8 -66577 -1 0 0; #X obj 779 118 prvu~; #X obj 780 142 vu 15 120 empty empty -1 -8 0 8 -66577 -1 1 0; #X obj 115 222 loadbang; #X obj 442 257 mtx_*~ 2 2 100; #X obj 537 257 mtx_*~ 2 2 100; #X obj 233 240 ambi_rot 2; #X obj 699 273 prvu~; #X obj 700 297 vu 15 120 empty empty -1 -8 0 8 -66577 -1 0 0; #X obj 719 273 prvu~; #X obj 720 297 vu 15 120 empty empty -1 -8 0 8 -66577 -1 0 0; #X obj 739 273 prvu~; #X obj 740 297 vu 15 120 empty empty -1 -8 0 8 -66577 -1 0 0; #X obj 759 273 prvu~; #X obj 760 297 vu 15 120 empty empty -1 -8 0 8 -66577 -1 0 0; #X obj 779 273 prvu~; #X obj 780 297 vu 15 120 empty empty -1 -8 0 8 -66577 -1 1 0; #X obj 411 257 *~ 1; #X obj 131 436 round_zero 1e-06; #X msg 147 343 real_ls \$1 \$2; #X msg 131 364 begin_pseudo_inverse; #X msg 115 385 end_pseudo_inverse; #X obj 115 245 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 131 414 ambi_decode3 2 2 8 0; #X msg 147 322 1 0 \, 2 45 \, 3 90 \, 4 135 \, 5 180 \, 6 225 \, 7 270 \, 8 315; #X obj 425 381 mtx_*~ 8 5 0 ________________; #X obj 115 264 t b b b b; #X obj 508 75 mull~ 1 100; #X obj 618 38 fadtodb; #X obj 551 55 dbtorms; #X obj 618 58 - 100; #X obj 618 82 vsl 15 121 0 120 0 1 empty empty empty 0 -8 0 8 -260818 -1 -1 10400 1; #X floatatom 637 80 5 0 0 0 - - -; #N canvas 0 0 462 312 __________________________ 0; #X obj 25 66 rvu~; #X obj 25 86 + 100; #X obj 25 106 dbtorms; #X obj 25 127 outlet; #X obj 75 66 rvu~; #X obj 75 86 + 100; #X obj 75 106 dbtorms; #X obj 75 127 outlet; #X obj 125 66 rvu~; #X obj 125 86 + 100; #X obj 125 106 dbtorms; #X obj 125 127 outlet; #X obj 175 66 rvu~; #X obj 175 86 + 100; #X obj 175 106 dbtorms; #X obj 175 127 outlet; #X obj 225 66 rvu~; #X obj 225 86 + 100; #X obj 225 106 dbtorms; #X obj 225 127 outlet; #X obj 275 66 rvu~; #X obj 275 86 + 100; #X obj 275 106 dbtorms; #X obj 275 127 outlet; #X obj 325 66 rvu~; #X obj 325 86 + 100; #X obj 325 106 dbtorms; #X obj 325 127 outlet; #X obj 375 66 rvu~; #X obj 375 86 + 100; #X obj 375 106 dbtorms; #X obj 375 127 outlet; #X obj 25 45 inlet~; #X obj 75 45 inlet~; #X obj 125 45 inlet~; #X obj 175 45 inlet~; #X obj 225 45 inlet~; #X obj 275 45 inlet~; #X obj 325 45 inlet~; #X obj 375 46 inlet~; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 4 0 5 0; #X connect 5 0 6 0; #X connect 6 0 7 0; #X connect 8 0 9 0; #X connect 9 0 10 0; #X connect 10 0 11 0; #X connect 12 0 13 0; #X connect 13 0 14 0; #X connect 14 0 15 0; #X connect 16 0 17 0; #X connect 17 0 18 0; #X connect 18 0 19 0; #X connect 20 0 21 0; #X connect 21 0 22 0; #X connect 22 0 23 0; #X connect 24 0 25 0; #X connect 25 0 26 0; #X connect 26 0 27 0; #X connect 28 0 29 0; #X connect 29 0 30 0; #X connect 30 0 31 0; #X connect 32 0 0 0; #X connect 33 0 4 0; #X connect 34 0 8 0; #X connect 35 0 12 0; #X connect 36 0 16 0; #X connect 37 0 20 0; #X connect 38 0 24 0; #X connect 39 0 28 0; #X restore 425 406 pd __________________________; #X obj 459 490 vsl 15 51 0 0.2 0 0 empty empty empty 0 -8 0 8 -1 -24198 -1 0 1; #X obj 486 460 vsl 15 51 0 0.2 0 0 empty empty empty 0 -8 0 8 -1 -24198 -1 0 1; #X obj 486 528 vsl 15 51 0 0.2 0 0 empty empty empty 0 -8 0 8 -1 -24198 -1 0 1; #X obj 516 450 vsl 15 51 0 0.2 0 0 empty empty empty 0 -8 0 8 -1 -24198 -1 0 1; #X obj 516 538 vsl 15 51 0 0.2 0 0 empty empty empty 0 -8 0 8 -1 -24198 -1 0 1; #X obj 546 460 vsl 15 51 0 0.2 0 0 empty empty empty 0 -8 0 8 -1 -24198 -1 0 1; #X obj 546 528 vsl 15 51 0 0.2 0 0 empty empty empty 0 -8 0 8 -1 -24198 -1 0 1; #X obj 573 490 vsl 15 51 0 0.2 0 0 empty empty empty 0 -8 0 8 -1 -24198 -1 0 1; #X msg 310 58 ambi_weight 1 1 1; #X msg 164 299 ambi_weight 1 1 0.3904; #X msg 89 466 ambi_weight 1 1 1; #X text 388 509 +90 degree; #X text 601 506 -90 degree; #X text 486 602 +-180 degree; #X obj 234 220 cnv 12 30 12 empty empty empty 20 12 0 14 -260818 -66577 0; #X obj 231 32 cnv 12 30 12 empty empty empty 20 12 0 14 -260818 -66577 0; #X floatatom 230 31 5 -180 180 0 - - -; #X text 232 14 phi; #X floatatom 233 219 5 -180 180 0 - - -; #X text 231 201 rho_z; #X obj 264 213 cnv 8 8 8 empty empty empty 20 12 0 14 -262144 -66577 0; #X obj 260 24 cnv 8 8 8 empty empty empty 20 12 0 14 -262144 -66577 0; #X text 341 114 ENCODING; #X text 309 378 DECODING; #X text 323 257 ROTATING; #X text 587 90 gain; #X text 24 119 iemmatrix \, iem_ambi \, iemgui; #X text 17 108 we need iemlib1 \, iemlib2 \,; #X text 78 596 IEM KUG; #X text 62 584 musil; #X text 92 584 @; #X text 98 584 iem.at; #X text 61 606 Graz \, Austria; #X text 13 573 (c) Thomas Musil 2000 - 2006; #N canvas 710 253 450 300 dependencies 0; #X text 41 49 this help-patch depends on several libraries:; #X text 90 66 iem_ambi; #X text 90 79 iemmatrix; #X text 91 91 zexy; #X obj 52 130 declare -stdlib extra/iem_ambi -stdlib extra/iemmatrix -stdlib extra/iemlib/iemlib1 -stdlib extra/iemlib/iemlib2; #X restore 50 650 pd dependencies; #X connect 0 0 2 0; #X connect 0 1 3 0; #X connect 1 0 0 0; #X connect 4 0 11 0; #X connect 5 0 12 0; #X connect 5 0 36 0; #X connect 5 1 14 0; #X connect 5 1 23 1; #X connect 5 2 16 0; #X connect 5 2 23 2; #X connect 5 3 18 0; #X connect 5 3 24 1; #X connect 5 4 20 0; #X connect 5 4 24 2; #X connect 6 0 7 0; #X connect 7 0 46 0; #X connect 9 0 5 0; #X connect 10 0 4 0; #X connect 11 0 9 0; #X connect 11 1 9 0; #X connect 12 0 13 0; #X connect 14 0 15 0; #X connect 16 0 17 0; #X connect 18 0 19 0; #X connect 20 0 21 0; #X connect 22 0 41 0; #X connect 23 0 28 0; #X connect 23 0 44 2; #X connect 23 1 30 0; #X connect 23 1 44 3; #X connect 24 0 32 0; #X connect 24 0 44 4; #X connect 24 1 34 0; #X connect 24 1 44 5; #X connect 25 0 23 0; #X connect 25 1 24 0; #X connect 26 0 27 0; #X connect 28 0 29 0; #X connect 30 0 31 0; #X connect 32 0 33 0; #X connect 34 0 35 0; #X connect 36 0 26 0; #X connect 36 0 44 1; #X connect 37 0 44 0; #X connect 38 0 42 0; #X connect 39 0 42 0; #X connect 40 0 42 0; #X connect 41 0 45 0; #X connect 42 0 37 0; #X connect 43 0 38 0; #X connect 44 0 52 0; #X connect 44 1 52 1; #X connect 44 2 52 2; #X connect 44 3 52 3; #X connect 44 4 52 4; #X connect 44 5 52 5; #X connect 44 6 52 6; #X connect 44 7 52 7; #X connect 45 0 40 0; #X connect 45 1 39 0; #X connect 45 2 43 0; #X connect 45 3 62 0; #X connect 46 0 5 1; #X connect 47 0 48 0; #X connect 47 0 49 0; #X connect 48 0 46 1; #X connect 49 0 51 0; #X connect 50 0 47 0; #X connect 52 0 56 0; #X connect 52 1 54 0; #X connect 52 2 53 0; #X connect 52 3 55 0; #X connect 52 4 57 0; #X connect 52 5 59 0; #X connect 52 6 60 0; #X connect 52 7 58 0; #X connect 61 0 4 0; #X connect 62 0 42 0; #X connect 63 0 42 0; #X connect 69 0 10 0; #X connect 71 0 25 0;