From bbce4104b02b5fd010917759acbb9c5ff5cb4b19 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 27 Mar 2014 11:25:12 +0100 Subject: [PATCH 01/81] scattering: initial commit --- SFS_general/besselh_derived.m | 65 ++++++++ SFS_general/sphbesselh_derived.m | 65 ++++++++ SFS_general/sphbesselj_derived.m | 64 ++++++++ SFS_general/sphbessely_derived.m | 64 ++++++++ .../driving_function_mono_wfs_cylscatter.m | 82 ++++++++++ .../driving_function_mono_wfs_sphscatter.m | 88 ++++++++++ SFS_plotting/plot_scatterer.m | 9 ++ SFS_scattering/cylexpR_mono_pw.m | 94 +++++++++++ SFS_scattering/cylexpS_mono_scatter.m | 43 +++++ SFS_scattering/eval_cylbasis_mono.m | 27 ++++ SFS_scattering/eval_cylbasis_mono_XYZgrid.m | 41 +++++ SFS_scattering/eval_sphbasis_mono.m | 33 ++++ SFS_scattering/eval_sphbasis_mono_XYZgrid.m | 43 +++++ SFS_scattering/sound_field_mono_cylbasis.m | 30 ++++ SFS_scattering/sound_field_mono_sphbasis.m | 32 ++++ SFS_scattering/sound_field_mono_sphexpR.m | 25 +++ SFS_scattering/sound_field_mono_sphexpS.m | 25 +++ SFS_scattering/sphexpR_mono_ps.m | 111 +++++++++++++ SFS_scattering/sphexpR_mono_pw.m | 102 ++++++++++++ SFS_scattering/sphexpS_mono_scatter.m | 48 ++++++ SFS_start.m | 1 + test_scattering.m | 150 ++++++++++++++++++ 22 files changed, 1242 insertions(+) create mode 100644 SFS_general/besselh_derived.m create mode 100644 SFS_general/sphbesselh_derived.m create mode 100644 SFS_general/sphbesselj_derived.m create mode 100644 SFS_general/sphbessely_derived.m create mode 100644 SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylscatter.m create mode 100644 SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphscatter.m create mode 100644 SFS_plotting/plot_scatterer.m create mode 100644 SFS_scattering/cylexpR_mono_pw.m create mode 100644 SFS_scattering/cylexpS_mono_scatter.m create mode 100644 SFS_scattering/eval_cylbasis_mono.m create mode 100644 SFS_scattering/eval_cylbasis_mono_XYZgrid.m create mode 100644 SFS_scattering/eval_sphbasis_mono.m create mode 100644 SFS_scattering/eval_sphbasis_mono_XYZgrid.m create mode 100644 SFS_scattering/sound_field_mono_cylbasis.m create mode 100644 SFS_scattering/sound_field_mono_sphbasis.m create mode 100644 SFS_scattering/sound_field_mono_sphexpR.m create mode 100644 SFS_scattering/sound_field_mono_sphexpS.m create mode 100644 SFS_scattering/sphexpR_mono_ps.m create mode 100644 SFS_scattering/sphexpR_mono_pw.m create mode 100644 SFS_scattering/sphexpS_mono_scatter.m create mode 100644 test_scattering.m diff --git a/SFS_general/besselh_derived.m b/SFS_general/besselh_derived.m new file mode 100644 index 00000000..34aca0f8 --- /dev/null +++ b/SFS_general/besselh_derived.m @@ -0,0 +1,65 @@ +function out = besselh_derived(nu,k,z) +% BESSELH_DERIVED derivative of cylindrical hankel function of k kind of order nu, and argument z +% +% Usage: out = besselh_derived(nu,k,z) +% +% Input parameters: +% nu - order of bessel function +% z - argument of bessel function +% +% Output parameters: +% out - value of bessel function at point z +% +% BESSELH_DERIVED(nu,z) derivation of cylindrical hankel function of +% order nu, k kind, and argument z +% +% References: +% (4.1-51) in Ziomek (1995) - "Fundamentals of acoustic field theory +% and space-time signal processing" +% +% see also: besselh + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + + +%% ===== Checking input parameters ======================================= +nargmin = 3; +nargmax = 3; +narginchk(nargmin,nargmax); +isargscalar(nu) +isargscalar(k) +isargnumeric(z) + + +%% ===== Computation ===================================================== +out = 0.5*(besselh(nu-1,k,z) - besselh(nu+1,k,z)); \ No newline at end of file diff --git a/SFS_general/sphbesselh_derived.m b/SFS_general/sphbesselh_derived.m new file mode 100644 index 00000000..d10d98ba --- /dev/null +++ b/SFS_general/sphbesselh_derived.m @@ -0,0 +1,65 @@ +function out = sphbesselh_derived(nu,k,z) +% SPHBESSELH_DERIVED derivative of spherical hankel function of k kind of order nu, and argument z +% +% Usage: out = sphbesselh_derived(nu,k,z) +% +% Input parameters: +% nu - order of bessel function +% z - argument of bessel function +% +% Output parameters: +% out - value of bessel function at point z +% +% SPHBESSELH_DERIVED(nu,z) derivation of spherical hankel function of +% order nu, k kind, and argument z +% +% References: +% (4.1-51) in Ziomek (1995) - "Fundamentals of acoustic field theory +% and space-time signal processing" +% +% see also: sphbesselh + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + + +%% ===== Checking input parameters ======================================= +nargmin = 3; +nargmax = 3; +narginchk(nargmin,nargmax); +isargscalar(nu) +isargscalar(k) +isargnumeric(z) + + +%% ===== Computation ===================================================== +out = 1/(2*nu+1) * (nu*sphbesselh(nu-1,k,z) - (nu+1)*sphbesselh(nu+1,k,z)); \ No newline at end of file diff --git a/SFS_general/sphbesselj_derived.m b/SFS_general/sphbesselj_derived.m new file mode 100644 index 00000000..f71d2ed8 --- /dev/null +++ b/SFS_general/sphbesselj_derived.m @@ -0,0 +1,64 @@ +function out = sphbesselj_derived(nu,z) +% SPHBESSELJ_DERIVED derivative of spherical bessel function of first kind of order nu, and argument z +% +% Usage: out = sphbesselj_derived(nu,z) +% +% Input parameters: +% nu - order of bessel function +% z - argument of bessel function +% +% Output parameters: +% out - value of bessel function at point z +% +% SPHBESSELJ_DERIVED(nu,z) derivation of spherical bessel function of +% order nu, first type, and argument z +% +% References: +% (4.1-51) in Ziomek (1995) - "Fundamentals of acoustic field theory +% and space-time signal processing" +% +% see also: sphbesselj + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + + +%% ===== Checking input parameters ======================================= +nargmin = 2; +nargmax = 2; +narginchk(nargmin,nargmax); +isargscalar(nu) +isargnumeric(z) + + +%% ===== Computation ===================================================== +out = 1/(2*nu+1) * (nu*sphbesselj(nu-1,z) - (nu+1)*sphbesselj(nu+1,z)); \ No newline at end of file diff --git a/SFS_general/sphbessely_derived.m b/SFS_general/sphbessely_derived.m new file mode 100644 index 00000000..685577b3 --- /dev/null +++ b/SFS_general/sphbessely_derived.m @@ -0,0 +1,64 @@ +function out = sphbessely_derived(nu,z) +% SPHBESSELY_DERIVED derivative of spherical bessel function of second kind of order nu, and argument z +% +% Usage: out = sphbessely_derived(nu,z) +% +% Input parameters: +% nu - order of bessel function +% z - argument of bessel function +% +% Output parameters: +% out - value of bessel function at point z +% +% SPHBESSELY_DERIVED(nu,z) derivation of spherical bessel function of +% order nu, second type, and argument z +% +% References: +% (4.1-51) in Ziomek (1995) - "Fundamentals of acoustic field theory +% and space-time signal processing" +% +% see also: sphbesselj + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + + +%% ===== Checking input parameters ======================================= +nargmin = 2; +nargmax = 2; +narginchk(nargmin,nargmax); +isargscalar(nu) +isargnumeric(z) + + +%% ===== Computation ===================================================== +out = 1/(2*nu+1) * (nu*sphbessely(nu-1,z) - (nu+1)*sphbessely(nu+1,z)); \ No newline at end of file diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylscatter.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylscatter.m new file mode 100644 index 00000000..6d1082b3 --- /dev/null +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylscatter.m @@ -0,0 +1,82 @@ +function D = driving_function_mono_wfs_cylscatter(x0,n0,Bl,f,xq,conf) + +%% ===== Checking of input parameters ================================== +nargmin = 4; +nargmax = 6; +narginchk(nargmin,nargmax); +isargmatrix(x0,n0); +isargpositivescalar(f); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 1; +nargmax = 4; +narginchk(nargmin,nargmax); +isargvector(nk); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 2; +nargmax = 4; +narginchk(nargmin,nargmax); +isargposition(xs); +isargpositivescalar(f); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 1; +nargmax = 4; +narginchk(nargmin,nargmax); +isargvector(nk); +if nargin Date: Thu, 27 Mar 2014 13:23:12 +0100 Subject: [PATCH 02/81] scattering: rename some files --- ...wfs_cylscatter.m => driving_function_mono_wfs_cylexpS.m} | 2 +- ...wfs_sphscatter.m => driving_function_mono_wfs_sphexpS.m} | 2 +- test_scattering.m | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename SFS_monochromatic/driving_functions_mono/{driving_function_mono_wfs_cylscatter.m => driving_function_mono_wfs_cylexpS.m} (93%) rename SFS_monochromatic/driving_functions_mono/{driving_function_mono_wfs_sphscatter.m => driving_function_mono_wfs_sphexpS.m} (94%) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylscatter.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m similarity index 93% rename from SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylscatter.m rename to SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m index 6d1082b3..cba1cb76 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylscatter.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m @@ -1,4 +1,4 @@ -function D = driving_function_mono_wfs_cylscatter(x0,n0,Bl,f,xq,conf) +function D = driving_function_mono_wfs_cylexpS(x0,n0,Bl,f,xq,conf) %% ===== Checking of input parameters ================================== nargmin = 4; diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphscatter.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m similarity index 94% rename from SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphscatter.m rename to SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m index 1d2ec740..5c5518bb 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphscatter.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m @@ -1,4 +1,4 @@ -function D = driving_function_mono_wfs_sphscatter(x0,n0,Bl,f,xq,conf) +function D = driving_function_mono_wfs_sphexpS(x0,n0,Bl,f,xq,conf) %% ===== Checking of input parameters ================================== nargmin = 4; diff --git a/test_scattering.m b/test_scattering.m index fb46b13d..91fbd61d 100644 --- a/test_scattering.m +++ b/test_scattering.m @@ -57,12 +57,12 @@ x0 = secondary_source_positions(conf); x0 = secondary_source_selection(x0,ns,'pw'); x0 = secondary_source_tapering(x0,conf); -D1sph = driving_function_mono_wfs_sphscatter(x0(:,1:3),x0(:,4:6),B1sph,f,xq,conf); +D1sph = driving_function_mono_wfs_sphexpS(x0(:,1:3),x0(:,4:6),B1sph,f,xq,conf); x0 = secondary_source_positions(conf); x0 = secondary_source_selection(x0,xs,'ps'); x0 = secondary_source_tapering(x0,conf); -D2sph = driving_function_mono_wfs_sphscatter(x0(:,1:3),x0(:,4:6),B2sph,f,xq,conf); +D2sph = driving_function_mono_wfs_sphexpS(x0(:,1:3),x0(:,4:6),B2sph,f,xq,conf); % driving for scattering with single cylinder conf.dimension = '3D'; @@ -70,7 +70,7 @@ x0 = secondary_source_positions(conf); x0 = secondary_source_selection(x0,ns,'pw'); x0 = secondary_source_tapering(x0,conf); -D1cyl = driving_function_mono_wfs_cylscatter(x0(:,1:3),x0(:,4:6),B1cyl,f,xq,conf); +D1cyl = driving_function_mono_wfs_cylexpS(x0(:,1:3),x0(:,4:6),B1cyl,f,xq,conf); %% WFS Sound Fields + Plotting % scattering with single sphere From 58a90cd2c719a667fdca43d62156f203aa4c05b8 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 28 Mar 2014 15:40:37 +0100 Subject: [PATCH 03/81] scattering: fix some minor bugs and add comments --- SFS_scattering/cylbasis_mono.m | 100 +++++++++++++++++++ SFS_scattering/cylbasis_mono_XYZgrid.m | 98 ++++++++++++++++++ SFS_scattering/cylexpR_mono_pw.m | 43 +++++--- SFS_scattering/cylexpS_mono_scatter.m | 51 ++++++++++ SFS_scattering/eval_cylbasis_mono.m | 27 ----- SFS_scattering/eval_cylbasis_mono_XYZgrid.m | 41 -------- SFS_scattering/eval_sphbasis_mono.m | 33 ------- SFS_scattering/eval_sphbasis_mono_XYZgrid.m | 43 -------- SFS_scattering/sound_field_mono_sphexpR.m | 2 +- SFS_scattering/sound_field_mono_sphexpS.m | 2 +- SFS_scattering/sphbasis_mono.m | 104 ++++++++++++++++++++ SFS_scattering/sphbasis_mono_XYZgrid.m | 100 +++++++++++++++++++ SFS_scattering/sphexpR_mono_ps.m | 33 +++++-- SFS_scattering/sphexpR_mono_pw.m | 25 ++++- SFS_scattering/sphexpS_mono_scatter.m | 87 +++++++++++++++- test_scattering.m | 17 ++-- 16 files changed, 626 insertions(+), 180 deletions(-) create mode 100644 SFS_scattering/cylbasis_mono.m create mode 100644 SFS_scattering/cylbasis_mono_XYZgrid.m delete mode 100644 SFS_scattering/eval_cylbasis_mono.m delete mode 100644 SFS_scattering/eval_cylbasis_mono_XYZgrid.m delete mode 100644 SFS_scattering/eval_sphbasis_mono.m delete mode 100644 SFS_scattering/eval_sphbasis_mono_XYZgrid.m create mode 100644 SFS_scattering/sphbasis_mono.m create mode 100644 SFS_scattering/sphbasis_mono_XYZgrid.m diff --git a/SFS_scattering/cylbasis_mono.m b/SFS_scattering/cylbasis_mono.m new file mode 100644 index 00000000..658872aa --- /dev/null +++ b/SFS_scattering/cylbasis_mono.m @@ -0,0 +1,100 @@ +function [Jn, H2n, Yn] = cylbasis_mono(r,phi,k,conf) +%Evaluate cylindrical basis functions for given input arguments +% +% Usage: [Jn, H2n, Yn] = cylbasis_mono(r,phi,k,conf) +% +% Input parameters: +% r - distance from z-axis in cylindrical coordinates +% phi - azimuth angle in cylindrical coordinates +% k - wave number +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% Jn - cell array of cylindrical bessel functions +% H2n - cell array of cylindrical hankel functions of 2nd kind +% Yn - cell array of cylindrical harmonics +% +% CYLBASIS_MONO(r,phi,k,conf) computes cylindrical basis functions for +% the given arguments r and phi. r and phi can be of arbitrary (but same) +% size. Output will be stored in cell arrays (one cell entry for each order) +% of length 2*conf.scattering.Nce+1 . Each cell array entry contains a +% matrix of the same size as r and phi. +% +% References: +% Williams (1999) - "Fourier Acoustics", ACADEMIC PRESS +% +% see also: cylbasis_mono_XYZgrid besselj besselh + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargequalsize(r,phi); +isargscalar(k); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 4; +nargmax = 6; +narginchk(nargmin,nargmax); +isargvector(X,Y,Z); +isargpositivescalar(f); +if nargin A R (x-x ) +% pw /__ n=-oo n n q +% +% with the cylyndrical expansion coefficients: +% +% n +% A = 4pi i exp (-i*n*phi ) +% n pw % % References: % Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the % Helmholtz Equation in three % Dimensions", ELSEVIER % -% see also: +% see also: eval_cylbasis_mono %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * @@ -56,20 +66,27 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 1; +nargmin = 2; nargmax = 4; narginchk(nargmin,nargmax); -isargvector(nk); +isargposition(nk); +isargpositivescalar(f); if nargin A R (x-x ) +% ind /__ n=0 n n q +% +% The scattered field is descriped by singular expansion coefficients, +% expanded around the center of the cylinder x0. +% +% \~~ oo +% p (x,f) = > B S (x-x ) +% sca /__ n=0 n n q +% +% Due to the boundary conditions on the surface of the cylinder the +% coefficients are related by: +% +% k . J' (kR) + sigma . H (kR) +% n n +% B = - ------------------------------ . A +% n k . H' (kR) + sigma . H (kR) n +% n n +% +% where k = 2*pi*f/c. +% +% References: +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three +% Dimensions", ELSEVIER +% +% see also: cylexpR_mono_pw + + %% ===== Checking of input parameters ================================== nargmin = 4; diff --git a/SFS_scattering/eval_cylbasis_mono.m b/SFS_scattering/eval_cylbasis_mono.m deleted file mode 100644 index 5dd9f6eb..00000000 --- a/SFS_scattering/eval_cylbasis_mono.m +++ /dev/null @@ -1,27 +0,0 @@ -function [Jn, H2n, Yn] = eval_cylbasis_mono(r,phi,k,conf) - - -%% ===== Configuration ================================================== -% Plotting result -Nce = conf.scattering.Nce; -showprogress = conf.showprogress; - -%% ===== Computation ==================================================== -kr = k.*r; % argument of bessel functions - -L = 2*Nce + 1; -Jn = cell(L,1); -H2n = cell(L,1); -Yn = cell(L,1); - -l = 0; -for n=-Nce:Nce - l = l + 1; - Jn{l} = besselj(n,kr); - H2n{l} = Jn{l} - 1j*bessely(n,kr); - Yn{l} = exp(1j*n*phi); - if showprogress, progress_bar(l,L); end % progress bar -end - -end - diff --git a/SFS_scattering/eval_cylbasis_mono_XYZgrid.m b/SFS_scattering/eval_cylbasis_mono_XYZgrid.m deleted file mode 100644 index 6935a51c..00000000 --- a/SFS_scattering/eval_cylbasis_mono_XYZgrid.m +++ /dev/null @@ -1,41 +0,0 @@ -function [J, H2, Y, x, y, z] = eval_cylbasis_mono_XYZgrid(X,Y,Z,f,xq,conf) - - -%% ===== Checking of input parameters ================================== -nargmin = 4; -nargmax = 6; -narginchk(nargmin,nargmax); -isargvector(X,Y,Z); -isargpositivescalar(f); -if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 4; +nargmax = 5; +narginchk(nargmin,nargmax); +isargequalsize(r,phi); +isargscalar(k); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 4; +nargmax = 6; +narginchk(nargmin,nargmax); +isargvector(X,Y,Z); +isargpositivescalar(f); +if nargin > A R (x-x ) +% pw /__ n=0 /__ m=-n n n q +% +% with the expansion coefficients (Gumerov, p. 145, eq. 4.2.5): +% +% m -m +% A = i . k . S (x - x ) +% n n s q +% +% The coefficients are stored in linear arrays with index l resulting from +% m and n: +% +% m 2 +% A = A ; with l = (n+1) - (n - m) +% l n % % References: % Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the % Helmholtz Equation in three % Dimensions", ELSEVIER % -% see also: +% see also: sphexpR_mono_ps eval_sphbasis_mono %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * diff --git a/SFS_scattering/sphexpR_mono_pw.m b/SFS_scattering/sphexpR_mono_pw.m index c2b09472..0f717b8f 100644 --- a/SFS_scattering/sphexpR_mono_pw.m +++ b/SFS_scattering/sphexpR_mono_pw.m @@ -1,4 +1,4 @@ -function Al = sphexpR_mono_pw(nk,f,x0,conf) +function Al = sphexpR_mono_pw(nk,f,xq,conf) %Regular Spherical Expansion of Plane Wave % % Usage: Al = sphexpR_mono_pw(nk,f,x0,conf) @@ -6,7 +6,7 @@ % Input parameters: % nk - propagation direction of plane wave % f - frequency -% x0 - optional expansion coordinate +% xq - optional expansion coordinate % conf - optional configuration struct (see SFS_config) % % Output parameters: @@ -14,14 +14,31 @@ % % SPHEXPR_MONO_PW(nk,x0,f,conf) computes the regular Spherical Expansion % Coefficients for a plane wave. The expansion will be done around the -% expansion coordinate x0. +% expansion coordinate xq: +% +% \~~ oo \~~ n m m +% p (x,f) = > > A R (x-x ) +% pw /__ n=0 /__ m=-n n n q +% +% with the expansion coefficients (Gumerov, p. 74, eq. 2.3.6): +% +% m n -m +% A = 4pi i Y (theta , phi ) +% n n pw pw +% +% The coefficients are stored in linear arrays with index l resulting from +% m and n: +% +% m 2 +% A = A ; with l = (n+1) - (n - m) +% l n % % References: % Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the % Helmholtz Equation in three % Dimensions", ELSEVIER % -% see also: +% see also: sphexpR_mono_ps eval_sphbasis_mono %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * diff --git a/SFS_scattering/sphexpS_mono_scatter.m b/SFS_scattering/sphexpS_mono_scatter.m index 742984fe..7fcaf7b5 100644 --- a/SFS_scattering/sphexpS_mono_scatter.m +++ b/SFS_scattering/sphexpS_mono_scatter.m @@ -1,4 +1,89 @@ -function Bl = sphscatter_mono(Al, R, sigma, f, conf) +function Bl = sphexpS_mono_scatter(Al, R, sigma, f, conf) +%Singular Spherical Expansion of sphere-scattered field +% +% Usage: Bl = sphexpS_mono_scatter(Al, R, sigma, f, conf) +% +% Input parameters: +% Al - regular spherical expansion of incident field (sphexpR_*) +% R - radius of sphere +% sigma - complex admittance of scatterer +% f - frequency in Hz +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% Bl - singular spherical expansion coefficients of +% scattered field +% +% SPHEXPS_MONO_SCATTER(xs,f,xq,conf) computes the singular spherical expansion +% coefficients of a field resulting from a scattering of an incident field +% at a sphere. Incident field is descriped by regular expansion coefficients +% (expansion center is expected to be at the center of the sphere xq): +% +% \~~ oo \~~ n m m +% p (x,f) = > > A R (x-x ) +% ind /__ n=0 /__ m=-n n n q +% +% The scattered field is descriped by singular expansion coefficients, +% expanded around the center of the sphere x0. +% +% \~~ oo \~~ n m m +% p (x,f) = > > B S (x-x ) +% sca /__ n=0 /__ m=-n n n q +% +% Due to the boundary conditions on the surface of the sphere the +% coefficients are related by: +% +% k . j' (kR) + sigma . j (kR) +% m n n m +% B = - ------------------------------ . A +% n k . h' (kR) + sigma . h (kR) n +% n n +% +% where k = 2*pi*f/c. The coefficients are stored in linear arrays with +% index l resulting from m and n: +% +% m m 2 +% A = A ; B = B with l = (n+1) - (n - m) +% l n l n +% +% References: +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three +% Dimensions", ELSEVIER +% +% see also: sphexpR_mono_ps, sphexpR_mono_pw + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** %% ===== Checking of input parameters ================================== nargmin = 4; diff --git a/test_scattering.m b/test_scattering.m index 91fbd61d..72f9b267 100644 --- a/test_scattering.m +++ b/test_scattering.m @@ -17,7 +17,7 @@ conf.plot.useplot = false; conf.scattering.Nse = 23; -conf.scattering.Nce = 100; +conf.scattering.Nce = 23; conf.scattering.timereverse = true; % time reverse wavefield of sph-/cylexpR_ conf.showprogress = true; @@ -50,8 +50,8 @@ % scattering with single cylinder B1cyl = cylexpS_mono_scatter(A1cyl, R, sigma, f, conf); -%% WFS Driving Signals -% driving for scattering with single sphere +%% WFS Driving Functions +% driving functions for scattering with single sphere conf.dimension = '2.5D'; conf.driving_functions = 'point_source'; x0 = secondary_source_positions(conf); @@ -64,7 +64,7 @@ x0 = secondary_source_tapering(x0,conf); D2sph = driving_function_mono_wfs_sphexpS(x0(:,1:3),x0(:,4:6),B2sph,f,xq,conf); -% driving for scattering with single cylinder +% driving functions for scattering with single cylinder conf.dimension = '3D'; conf.driving_functions = 'line_source'; x0 = secondary_source_positions(conf); @@ -95,10 +95,10 @@ %% Evaluate spherical and cylindrical basis functions [Jsphn, Hsphn, Ysphnm] = ... - eval_sphbasis_mono_XYZgrid(xrange,yrange,zrange,f,xq,conf); + sphbasis_mono_XYZgrid(xrange,yrange,zrange,f,xq,conf); [Jcyln, Hcyln, Ycyln] = ... - eval_cylbasis_mono_XYZgrid(xrange,yrange,zrange,f,xq,conf); + cylbasis_mono_XYZgrid(xrange,yrange,zrange,f,xq,conf); %% Spherical Expansion Sound Fields + Plotting % incident fields P1sph = sound_field_mono_sphbasis(A1sph, Jsphn, Ysphnm, conf); @@ -144,7 +144,4 @@ title('scattered field'); plot_sound_field(P1cyl + P1cylscat ,x1,y1,z1, [], conf); plot_scatterer(xq,R); -title('incident field + scattered field'); - - -%% Plotting +title('incident field + scattered field'); \ No newline at end of file From e9f70a9997e7e9e8187778a1097ec40ecdc5a2e8 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Mon, 31 Mar 2014 10:36:27 +0200 Subject: [PATCH 04/81] scattering: further comments and simplify sound field simulation --- SFS_scattering/sound_field_mono_basis.m | 97 ++++++++++++++++++++++ SFS_scattering/sound_field_mono_cylbasis.m | 30 ------- SFS_scattering/sound_field_mono_cylexpR.m | 76 +++++++++++++++++ SFS_scattering/sound_field_mono_cylexpS.m | 76 +++++++++++++++++ SFS_scattering/sound_field_mono_sphbasis.m | 32 ------- SFS_scattering/sound_field_mono_sphexpR.m | 53 +++++++++++- SFS_scattering/sound_field_mono_sphexpS.m | 53 +++++++++++- test_scattering.m | 12 +-- 8 files changed, 359 insertions(+), 70 deletions(-) create mode 100644 SFS_scattering/sound_field_mono_basis.m delete mode 100644 SFS_scattering/sound_field_mono_cylbasis.m create mode 100644 SFS_scattering/sound_field_mono_cylexpR.m create mode 100644 SFS_scattering/sound_field_mono_cylexpS.m delete mode 100644 SFS_scattering/sound_field_mono_sphbasis.m diff --git a/SFS_scattering/sound_field_mono_basis.m b/SFS_scattering/sound_field_mono_basis.m new file mode 100644 index 00000000..286506dd --- /dev/null +++ b/SFS_scattering/sound_field_mono_basis.m @@ -0,0 +1,97 @@ +function P = sound_field_mono_basis(AB, JH2n, Y,conf) +%SOUND_FIELD_MONO_BASIS simulates a sound field with cylindrical/spherical +%basic functions +% +% Usage: P = sound_field_mono_basis(AB, JH2n, Y,conf) +% +% Input parameters: +% AB - regular/singular cylindrical/spherical expansion coefficients +% JH2n - cell array of cylindrical/spherical bessel/hankel(2nd kind) functions +% Y - cell array of cylindrical/spherical harmonics +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% P - resulting soundfield +% +% SOUND_FIELD_MONO_BASIS(AB, JH2n, Y,conf) +% +% see also: cylbasis_mono_XYZgrid, sphbasis_mono_XYZgrid + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargvector(AB); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 5; +nargmax = 7; +narginchk(nargmin,nargmax); +isargvector(X,Y,Z,Al); +isargpositivescalar(f); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 5; +nargmax = 7; +narginchk(nargmin,nargmax); +isargvector(X,Y,Z,Bl); +isargpositivescalar(f); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** %% ===== Checking of input parameters ================================== nargmin = 5; @@ -20,6 +71,6 @@ %% ===== Computation ==================================================== [Jn, ~, Ynm, x, y, z] = sphbasis_mono_XYZgrid(X,Y,Z,f,x0,conf); -P = sound_field_mono_sphbasis(Al,Jn,Ynm,conf); +P = sound_field_mono_basis(Al,Jn,Ynm,conf); end diff --git a/SFS_scattering/sound_field_mono_sphexpS.m b/SFS_scattering/sound_field_mono_sphexpS.m index 91e11553..40e027fe 100644 --- a/SFS_scattering/sound_field_mono_sphexpS.m +++ b/SFS_scattering/sound_field_mono_sphexpS.m @@ -1,5 +1,56 @@ function [P, x, y, z] = sound_field_mono_sphexpS(X,Y,Z,Bl,f,x0,conf) +%SOUND_FIELD_MONO_SPHEXPR simulates a sound field with singular spherical +%expansion coefficients +% +% Usage: [P, x, y, z] = sound_field_mono_sphexpS(X,Y,Z,Bl,f,x0,conf) +% +% Input parameters: +% X - x-axis / m; single value or [xmin,xmax] +% Y - y-axis / m; single value or [ymin,ymax] +% Z - z-axis / m; single value or [zmin,zmax] +% Bl - singular spherical expansion coefficients +% f - frequency in Hz +% x0 - optional expansion center coordinates, default: [0, 0, 0] +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% P - resulting soundfield +% +% SOUND_FIELD_MONO_SPHEXPS(X,Y,Z,Bl,f,x0,conf) +% +% see also: sphbasis_mono_XYZgrid, sound_field_mono_basis +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** %% ===== Checking of input parameters ================================== nargmin = 5; @@ -20,6 +71,6 @@ %% ===== Computation ==================================================== [~, Hn, Ynm, x, y, z] = sphbasis_mono_XYZgrid(X,Y,Z,f,x0,conf); -P = sound_field_mono_sphbasis(Bl,Hn,Ynm,conf); +P = sound_field_mono_basis(Bl,Hn,Ynm,conf); end diff --git a/test_scattering.m b/test_scattering.m index 72f9b267..56d4ab82 100644 --- a/test_scattering.m +++ b/test_scattering.m @@ -101,15 +101,15 @@ cylbasis_mono_XYZgrid(xrange,yrange,zrange,f,xq,conf); %% Spherical Expansion Sound Fields + Plotting % incident fields -P1sph = sound_field_mono_sphbasis(A1sph, Jsphn, Ysphnm, conf); -P2sph = sound_field_mono_sphbasis(A2sph, Jsphn, Ysphnm, conf); -P1cyl = sound_field_mono_cylbasis(A1cyl, Jcyln, Ycyln, conf); +P1sph = sound_field_mono_basis(A1sph, Jsphn, Ysphnm, conf); +P2sph = sound_field_mono_basis(A2sph, Jsphn, Ysphnm, conf); +P1cyl = sound_field_mono_basis(A1cyl, Jcyln, Ycyln, conf); % scattering with single sphere -P1sphscat = sound_field_mono_sphbasis(B1sph, Hsphn, Ysphnm, conf); -P2sphscat = sound_field_mono_sphbasis(B2sph, Hsphn, Ysphnm, conf); +P1sphscat = sound_field_mono_basis(B1sph, Hsphn, Ysphnm, conf); +P2sphscat = sound_field_mono_basis(B2sph, Hsphn, Ysphnm, conf); % scattering with single cylinder -P1cylscat = sound_field_mono_cylbasis(B1cyl, Hcyln, Ycyln, conf); +P1cylscat = sound_field_mono_basis(B1cyl, Hcyln, Ycyln, conf); [~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); From f8b2486eaf2857244650653ce9de4b6e1174e3dd Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 8 Apr 2014 10:36:04 +0200 Subject: [PATCH 05/81] scattering: add some comments and minor changes --- .../driving_function_mono_wfs_cylexpS.m | 80 +++++++++++++++++- .../driving_function_mono_wfs_sphexpS.m | 84 ++++++++++++++++++- SFS_scattering/sound_field_mono_cylexpS.m | 2 +- test_scattering.m | 7 +- 4 files changed, 161 insertions(+), 12 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m index cba1cb76..61d0f106 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m @@ -1,4 +1,61 @@ function D = driving_function_mono_wfs_cylexpS(x0,n0,Bl,f,xq,conf) +%DRIVING_FUNCTION_MONO_WFS_CYLEXPS computes the time reversed wfs driving +%functions for a sound field expressed by singular cylindrical expansion coefficients. +% +% Usage: D = driving_function_mono_wfs_cylexpS(x0,n0,Bl,f,xq,conf) +% +% Input parameters: +% x0 - position of the secondary sources / m [nx3] +% n0 - directions of the secondary sources / m [nx3] +% Bl - singular spherical expansion coefficients of sound field +% f - frequency in Hz +% xq - optional expansion center coordinates, default: [0, 0, 0] +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% D - driving function signal [nx1] +% +% DRIVING_FUNCTION_MONO_WFS_CYLEXPS(x0,n0,Bl,f,xq,conf) +% +% see also: driving_function_mono_wfs_sphexpS +% +% References: +% Spors2011 - "Local Sound Field Synthesis by Virtual Acoustic Scattering +% and Time-Reversal" (AES131) +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the Helmholtz +% Equation in three Dimensions", ELSEVIER + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** %% ===== Checking of input parameters ================================== nargmin = 4; @@ -57,10 +114,29 @@ % indexing the expansion coefficients L = 2*Nce+1; -Al = zeros(L,1); l = 0; + + if strcmp('2D',dimension) || strcmp('3D',dimension) - if (strcmp('line_source',driving_functions)) + + % === 2- or 3-Dimensional ============================================ + + if (strcmp('default',driving_functions)) + % --- SFS Toolbox ------------------------------------------------ + % D using a line source + % + % d + % D(x0, w) = --- conj(-Ps(x0,w)) + % d n + % with singular cylindrical expansion of the sound field: + % \~~ oo + % Ps(x,w) = > B S (x-xq) + % /__ n=-oo n n + % singular cylindrical basis functions + % (2) + % S (x) = H (kr) . exp(j n phi) + % n n + for n=-Nce:Nce l = l + 1; h_prime = k.*besselh_derived(n,2,kr); diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m index 5c5518bb..a2b3fdb4 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m @@ -1,4 +1,62 @@ function D = driving_function_mono_wfs_sphexpS(x0,n0,Bl,f,xq,conf) +%DRIVING_FUNCTION_MONO_WFS_CYLEXPS computes the time reversed wfs driving +%functions for a sound field expressed by singular spherical expansion coefficients. +% +% Usage: D = driving_function_mono_wfs_cylexpS(x0,n0,Bl,f,xq,conf) +% +% Input parameters: +% x0 - position of the secondary sources / m [nx3] +% n0 - directions of the secondary sources / m [nx3] +% Bl - singular spherical expansion coefficients of sound field% +% f - frequency in Hz +% xq - optional expansion center coordinates, default: [0, 0, 0] +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% D - driving function signal [nx1] +% +% DRIVING_FUNCTION_MONO_WFS_CYLEXPS(x0,n0,Bl,f,xq,conf) +% +% see also: driving_function_mono_wfs_cylexpS +% +% References: +% Spors2011 - "Local Sound Field Synthesis by Virtual Acoustic Scattering +% and Time-Reversal" (AES131) +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the Helmholtz +% Equation in three Dimensions", ELSEVIER + + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** %% ===== Checking of input parameters ================================== nargmin = 4; @@ -62,8 +120,28 @@ % indexing the expansion coefficients L = (Nse + 1).^2; l = 0; -if strcmp('2.5D',dimension) - if (strcmp('point_source',driving_functions)) + + +if strcmp('2D',dimension) || strcmp('3D',dimension) + + % === 2- or 3-Dimensional ============================================ + + if (strcmp('default',driving_functions)) + % --- SFS Toolbox ------------------------------------------------ + % D using a point source + % + % d + % D(x0, w) = --- conj(-Ps(x0,w)) + % d n + % with singular spherical expansion of the sound field: + % \~~ N \~~ n m m + % Ps(x,w) = > > B S (x-xq) + % /__ n=0 /__ m=-n n n + % singular spherical basis functions: + % m (2) m + % S (x) = h (kr) . Y (theta, phi) + % n n n + for n=0:Nse h_prime = k.*sphbesselh_derived(n,2,kr); h = sphbesselh(n, 2, kr); @@ -72,7 +150,7 @@ Ynm = sphharmonics(n,m, theta, phi); Gradr = Gradr + ( Bl(l).*h_prime.*Ynm); Gradphi = Gradphi + 1./r.*( Bl(l).*h.*1j.*m.*Ynm ); - %Gradtheta = 0; + %Gradtheta = 0; TODO end if showprogress, progress_bar(l,L); end % progress bar end diff --git a/SFS_scattering/sound_field_mono_cylexpS.m b/SFS_scattering/sound_field_mono_cylexpS.m index 92eddcc6..2719ceb5 100644 --- a/SFS_scattering/sound_field_mono_cylexpS.m +++ b/SFS_scattering/sound_field_mono_cylexpS.m @@ -8,7 +8,7 @@ % X - x-axis / m; single value or [xmin,xmax] % Y - y-axis / m; single value or [ymin,ymax] % Z - z-axis / m; single value or [zmin,zmax] -% Bl - regular cylindrical expansion coefficients +% Bl - singular cylindrical expansion coefficients % f - frequency in Hz % x0 - optional expansion center coordinates, default: [0, 0, 0] % conf - optional configuration struct (see SFS_config) diff --git a/test_scattering.m b/test_scattering.m index 56d4ab82..3ce67b50 100644 --- a/test_scattering.m +++ b/test_scattering.m @@ -7,8 +7,7 @@ %% Parameters conf = SFS_config_example; -conf.dimension = '2.5D'; -conf.driving_functions = 'point_source'; +conf.dimension = '3D'; conf.secondary_sources.geometry = 'linear'; conf.secondary_sources.number = 40; conf.secondary_sources.size = 6; @@ -52,8 +51,6 @@ %% WFS Driving Functions % driving functions for scattering with single sphere -conf.dimension = '2.5D'; -conf.driving_functions = 'point_source'; x0 = secondary_source_positions(conf); x0 = secondary_source_selection(x0,ns,'pw'); x0 = secondary_source_tapering(x0,conf); @@ -65,8 +62,6 @@ D2sph = driving_function_mono_wfs_sphexpS(x0(:,1:3),x0(:,4:6),B2sph,f,xq,conf); % driving functions for scattering with single cylinder -conf.dimension = '3D'; -conf.driving_functions = 'line_source'; x0 = secondary_source_positions(conf); x0 = secondary_source_selection(x0,ns,'pw'); x0 = secondary_source_tapering(x0,conf); From d26418bfd03360b2ba9b91ff84ab69025c3e732f Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 27 Mar 2014 11:27:46 +0100 Subject: [PATCH 06/81] scattering: multiple sphere scattering --- SFS_scattering/sphexpSR_ab.m | 68 +++++++++ SFS_scattering/sphexpSR_mono.m | 159 +++++++++++++++++++++ SFS_scattering/sphexpS_mono_multiscatter.m | 57 ++++++++ SFS_scattering/sphexp_access.m | 80 +++++++++++ SFS_scattering/sphexp_index.m | 79 ++++++++++ 5 files changed, 443 insertions(+) create mode 100644 SFS_scattering/sphexpSR_ab.m create mode 100644 SFS_scattering/sphexpSR_mono.m create mode 100644 SFS_scattering/sphexpS_mono_multiscatter.m create mode 100644 SFS_scattering/sphexp_access.m create mode 100644 SFS_scattering/sphexp_index.m diff --git a/SFS_scattering/sphexpSR_ab.m b/SFS_scattering/sphexpSR_ab.m new file mode 100644 index 00000000..2e178183 --- /dev/null +++ b/SFS_scattering/sphexpSR_ab.m @@ -0,0 +1,68 @@ +function [a, b] = sphexpSR_ab(Nse,conf) +% +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 0; +nargmax = 2; +narginchk(nargmin,nargmax); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 2; +nargmax = 3; +narginchk(nargmin,nargmax); +isargposition(xpq); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 2; +nargmax = 5; +narginchk(nargmin,nargmax); +isargscalar(m1); +if nargin == nargmin + n1 = abs(m1); +end +isargscalar(n1); +if nargin < 4 + m2 = 0; +end +isargscalar(m2); +if nargin n1 || abs(m2) > n2 + a = 0; +else + [l1, l2] = sphexp_index(m1, n1, m2, n2); + a = A(l1,l2); +end +end + + diff --git a/SFS_scattering/sphexp_index.m b/SFS_scattering/sphexp_index.m new file mode 100644 index 00000000..f2c04130 --- /dev/null +++ b/SFS_scattering/sphexp_index.m @@ -0,0 +1,79 @@ +function [l1, l2] = sphexp_index(m1, n1, m2, n2) +%Calculate index(indices) for array of spherical expansion coefficients +% +% Usage: [l1, l2] = sphexp_index(m1, n1, m2, n2) +% +% Input parameters: +% m1 - order of 1st dimension +% n1 - degree of 1st dimension (optional, default = |m1|) +% m2 - order of 2st dimension (optional, default = 0) +% n2 - degree of 2st dimension (optional, default = |m2|) +% +% Output parameters: +% l1 - regular Spherical Expansion Coefficients +% l2 - regular Spherical Expansion Coefficients +% +% SPHEXP_INDEX(m1, n1, m2, n2) computes one/two indices for accessing +% 1D/2D arrays of spherical expansion coefficients +% A(n1,m1) => A(l1) ; A(n2,m2) => A(l2) +% +% see also: sphexp_access + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 1; +nargmax = 4; +narginchk(nargmin,nargmax); +isargpositivescalar(n1); +isargscalar(m1); +if nargin == nargmin + n1 = abs(m1); +end +if nargin < 3 + m2 = 0; +end +if nargin n1 || abs(m2) > n2 + error('%s: |m1| > n1 or |m2| > n2',upper(mfilename)); +end + +%% ===== Computation ==================================================== +l1 = (n1 + 1).^2 - (n1 - m1); +l2 = (n2 + 1).^2 - (n2 - m2); +end + From c17e284610f51a60cd21aa6276813f431d6cda10 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 10 Apr 2014 10:40:04 +0200 Subject: [PATCH 07/81] scattering: add multiple scattering for cylindrical coordinates --- SFS_scattering/cylexpRR_mono.m | 93 +++++++++++++++++++++ SFS_scattering/cylexpSR_mono.m | 94 ++++++++++++++++++++++ SFS_scattering/cylexpS_mono_multiscatter.m | 57 +++++++++++++ SFS_scattering/sphexpR_mono_ps.m | 4 +- test_scattering.m | 66 ++++++++++++++- 5 files changed, 308 insertions(+), 6 deletions(-) create mode 100644 SFS_scattering/cylexpRR_mono.m create mode 100644 SFS_scattering/cylexpSR_mono.m create mode 100644 SFS_scattering/cylexpS_mono_multiscatter.m diff --git a/SFS_scattering/cylexpRR_mono.m b/SFS_scattering/cylexpRR_mono.m new file mode 100644 index 00000000..eaf733d8 --- /dev/null +++ b/SFS_scattering/cylexpRR_mono.m @@ -0,0 +1,93 @@ +function [Alplus, RRplus, Alminus, RRminus] = cylexpRR_mono(Al, xq, f, conf) +%Regular-To-Regular Cylindrical Reexpansion (Translatory shift of Expansion) +% +% Usage: [Alplus, RRplus, Alminus, RRminus] = cylexpRR_mono(Al, xq, f, conf) +% +% Input parameters: +% Al - original regular cylindrical expansion coefficients [nx1] +% xq - original expansion center coordinate +% f - frequency +% +% Output parameters: +% Alplus - regular cylindrical expansion coefficients [nx1] +% RRplus - regular-to-regular cylindrical reexpansion coefficients [nxn] +% Alminus - regular cylindrical expansion coefficients [nx1] +% RRminus - regular-to-regular cylindrical reexpansion coefficients [nxn] + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargposition(xq); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargposition(xq); +if nargin Date: Mon, 7 Jul 2014 19:24:03 +0200 Subject: [PATCH 08/81] add regular cylindrical expansion for a line source --- SFS_scattering/cylexpR_mono_ls.m | 117 +++++++++++++++++++++++++++++++ test_scattering.m | 2 + 2 files changed, 119 insertions(+) create mode 100644 SFS_scattering/cylexpR_mono_ls.m diff --git a/SFS_scattering/cylexpR_mono_ls.m b/SFS_scattering/cylexpR_mono_ls.m new file mode 100644 index 00000000..2796e0ef --- /dev/null +++ b/SFS_scattering/cylexpR_mono_ls.m @@ -0,0 +1,117 @@ +function Al = cylexpR_mono_ls(xs,f,xq,conf) +%Regular Cylindrical Expansion of Line Source +% +% Usage: Al = cylexpR_mono_pw(xs,f,xq,conf) +% +% Input parameters: +% xs - position of line source +% f - frequency +% xq - optional expansion center +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% Al - regular cylindrical Expansion Coefficients +% +% CYLEXPR_MONO_PW(nk,xq,f,conf) computes the regular cylindrical +% expansion coefficients for a line source. The expansion will be done +% around the expansion coordinate xq: +% +% \~~ oo +% p (x,f) = > A R (x-x ) +% pw /__ n=-oo n n q +% +% with the cylyndrical expansion coefficients: +% +% n +% A = 4pi i exp (-i*n*phi ) +% n pw +% +% References: +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three +% Dimensions", ELSEVIER +% +% see also: eval_cylbasis_mono + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 2; +nargmax = 4; +narginchk(nargmin,nargmax); +isargposition(xs); +isargpositivescalar(f); +if nargin Date: Thu, 16 Apr 2015 10:27:40 +0200 Subject: [PATCH 09/81] huge bugfixing and renaming of spherical expansion part --- SFS_scattering/sound_field_mono_basis.m | 5 + ...no_sphexpR.m => sound_field_mono_sphexp.m} | 26 +- SFS_scattering/sphexpSR_mono.m | 159 --------- SFS_scattering/sphexpS_mono_multiscatter.m | 57 --- ...o_sphexpS.m => sphexp_mono_multiscatter.m} | 75 ++-- .../{sphexpR_mono_ps.m => sphexp_mono_ps.m} | 83 +++-- .../{sphexpR_mono_pw.m => sphexp_mono_pw.m} | 66 ++-- ...S_mono_scatter.m => sphexp_mono_scatter.m} | 16 +- SFS_scattering/sphexp_mono_translation.m | 229 ++++++++++++ ...SR_ab.m => sphexp_translation_auxiliary.m} | 21 +- test_scattering.m | 335 ++++++++++-------- 11 files changed, 587 insertions(+), 485 deletions(-) rename SFS_scattering/{sound_field_mono_sphexpR.m => sound_field_mono_sphexp.m} (84%) delete mode 100644 SFS_scattering/sphexpSR_mono.m delete mode 100644 SFS_scattering/sphexpS_mono_multiscatter.m rename SFS_scattering/{sound_field_mono_sphexpS.m => sphexp_mono_multiscatter.m} (68%) rename SFS_scattering/{sphexpR_mono_ps.m => sphexp_mono_ps.m} (68%) rename SFS_scattering/{sphexpR_mono_pw.m => sphexp_mono_pw.m} (79%) rename SFS_scattering/{sphexpS_mono_scatter.m => sphexp_mono_scatter.m} (92%) create mode 100644 SFS_scattering/sphexp_mono_translation.m rename SFS_scattering/{sphexpSR_ab.m => sphexp_translation_auxiliary.m} (85%) diff --git a/SFS_scattering/sound_field_mono_basis.m b/SFS_scattering/sound_field_mono_basis.m index 286506dd..79baaa97 100644 --- a/SFS_scattering/sound_field_mono_basis.m +++ b/SFS_scattering/sound_field_mono_basis.m @@ -66,6 +66,7 @@ %% ===== Configuration ================================================== % Plotting result showprogress = conf.showprogress; +usenormalisation = conf.usenormalisation; %% ===== Computation ==================================================== L = length(Y); @@ -93,5 +94,9 @@ , 'spherical basic funcions'],upper(mfilename)); end +if usenormalisation + P = P./max(abs(P(:))); +end + end diff --git a/SFS_scattering/sound_field_mono_sphexpR.m b/SFS_scattering/sound_field_mono_sphexp.m similarity index 84% rename from SFS_scattering/sound_field_mono_sphexpR.m rename to SFS_scattering/sound_field_mono_sphexp.m index cc41b6b2..de9365ca 100644 --- a/SFS_scattering/sound_field_mono_sphexpR.m +++ b/SFS_scattering/sound_field_mono_sphexp.m @@ -1,14 +1,15 @@ -function [P, x, y, z] = sound_field_mono_sphexpR(X,Y,Z,Al,f,x0,conf) +function [P, x, y, z] = sound_field_mono_sphexp(X,Y,Z,ABnm,mode,f,xq,conf) %SOUND_FIELD_MONO_SPHEXPR simulates a sound field with regular spherical %expansion coefficients % -% Usage: [P, x, y, z] = sound_field_mono_sphexpR(X,Y,Z,Al,f,x0,conf) +% Usage: [P, x, y, z] = sound_field_mono_sphexp(X,Y,Z,Al,f,x0,conf) % % Input parameters: % X - x-axis / m; single value or [xmin,xmax] % Y - y-axis / m; single value or [ymin,ymax] % Z - z-axis / m; single value or [zmin,zmax] -% Al - regular spherical expansion coefficients +% ABnm - regular/singular spherical expansion coefficients +% mode - 'R' for regular, 'S' for singular % f - frequency in Hz % x0 - optional expansion center coordinates, default: [0, 0, 0] % conf - optional configuration struct (see SFS_config) @@ -16,7 +17,7 @@ % Output parameters: % P - resulting soundfield % -% SOUND_FIELD_MONO_SPHEXPR(X,Y,Z,Al,f,x0,conf) +% SOUND_FIELD_MONO_SPHEXPR(X,Y,Z,ABnm,mode,f,xq,conf) % % see also: sphbasis_mono_XYZgrid, sound_field_mono_basis @@ -53,10 +54,10 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 5; -nargmax = 7; +nargmin = 6; +nargmax = 8; narginchk(nargmin,nargmax); -isargvector(X,Y,Z,Al); +isargvector(X,Y,Z,ABnm); isargpositivescalar(f); if nargin. * -% * -% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * -% field synthesis methods like wave field synthesis or higher order * -% ambisonics. * -% * -% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * -%***************************************************************************** - -%% ===== Checking of input parameters ================================== -nargmin = 2; -nargmax = 3; -narginchk(nargmin,nargmax); -isargposition(xpq); -if nargin > A R (x-x ) -% pw /__ n=0 /__ m=-n n n q +% Regular Expansion: +% \~~ oo \~~ n m m +% p (x,f) = > > A R (x-x ) +% ps,R /__ n=0 /__ m=-n n n q % -% with the expansion coefficients (Gumerov, p. 145, eq. 4.2.5): +% with the expansion coefficients (Gumerov2004, eq. 3.2.2): +% m -m +% A = -i . k . S (x - x ) +% n n s q % -% m -m -% A = i . k . S (x - x ) -% n n s q +% Singular Expansion: +% \~~ oo \~~ n m m +% p (x,f) = > > B S (x-x ) +% ps,S /__ n=0 /__ m=-n n n q +% +% with the expansion coefficients (Gumerov2004, eq. 3.2.2): +% m -m +% B = -i . k . R (x - x ) +% n n s q % % The coefficients are stored in linear arrays with index l resulting from % m and n: % -% m 2 -% A = A ; with l = (n+1) - (n - m) -% l n +% m m 2 +% A = A ; B = B with l = (n+1) - (n - m) +% l n l n % % References: % Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the % Helmholtz Equation in three % Dimensions", ELSEVIER % -% see also: sphexpR_mono_ps eval_sphbasis_mono +% see also: sphexp_access sphexp_index sphbasis_mono %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * @@ -73,8 +84,8 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 2; -nargmax = 4; +nargmin = 3; +nargmax = 5; narginchk(nargmin,nargmax); isargposition(xs); isargpositivescalar(f); @@ -91,37 +102,43 @@ %% ===== Configuration ================================================== showprogress = conf.showprogress; Nse = conf.scattering.Nse; -timereverse = conf.scattering.timereverse; +c = conf.c; -%% ===== Computation ==================================================== +%% ===== Variables ====================================================== % convert (xs-xq) into spherical coordinates r = sqrt(sum((xs-xq).^2)); phi = atan2(xs(2)-xq(2),xs(1)-xq(1)); theta = asin((xs(3)-xq(3))/r); % frequency -k = 2.*pi.*f./conf.c; +k = 2.*pi.*f./c; kr = k.*r; -if (timereverse) - H = @(x) conj(1j*k*sphbesselh(x,2,kr)); +% select suitable basis function +if strcmp('R', mode) + sphbasis = @(nu,z) sphbesselh(nu,2,z); +elseif strcmp('S', mode) + sphbasis = @sphbesselj; else - H = @(x) 1j*k*sphbesselh(x,2,kr); + error('unknown mode:'); end +%% ===== Computation ==================================================== L = (Nse + 1).^2; -Al = zeros(L,1); +Anm = zeros(L,1); for n=0:Nse - Hn = H(n); + cn = -1j*k*sphbasis(n,kr); for m=0:n - l_plus = (n + 1).^2 - (n - m); - l_minus = (n + 1).^2 - (n + m); - % caution: symmetry relation depends on definition of spherical harmonics - Ynm = sphharmonics(n,-m, theta, phi); % spherical harmonics - Al(l_plus) = Hn.*Ynm; - Al(l_minus) = Hn.*conj(Ynm); + % spherical harmonics: conj(Y_n^m) = Y_n^-m (Gumerov2004, eq. 2.1.59) + Ynm = sphharmonics(n,m, theta, phi); + % -m + v = sphexp_index(-m,n); + Anm(v) = cn.*Ynm; + % +m + v = sphexp_index(m,n); + Anm(v) = cn.*conj(Ynm); end - if showprogress, progress_bar(l_plus,L); end % progress bar + if showprogress, progress_bar(v,L); end % progress bar end end diff --git a/SFS_scattering/sphexpR_mono_pw.m b/SFS_scattering/sphexp_mono_pw.m similarity index 79% rename from SFS_scattering/sphexpR_mono_pw.m rename to SFS_scattering/sphexp_mono_pw.m index 0f717b8f..5cfca8ba 100644 --- a/SFS_scattering/sphexpR_mono_pw.m +++ b/SFS_scattering/sphexp_mono_pw.m @@ -1,10 +1,10 @@ -function Al = sphexpR_mono_pw(nk,f,xq,conf) +function Anm = sphexp_mono_pw(npw, f, xq, conf) %Regular Spherical Expansion of Plane Wave % -% Usage: Al = sphexpR_mono_pw(nk,f,x0,conf) +% Usage: Al = sphexpR_mono_pw(npw,f,xq,conf) % % Input parameters: -% nk - propagation direction of plane wave +% npw - unit vector propagation direction of plane wave % f - frequency % xq - optional expansion coordinate % conf - optional configuration struct (see SFS_config) @@ -12,7 +12,7 @@ % Output parameters: % Al - regular Spherical Expansion Coefficients % -% SPHEXPR_MONO_PW(nk,x0,f,conf) computes the regular Spherical Expansion +% SPHEXP_MONO_PW(npw,f,xq,conf) computes the regular Spherical Expansion % Coefficients for a plane wave. The expansion will be done around the % expansion coordinate xq: % @@ -22,8 +22,8 @@ % % with the expansion coefficients (Gumerov, p. 74, eq. 2.3.6): % -% m n -m -% A = 4pi i Y (theta , phi ) +% m -n -m +% A = 4pi i Y (theta , phi ) % n n pw pw % % The coefficients are stored in linear arrays with index l resulting from @@ -38,7 +38,7 @@ % Helmholtz Equation in three % Dimensions", ELSEVIER % -% see also: sphexpR_mono_ps eval_sphbasis_mono +% see also: sphexp_access sphexp_index sphbasis_mono %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * @@ -76,44 +76,54 @@ nargmin = 1; nargmax = 4; narginchk(nargmin,nargmax); -isargvector(nk); +isargposition(npw); if nargin > B S (x-x ) @@ -51,7 +51,7 @@ % Helmholtz Equation in three % Dimensions", ELSEVIER % -% see also: sphexpR_mono_ps, sphexpR_mono_pw +% see also: sphexp_mono_ps, sphexp_mono_pw %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * @@ -89,7 +89,7 @@ nargmin = 4; nargmax = 5; narginchk(nargmin,nargmax); -isargvector(Al); +isargvector(Anm); isargscalar(sigma); isargpositivescalar(f,R); if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargposition(t); +isargchar(mode); +if nargin Date: Thu, 16 Apr 2015 12:14:45 +0200 Subject: [PATCH 10/81] allow vectors as inputs of index and access function --- SFS_scattering/sphexp_access.m | 31 ++++++++++++++++++------------- SFS_scattering/sphexp_index.m | 16 ++++++++++------ 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/SFS_scattering/sphexp_access.m b/SFS_scattering/sphexp_access.m index 21e41bdf..5520c0fb 100644 --- a/SFS_scattering/sphexp_access.m +++ b/SFS_scattering/sphexp_access.m @@ -1,5 +1,5 @@ function a = sphexp_access(A, m1, n1, m2, n2) -%Calculate index(indices) for array of spherical expansion coefficients +%Access array elements of spherical expansion coefficients % % Usage: a = sphexp_access(A, m1, n1, m2, n2) % @@ -53,28 +53,33 @@ nargmin = 2; nargmax = 5; narginchk(nargmin,nargmax); -isargscalar(m1); +isargvector(m1); if nargin == nargmin n1 = abs(m1); +else + isargvector(n1); end -isargscalar(n1); if nargin < 4 m2 = 0; +else + isargvector(m2); end -isargscalar(m2); if nargin n1 || abs(m2) > n2 - a = 0; -else - [l1, l2] = sphexp_index(m1, n1, m2, n2); - a = A(l1,l2); -end -end +a = zeros(max(length(m1), length(n1)),max(length(m2), length(n2))); + +s1 = abs(m1) <= n1; +s2 = abs(m2) <= n2; +if any(s1) && any(s2) + [l1, l2] = sphexp_index(m1(s1), n1(s1), m2(s2), n2(s2)); + a(s1,s2) = A(l1,l2); +end + +end diff --git a/SFS_scattering/sphexp_index.m b/SFS_scattering/sphexp_index.m index f2c04130..269f1c4e 100644 --- a/SFS_scattering/sphexp_index.m +++ b/SFS_scattering/sphexp_index.m @@ -55,20 +55,24 @@ nargmin = 1; nargmax = 4; narginchk(nargmin,nargmax); -isargpositivescalar(n1); -isargscalar(m1); +isargvector(m1); if nargin == nargmin n1 = abs(m1); +else + isargvector(n1); end if nargin < 3 m2 = 0; +else + isargvector(m2); end -if nargin n1 || abs(m2) > n2 + +if any( abs(m1) > n1 | abs(m2) > n2 ) error('%s: |m1| > n1 or |m2| > n2',upper(mfilename)); end From fe26afb5b268d67e3fc44540d76816b05d7a64b1 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 16 Apr 2015 13:15:25 +0200 Subject: [PATCH 11/81] improve documentation of spherical translation function --- SFS_scattering/sphexp_mono_translation.m | 31 +++++++++ SFS_scattering/sphexp_translation_auxiliary.m | 69 +++++++++++++++++-- 2 files changed, 93 insertions(+), 7 deletions(-) diff --git a/SFS_scattering/sphexp_mono_translation.m b/SFS_scattering/sphexp_mono_translation.m index 552f1589..ffac0779 100644 --- a/SFS_scattering/sphexp_mono_translation.m +++ b/SFS_scattering/sphexp_mono_translation.m @@ -1,11 +1,41 @@ function [EF, EFm] = sphexp_mono_translation(t, mode, f, conf) +% Spherical translation coefficients (multipole re-expansion) % +% Usage: [EF, EFm] = sphexp_mono_translation(t, mode, f, conf) +% +% Input parameters: +% t - translatory shift [1x3] / m +% mode - 'RS' for regular-to-singular reexpansion +% 'RR' for regular-to-regular reexpansion +% 'SR' for singular-to-regular reexpansion +% 'SS' for singular-to-singular reexpansion +% f - frequency / Hz +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% EF - singular spherical expansion coefficients of +% scattered field +% +% SPHEXP_MONO_TRANSLATION(t, mode, f, conf) computes the spherical re-expansion +% coefficients to perform as translatory shift of spherical basis function. +% Multipole Re-expansion computes the spherical basis function for a shifted +% coordinate system (x+t) based on the original basis functions for (x). +% +% m \~~ inf \~~ l s,m s +% E (x + t) = > > (E|F) (t) F (x) +% n /__ l=0 /__ s=-l l,n l +% +% where {E,F} = {R,S}. R denotes the regular spherical basis function, while +% S symbolizes the singular spherical basis function. Note that (S|S) and +% (S|R) are respectively equivalent to (R|R) and (R|S). % % References: % Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the % Helmholtz Equation in three % Dimensions", ELSEVIER % +% see also: sphexp_mono_ps, sphexp_mono_pw +% %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * % Assessment of IP-based Applications * @@ -44,6 +74,7 @@ narginchk(nargmin,nargmax); isargposition(t); isargchar(mode); +isargpositivescalar(f); if nargin Date: Thu, 16 Apr 2015 13:18:06 +0200 Subject: [PATCH 12/81] adapt indexing of scattering function --- SFS_scattering/sphexp_mono_scatter.m | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/SFS_scattering/sphexp_mono_scatter.m b/SFS_scattering/sphexp_mono_scatter.m index 9dd5650c..b2fef92d 100644 --- a/SFS_scattering/sphexp_mono_scatter.m +++ b/SFS_scattering/sphexp_mono_scatter.m @@ -102,13 +102,15 @@ showprogress = conf.showprogress; Nse = conf.scattering.Nse; -%% ===== Computation ==================================================== +%% ===== Variables ====================================================== k = 2*pi*f/conf.c; kR = k.*R; L = (Nse + 1).^2; Bnm = zeros(L,1); +%% ===== Computation ==================================================== + if isinf(sigma) T = @(x) -sphbesselj(x,kR)./sphbesselh(x,2,kR); elseif sigma == 0 @@ -118,15 +120,13 @@ ./(k.*sphbesselh_derived(x,2,kR)+sigma.*sphbesselh(x,2,kR)); end -l = 0; for n=0:Nse fac = T(n); - for m=-n:n - l = l+1; - % coefficients - Bnm(l) = fac.*Anm(l); - end - if showprogress, progress_bar(l,L); end % progress bar + + v = sphexp_index(-n:n,n); + Bnm(v) = fac.*Anm(v); + + if showprogress, progress_bar(v(end),L); end % progress bar end end From ef73339dfa5a1af3ab9789f682cda1f113a8797a Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 16 Apr 2015 14:42:12 +0200 Subject: [PATCH 13/81] rework wfs driving function for spherical expansion --- ...S.m => driving_function_mono_wfs_sphexp.m} | 140 ++++++++++-------- test_scattering.m | 25 +++- 2 files changed, 97 insertions(+), 68 deletions(-) rename SFS_monochromatic/driving_functions_mono/{driving_function_mono_wfs_sphexpS.m => driving_function_mono_wfs_sphexp.m} (60%) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m similarity index 60% rename from SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m rename to SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m index a2b3fdb4..0d3d4764 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexpS.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m @@ -1,13 +1,14 @@ -function D = driving_function_mono_wfs_sphexpS(x0,n0,Bl,f,xq,conf) -%DRIVING_FUNCTION_MONO_WFS_CYLEXPS computes the time reversed wfs driving -%functions for a sound field expressed by singular spherical expansion coefficients. +function D = driving_function_mono_wfs_sphexp(x0,n0,ABnm,mode,f,xq,conf) +%computes the wfs driving functions for a sound field expressed by spherical +%expansion coefficients. % -% Usage: D = driving_function_mono_wfs_cylexpS(x0,n0,Bl,f,xq,conf) +% Usage: D = driving_function_mono_wfs_sphexp(x0,n0,Bl,mode,f,xq,conf) % % Input parameters: % x0 - position of the secondary sources / m [nx3] % n0 - directions of the secondary sources / m [nx3] -% Bl - singular spherical expansion coefficients of sound field% +% ABnm - singular spherical expansion coefficients of sound field +% mode - 'R' for regular expansion, 'S' for singular expansion % f - frequency in Hz % xq - optional expansion center coordinates, default: [0, 0, 0] % conf - optional configuration struct (see SFS_config) @@ -15,9 +16,9 @@ % Output parameters: % D - driving function signal [nx1] % -% DRIVING_FUNCTION_MONO_WFS_CYLEXPS(x0,n0,Bl,f,xq,conf) +% DRIVING_FUNCTION_MONO_WFS_SPHEXP(x0,n0,Bl,mode,f,xq,conf) % -% see also: driving_function_mono_wfs_cylexpS +% see also: driving_function_mono_wfs_cylexp % % References: % Spors2011 - "Local Sound Field Synthesis by Virtual Acoustic Scattering @@ -25,7 +26,6 @@ % Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the Helmholtz % Equation in three Dimensions", ELSEVIER - %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * % Assessment of IP-based Applications * @@ -59,11 +59,12 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 4; -nargmax = 6; +nargmin = 5; +nargmax = 7; narginchk(nargmin,nargmax); isargmatrix(x0,n0); isargpositivescalar(f); +isargchar(mode); if nargin > B F (x-xq) + % /__ n=0 /__ m=-n n n + % + % where F = {R,S}. + % + % regular spherical basis functions: + % m m + % R (x) = j (kr) . Y (theta, phi) + % n n n + % singular spherical basis functions: + % m (2) m + % S (x) = h (kr) . Y (theta, phi) + % n n n -if strcmp('2D',dimension) || strcmp('3D',dimension) - - % === 2- or 3-Dimensional ============================================ - - if (strcmp('default',driving_functions)) - % --- SFS Toolbox ------------------------------------------------ - % D using a point source - % - % d - % D(x0, w) = --- conj(-Ps(x0,w)) - % d n - % with singular spherical expansion of the sound field: - % \~~ N \~~ n m m - % Ps(x,w) = > > B S (x-xq) - % /__ n=0 /__ m=-n n n - % singular spherical basis functions: - % m (2) m - % S (x) = h (kr) . Y (theta, phi) - % n n n - - for n=0:Nse - h_prime = k.*sphbesselh_derived(n,2,kr); - h = sphbesselh(n, 2, kr); - for m=-n:n - l = l + 1; - Ynm = sphharmonics(n,m, theta, phi); - Gradr = Gradr + ( Bl(l).*h_prime.*Ynm); - Gradphi = Gradphi + 1./r.*( Bl(l).*h.*1j.*m.*Ynm ); - %Gradtheta = 0; TODO - end - if showprogress, progress_bar(l,L); end % progress bar + for n=0:Nse + cn_prime = k.*sphbasis_derived(n,kr); + cn = sphbasis(n, kr); + for m=-n:n + l = l + 1; + Ynm = sphharmonics(n,m, theta0, phi0); + Gradr = Gradr + ( ABnm(l).*cn_prime.*Ynm); + Gradphi = Gradphi + 1./r0.*( ABnm(l).*cn.*1j.*m.*Ynm ); + %Gradtheta = 0; TODO end - % directional gradient + time reversion (conjugate complex) - D = Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0theta.*Gradtheta; - D = -conj(D); - else - error(['%s: %s, this type of driving function is not implemented ', ... - 'for a 2.5D point source.'],upper(mfilename),driving_functions); + if showprogress, progress_bar(l,L); end % progress bar end + % directional gradient + D = Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0theta.*Gradtheta; else - error('%s: the dimension %s is unknown.',upper(mfilename),dimension); + error(['%s: %s, this type of driving function is not implemented ', ... + 'for a 2.5D point source.'],upper(mfilename),driving_functions); end diff --git a/test_scattering.m b/test_scattering.m index 22cb844f..ade0c448 100644 --- a/test_scattering.m +++ b/test_scattering.m @@ -2,15 +2,15 @@ close all; clear variables; % SFS Toolbox -addpath('~/projects/sfstoolbox'); SFS_start; +SFS_start; %% Parameters conf = SFS_config_example; conf.dimension = '3D'; conf.secondary_sources.geometry = 'linear'; -conf.secondary_sources.number = 40; -conf.secondary_sources.size = 6; +conf.secondary_sources.number = 60; +conf.secondary_sources.size = 2; conf.secondary_sources.center = [0, 2, 0]; conf.plot.useplot = false; @@ -85,6 +85,25 @@ plot_scatterer(xq,R); title('point source (shifted reexpansion)'); +%% WFS Reproduction of Spherical Expansion +% loudspeakers +x0 = secondary_source_positions(conf); + +% compute driving functions +D1sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),A1sph,'R',f,xq,conf); +D2sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),A2sph,'R',f,xq,conf); + +% compute fields +P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sph,f,conf); +P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sph,f,conf); + +% plot +[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); + +plot_sound_field(P1sphwfs ,x1,y1,z1, x0, conf); +title('plane wave'); +plot_sound_field(P2sphwfs ,x1,y1,z1, x0, conf); +title('point source'); %% Cylindrical expansion % A1cyl = cylexpR_mono_pw(ns,f,xq,conf); % regular expansion plane wave From 2b505bf49509898d42cb9e7dd849cc3cb09ff5f0 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 16 Apr 2015 17:32:40 +0200 Subject: [PATCH 14/81] fix some bugs in sphexp_access --- SFS_scattering/sphexp_access.m | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/SFS_scattering/sphexp_access.m b/SFS_scattering/sphexp_access.m index 5520c0fb..8c401a39 100644 --- a/SFS_scattering/sphexp_access.m +++ b/SFS_scattering/sphexp_access.m @@ -56,7 +56,7 @@ isargvector(m1); if nargin == nargmin n1 = abs(m1); -else +else isargvector(n1); end if nargin < 4 @@ -72,10 +72,13 @@ %% ===== Computation ==================================================== -a = zeros(max(length(m1), length(n1)),max(length(m2), length(n2))); +a = zeros(length(m1)*length(n1),length(m2)*length(n2)); + +[m1, n1] = meshgrid(m1, n1); +[m2, n2] = meshgrid(m2, n2); -s1 = abs(m1) <= n1; -s2 = abs(m2) <= n2; +s1 = abs(m1(:)) <= n1(:); +s2 = abs(m2(:)) <= n2(:); if any(s1) && any(s2) [l1, l2] = sphexp_index(m1(s1), n1(s1), m2(s2), n2(s2)); From 6229fc5f1767c96d3228ee3146eb0b37e2dd98d5 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 16 Apr 2015 17:33:39 +0200 Subject: [PATCH 15/81] first working version of wfs + spherical expansion --- .../driving_function_mono_wfs_sphexp.m | 6 +- test_scattering.m | 64 +++++++++++++++++-- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m index 0d3d4764..66a54578 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m @@ -118,11 +118,11 @@ % select suitable basis function if strcmp('R', mode) - sphbasis = @(nu,z) sphbesselh(nu,2,z); - sphbasis_derived = @(nu,z) sphbesselh_derived(nu,2,z); -elseif strcmp('S', mode) sphbasis = @sphbesselj; sphbasis_derived = @sphbesselj_derived; +elseif strcmp('S', mode) + sphbasis = @(nu,z) sphbesselh(nu,2,z); + sphbasis_derived = @(nu,z) sphbesselh_derived(nu,2,z); else error('unknown mode:'); end diff --git a/test_scattering.m b/test_scattering.m index ade0c448..38dbbe35 100644 --- a/test_scattering.m +++ b/test_scattering.m @@ -10,19 +10,19 @@ conf.dimension = '3D'; conf.secondary_sources.geometry = 'linear'; conf.secondary_sources.number = 60; -conf.secondary_sources.size = 2; -conf.secondary_sources.center = [0, 2, 0]; +conf.secondary_sources.size = 4; +conf.secondary_sources.center = [0, 0, 0]; conf.plot.useplot = false; -conf.scattering.Nse = 15; +conf.scattering.Nse = 23; conf.scattering.Nce = 23; conf.showprogress = true; conf.resolution = 400; ns = [0, -1, 0]; % propagation direction of plane wave -xs = [0, 3, 0]; % position of point source +xs = [0, 0.5, 0]; % position of point source f = 1500; xrange = [-2 2]; yrange = [-2 2]; @@ -31,7 +31,7 @@ % scatterer sigma = inf; % admittance of scatterer (inf to soft scatterer) R = 0.3; -xq = [ 0, 0, 0]; +xq = [ 0, -1.0, 0]; xt = [ 0.5, 0.5, 0]*R; conf.xref = xq; @@ -85,6 +85,15 @@ plot_scatterer(xq,R); title('point source (shifted reexpansion)'); +%% Scattering with Sphere +% scatterer is assumed to be located at coordinates origin +B1sph = sphexp_mono_scatter(A1sph, R, sigma, f, conf); +B2sph = sphexp_mono_scatter(A2sph, R, sigma, f, conf); + +% compute fields +P1sph_scatter = sound_field_mono_basis(A1sph, Hsphn, Ysphnm, conf); +P2sph_scatter = sound_field_mono_basis(A2sph, Hsphn, Ysphnm, conf); + %% WFS Reproduction of Spherical Expansion % loudspeakers x0 = secondary_source_positions(conf); @@ -105,6 +114,51 @@ plot_sound_field(P2sphwfs ,x1,y1,z1, x0, conf); title('point source'); +%% WFS Reproduction of focused source using time reversal + +% singular spherical expansion of point source +B1sph = sphexp_mono_ps(xs, 'S', f, xs, conf); + +% compute driving functions +D3sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),B1sph,'S',f,xs,conf); + +% compute fields (point and focused source) +P3sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',D3sph,f,conf); +P3sphwfs_conj = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(D3sph),f,conf); + +% plot +plot_sound_field(P3sphwfs ,x1,y1,z1, x0, conf); +title('point source'); +plot_sound_field(P3sphwfs_conj ,x1,y1,z1, x0, conf); +title('focused source'); + +%% WFS Reproduction using virtual Scatterer and time reversal +% loudspeakers +x0 = secondary_source_positions(conf); + +% compute timereversed incident field +A1sph_timereversed = sphexp_mono_timereverse(A1sph); +A2sph_timereversed = sphexp_mono_timereverse(A2sph); +% compute scattered field +B1sph = sphexp_mono_scatter(A1sph_timereversed, R, sigma, f, conf); +B2sph = sphexp_mono_scatter(A2sph_timereversed, R, sigma, f, conf); +% compute driving functions +D1sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),B1sph,'S',f,xq,conf); +D2sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),B2sph,'S',f,xq,conf); +% compute fields +P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(D1sph),f,conf); +P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(D2sph),f,conf); + +% plot +[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); + +plot_sound_field(P1sphwfs ,x1,y1,z1, x0, conf); +title('plane wave'); +plot_scatterer(xq,R); +plot_sound_field(P2sphwfs ,x1,y1,z1, x0, conf); +title('point source'); +plot_scatterer(xq,R); + %% Cylindrical expansion % A1cyl = cylexpR_mono_pw(ns,f,xq,conf); % regular expansion plane wave % A2cyl = cylexpR_mono_pw(ns,f,xq+xt,conf); % regular expansion plane wave From b9cb9d759774f31967f4590e76a157c8d0fca35f Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 24 Apr 2015 11:09:18 +0200 Subject: [PATCH 16/81] 2.5D nfchoa for spherical expansion of soundfield --- .../driving_function_mono_nfchoa_sphexp.m | 138 ++++++++++++++++++ test_scattering.m | 26 +++- 2 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m new file mode 100644 index 00000000..afa73347 --- /dev/null +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -0,0 +1,138 @@ +function D = driving_function_mono_nfchoa_sphexp(x0,Pnm,f,conf) +%computes the nfchoa driving functions for a sound field expressed by regular +%spherical expansion coefficients. +% +% Usage: D = driving_function_mono_nfchoa_sphexp(x0,Pnm,f,N,conf) +% +% Input parameters: +% x0 - position of the secondary sources / m [nx3] +% Pnm - regular spherical expansion coefficients of sound field +% f - frequency in Hz +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% D - driving function signal [nx1] +% +% DRIVING_FUNCTION_MONO_NFCHOA_SPHEXP(x0,Pnm,f,N,conf) returns NFCHOA +% driving signals for the given secondary sources, the virtual sound expressed +% by regular spherical expansion coefficients and the frequency f. +% +% see also: driving_function_mono_wfs_sphexp + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargmatrix(x0); +isargvector(Pnm); +isargpositivescalar(f); +if nargin > P j (kr) . Y (theta, phi) + % /__ n=0 /__ m=-n n n n + % + % and 3D free field Green's Function: + % \~~ oo \~~ n m m + % G (x0,f) = > > G . j (kr) . Y (theta, phi) + % ps /__ n=0 /__ m=-n n n n + % + % with the regular expansion coefficients (Gumerov2004, eq. 3.2.2): + % m (2) -m + % G = -i . k . h (kr0) Y (pi/2, 0) + % n n n + + for m=-Nse:Nse + D = D + sphexp_access(Pnm, m) ./ ... + (sphbesselh(abs(m),2,kr0) .* sphharmonics(abs(m),-m, 0, 0) ) ... + .* exp(1i.*m.*phi0); + end + + D = D./(-1j*2.*pi*kr0); + +elseif strcmp('3D',dimension) + % === 3-Dimensional ================================================== + + to_be_implemented; +else + error('%s: the dimension %s is unknown.',upper(mfilename),dimension); +end diff --git a/test_scattering.m b/test_scattering.m index 38dbbe35..0d16118c 100644 --- a/test_scattering.m +++ b/test_scattering.m @@ -7,10 +7,10 @@ %% Parameters conf = SFS_config_example; -conf.dimension = '3D'; -conf.secondary_sources.geometry = 'linear'; +conf.dimension = '2.5D'; +conf.secondary_sources.geometry = 'circular'; conf.secondary_sources.number = 60; -conf.secondary_sources.size = 4; +conf.secondary_sources.size = 3; conf.secondary_sources.center = [0, 0, 0]; conf.plot.useplot = false; @@ -23,7 +23,7 @@ ns = [0, -1, 0]; % propagation direction of plane wave xs = [0, 0.5, 0]; % position of point source -f = 1500; +f = 1000; xrange = [-2 2]; yrange = [-2 2]; zrange = 0; @@ -159,6 +159,24 @@ title('point source'); plot_scatterer(xq,R); +%% generic NFCHOA +% loudspeakers +x0 = secondary_source_positions(conf); +% compute driving functions +D1sph = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph, f, conf); +D2sph = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph, f, conf); +% compute fields +P1sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sph,f,conf); +P2sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sph,f,conf); + +% plot +[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); + +plot_sound_field(P1sphhoa, x1,y1,z1, x0, conf); +title('plane wave'); +plot_sound_field(P2sphhoa ,x1,y1,z1, x0, conf); +title('point source'); + %% Cylindrical expansion % A1cyl = cylexpR_mono_pw(ns,f,xq,conf); % regular expansion plane wave % A2cyl = cylexpR_mono_pw(ns,f,xq+xt,conf); % regular expansion plane wave From c9d90e2162185b149c0f394bd4b534b4b67090a8 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 24 Apr 2015 11:48:22 +0200 Subject: [PATCH 17/81] optional computation of tesseral reexpansion coefficients --- SFS_scattering/sphexp_mono_translation.m | 56 +++++++++++++----------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/SFS_scattering/sphexp_mono_translation.m b/SFS_scattering/sphexp_mono_translation.m index ffac0779..7a756716 100644 --- a/SFS_scattering/sphexp_mono_translation.m +++ b/SFS_scattering/sphexp_mono_translation.m @@ -28,11 +28,14 @@ % where {E,F} = {R,S}. R denotes the regular spherical basis function, while % S symbolizes the singular spherical basis function. Note that (S|S) and % (S|R) are respectively equivalent to (R|R) and (R|S). +% The reexpansion coefficients can seperated into sectorial +% (n = abs|m| and/or l = abs|s|) and tesseral (else) coefficients. Latter will +% only be computed, if conf.dimensions == '3D'. % -% References: -% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the -% Helmholtz Equation in three -% Dimensions", ELSEVIER +% References: +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three +% Dimensions", ELSEVIER % % see also: sphexp_mono_ps, sphexp_mono_pw % @@ -84,6 +87,7 @@ %% ===== Configuration ================================================== showprogress = conf.showprogress; Nse = conf.scattering.Nse; +dimension = conf.dimension; %% ===== Variables ====================================================== % convert (xpq) into spherical coordinates @@ -204,21 +208,24 @@ end %% ===== Tesseral Coefficients ========================================== -for m=-Nse:Nse - for s=-Nse:Nse - - lowerbound = Nse - max(abs(m),abs(s)); - % left propagation - for n=(0:lowerbound-1)+abs(m) - amn1 = 1./sphexp_access(a,m,n); - amn2 = sphexp_access(a,m,n-1); - for l=(abs(s)-abs(m)+n+1):(2*Nse-n-1) - [v, w] = sphexp_index(s,l, m, n+1); - S(v,w) = amn1 * ( ... - amn2 * sphexp_access(S,s,l ,m,n-1) - ... - sphexp_access(a,s,l) * sphexp_access(S,s,l+1,m,n) + ... - sphexp_access(a,s,l-1) * sphexp_access(S,s,l-1,m,n) ... - ); +if strcmp('3D',dimension) + + for m=-Nse:Nse + for s=-Nse:Nse + + lowerbound = Nse - max(abs(m),abs(s)); + % left propagation + for n=(0:lowerbound-1)+abs(m) + amn1 = 1./sphexp_access(a,m,n); + amn2 = sphexp_access(a,m,n-1); + for l=(abs(s)-abs(m)+n+1):(2*Nse-n-1) + [v, w] = sphexp_index(m, n+1, s, l); + S(v,w) = amn1 * ( ... + amn2 * sphexp_access(S,m,n-1,s,l) - ... + sphexp_access(a,s,l) * sphexp_access(S,m,n ,s,l+1) + ... + sphexp_access(a,s,l-1) * sphexp_access(S,m,n ,s,l-1) ... + ); + end end end % up propagation @@ -233,11 +240,11 @@ sphexp_access(a,m,n-1) * sphexp_access(S,s,l ,m,n-1)... ); end - end - end - if showprogress, progress_bar(m+Nse,2*Nse); end % progress bar -end + end + if showprogress, progress_bar(m+Nse,2*Nse); end % progress bar + end +end %% ====== Final Calculation Steps ======================================= L = (Nse + 1)^2; EF = S(1:L,1:L); % (E|F)(t) @@ -254,7 +261,4 @@ end end -EF = EF.'; -EFm = EFm.'; - end From 14c794fc79c8f86fd8ae3238368daa12e8b8563b Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 24 Apr 2015 14:09:42 +0200 Subject: [PATCH 18/81] remove error handling to speed up computation --- SFS_scattering/sphexp_access.m | 15 ++------------- SFS_scattering/sphexp_index.m | 18 ++---------------- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/SFS_scattering/sphexp_access.m b/SFS_scattering/sphexp_access.m index 8c401a39..f43a08a7 100644 --- a/SFS_scattering/sphexp_access.m +++ b/SFS_scattering/sphexp_access.m @@ -50,28 +50,17 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 2; -nargmax = 5; -narginchk(nargmin,nargmax); -isargvector(m1); -if nargin == nargmin +if nargin < 3 n1 = abs(m1); -else - isargvector(n1); end if nargin < 4 m2 = 0; -else - isargvector(m2); end -if nargin n1 | abs(m2) > n2 ) - error('%s: |m1| > n1 or |m2| > n2',upper(mfilename)); end %% ===== Computation ==================================================== From a491a4c578fe0412050d657ffd1f86df017449bf Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 24 Apr 2015 14:14:45 +0200 Subject: [PATCH 19/81] check for z-coord of translation vector to speed up computation --- SFS_scattering/sphexp_mono_translation.m | 30 +++++++++++------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/SFS_scattering/sphexp_mono_translation.m b/SFS_scattering/sphexp_mono_translation.m index 7a756716..c027cd6b 100644 --- a/SFS_scattering/sphexp_mono_translation.m +++ b/SFS_scattering/sphexp_mono_translation.m @@ -138,7 +138,7 @@ % for l=0:2*Nse % n=l Hn = sqrt(4*pi)*sphbasis(l,kr); % radial basis function (see Variables) - for s=0:l % m=s + for s=l:-inc:0 % m=s % spherical harmonics: conj(Y_n^m) = Y_n^-m (Gumerov2004, eq. 2.1.59) Ynm = sphharmonics(l,s, theta, phi); @@ -169,7 +169,7 @@ % NOTE: sphexp_access(b, -m-1) == sphexp_access(b, -m-1, m+1) bm = 1./sphexp_access(b,-m-1); for l=1:(2*Nse-m-1) - for s=-l:l + for s=-l:inc:l % +m [v, w] = sphexp_index(s,l,m+1); S(v,w) = bm * ( ... @@ -196,13 +196,13 @@ % while {E,F} = {R,S} % for l=1:Nse - for s=[-l,l] - for n=1:(2*Nse-l) - for m=(-n+1):(n-1) - % +s - [v, w] = sphexp_index( s, l, m, n); - S(v,w) = (-1).^(l+n)*sphexp_access(S,-m,n,-s); - end + for n=1:(2*Nse-l) + for m=(-n+1):(n-1) + s = [-l,l]; + m = (-n+inc):inc:(n-inc); + + [v, w] = sphexp_index( s, l, m, n); + S(v,w) = (-1).^(l+n)*sphexp_access(S,-m,n,-s).'; end end end @@ -212,7 +212,7 @@ for m=-Nse:Nse for s=-Nse:Nse - + lowerbound = Nse - max(abs(m),abs(s)); % left propagation for n=(0:lowerbound-1)+abs(m) @@ -252,12 +252,10 @@ EFm = zeros(L); for n=0:Nse for l=0:Nse - for m=-n:n - for s=-l:l - [v, w] = sphexp_index(s,l,m,n); - EFm(v,w) = (-1).^(l+n)*sphexp_access(EF,s,l,m,n); - end - end + m = -n:inc:n; + s = -l:inc:l; + [v, w] = sphexp_index(s,l,m,n); + EFm(v,w) = (-1).^(l+n)*sphexp_access(EF,s,l,m,n); end end From 0dd8a06fa6d7fb43c3c2be1736fd0986395a1185 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 24 Apr 2015 14:15:40 +0200 Subject: [PATCH 20/81] modal bandlimitation of spherical expansion coefficients --- SFS_scattering/sphexp_bandlimit.m | 64 +++++++++++++++++++++++++++++++ test_scattering.m | 35 ++++++++++++----- 2 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 SFS_scattering/sphexp_bandlimit.m diff --git a/SFS_scattering/sphexp_bandlimit.m b/SFS_scattering/sphexp_bandlimit.m new file mode 100644 index 00000000..6521388b --- /dev/null +++ b/SFS_scattering/sphexp_bandlimit.m @@ -0,0 +1,64 @@ +function Anm = sphexp_bandlimit(Anm, N) +% +% Usage: Anm = sphexp_bandlimit(Anm, N) +% +% Input parameters: +% Anm - 1D array of spherical expansion coefficients +% +% Output parameters: +% Anm - 1D array of bandlimited spherical expansion coefficients +% +% SPHEXP_BANDLIMIT(Anm, N) sets coefficients belonging to an order higher +% than N to zero. +% +% see also: sphexp_access + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 1; +nargmax = 4; +narginchk(nargmin,nargmax); +isargvector(Anm); +isargpositivescalar(N); + +if any( (N^2 + 1) > length(Anm) ) + error('%s: order(%d) exceeds size of array',upper(mfilename), N); +end + +%% ===== Computation ==================================================== +v = sphexp_index(+N,N); +Anm(v+1:end) = 0; + +end + diff --git a/test_scattering.m b/test_scattering.m index 0d16118c..efc58d3b 100644 --- a/test_scattering.m +++ b/test_scattering.m @@ -22,8 +22,8 @@ conf.resolution = 400; ns = [0, -1, 0]; % propagation direction of plane wave -xs = [0, 0.5, 0]; % position of point source -f = 1000; +xs = [0, 2, 0]; % position of point source +f = 1200; xrange = [-2 2]; yrange = [-2 2]; zrange = 0; @@ -32,7 +32,7 @@ sigma = inf; % admittance of scatterer (inf to soft scatterer) R = 0.3; xq = [ 0, -1.0, 0]; -xt = [ 0.5, 0.5, 0]*R; +xt = [ 0.5, 0.5, 0]; conf.xref = xq; display(conf.scattering) @@ -44,7 +44,7 @@ A2sph = sphexp_mono_ps(xs,'R',f,xq,conf); A2sph_shift = sphexp_mono_ps(xs,'R', f,xq+xt,conf); % regular-to-regular spherical reexpansion (translatory shift) -RRsph = sphexp_mono_translation(-xt, 'RR', f, conf); +[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', f, conf); A1spht = RRsph*A1sph; A2spht = RRsph*A2sph; @@ -162,20 +162,35 @@ %% generic NFCHOA % loudspeakers x0 = secondary_source_positions(conf); + +A1spht_shift = RRsphm*sphexp_bandlimit(A1sph_shift,10); +A2spht_shift = RRsphm*sphexp_bandlimit(A2sph_shift,10); + % compute driving functions -D1sph = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph, f, conf); -D2sph = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph, f, conf); +D1sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph, f, conf); +D2sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph, f, conf); +% compute driving functions for shifted expansions +D1sphhoat = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1spht_shift, f, conf); +D2sphhoat = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2spht_shift, f, conf); + % compute fields -P1sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sph,f,conf); -P2sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sph,f,conf); +P1sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoa,f,conf); +P2sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoa,f,conf); +% compute fields +P1sphhoat = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoat,f,conf); +P2sphhoat = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoat,f,conf); % plot [~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); plot_sound_field(P1sphhoa, x1,y1,z1, x0, conf); -title('plane wave'); +title('NFCHOA: plane wave'); plot_sound_field(P2sphhoa ,x1,y1,z1, x0, conf); -title('point source'); +title('NFCHOA: point source'); +plot_sound_field(P1sphhoat/5, x1,y1,z1, x0, conf); +title('NFCHOA: plane wave (shifted reexpansion)'); +plot_sound_field(P2sphhoat/5, x1,y1,z1, x0, conf); +title('NFCHOA: point source (shifted reexpansion)'); %% Cylindrical expansion % A1cyl = cylexpR_mono_pw(ns,f,xq,conf); % regular expansion plane wave From 59d1c86cef88217676da798cd12a3fbbb1e51efc Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 28 Apr 2015 09:53:02 +0200 Subject: [PATCH 21/81] fix bug due to rebase --- SFS_scattering/sphexp_mono_translation.m | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/SFS_scattering/sphexp_mono_translation.m b/SFS_scattering/sphexp_mono_translation.m index c027cd6b..8db6e7b0 100644 --- a/SFS_scattering/sphexp_mono_translation.m +++ b/SFS_scattering/sphexp_mono_translation.m @@ -115,6 +115,13 @@ end %% ===== Sectorial Coefficients ========================================= +% if translation vector's z-coordinate is zero, many coefficients are zero +% this is to save some computation time +if t(3) == 0 + inc = 2; +else + inc = 1; +end % for n=0, m=0 (Gumerov2004, eq. 3.2.5) % @@ -197,13 +204,10 @@ % for l=1:Nse for n=1:(2*Nse-l) - for m=(-n+1):(n-1) - s = [-l,l]; - m = (-n+inc):inc:(n-inc); - - [v, w] = sphexp_index( s, l, m, n); - S(v,w) = (-1).^(l+n)*sphexp_access(S,-m,n,-s).'; - end + s = [-l,l]; + m = (-n+inc):inc:(n-inc); + [v, w] = sphexp_index( s, l, m, n); + S(v,w) = (-1).^(l+n)*sphexp_access(S,-m,n,-s, l).'; end end From d9f6a69f5b4088e8ace1e8e31db5d63aa7031b30 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 28 Apr 2015 11:23:07 +0200 Subject: [PATCH 22/81] split test scripts --- test_scattering.m => test_exp.m | 106 +---------------- test_exp_nfchoa.m | 70 +++++++++++ test_exp_wfs.m | 201 ++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+), 104 deletions(-) rename test_scattering.m => test_exp.m (69%) create mode 100644 test_exp_nfchoa.m create mode 100644 test_exp_wfs.m diff --git a/test_scattering.m b/test_exp.m similarity index 69% rename from test_scattering.m rename to test_exp.m index efc58d3b..45c9da76 100644 --- a/test_scattering.m +++ b/test_exp.m @@ -8,10 +8,6 @@ conf = SFS_config_example; conf.dimension = '2.5D'; -conf.secondary_sources.geometry = 'circular'; -conf.secondary_sources.number = 60; -conf.secondary_sources.size = 3; -conf.secondary_sources.center = [0, 0, 0]; conf.plot.useplot = false; @@ -22,7 +18,7 @@ conf.resolution = 400; ns = [0, -1, 0]; % propagation direction of plane wave -xs = [0, 2, 0]; % position of point source +xs = [0, 1.0, 0]; % position of point source f = 1200; xrange = [-2 2]; yrange = [-2 2]; @@ -31,7 +27,7 @@ % scatterer sigma = inf; % admittance of scatterer (inf to soft scatterer) R = 0.3; -xq = [ 0, -1.0, 0]; +xq = [ 0, -1, 0]; xt = [ 0.5, 0.5, 0]; conf.xref = xq; @@ -94,104 +90,6 @@ P1sph_scatter = sound_field_mono_basis(A1sph, Hsphn, Ysphnm, conf); P2sph_scatter = sound_field_mono_basis(A2sph, Hsphn, Ysphnm, conf); -%% WFS Reproduction of Spherical Expansion -% loudspeakers -x0 = secondary_source_positions(conf); - -% compute driving functions -D1sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),A1sph,'R',f,xq,conf); -D2sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),A2sph,'R',f,xq,conf); - -% compute fields -P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sph,f,conf); -P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sph,f,conf); - -% plot -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); - -plot_sound_field(P1sphwfs ,x1,y1,z1, x0, conf); -title('plane wave'); -plot_sound_field(P2sphwfs ,x1,y1,z1, x0, conf); -title('point source'); - -%% WFS Reproduction of focused source using time reversal - -% singular spherical expansion of point source -B1sph = sphexp_mono_ps(xs, 'S', f, xs, conf); - -% compute driving functions -D3sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),B1sph,'S',f,xs,conf); - -% compute fields (point and focused source) -P3sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',D3sph,f,conf); -P3sphwfs_conj = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(D3sph),f,conf); - -% plot -plot_sound_field(P3sphwfs ,x1,y1,z1, x0, conf); -title('point source'); -plot_sound_field(P3sphwfs_conj ,x1,y1,z1, x0, conf); -title('focused source'); - -%% WFS Reproduction using virtual Scatterer and time reversal -% loudspeakers -x0 = secondary_source_positions(conf); - -% compute timereversed incident field -A1sph_timereversed = sphexp_mono_timereverse(A1sph); -A2sph_timereversed = sphexp_mono_timereverse(A2sph); -% compute scattered field -B1sph = sphexp_mono_scatter(A1sph_timereversed, R, sigma, f, conf); -B2sph = sphexp_mono_scatter(A2sph_timereversed, R, sigma, f, conf); -% compute driving functions -D1sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),B1sph,'S',f,xq,conf); -D2sph = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6),B2sph,'S',f,xq,conf); -% compute fields -P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(D1sph),f,conf); -P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(D2sph),f,conf); - -% plot -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); - -plot_sound_field(P1sphwfs ,x1,y1,z1, x0, conf); -title('plane wave'); -plot_scatterer(xq,R); -plot_sound_field(P2sphwfs ,x1,y1,z1, x0, conf); -title('point source'); -plot_scatterer(xq,R); - -%% generic NFCHOA -% loudspeakers -x0 = secondary_source_positions(conf); - -A1spht_shift = RRsphm*sphexp_bandlimit(A1sph_shift,10); -A2spht_shift = RRsphm*sphexp_bandlimit(A2sph_shift,10); - -% compute driving functions -D1sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph, f, conf); -D2sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph, f, conf); -% compute driving functions for shifted expansions -D1sphhoat = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1spht_shift, f, conf); -D2sphhoat = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2spht_shift, f, conf); - -% compute fields -P1sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoa,f,conf); -P2sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoa,f,conf); -% compute fields -P1sphhoat = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoat,f,conf); -P2sphhoat = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoat,f,conf); - -% plot -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); - -plot_sound_field(P1sphhoa, x1,y1,z1, x0, conf); -title('NFCHOA: plane wave'); -plot_sound_field(P2sphhoa ,x1,y1,z1, x0, conf); -title('NFCHOA: point source'); -plot_sound_field(P1sphhoat/5, x1,y1,z1, x0, conf); -title('NFCHOA: plane wave (shifted reexpansion)'); -plot_sound_field(P2sphhoat/5, x1,y1,z1, x0, conf); -title('NFCHOA: point source (shifted reexpansion)'); - %% Cylindrical expansion % A1cyl = cylexpR_mono_pw(ns,f,xq,conf); % regular expansion plane wave % A2cyl = cylexpR_mono_pw(ns,f,xq+xt,conf); % regular expansion plane wave diff --git a/test_exp_nfchoa.m b/test_exp_nfchoa.m new file mode 100644 index 00000000..f62ff7b4 --- /dev/null +++ b/test_exp_nfchoa.m @@ -0,0 +1,70 @@ +%% initialize +close all; +clear variables; +% SFS Toolbox +SFS_start; + +%% Parameters +conf = SFS_config_example; + +conf.dimension = '2.5D'; +conf.secondary_sources.geometry = 'circular'; +conf.secondary_sources.number = 60; +conf.secondary_sources.size = 3; +conf.secondary_sources.center = [0, 0, 0]; + +conf.plot.useplot = false; + +conf.scattering.Nse = 23; +conf.scattering.Nce = 23; + +conf.showprogress = true; +conf.resolution = 400; + +ns = [0, -1, 0]; % propagation direction of plane wave +xs = [0, 2, 0]; % position of point source +f = 1200; +xrange = [-2 2]; +yrange = [-2 2]; +zrange = 0; + +xq = conf.secondary_sources.center; +xt = [ 0.5, 0.5, 0]; +conf.xref = xq; + +display(conf.scattering) + +%% generic NFCHOA +% regular spherical expansion of plane wave and point source +A1sph = sphexp_mono_pw(ns,f,xq+xt,conf); +A2sph = sphexp_mono_ps(xs,'R', f,xq+xt,conf); +% regular-to-regular spherical reexpansion (translatory shift) +[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', f, conf); +% shift spherical expansion back to xq +A1sph_shift = RRsph*sphexp_bandlimit(A1sph,10); +A2sph_shift = RRsph*sphexp_bandlimit(A2sph,10); +% loudspeakers +x0 = secondary_source_positions(conf); +% compute driving functions +D1sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph, f, conf); +D2sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph, f, conf); +% compute driving functions for shifted expansions +D1sphhoa_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph_shift, f, conf); +D2sphhoa_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph_shift, f, conf); +% compute fields +P1sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoa,f,conf); +P2sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoa,f,conf); +% compute fields +P1sphhoa_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoa_shift,f,conf); +P2sphhoa_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoa_shift,f,conf); +% plot +[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); + +plot_sound_field(P1sphhoa, x1,y1,z1, x0, conf); +title('NFCHOA: plane wave'); +plot_sound_field(P2sphhoa ,x1,y1,z1, x0, conf); +title('NFCHOA: point source'); +plot_sound_field(P1sphhoa_shift/5, x1,y1,z1, x0, conf); +title('NFCHOA: plane wave (shifted reexpansion)'); +plot_sound_field(P2sphhoa_shift/5, x1,y1,z1, x0, conf); +title('NFCHOA: point source (shifted reexpansion)'); \ No newline at end of file diff --git a/test_exp_wfs.m b/test_exp_wfs.m new file mode 100644 index 00000000..86fff5ef --- /dev/null +++ b/test_exp_wfs.m @@ -0,0 +1,201 @@ +%% initialize +close all; +clear variables; +% SFS Toolbox +SFS_start; + +%% Parameters +conf = SFS_config_example; + +conf.dimension = '2.5D'; +conf.secondary_sources.geometry = 'linear'; +conf.secondary_sources.number = 60; +conf.secondary_sources.size = 4; +conf.secondary_sources.center = [0, 0, 0]; + +conf.plot.useplot = false; + +conf.scattering.Nse = 23; +conf.scattering.Nce = 23; + +conf.showprogress = true; +conf.resolution = 400; + +ns = [0, -1, 0]; % propagation direction of plane wave +xs = [0, 1.0, 0]; % position of point source +f = 1200; +xrange = [-2 2]; +yrange = [-2 2]; +zrange = 0; + +% scatterer +sigma = inf; % admittance of scatterer (inf to soft scatterer) +R = 0.3; +xq = [ 0, -1, 0]; +xt = [ 0.5, 0.5, 0]; +conf.xref = xq; + +display(conf.scattering) + +%% Spherical Expansion +% spherical expansion +A1sph = sphexp_mono_pw(ns,f,xq,conf); +A1sph_shift = sphexp_mono_pw(ns,f,xq+xt,conf); +A2sph = sphexp_mono_ps(xs,'R',f,xq,conf); +A2sph_shift = sphexp_mono_ps(xs,'R', f,xq+xt,conf); +% regular-to-regular spherical reexpansion (translatory shift) +[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', f, conf); +A1spht = RRsph*A1sph; +A2spht = RRsph*A2sph; + +% Evaluate spherical basis functions +[Jsphn, Hsphn, Ysphnm] = ... + sphbasis_mono_XYZgrid(xrange,yrange,zrange,f,xq,conf); +% +[Jsphnt, Hsphnt, Ysphnmt] = ... + sphbasis_mono_XYZgrid(xrange,yrange,zrange,f,xq+xt,conf); + +% compute fields +P1sph = sound_field_mono_basis(A1sph, Jsphn, Ysphnm, conf); +P1sph_shift = sound_field_mono_basis(A1sph_shift, Jsphnt, Ysphnmt, conf); +P1spht = sound_field_mono_basis(A1spht, Jsphnt, Ysphnmt, conf); +P2sph = sound_field_mono_basis(A2sph, Jsphn, Ysphnm, conf); +P2sph_shift = sound_field_mono_basis(A2sph_shift, Jsphnt, Ysphnmt, conf); +P2spht = sound_field_mono_basis(A2spht, Jsphnt, Ysphnmt, conf); + +% plot +[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); + +plot_sound_field(P1sph ,x1,y1,z1, [], conf); +plot_scatterer(xq,R); +title('plane wave'); +plot_sound_field(P1sph_shift ,x1,y1,z1, [], conf); +plot_scatterer(xq,R); +title('plane wave (shifted expansion)'); +plot_sound_field(P1spht ,x1,y1,z1, [], conf); +plot_scatterer(xq,R); +title('plane wave (shifted reexpansion)'); +plot_sound_field(P2sph ,x1,y1,z1, [], conf); +plot_scatterer(xq,R); +title('point source'); +plot_sound_field(P2sph_shift ,x1,y1,z1, [], conf); +plot_scatterer(xq,R); +title('point source (shifted expansion)'); +plot_sound_field(P2spht ,x1,y1,z1, [], conf); +plot_scatterer(xq,R); +title('point source (shifted reexpansion)'); + +%% Scattering with Sphere +% scatterer is assumed to be located at coordinates origin +B1sph = sphexp_mono_scatter(A1sph, R, sigma, f, conf); +B2sph = sphexp_mono_scatter(A2sph, R, sigma, f, conf); + +% compute fields +P1sph_scatter = sound_field_mono_basis(A1sph, Hsphn, Ysphnm, conf); +P2sph_scatter = sound_field_mono_basis(A2sph, Hsphn, Ysphnm, conf); + +%% WFS Reproduction of Spherical Expansion +% regular spherical expansion of plane wave and point source +A1sph = sphexp_mono_pw(ns,f,xq,conf); +A2sph = sphexp_mono_ps(xs,'R',f,xq,conf); +% loudspeakers +x0 = secondary_source_positions(conf); +x0pw = secondary_source_selection(x0,ns,'pw'); +x0ps = secondary_source_selection(x0,xs,'ps'); +% compute driving functions and sound fields +D1sph = driving_function_mono_wfs_sphexp(x0pw(:,1:3),x0pw(:,4:6),A1sph,'R',f,xq,conf); +D2sph = driving_function_mono_wfs_sphexp(x0ps(:,1:3),x0ps(:,4:6),A2sph,'R',f,xq,conf); +% compute fields +P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0pw,'ps',D1sph,f,conf); +P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0ps,'ps',D2sph,f,conf); +% plot +[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); + +plot_sound_field(P1sphwfs ,x1,y1,z1, x0pw, conf); +title('plane wave'); +plot_sound_field(P2sphwfs ,x1,y1,z1, x0ps, conf); +title('point source'); + +%% WFS Reproduction of focused source using time reversal +% singular spherical expansion of point source +B1sph = sphexp_mono_ps(xs, 'S', f, xs, conf); +% loudspeakers +x0 = secondary_source_positions(conf); +x0ps = secondary_source_selection(x0,xs,'ps'); +x0fs = secondary_source_selection(x0,[xs,0 1 0],'fs'); +% compute driving functions +D1sph = driving_function_mono_wfs_sphexp(x0ps(:,1:3),x0ps(:,4:6),B1sph,'S',f,xs,conf); +D2sph = driving_function_mono_wfs_sphexp(x0fs(:,1:3),x0fs(:,4:6),B1sph,'S',f,xs,conf); +% compute fields +P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sph,f,conf); +P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(D2sph),f,conf); +% plot +[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); + +plot_sound_field(P1sphwfs,x1,y1,z1, x0, conf); +title('point source'); +plot_sound_field(P2sphwfs,x1,y1,z1, x0, conf); +title('focused source'); + +%% WFS Reproduction using virtual Scatterer and time reversal +% regular spherical expansion of plane wave and point source +A1sph = sphexp_mono_pw(ns,f,xq,conf); +A2sph = sphexp_mono_ps(xs,'R',f,xq,conf); +% compute timereversed incident field +A1sph_timereversed = sphexp_mono_timereverse(A1sph); +A2sph_timereversed = sphexp_mono_timereverse(A2sph); +% compute scattered field +B1sph = sphexp_mono_scatter(A1sph_timereversed, R, sigma, f, conf); +B2sph = sphexp_mono_scatter(A2sph_timereversed, R, sigma, f, conf); +% loudspeakers +x0 = secondary_source_positions(conf); +x0pw = secondary_source_selection(x0,ns,'pw'); +x0ps = secondary_source_selection(x0,xs,'ps'); +% compute driving functions +D1sph = driving_function_mono_wfs_sphexp(x0pw(:,1:3),x0pw(:,4:6),B1sph,'S',f,xq,conf); +D2sph = driving_function_mono_wfs_sphexp(x0ps(:,1:3),x0ps(:,4:6),B2sph,'S',f,xq,conf); +% compute fields +P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0pw,'ps',conj(D1sph),f,conf); +P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0ps,'ps',conj(D2sph),f,conf); +% plot +[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); + +plot_sound_field(P1sphwfs ,x1,y1,z1, x0pw, conf); +title('plane wave'); +plot_scatterer(xq,R); +plot_sound_field(P2sphwfs ,x1,y1,z1, x0ps, conf); +title('point source'); +plot_scatterer(xq,R); + +%% generic NFCHOA +% loudspeakers +x0 = secondary_source_positions(conf); + +A1spht_shift = RRsphm*sphexp_bandlimit(A1sph_shift,10); +A2spht_shift = RRsphm*sphexp_bandlimit(A2sph_shift,10); + +% compute driving functions +D1sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph, f, conf); +D2sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph, f, conf); +% compute driving functions for shifted expansions +D1sphhoat = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1spht_shift, f, conf); +D2sphhoat = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2spht_shift, f, conf); + +% compute fields +P1sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoa,f,conf); +P2sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoa,f,conf); +% compute fields +P1sphhoat = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoat,f,conf); +P2sphhoat = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoat,f,conf); + +% plot +[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); + +plot_sound_field(P1sphhoa, x1,y1,z1, x0, conf); +title('NFCHOA: plane wave'); +plot_sound_field(P2sphhoa ,x1,y1,z1, x0, conf); +title('NFCHOA: point source'); +plot_sound_field(P1sphhoat/5, x1,y1,z1, x0, conf); +title('NFCHOA: plane wave (shifted reexpansion)'); +plot_sound_field(P2sphhoat/5, x1,y1,z1, x0, conf); +title('NFCHOA: point source (shifted reexpansion)'); \ No newline at end of file From cde6b2d24c7b2f85d9eb587ce93b9eea87d08489 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 28 Apr 2015 11:24:07 +0200 Subject: [PATCH 23/81] fix bug related to conjugate symmetry relations of spherical harmonics --- SFS_scattering/sphexp_mono_translation.m | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SFS_scattering/sphexp_mono_translation.m b/SFS_scattering/sphexp_mono_translation.m index 8db6e7b0..5fcb053f 100644 --- a/SFS_scattering/sphexp_mono_translation.m +++ b/SFS_scattering/sphexp_mono_translation.m @@ -125,11 +125,11 @@ % for n=0, m=0 (Gumerov2004, eq. 3.2.5) % -% s, 0 s, 0 ___ -l -s +% s, 0 s, 0 ___ l -s % (S|R) = (R|S) = \|4pi (-1) S (t) % l, 0 l, 0 l % -% s, 0 s, 0 ___ -l -s +% s, 0 s, 0 ___ l -s % (S|S) = (R|R) = \|4pi (-1) R (t) % l, 0 l, 0 l % @@ -150,12 +150,12 @@ Ynm = sphharmonics(l,s, theta, phi); v = sphexp_index(s,l); - S(v,1) = (-1).^l*Hn.*Ynm; % s,l, m=0, n=0 - S(1,v) = Hn.*conj(Ynm); % s=0,l=0, m, n + S(v,1) = (-1).^l*Hn.*conj(Ynm); % s,l, m=0, n=0 + S(1,v) = Hn.*Ynm; % s=0,l=0, m, n v = sphexp_index(-s,l); - S(v,1) = (-1).^l*Hn.*conj(Ynm); % -s,l, m=0, n=0 - S(1,v) = Hn.*Ynm; % s=0,l=0, -m, n + S(v,1) = (-1).^l*Hn.*Ynm; % -s,l, m=0, n=0 + S(1,v) = Hn.*conj(Ynm); % s=0,l=0, -m, n end if showprogress, progress_bar(v,L); end % progress bar end From 9ab4b6d5114c5b2b92db1b5c446fd463a07647fa Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 30 Apr 2015 10:29:51 +0200 Subject: [PATCH 24/81] get order of spherical expansion from size of coefficient array --- .../driving_function_mono_nfchoa_sphexp.m | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index afa73347..59270ac9 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -1,4 +1,4 @@ -function D = driving_function_mono_nfchoa_sphexp(x0,Pnm,f,conf) +function D = driving_function_mono_nfchoa_sphexp(x0, Pnm,f,conf) %computes the nfchoa driving functions for a sound field expressed by regular %spherical expansion coefficients. % @@ -63,20 +63,24 @@ else isargstruct(conf); end +if mod(sqrt(size(Pnm, 1)),1) ~= 0 + error(['%s: number of columns of Pnm (%s) is not the square of an', ... + 'integer.'], upper(mfilename), sqrt(size(Pnm, 1))); +end %% ===== Configuration ================================================== c = conf.c; dimension = conf.dimension; -driving_functions = conf.driving_functions; -Nse = conf.scattering.Nse; -X0 = conf.secondary_sources.center; +Xc = conf.secondary_sources.center; %% ===== Variables ====================================================== +Nse = sqrt(size(Pnm, 1))-1; + %% ===== Computation ==================================================== % Calculate the driving function in time-frequency domain % secondary source positions -x00 = bsxfun(@minus,x0,X0); +x00 = bsxfun(@minus,x0,Xc); [phi0,theta0,r0] = cart2sph(x00(:,1),x00(:,2),x00(:,3)); % frequency depended stuff @@ -91,13 +95,10 @@ if strcmp('2D',dimension) % === 2-Dimensional ================================================== - error('%s: %s, 2D driving function is not implemented.',upper(mfilename)); + to_be_implemented; elseif strcmp('2.5D',dimension) % === 2.5-Dimensional ================================================ - - % --- SFS Toolbox ------------------------------------------------ - % % m % __ P % 1 \ |m| From 236b5901929edfcf8edcee278e738a8e00b95923 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 30 Apr 2015 11:32:30 +0200 Subject: [PATCH 25/81] 2.5D HOA with variable reference radius (very experimental) --- .../driving_function_mono_nfchoa_sphexp.m | 101 +++++++++++++----- SFS_scattering/sphexp_mono_translation.m | 4 - 2 files changed, 72 insertions(+), 33 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index 59270ac9..6e3d7498 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -72,6 +72,7 @@ c = conf.c; dimension = conf.dimension; Xc = conf.secondary_sources.center; +xref = conf.xref - Xc; %% ===== Variables ====================================================== Nse = sqrt(size(Pnm, 1))-1; @@ -87,6 +88,11 @@ omega = 2*pi*f; k = omega/c; kr0 = k.*r0; + +% reference radius +[~, ~, rref] = cart2sph(xref(1),xref(2),xref(3)); +krref = k.*rref; + % initialize empty driving signal D = zeros(size(x0,1),1); @@ -99,36 +105,73 @@ elseif strcmp('2.5D',dimension) % === 2.5-Dimensional ================================================ - % m - % __ P - % 1 \ |m| - % D(phi0,w) = ------ /__ -------- e^(i m (phi0)) - % 2pi r0 m=-N..N m - % G - % |m| - % - % with regular spherical expansion of the sound field: - % \~~ N \~~ n m m - % P(x,w) = > > P j (kr) . Y (theta, phi) - % /__ n=0 /__ m=-n n n n - % - % and 3D free field Green's Function: - % \~~ oo \~~ n m m - % G (x0,f) = > > G . j (kr) . Y (theta, phi) - % ps /__ n=0 /__ m=-n n n n - % - % with the regular expansion coefficients (Gumerov2004, eq. 3.2.2): - % m (2) -m - % G = -i . k . h (kr0) Y (pi/2, 0) - % n n n - - for m=-Nse:Nse - D = D + sphexp_access(Pnm, m) ./ ... - (sphbesselh(abs(m),2,kr0) .* sphharmonics(abs(m),-m, 0, 0) ) ... - .* exp(1i.*m.*phi0); - end - D = D./(-1j*2.*pi*kr0); + if (rref == 0) + % --- Xref == Xc ---------------------------------------------------- + % m + % __ P + % 1 \ |m| + % D(phi0,w) = ------ /__ -------- e^(i m (phi0)) + % 2pi r0 m=-N..N m + % G + % |m| + % + % with regular spherical expansion of the sound field: + % \~~ N \~~ n m m + % P(x,w) = > > P j (kr) . Y (theta, phi) + % /__ n=0 /__ m=-n n n n + % + % and 3D free field Green's Function: + % \~~ oo \~~ n m m + % G (x0,f) = > > G . j (kr) . Y (theta, phi) + % ps /__ n=0 /__ m=-n n n n + % + % with the regular expansion coefficients (Gumerov2004, eq. 3.2.2): + % m (2) -m + % G = -i . k . h (kr0) Y (pi/2, 0) + % n n n + + for m=-Nse:Nse + D = D + sphexp_access(Pnm, m) ./ ... + (sphbesselh(abs(m),2,kr0) .* sphharmonics(abs(m),-m, 0, 0) ) ... + .* exp(1i.*m.*phi0); + end + + D = D./(-1i*2.*pi*kr0); + else + % --- Xref ~= Xc ---------------------------------------------------- + % + % if the reference position is not in the middle of the array, things + % get a 'little' more complicated + + hn = zeros(size(x0,1),1,Nse+1); + jn = hn; + for n=0:Nse + hn(:,:,n+1) = sphbesselh(n,2,kr0); + jn(:,:,n+1) = sphbesselj(n,krref); + end + + for m=-Nse:Nse + Pm = 0; + Gm = 0; + % for theta=0 the legendre polynom is zero if n+m is odd + for n=abs(m):2:Nse + factor = jn(:,:,n+1) .* ... + (-1).^(m) .* ... + sqrt( (2*n+1) ./ (4*pi) ) .* ... + sqrt( factorial(n-abs(m)) ./ factorial(n+abs(m)) ) .* ... + asslegendre(n,abs(m),0); + + Pm = Pm + sphexp_access(Pnm, m, n) .* factor; + + Gm = Gm + (-1i*k) .* hn(:,:,n+1) .* sphharmonics(n, -m, 0, 0) .* factor; + end + + D = D + Pm ./ Gm .* exp(1i.*m.*phi0); + end + + D = D./(2.*pi*r0); + end elseif strcmp('3D',dimension) % === 3-Dimensional ================================================== diff --git a/SFS_scattering/sphexp_mono_translation.m b/SFS_scattering/sphexp_mono_translation.m index 5fcb053f..af9181ea 100644 --- a/SFS_scattering/sphexp_mono_translation.m +++ b/SFS_scattering/sphexp_mono_translation.m @@ -212,8 +212,6 @@ end %% ===== Tesseral Coefficients ========================================== -if strcmp('3D',dimension) - for m=-Nse:Nse for s=-Nse:Nse @@ -247,8 +245,6 @@ end if showprogress, progress_bar(m+Nse,2*Nse); end % progress bar end - -end %% ====== Final Calculation Steps ======================================= L = (Nse + 1)^2; EF = S(1:L,1:L); % (E|F)(t) From a1745d1fc8339e6755e373cc6971ea53041257df Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Wed, 13 May 2015 13:28:52 +0200 Subject: [PATCH 26/81] add plots for testing 2.5HOA with different reference radii --- test_exp_nfchoa.m | 78 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/test_exp_nfchoa.m b/test_exp_nfchoa.m index f62ff7b4..f9616ef3 100644 --- a/test_exp_nfchoa.m +++ b/test_exp_nfchoa.m @@ -1,5 +1,5 @@ %% initialize -close all; +% close all; clear variables; % SFS Toolbox SFS_start; @@ -23,48 +23,92 @@ ns = [0, -1, 0]; % propagation direction of plane wave xs = [0, 2, 0]; % position of point source -f = 1200; +f = 300; xrange = [-2 2]; yrange = [-2 2]; zrange = 0; xq = conf.secondary_sources.center; xt = [ 0.5, 0.5, 0]; -conf.xref = xq; +conf.xref = xt; display(conf.scattering) %% generic NFCHOA -% regular spherical expansion of plane wave and point source +% regular spherical expansion of plane wave and point source at xq +A1sph_original = sphexp_mono_pw(ns,f,xq,conf); +A2sph_original = sphexp_mono_ps(xs,'R', f,xq,conf); +% regular spherical expansion of plane wave and point source at xq+xt A1sph = sphexp_mono_pw(ns,f,xq+xt,conf); A2sph = sphexp_mono_ps(xs,'R', f,xq+xt,conf); % regular-to-regular spherical reexpansion (translatory shift) -[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', f, conf); +% [RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', f, conf); % shift spherical expansion back to xq -A1sph_shift = RRsph*sphexp_bandlimit(A1sph,10); -A2sph_shift = RRsph*sphexp_bandlimit(A2sph,10); +% A1sph_shift = RRsph*sphexp_bandlimit(A1sph,10); +% A2sph_shift = RRsph*sphexp_bandlimit(A2sph,10); % loudspeakers x0 = secondary_source_positions(conf); % compute driving functions -D1sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph, f, conf); -D2sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph, f, conf); +D1sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph_original, f, conf); +D2sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph_original, f, conf); % compute driving functions for shifted expansions -D1sphhoa_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph_shift, f, conf); -D2sphhoa_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph_shift, f, conf); +% D1sphhoa_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph_shift, f, conf); +% D2sphhoa_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph_shift, f, conf); % compute fields P1sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoa,f,conf); P2sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoa,f,conf); % compute fields -P1sphhoa_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoa_shift,f,conf); -P2sphhoa_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoa_shift,f,conf); +% P1sphhoa_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoa_shift,f,conf); +% P2sphhoa_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoa_shift,f,conf); % plot [~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); plot_sound_field(P1sphhoa, x1,y1,z1, x0, conf); title('NFCHOA: plane wave'); +plot_scatterer(xq, norm(xt)); plot_sound_field(P2sphhoa ,x1,y1,z1, x0, conf); title('NFCHOA: point source'); -plot_sound_field(P1sphhoa_shift/5, x1,y1,z1, x0, conf); -title('NFCHOA: plane wave (shifted reexpansion)'); -plot_sound_field(P2sphhoa_shift/5, x1,y1,z1, x0, conf); -title('NFCHOA: point source (shifted reexpansion)'); \ No newline at end of file +plot_scatterer(xq, norm(xt)); +% plot_sound_field(P1sphhoa_shift/5, x1,y1,z1, x0, conf); +% title('NFCHOA: plane wave (shifted reexpansion)'); +% plot_sound_field(P2sphhoa_shift/5, x1,y1,z1, x0, conf); +% title('NFCHOA: point source (shifted reexpansion)'); + +x1 = cosd(0:1:359).'*((0:0.1:1.4)*norm(xt)) + xq(1); +y1 = sind(0:1:359).'*((0:0.1:1.4)*norm(xt)) + xq(2); +z1 = zeros(size(x1)) + xq(3); + + +conf.showprogress = 0; +for rdx=1:size(x1,2) + for idx=1:size(x1,1) + P1ring(idx,rdx) = sound_field_mono(x1(idx, rdx), y1(idx, rdx), z1(idx, rdx),x0,'ps',D1sphhoa,f,conf); + P2ring(idx,rdx) = sound_field_mono(x1(idx, rdx), y1(idx, rdx), z1(idx, rdx),x0,'ps',D2sphhoa,f,conf); + + P1ring_gt(idx,rdx) = sound_field_mono(x1(idx, rdx), y1(idx, rdx), z1(idx, rdx),[ns, 1, 0, 0, 1], 'pw', 1, f,conf); + P2ring_gt(idx,rdx) = sound_field_mono(x1(idx, rdx), y1(idx, rdx), z1(idx, rdx),[xs, 1, 0, 0, 1], 'ps', 1, f,conf); + end +end +conf.showprogress = 1; + +figure; +subplot(2,2,1); +imagesc((0:0.1:1.4), 0:1:359, db(P1ring./P1ring_gt)); +colorbar; +colormap jet; +title('AMPLITUDE RATIO: plane wave'); +subplot(2,2,2); +imagesc((0:0.1:1.4), 0:1:359, angle(P1ring./P1ring_gt)); +colorbar; +colormap jet; +title('PHASE DIFFERENCE: plane wave'); +subplot(2,2,3); +imagesc((0:0.1:1.4), 0:1:359, db(P2ring./P2ring_gt)); +colorbar; +colormap jet; +title('AMPLITUDE RATIO: point source'); +subplot(2,2,4); +imagesc((0:0.1:1.4), 0:1:359, angle(P2ring./P2ring_gt)); +colorbar; +colormap jet; +title('PHASE DIFFERENCE: point source'); From f7ed16c859cc3250abb646d0a8d498f3cd8e7963 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 19 May 2015 11:49:15 +0200 Subject: [PATCH 27/81] add normalization of driving function in order to get correct sound pressure level compared to pressure of virtual source --- .../driving_function_mono_nfchoa_sphexp.m | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index 6e3d7498..9e6c25f3 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -72,6 +72,7 @@ c = conf.c; dimension = conf.dimension; Xc = conf.secondary_sources.center; +N0 = conf.secondary_sources.number; xref = conf.xref - Xc; %% ===== Variables ====================================================== @@ -136,13 +137,12 @@ (sphbesselh(abs(m),2,kr0) .* sphharmonics(abs(m),-m, 0, 0) ) ... .* exp(1i.*m.*phi0); end - - D = D./(-1i*2.*pi*kr0); + D = D./(-1i*k); % factor from expansion of 3D free field Green's Function else % --- Xref ~= Xc ---------------------------------------------------- - % - % if the reference position is not in the middle of the array, things - % get a 'little' more complicated + % + % if the reference position is not in the middle of the array, things + % get a 'little' more complicated hn = zeros(size(x0,1),1,Nse+1); jn = hn; @@ -169,9 +169,9 @@ D = D + Pm ./ Gm .* exp(1i.*m.*phi0); end - - D = D./(2.*pi*r0); - end + end + + D = D/N0; % normalization due to angular sampling elseif strcmp('3D',dimension) % === 3-Dimensional ================================================== From 1ae3851fb10853afba7f3c8a5331a646d427aadf Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 19 May 2015 17:45:12 +0200 Subject: [PATCH 28/81] fix bug --- SFS_scattering/sound_field_mono_sphexp.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SFS_scattering/sound_field_mono_sphexp.m b/SFS_scattering/sound_field_mono_sphexp.m index de9365ca..fa6762fe 100644 --- a/SFS_scattering/sound_field_mono_sphexp.m +++ b/SFS_scattering/sound_field_mono_sphexp.m @@ -11,7 +11,7 @@ % ABnm - regular/singular spherical expansion coefficients % mode - 'R' for regular, 'S' for singular % f - frequency in Hz -% x0 - optional expansion center coordinates, default: [0, 0, 0] +% xq - optional expansion center coordinates, default: [0, 0, 0] % conf - optional configuration struct (see SFS_config) % % Output parameters: @@ -65,9 +65,9 @@ isargstruct(conf); end if nargin == nargmin - x0 = [0, 0, 0]; + xq = [0, 0, 0]; end -isargposition(x0); +isargposition(xq); %% ===== Computation ==================================================== [jn, hn, Ynm, x, y, z] = sphbasis_mono_XYZgrid(X,Y,Z,f,xq,conf); From 3f78407e04f329cdd77a8a2d75b61379a3bf4600 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Wed, 20 May 2015 15:12:25 +0200 Subject: [PATCH 29/81] fix obsolete input argument in documentation of nfchoa_sphexp driving function --- .../driving_function_mono_nfchoa_sphexp.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index 9e6c25f3..c8dea9d0 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -2,7 +2,7 @@ %computes the nfchoa driving functions for a sound field expressed by regular %spherical expansion coefficients. % -% Usage: D = driving_function_mono_nfchoa_sphexp(x0,Pnm,f,N,conf) +% Usage: D = driving_function_mono_nfchoa_sphexp(x0,Pnm,f,conf) % % Input parameters: % x0 - position of the secondary sources / m [nx3] @@ -13,7 +13,7 @@ % Output parameters: % D - driving function signal [nx1] % -% DRIVING_FUNCTION_MONO_NFCHOA_SPHEXP(x0,Pnm,f,N,conf) returns NFCHOA +% DRIVING_FUNCTION_MONO_NFCHOA_SPHEXP(x0,Pnm,f,conf) returns NFCHOA % driving signals for the given secondary sources, the virtual sound expressed % by regular spherical expansion coefficients and the frequency f. % From 44ae845e8acbad0aeec2324b03046d80b7b15904 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 22 May 2015 11:24:16 +0200 Subject: [PATCH 30/81] add nfchoa driving in harmonics domain for sphexp --- ...driving_function_mono_nfchoa_harm_sphexp.m | 187 ++++++++++++++++++ .../driving_function_mono_nfchoa_sphexp.m | 2 +- SFS_scattering/sound_field_mono_sphbasis.m | 92 +++++++++ SFS_scattering/sound_field_mono_sphexp.m | 32 +-- SFS_scattering/sphbasis_mono.m | 41 ++-- 5 files changed, 318 insertions(+), 36 deletions(-) create mode 100644 SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_harm_sphexp.m create mode 100644 SFS_scattering/sound_field_mono_sphbasis.m diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_harm_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_harm_sphexp.m new file mode 100644 index 00000000..24175b9a --- /dev/null +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_harm_sphexp.m @@ -0,0 +1,187 @@ +function Dnm = driving_function_mono_nfchoa_harm_sphexp(Pnm, f, conf) +%computes the nfchoa driving functions for a sound field expressed by regular +%spherical expansion coefficients. +% +% Usage: D = driving_function_mono_nfchoa_harm_sphexp(Pnm, f, conf) +% +% Input parameters: +% Pnm - regular spherical expansion coefficients of virtual +% sound field [nx1] +% f - frequency in Hz +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% Dnm - regular spherical expansion coefficients of driving +% function signal +% +% DRIVING_FUNCTION_MONO_NFCHOA_HARM_SPHEXP(Pnm, f, conf) returns regular +% spherical expansion coefficients of the NFCHOA driving function for a +% virtual sound expressed by regular spherical expansion coefficients +% and the frequency f. +% +% see also: driving_function_mono_nfchoa_sphexp + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 2; +nargmax = 3; +narginchk(nargmin,nargmax); +isargvector(Pnm); +isargsquaredinteger(length(Pnm)); +isargpositivescalar(f); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargvector(ABnm); +if nargin Date: Fri, 22 May 2015 12:49:57 +0200 Subject: [PATCH 31/81] some renaming and moving of files --- .../{ => kx}/driving_function_mono_sdm_kx.m | 0 .../driving_function_mono_sdm_kx_fs.m | 0 .../driving_function_mono_sdm_kx_ls.m | 0 .../driving_function_mono_sdm_kx_ps.m | 0 .../driving_function_mono_sdm_kx_pw.m | 0 .../{ => kx}/sound_field_mono_sdm_kx.m | 0 ...driving_function_mono_nfchoa_harm_sphexp.m | 0 .../sphexp}/sound_field_mono_sphbasis.m | 0 .../sphexp}/sound_field_mono_sphexp.m | 0 .../sphexp}/sphexp_access.m | 0 .../sphexp}/sphexp_bandlimit.m | 0 .../sphexp}/sphexp_index.m | 0 .../sphexp}/sphexp_mono_multiscatter.m | 0 .../sphexp}/sphexp_mono_ps.m | 0 .../sphexp}/sphexp_mono_pw.m | 0 .../sphexp}/sphexp_mono_scatter.m | 0 .../sphexp/sphexp_mono_timereverse.m | 165 +++++++----------- .../sphexp}/sphexp_mono_translation.m | 0 .../sphexp}/sphexp_translation_auxiliary.m | 0 SFS_scattering/sphbasis_mono_grid.m | 134 ++++++++++++++ 20 files changed, 199 insertions(+), 100 deletions(-) rename SFS_monochromatic/{ => kx}/driving_function_mono_sdm_kx.m (100%) rename SFS_monochromatic/{driving_functions_mono => kx}/driving_function_mono_sdm_kx_fs.m (100%) rename SFS_monochromatic/{driving_functions_mono => kx}/driving_function_mono_sdm_kx_ls.m (100%) rename SFS_monochromatic/{driving_functions_mono => kx}/driving_function_mono_sdm_kx_ps.m (100%) rename SFS_monochromatic/{driving_functions_mono => kx}/driving_function_mono_sdm_kx_pw.m (100%) rename SFS_monochromatic/{ => kx}/sound_field_mono_sdm_kx.m (100%) rename SFS_monochromatic/{driving_functions_mono => sphexp}/driving_function_mono_nfchoa_harm_sphexp.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sound_field_mono_sphbasis.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sound_field_mono_sphexp.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphexp_access.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphexp_bandlimit.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphexp_index.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphexp_mono_multiscatter.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphexp_mono_ps.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphexp_mono_pw.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphexp_mono_scatter.m (100%) rename SFS_scattering/sphbasis_mono_XYZgrid.m => SFS_monochromatic/sphexp/sphexp_mono_timereverse.m (61%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphexp_mono_translation.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphexp_translation_auxiliary.m (100%) create mode 100644 SFS_scattering/sphbasis_mono_grid.m diff --git a/SFS_monochromatic/driving_function_mono_sdm_kx.m b/SFS_monochromatic/kx/driving_function_mono_sdm_kx.m similarity index 100% rename from SFS_monochromatic/driving_function_mono_sdm_kx.m rename to SFS_monochromatic/kx/driving_function_mono_sdm_kx.m diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_sdm_kx_fs.m b/SFS_monochromatic/kx/driving_function_mono_sdm_kx_fs.m similarity index 100% rename from SFS_monochromatic/driving_functions_mono/driving_function_mono_sdm_kx_fs.m rename to SFS_monochromatic/kx/driving_function_mono_sdm_kx_fs.m diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_sdm_kx_ls.m b/SFS_monochromatic/kx/driving_function_mono_sdm_kx_ls.m similarity index 100% rename from SFS_monochromatic/driving_functions_mono/driving_function_mono_sdm_kx_ls.m rename to SFS_monochromatic/kx/driving_function_mono_sdm_kx_ls.m diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_sdm_kx_ps.m b/SFS_monochromatic/kx/driving_function_mono_sdm_kx_ps.m similarity index 100% rename from SFS_monochromatic/driving_functions_mono/driving_function_mono_sdm_kx_ps.m rename to SFS_monochromatic/kx/driving_function_mono_sdm_kx_ps.m diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_sdm_kx_pw.m b/SFS_monochromatic/kx/driving_function_mono_sdm_kx_pw.m similarity index 100% rename from SFS_monochromatic/driving_functions_mono/driving_function_mono_sdm_kx_pw.m rename to SFS_monochromatic/kx/driving_function_mono_sdm_kx_pw.m diff --git a/SFS_monochromatic/sound_field_mono_sdm_kx.m b/SFS_monochromatic/kx/sound_field_mono_sdm_kx.m similarity index 100% rename from SFS_monochromatic/sound_field_mono_sdm_kx.m rename to SFS_monochromatic/kx/sound_field_mono_sdm_kx.m diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_harm_sphexp.m b/SFS_monochromatic/sphexp/driving_function_mono_nfchoa_harm_sphexp.m similarity index 100% rename from SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_harm_sphexp.m rename to SFS_monochromatic/sphexp/driving_function_mono_nfchoa_harm_sphexp.m diff --git a/SFS_scattering/sound_field_mono_sphbasis.m b/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m similarity index 100% rename from SFS_scattering/sound_field_mono_sphbasis.m rename to SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m diff --git a/SFS_scattering/sound_field_mono_sphexp.m b/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m similarity index 100% rename from SFS_scattering/sound_field_mono_sphexp.m rename to SFS_monochromatic/sphexp/sound_field_mono_sphexp.m diff --git a/SFS_scattering/sphexp_access.m b/SFS_monochromatic/sphexp/sphexp_access.m similarity index 100% rename from SFS_scattering/sphexp_access.m rename to SFS_monochromatic/sphexp/sphexp_access.m diff --git a/SFS_scattering/sphexp_bandlimit.m b/SFS_monochromatic/sphexp/sphexp_bandlimit.m similarity index 100% rename from SFS_scattering/sphexp_bandlimit.m rename to SFS_monochromatic/sphexp/sphexp_bandlimit.m diff --git a/SFS_scattering/sphexp_index.m b/SFS_monochromatic/sphexp/sphexp_index.m similarity index 100% rename from SFS_scattering/sphexp_index.m rename to SFS_monochromatic/sphexp/sphexp_index.m diff --git a/SFS_scattering/sphexp_mono_multiscatter.m b/SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m similarity index 100% rename from SFS_scattering/sphexp_mono_multiscatter.m rename to SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m diff --git a/SFS_scattering/sphexp_mono_ps.m b/SFS_monochromatic/sphexp/sphexp_mono_ps.m similarity index 100% rename from SFS_scattering/sphexp_mono_ps.m rename to SFS_monochromatic/sphexp/sphexp_mono_ps.m diff --git a/SFS_scattering/sphexp_mono_pw.m b/SFS_monochromatic/sphexp/sphexp_mono_pw.m similarity index 100% rename from SFS_scattering/sphexp_mono_pw.m rename to SFS_monochromatic/sphexp/sphexp_mono_pw.m diff --git a/SFS_scattering/sphexp_mono_scatter.m b/SFS_monochromatic/sphexp/sphexp_mono_scatter.m similarity index 100% rename from SFS_scattering/sphexp_mono_scatter.m rename to SFS_monochromatic/sphexp/sphexp_mono_scatter.m diff --git a/SFS_scattering/sphbasis_mono_XYZgrid.m b/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m similarity index 61% rename from SFS_scattering/sphbasis_mono_XYZgrid.m rename to SFS_monochromatic/sphexp/sphexp_mono_timereverse.m index 471f749e..b5c63cc8 100644 --- a/SFS_scattering/sphbasis_mono_XYZgrid.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m @@ -1,100 +1,65 @@ -function [Jsph, H2sph, Ysph, x, y, z] = sphbasis_mono_XYZgrid(X,Y,Z,f,xq,conf) -%Evaluate basis functions for given grid in cartesian coordinates -% -% -% Usage: [Jsph, H2sph, Ysph, x, y, z] = sphbasis_mono_XYZgrid(X,Y,Z,f,xq,conf) -% -% Input parameters: -% X - x-axis / m; single value or [xmin,xmax] -% Y - y-axis / m; single value or [ymin,ymax] -% Z - z-axis / m; single value or [zmin,zmax] -% f - frequency in Hz -% xq - optional center of coordinate system -% conf - optional configuration struct (see SFS_config) -% -% Output parameters: -% Jsph - cell array of spherical bessel functions -% H2sph - cell array of spherical hankel functions of 2nd kind -% Ysph - cell array of spherical harmonics -% x - corresponding x axis / m -% y - corresponding y axis / m -% z - corresponding z axis / m -% -% SPHBASIS_MONO_XYZGRID(X,Y,Z,f,xq,conf) computes spherical basis functions -% for given grid in cartesian coordinates. This is a wrapper function for -% sphbasis_mono. -% -% see also: sphbasis_mono - -%***************************************************************************** -% Copyright (c) 2010-2014 Quality & Usability Lab, together with * -% Assessment of IP-based Applications * -% Telekom Innovation Laboratories, TU Berlin * -% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * -% * -% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * -% Universitaet Rostock * -% Richard-Wagner-Strasse 31, 18119 Rostock * -% * -% This file is part of the Sound Field Synthesis-Toolbox (SFS). * -% * -% The SFS 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 3 of the License, or (at your option) * -% any later version. * -% * -% The SFS 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, see . * -% * -% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * -% field synthesis methods like wave field synthesis or higher order * -% ambisonics. * -% * -% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * -%***************************************************************************** - -%% ===== Checking of input parameters ================================== -nargmin = 4; -nargmax = 6; -narginchk(nargmin,nargmax); -isargvector(X,Y,Z); -isargpositivescalar(f); -if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 1; +nargmax = 1; +narginchk(nargmin,nargmax); +isargvector(ABnm); + +%% ===== Variables ====================================================== +Nse = sqrt(length(ABnm)) - 1; +isargpositivescalar(Nse); +if mod(Nse,1) ~= 0 + error('%s: Length of Array must be square of an integer'); +end + +%% ===== Computation ==================================================== + +for n=0:Nse + v = sphexp_index(-n:n,n); + ABnm(v) = conj(sphexp_access(ABnm,n:-1:-n,n)); +end + +end + diff --git a/SFS_scattering/sphexp_mono_translation.m b/SFS_monochromatic/sphexp/sphexp_mono_translation.m similarity index 100% rename from SFS_scattering/sphexp_mono_translation.m rename to SFS_monochromatic/sphexp/sphexp_mono_translation.m diff --git a/SFS_scattering/sphexp_translation_auxiliary.m b/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m similarity index 100% rename from SFS_scattering/sphexp_translation_auxiliary.m rename to SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m diff --git a/SFS_scattering/sphbasis_mono_grid.m b/SFS_scattering/sphbasis_mono_grid.m new file mode 100644 index 00000000..7afa0576 --- /dev/null +++ b/SFS_scattering/sphbasis_mono_grid.m @@ -0,0 +1,134 @@ +function [jn, h2n, Ynm, x, y, z] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf) +%Evaluate spherical basis functions for given grid in cartesian coordinates +% +% +% Usage: [jn, h2n, Ynm, x, y, z] = sphbasis_mono_grid(X,Y,Z,f,xq,conf) +% +% Input parameters: +% X - x-axis / m; single value or [xmin,xmax] or nD-array +% Y - y-axis / m; single value or [ymin,ymax] or nD-array +% Z - z-axis / m; single value or [zmin,zmax] or nD-array +% Nse - maximum order of spherical basis functions +% f - frequency in Hz +% xq - optional center of coordinate system +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% jn - cell array of spherical bessel functions +% h2n - cell array of spherical hankel functions of 2nd kind +% Ynm - cell array of spherical harmonics +% x - corresponding x axis / m +% y - corresponding y axis / m +% z - corresponding z axis / m +% +% SPHBASIS_MONO_GRID(X,Y,Z,f,xq,conf) computes spherical basis functions +% for given grid in cartesian coordinates. This is a wrapper function for +% sphbasis_mono. +% For the input of X,Y,Z (DIM as a wildcard) : +% * if DIM is given as single value, the respective dimension is +% squeezed, so that dimensionality of the simulated sound field P is +% decreased by one. +% * if DIM is given as [dimmin, dimmax], a linear grid for the +% respective dimension with a resolution defined in conf.resolution is +% established +% * if DIM is given as n-dimensional array, the other dimensions have +% to be given as n-dimensional arrays of the same size or as a single value. +% Each triple of X,Y,Z is interpreted as an evaluation point in an +% customized grid. For this option, plotting and normalisation is disabled. +% +% see also: sphbasis_mono + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 5; +nargmax = 7; +narginchk(nargmin,nargmax); + +isargnumeric(X,Y,Z); +% unique index encoding which dimension is an nd-array +customGrid = (numel(X) > 2) + 2*(numel(Y) > 2) + 4*(numel(Z) > 2); +switch customGrid + case 1 + isargscalar(Y,Z); + case 2 + isargscalar(X,Z); + case 3 + isargequalsize(X,Y); isargscalar(Z); + case 4 + isargscalar(X,Y); + case 5 + isargequalsize(X,Z); isargscalar(Y); + case 6 + isargequalsize(Y,Z); isargscalar(X); + case 7 + isargequalsize(X,Y,Z); + otherwise + isargvector(X,Y,Z); +end +isargpositivescalar(f,Nse); +if nargin Date: Fri, 22 May 2015 14:12:53 +0200 Subject: [PATCH 32/81] move sphbasis function --- {SFS_scattering => SFS_monochromatic/sphexp}/sphbasis_mono.m | 0 {SFS_scattering => SFS_monochromatic/sphexp}/sphbasis_mono_grid.m | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphbasis_mono.m (100%) rename {SFS_scattering => SFS_monochromatic/sphexp}/sphbasis_mono_grid.m (100%) diff --git a/SFS_scattering/sphbasis_mono.m b/SFS_monochromatic/sphexp/sphbasis_mono.m similarity index 100% rename from SFS_scattering/sphbasis_mono.m rename to SFS_monochromatic/sphexp/sphbasis_mono.m diff --git a/SFS_scattering/sphbasis_mono_grid.m b/SFS_monochromatic/sphexp/sphbasis_mono_grid.m similarity index 100% rename from SFS_scattering/sphbasis_mono_grid.m rename to SFS_monochromatic/sphexp/sphbasis_mono_grid.m From 7e37fbc109c3b7edbe2bb405fe4e07bbf5b2f90e Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 22 May 2015 14:53:41 +0200 Subject: [PATCH 33/81] calculate sound field out of sht of driving function --- ...driving_function_mono_nfchoa_sht_sphexp.m} | 8 +- .../sphexp/sound_field_mono_nfchoa_sht.m | 85 +++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) rename SFS_monochromatic/sphexp/{driving_function_mono_nfchoa_harm_sphexp.m => driving_function_mono_nfchoa_sht_sphexp.m} (93%) create mode 100644 SFS_monochromatic/sphexp/sound_field_mono_nfchoa_sht.m diff --git a/SFS_monochromatic/sphexp/driving_function_mono_nfchoa_harm_sphexp.m b/SFS_monochromatic/sphexp/driving_function_mono_nfchoa_sht_sphexp.m similarity index 93% rename from SFS_monochromatic/sphexp/driving_function_mono_nfchoa_harm_sphexp.m rename to SFS_monochromatic/sphexp/driving_function_mono_nfchoa_sht_sphexp.m index 24175b9a..f71212f5 100644 --- a/SFS_monochromatic/sphexp/driving_function_mono_nfchoa_harm_sphexp.m +++ b/SFS_monochromatic/sphexp/driving_function_mono_nfchoa_sht_sphexp.m @@ -1,8 +1,8 @@ -function Dnm = driving_function_mono_nfchoa_harm_sphexp(Pnm, f, conf) -%computes the nfchoa driving functions for a sound field expressed by regular -%spherical expansion coefficients. +function Dnm = driving_function_mono_nfchoa_sht_sphexp(Pnm, f, conf) +%computes the spherical harmonics transform of nfchoa driving functions +%for a sound field expressed by regular spherical expansion coefficients. % -% Usage: D = driving_function_mono_nfchoa_harm_sphexp(Pnm, f, conf) +% Usage: D = driving_function_mono_nfchoa_sht_sphexp(Pnm, f, conf) % % Input parameters: % Pnm - regular spherical expansion coefficients of virtual diff --git a/SFS_monochromatic/sphexp/sound_field_mono_nfchoa_sht.m b/SFS_monochromatic/sphexp/sound_field_mono_nfchoa_sht.m new file mode 100644 index 00000000..e41dcda7 --- /dev/null +++ b/SFS_monochromatic/sphexp/sound_field_mono_nfchoa_sht.m @@ -0,0 +1,85 @@ +function [P, x, y, z] = sound_field_mono_nfchoa_sht(X,Y,Z,Dnm,f,conf) +%SOUND_FIELD_MONO_NFCHOA_SHT simulates a sound field given with the +%spherical harmonics transform of the nfchoa driving function +% +% Usage: [P, x, y, z] = sound_field_mono_sht(X,Y,Z,Dnm,f,conf) +% +% Input parameters: +% X - x-axis / m; single value or [xmin,xmax] or nD-array +% Y - y-axis / m; single value or [ymin,ymax] or nD-array +% Z - z-axis / m; single value or [zmin,zmax] or nD-array +% Dnm - spherical harmonics transform of nfchoa driving function +% f - frequency in Hz +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% P - resulting soundfield +% +% SOUND_FIELD_MONO_NFCHOA_SHT(X,Y,Z,ABnm,mode,f,conf) +% +% see also: sphbasis_mono_grid, sound_field_mono_sphexp + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 5; +nargmax = 7; +narginchk(nargmin,nargmax); +isargvector(Dnm); +isargsquaredinteger(length(Dnm)); +isargnumeric(X,Y,Z); +isargpositivescalar(f); +if nargin Date: Fri, 22 May 2015 15:00:12 +0200 Subject: [PATCH 34/81] again some renaming --- .../{sphexp => sht}/driving_function_mono_nfchoa_sht_sphexp.m | 0 SFS_monochromatic/{sphexp => sht}/sound_field_mono_nfchoa_sht.m | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename SFS_monochromatic/{sphexp => sht}/driving_function_mono_nfchoa_sht_sphexp.m (100%) rename SFS_monochromatic/{sphexp => sht}/sound_field_mono_nfchoa_sht.m (100%) diff --git a/SFS_monochromatic/sphexp/driving_function_mono_nfchoa_sht_sphexp.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m similarity index 100% rename from SFS_monochromatic/sphexp/driving_function_mono_nfchoa_sht_sphexp.m rename to SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m diff --git a/SFS_monochromatic/sphexp/sound_field_mono_nfchoa_sht.m b/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m similarity index 100% rename from SFS_monochromatic/sphexp/sound_field_mono_nfchoa_sht.m rename to SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m From f78a98e534fb39d10c5f0c8ffa902bec0d24df6e Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 22 May 2015 15:25:07 +0200 Subject: [PATCH 35/81] add Nse to input parameters instead of conf. --- SFS_monochromatic/sphexp/sphexp_mono_ps.m | 23 ++++++++-------- SFS_monochromatic/sphexp/sphexp_mono_pw.m | 20 +++++++------- .../sphexp/sphexp_mono_scatter.m | 26 +++++-------------- .../sphexp/sphexp_mono_timereverse.m | 11 +++----- .../sphexp/sphexp_mono_translation.m | 10 +++---- 5 files changed, 35 insertions(+), 55 deletions(-) diff --git a/SFS_monochromatic/sphexp/sphexp_mono_ps.m b/SFS_monochromatic/sphexp/sphexp_mono_ps.m index a3878c36..2ea0219d 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_ps.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_ps.m @@ -1,19 +1,20 @@ -function Anm = sphexp_mono_ps(xs, mode, f, xq, conf) +function Anm = sphexp_mono_ps(xs, mode, Nse, f, xq, conf) %Regular/Singular Spherical Expansion of Point Source % -% Usage: Al = sphexpR_mono_ps(xs,f,xq,conf) +% Usage: Al = sphexpR_mono_ps(xs,f,Nse,xq,conf) % % Input parameters: % xs - position of point source % mode - 'R' for regular, 'S' for singular % f - frequency +% Nse - maximum order of spherical basis functions % xq - optional expansion center coordinate % conf - optional configuration struct (see SFS_config) % % Output parameters: % Al - regular Spherical Expansion Coefficients % -% SPHEXP_MONO_PS(xs, mode, f, xq, conf) computes the regular/singular +% SPHEXP_MONO_PS(xs, mode, f, Nse, xq, conf) computes the regular/singular % Spherical Expansion Coefficients for a point source at xs. The expansion % will be done around the expansion coordinate xq: % @@ -84,11 +85,11 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 3; -nargmax = 5; +nargmin = 4; +nargmax = 6; narginchk(nargmin,nargmax); isargposition(xs); -isargpositivescalar(f); +isargpositivescalar(f, Nse); if nargin Date: Fri, 22 May 2015 16:49:40 +0200 Subject: [PATCH 36/81] bug fixing and restructuring of test scripts --- .../sht/sound_field_mono_nfchoa_sht.m | 47 +++- .../sphexp/sound_field_mono_sphbasis.m | 41 +-- .../sphexp/sound_field_mono_sphexp.m | 2 +- .../sphexp/sphexp_mono_scatter.m | 20 +- .../sphexp/sphexp_mono_translation.m | 1 - test_exp.m | 245 ------------------ test_exp_nfchoa.m | 123 +++------ test_sphexp.m | 89 +++++++ 8 files changed, 198 insertions(+), 370 deletions(-) delete mode 100644 test_exp.m create mode 100644 test_sphexp.m diff --git a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m b/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m index e41dcda7..f88a41a8 100644 --- a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m +++ b/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m @@ -53,21 +53,37 @@ %% ===== Checking of input parameters ================================== nargmin = 5; -nargmax = 7; +nargmax = 6; narginchk(nargmin,nargmax); isargvector(Dnm); isargsquaredinteger(length(Dnm)); isargnumeric(X,Y,Z); +% unique index encoding which dimension is an nd-array +customGrid = (numel(X) > 2) + 2*(numel(Y) > 2) + 4*(numel(Z) > 2); +switch customGrid + case 1 + isargscalar(Y,Z); + case 2 + isargscalar(X,Z); + case 3 + isargequalsize(X,Y); isargscalar(Z); + case 4 + isargscalar(X,Y); + case 5 + isargequalsize(X,Z); isargscalar(Y); + case 6 + isargequalsize(Y,Z); isargscalar(X); + case 7 + isargequalsize(X,Y,Z); + otherwise + isargvector(X,Y,Z); +end isargpositivescalar(f); if nargin > A R (x-x ) @@ -86,13 +87,18 @@ %% ===== Checking of input parameters ================================== nargmin = 4; -nargmax = 4; +nargmax = 5; narginchk(nargmin,nargmax); isargvector(Anm); L = length(Anm); isargsquaredinteger(L); isargscalar(sigma); isargpositivescalar(f,R); +if nargin Date: Fri, 22 May 2015 16:50:25 +0200 Subject: [PATCH 37/81] add some paths to startup scripts --- SFS_start.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SFS_start.m b/SFS_start.m index 780c5206..16f951cc 100644 --- a/SFS_start.m +++ b/SFS_start.m @@ -64,6 +64,8 @@ function SFS_start() addpath([basepath,'/SFS_ir']); addpath([basepath,'/SFS_monochromatic']); addpath([basepath,'/SFS_monochromatic/driving_functions_mono']); + addpath([basepath,'/SFS_monochromatic/sphexp']); + addpath([basepath,'/SFS_monochromatic/sht']); addpath([basepath,'/SFS_plotting']); addpath([basepath,'/SFS_scattering']); addpath([basepath,'/SFS_ssr']); From 9d5355e6a6a1a8886aa83dedb45a7263194f629e Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 22 May 2015 16:50:55 +0200 Subject: [PATCH 38/81] normalize sound field at plot --- SFS_plotting/plot_sound_field.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SFS_plotting/plot_sound_field.m b/SFS_plotting/plot_sound_field.m index 095e4a0a..442e26d0 100644 --- a/SFS_plotting/plot_sound_field.m +++ b/SFS_plotting/plot_sound_field.m @@ -167,6 +167,11 @@ function plot_sound_field(P,x,y,z,x0,conf) if usenormalisation P_dB = P_dB - max(P_dB(:)); end +else + if usenormalisation + % === Scale signal (at xref) === + P = norm_sound_field_at_xref(P,x,y,z,conf); + end end % Plotting From 4a298ded25879f098b472ddbd011733b57d8215e Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 22 May 2015 18:36:14 +0200 Subject: [PATCH 39/81] spherical expansion of line sources --- .../circexp/circexp_mono_ls.m | 74 +++++------ SFS_monochromatic/sphexp/sphexp_mono_ls.m | 116 ++++++++++++++++++ SFS_monochromatic/sphexp/sphexp_mono_ps.m | 7 +- SFS_start.m | 3 +- 4 files changed, 160 insertions(+), 40 deletions(-) rename SFS_scattering/cylexpR_mono_ls.m => SFS_monochromatic/circexp/circexp_mono_ls.m (71%) create mode 100644 SFS_monochromatic/sphexp/sphexp_mono_ls.m diff --git a/SFS_scattering/cylexpR_mono_ls.m b/SFS_monochromatic/circexp/circexp_mono_ls.m similarity index 71% rename from SFS_scattering/cylexpR_mono_ls.m rename to SFS_monochromatic/circexp/circexp_mono_ls.m index 2796e0ef..0422e77e 100644 --- a/SFS_scattering/cylexpR_mono_ls.m +++ b/SFS_monochromatic/circexp/circexp_mono_ls.m @@ -1,37 +1,42 @@ -function Al = cylexpR_mono_ls(xs,f,xq,conf) -%Regular Cylindrical Expansion of Line Source +function ABm = circexp_mono_ls(xs, mode, Nce, f, xq, conf) +%Regular/Singular Cylindrical Expansion of Line Source % -% Usage: Al = cylexpR_mono_pw(xs,f,xq,conf) +% Usage: ABm = circexp_mono_ls(xs, mode, Nce, f, xq, conf) % % Input parameters: -% xs - position of line source +% xs - position of line source +% mode - 'R' for regular, 'S' for singular +% Nse - maximum order of spherical basis functions % f - frequency % xq - optional expansion center % conf - optional configuration struct (see SFS_config) % % Output parameters: -% Al - regular cylindrical Expansion Coefficients +% ABm - regular cylindrical Expansion Coefficients % -% CYLEXPR_MONO_PW(nk,xq,f,conf) computes the regular cylindrical +% circexp_mono_ls(nk,xq,f,conf) computes the regular cylindrical % expansion coefficients for a line source. The expansion will be done % around the expansion coordinate xq: % -% \~~ oo -% p (x,f) = > A R (x-x ) -% pw /__ n=-oo n n q +% Regular Expansion: +% \~~ oo +% p (x,f) = > A R (x-x ) +% ls,R /__ n=-oo n n q % -% with the cylyndrical expansion coefficients: +% with the expansion coefficients: +% m -i +% A = --- S (x -x ) +% n 4 n s q % -% n -% A = 4pi i exp (-i*n*phi ) -% n pw +% Singular Expansion: +% \~~ oo m +% p (x,f) = > B S (x-x ) +% ls,R /__ n=-oo n n q % -% References: -% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the -% Helmholtz Equation in three -% Dimensions", ELSEVIER -% -% see also: eval_cylbasis_mono +% with the expansion coefficients): +% m -i +% A = --- R (x -x ) +% n 4 n s q %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * @@ -66,51 +71,50 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 2; -nargmax = 4; +nargmin = 4; +nargmax = 6; narginchk(nargmin,nargmax); isargposition(xs); -isargpositivescalar(f); +isargpositivescalar(f, Nce); if nargin > A R (x-x ) +% ps,R /__ n=0 /__ m=-n n n q +% +% with the expansion coefficients (Gumerov2004, eq. 3.2.2): +% m -m +% A = -i . k . S (x - x ) +% n n s q +% +% Singular Expansion: +% \~~ oo \~~ n m m +% p (x,f) = > > B S (x-x ) +% ps,S /__ n=0 /__ m=-n n n q +% +% with the expansion coefficients (Gumerov2004, eq. 3.2.2): +% m -m +% B = -i . k . R (x - x ) +% n n s q +% +% The coefficients are stored in linear arrays with index l resulting from +% m and n: +% +% m m 2 +% A = A ; B = B with l = (n+1) - (n - m) +% l n l n +% +% References: +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three +% Dimensions", ELSEVIER +% +% see also: sphexp_access sphexp_index sphbasis_mono + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 4; +nargmax = 6; +narginchk(nargmin,nargmax); +isargposition(xs); +isargpositivescalar(f, Nse); +if nargin Date: Fri, 22 May 2015 18:37:49 +0200 Subject: [PATCH 40/81] 3-dimensional nfchoa driving function in SHT-domain --- .../driving_function_mono_nfchoa_sht_sphexp.m | 16 +++- .../sht/sound_field_mono_nfchoa_sht.m | 50 +++++++++--- test_exp_nfchoa.m | 81 +++++++++++++------ 3 files changed, 107 insertions(+), 40 deletions(-) diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m index f71212f5..ccba71ee 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m @@ -90,6 +90,9 @@ %% ===== Computation ==================================================== % Calculate the driving function in time-frequency domain +% initialize empty driving signal +Dnm = zeros(size(Pnm)); + if strcmp('2D',dimension) % === 2-Dimensional ================================================== @@ -105,8 +108,6 @@ % === 2.5-Dimensional ================================================ if strcmp('default',driving_functions) - % initialize empty driving signal - Dnm = zeros(size(Pnm)); if (rref == 0) % --- Xref == Xc ------------------------------------------------- @@ -176,8 +177,15 @@ % === 3-Dimensional ================================================== if strcmp('default',driving_functions) - % --- SFS Toolbox -------------------------------------------------- - to_be_implemented; + + for n=0:Nse + Gn0 = (-1i*k) .* sphbesselh(n,2,kr0) .* sphharmonics(n, 0, pi/2, 0); + + v = sphexp_index(-n:n, n); + Dnm(v) = sqrt( (2*n+1) ./ (4*pi) ) .* Pnm(v) ./ Gn0; + end + + Dnm = Dnm./(2*pi*r0.^2); else error('%s: %s, this type of driving function is not implemented ', ... upper(mfilename), driving_functions); diff --git a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m b/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m index f88a41a8..8008d6ad 100644 --- a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m +++ b/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m @@ -88,6 +88,7 @@ %% ===== Configuration ================================================== Xc = conf.secondary_sources.center; r0 = conf.secondary_sources.size / 2; +dimension = conf.dimension; %% ===== Variables ====================================================== Nse = sqrt(length(Dnm)) - 1; @@ -101,18 +102,45 @@ % find coordinates, which are inside and outside the loudspeaker array select = sqrt((X-Xc(1)).^2 + (Y-Xc(2)).^2 + (Z-Xc(3)).^2) <= r0; -P = zeros(size(X)); +if strcmp('2D',dimension) + % === 2-Dimensional ================================================== + + error('%s: 2D not supported.',upper(mfilename)); -% regular expansion for the coordinates inside -Gnm = sphexp_mono_ps([r0, 0, 0], 'R', Nse, f, [0,0,0], conf); -Pnm = Gnm .* Dnm; -P(select) = sound_field_mono_sphexp(X(select),Y(select),Z(select), Pnm, ... - 'R', f, Xc,conf); +elseif strcmp('2.5D',dimension) + % === 2.5-Dimensional ================================================ + + % regular expansion for the coordinates inside + GnmR = 2*pi*r0*sphexp_mono_ps([r0, 0, 0], 'R', Nse, f, [0,0,0], conf); + + % singular expansion for the coordinates outside + GnmS = 2*pi*r0*sphexp_mono_ps([r0, 0, 0], 'S', Nse, f, [0,0,0], conf); + +elseif strcmp('3D',dimension) + % === 3-Dimensional ================================================== + + % regular expansion for the coordinates inside + GnmR = sphexp_mono_ps([0, 0, r0], 'R', Nse, f, [0,0,0], conf); + + % singular expansion for the coordinates outside + GnmS = sphexp_mono_ps([0, 0, r0], 'S', Nse, f, [0,0,0], conf); + + for n=0:Nse + v = sphexp_index(-n:n,n); + w = sphexp_index(0,n); + GnmR(v) = 2*pi*r0^2*sqrt(4*pi / (2*n+1))*GnmR(w); + GnmS(v) = 2*pi*r0^2*sqrt(4*pi / (2*n+1))*GnmS(w); + end +else + error('%s: the dimension %s is unknown.',upper(mfilename),dimension); +end -% singular expansion for the coordinates outside -Gnm = sphexp_mono_ps([r0, 0, 0], 'S', Nse, f, [0,0,0], conf); -Pnm = Gnm .* Dnm; -P(~select) = sound_field_mono_sphexp(X(~select),Y(~select),Z(~select), Pnm, ... - 'S', f, Xc,conf); +P = zeros(size(X)); +PnmR = GnmR .* Dnm; +P(select) = sound_field_mono_sphexp(X(select),Y(select),Z(select), PnmR, ... + 'R', f, Xc,conf); +PnmS = GnmS .* Dnm; +P(~select) = sound_field_mono_sphexp(X(~select),Y(~select),Z(~select), ... + PnmS, 'S', f, Xc,conf); end \ No newline at end of file diff --git a/test_exp_nfchoa.m b/test_exp_nfchoa.m index e7f5d5b6..9035a35d 100644 --- a/test_exp_nfchoa.m +++ b/test_exp_nfchoa.m @@ -9,17 +9,18 @@ conf.showprogress = true; % plotting +conf.plot.usedb = true; conf.plot.useplot = false; +conf.usenormalisation = false; conf.resolution = 400; -xrange = [-2 2]; +xrange = 0; yrange = [-2 2]; zrange = 0; [~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); % secondary sources -conf.dimension = '2.5D'; conf.secondary_sources.geometry = 'circular'; conf.secondary_sources.number = 200; conf.secondary_sources.size = 3; @@ -36,12 +37,14 @@ r0 = conf.secondary_sources.size / 2; %% Spherical Expansion Coefficients -% regular spherical expansion of plane wave and point source at xq -A1nm_original = sphexp_mono_pw(ns,Nse,f,xq,conf); -A2nm_original = sphexp_mono_ps(xs,'R',Nse,f,xq,conf); -% regular spherical expansion of plane wave and point source at xq+xt -A1nm = sphexp_mono_pw(ns,Nse,f,xq+xt,conf); -A2nm = sphexp_mono_ps(xs,'R',Nse,f,xq+xt,conf); +% regular spherical expansion at xq +Apwnm_original = sphexp_mono_pw(ns,Nse,f,xq,conf); +Apsnm_original = sphexp_mono_ps(xs,'R',Nse,f,xq,conf); +Alsnm_original = sphexp_mono_ls(xs,'R',Nse,f,xq,conf); +% regular spherical expansion at xq+xt +Apwnm = sphexp_mono_pw(ns,Nse,f,xq+xt,conf); +Apsnm = sphexp_mono_ps(xs,'R',Nse,f,xq+xt,conf); +Alsnm = sphexp_mono_ls(xs,'R',Nse,f,xq+xt,conf); % regular-to-regular spherical reexpansion (translatory shift) % [RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', f, conf); % shift spherical expansion back to xq @@ -49,29 +52,57 @@ % A2sph_shift = RRsph*sphexp_bandlimit(A2sph,10); %% generic NFCHOA in spatial domain +conf.dimension = '2.5D'; % loudspeakers x0 = secondary_source_positions(conf); % compute driving functions -D1 = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1nm_original, f, conf); -D2 = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2nm_original, f, conf); +Dpw = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apwnm_original, f, conf); +Dps = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apsnm_original, f, conf); +Dls = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Alsnm_original, f, conf); +% compute fields +Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw,f,conf); +Pps = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps,f,conf); +Pls = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dps,f,conf); +% plot +plot_sound_field(Ppw, x1,y1,z1, [], conf); +title('2.5D NFCHOA (spatial domain): plane wave'); +plot_sound_field(Pps, x1,y1,z1, [], conf); +title('2.5D NFCHOA (spatial domain): point source'); +plot_sound_field(Pls, x1,y1,z1, [], conf); +title('2.5D NFCHOA (spatial domain): line source'); + +%% generic 2.5D NFCHOA in spherical harmonics domain +conf.dimension = '2.5D'; +% compute driving functions +Dpwnm = driving_function_mono_nfchoa_sht_sphexp(Apwnm_original,f,conf); +Dpsnm = driving_function_mono_nfchoa_sht_sphexp(Apsnm_original,f,conf); +Dlsnm = driving_function_mono_nfchoa_sht_sphexp(Alsnm_original,f,conf); % compute fields -P1 = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1,f,conf); -P2 = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2,f,conf); +Ppw = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpwnm, f, conf); +Pps = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpsnm, f, conf); +Pls = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dlsnm, f, conf); % plot -plot_sound_field(P1, x1,y1,z1, [], conf); -title('NFCHOA (spatial domain): plane wave'); -plot_sound_field(P2, x1,y1,z1, [], conf); -title('NFCHOA (spatial domain): point source'); +plot_sound_field(Ppw, x1,y1,z1, [], conf); +title('2.5D NFCHOA (sht domain): plane wave'); +plot_sound_field(Pps, x1,y1,z1, [], conf); +title('2.5D NFCHOA (sht domain): point source'); +plot_sound_field(Pls, x1,y1,z1, [], conf); +title('2.5D NFCHOA (sht domain): line source'); -%% generice NFCHOA in spherical harmonics domain +%% generic 3D NFCHOA in spherical harmonics domain +conf.dimension = '3D'; % compute driving functions -D1nm = driving_function_mono_nfchoa_sht_sphexp(A1nm_original,f,conf); -D2nm = driving_function_mono_nfchoa_sht_sphexp(A2nm_original,f,conf); +Dpwnm = driving_function_mono_nfchoa_sht_sphexp(Apwnm_original,f,conf); +Dpsnm = driving_function_mono_nfchoa_sht_sphexp(Apsnm_original,f,conf); +Dlsnm = driving_function_mono_nfchoa_sht_sphexp(Alsnm_original,f,conf); % compute fields -P1 = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, D1nm, f, conf); -P2 = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, D2nm, f, conf); +Ppw = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpwnm, f, conf); +Pps = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpsnm, f, conf); +Pls = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dlsnm, f, conf); % plot -plot_sound_field(P1, x1,y1,z1, [], conf); -title('NFCHOA (sht domain): plane wave'); -plot_sound_field(P2, x1,y1,z1, [], conf); -title('NFCHOA (sht domain): point source'); \ No newline at end of file +plot_sound_field(Ppw, x1,y1,z1, [], conf); +title('3D NFCHOA (sht domain): plane wave'); +plot_sound_field(Pps, x1,y1,z1, [], conf); +title('3D NFCHOA (sht domain): point source'); +plot_sound_field(Pls./Plgt, x1,y1,z1, [], conf); +title('3D NFCHOA (sht domain): line source'); \ No newline at end of file From 07e796c0e78f4575ef898f5ba62add5235969a55 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 26 May 2015 17:16:31 +0200 Subject: [PATCH 41/81] fix bug related to different sizes of X,Y,Z --- .../sht/sound_field_mono_nfchoa_sht.m | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m b/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m index 8008d6ad..109dfff3 100644 --- a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m +++ b/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m @@ -95,12 +95,29 @@ %% ===== Computation ==================================================== if customGrid + switch customGrid + case 1 + Y = repmat(Y, size(X)); + Z = repmat(Z, size(X)); + case 2 + X = repmat(X, size(Y)); + Z = repmat(Z, size(Y)); + case 3 + Z = repmat(Z, size(Y)); + case 4 + X = repmat(X, size(Z)); + Y = repmat(Y, size(Z)); + case 5 + Y = repmat(Y, size(Z)); + case 6 + X = repmat(X, size(Z)); + end x = X; y = Y; z = Z; else [X,Y,Z,x,y,z] = xyz_grid(X,Y,Z,conf); end % find coordinates, which are inside and outside the loudspeaker array -select = sqrt((X-Xc(1)).^2 + (Y-Xc(2)).^2 + (Z-Xc(3)).^2) <= r0; +select = sqrt((X(:)-Xc(1)).^2 + (Y(:)-Xc(2)).^2 + (Z(:)-Xc(3)).^2) <= r0; if strcmp('2D',dimension) % === 2-Dimensional ================================================== @@ -137,10 +154,16 @@ P = zeros(size(X)); -PnmR = GnmR .* Dnm; -P(select) = sound_field_mono_sphexp(X(select),Y(select),Z(select), PnmR, ... - 'R', f, Xc,conf); -PnmS = GnmS .* Dnm; -P(~select) = sound_field_mono_sphexp(X(~select),Y(~select),Z(~select), ... - PnmS, 'S', f, Xc,conf); + +if any(select(:)) + Pnm = GnmR .* Dnm; + P(select) = sound_field_mono_sphexp(X(select),Y(select),Z(select), Pnm, ... + 'R', f, Xc,conf); +end +if any(~select(:)) + Pnm = GnmS .* Dnm; + P(~select) = sound_field_mono_sphexp(X(~select),Y(~select),Z(~select), ... + Pnm, 'S', f, Xc,conf); +end + end \ No newline at end of file From b2d713e5788c540fc5cee1204b91ad3a609fd022 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Mon, 15 Jun 2015 13:36:22 +0200 Subject: [PATCH 42/81] extend frequency parameter to vector --- .../driving_function_mono_nfchoa_sht_sphexp.m | 49 ++++++++++--------- SFS_monochromatic/sphexp/sphexp_mono_ps.m | 22 +++++---- SFS_monochromatic/sphexp/sphexp_mono_pw.m | 27 +++++----- .../sphexp/sphexp_mono_translation.m | 2 + test_exp_nfchoa.m | 2 +- 5 files changed, 52 insertions(+), 50 deletions(-) diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m index ccba71ee..f87bba61 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m @@ -6,13 +6,13 @@ % % Input parameters: % Pnm - regular spherical expansion coefficients of virtual -% sound field [nx1] -% f - frequency in Hz +% sound field [nxm] +% f - frequency in Hz [m x 1] or [1 x m] % conf - optional configuration struct (see SFS_config) % % Output parameters: % Dnm - regular spherical expansion coefficients of driving -% function signal +% function signal [n x m] % % DRIVING_FUNCTION_MONO_NFCHOA_HARM_SPHEXP(Pnm, f, conf) returns regular % spherical expansion coefficients of the NFCHOA driving function for a @@ -57,14 +57,18 @@ nargmin = 2; nargmax = 3; narginchk(nargmin,nargmax); -isargvector(Pnm); -isargsquaredinteger(length(Pnm)); -isargpositivescalar(f); +isargmatrix(Pnm); +isargsquaredinteger(size(Pnm,1)); +isargvector(f); if nargin Date: Mon, 15 Jun 2015 13:56:08 +0200 Subject: [PATCH 43/81] add help for checking if argument is squared integer --- SFS_helper/isargsquaredinteger.m | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 SFS_helper/isargsquaredinteger.m diff --git a/SFS_helper/isargsquaredinteger.m b/SFS_helper/isargsquaredinteger.m new file mode 100644 index 00000000..643bf75c --- /dev/null +++ b/SFS_helper/isargsquaredinteger.m @@ -0,0 +1,55 @@ +function isargsquaredinteger(varargin) +%ISARGSQUAREDINTEGER tests if the given arg is a scalar, which is the +%square of an integer +% +% +% Usage: isargsquaredinteger(arg1,arg2,...) +% +% Input options: +% args - list of args +% +% ISARGPOSITIVESCALAR(args) tests if all given args are a positive +% scalar and returns an error otherwise. +% +% See also: isargscalar, isargnegativescalar + +%***************************************************************************** +% Copyright (c) 2010-2015 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2015 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + + +%% ===== Checking for scalar ============================================= +for ii = 1:nargin + if ( ~isnumeric(varargin{ii}) || ~isscalar(varargin{ii}) || ... + mod(sqrt(varargin{ii}), 1) ~= 0 ) + error('%s need to be the square of an integer.',inputname(ii)); + end +end From b969f12d4527a5217e2fb5284733f9de03603fb2 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Mon, 15 Jun 2015 17:45:30 +0200 Subject: [PATCH 44/81] add conversion function for circular to spherical expansion --- .../sphexp/sphexp_convert_circexp.m | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 SFS_monochromatic/sphexp/sphexp_convert_circexp.m diff --git a/SFS_monochromatic/sphexp/sphexp_convert_circexp.m b/SFS_monochromatic/sphexp/sphexp_convert_circexp.m new file mode 100644 index 00000000..c5c0ac5c --- /dev/null +++ b/SFS_monochromatic/sphexp/sphexp_convert_circexp.m @@ -0,0 +1,66 @@ +function Anm = sphexp_convert_circexp(Am) +% compute converts circular expansion into spherical expansion coefficients +% +% Usage: Anm = sphexp_convert_circexp(Am) +% +% Input parameters: +% Am - regular circular expansion coefficients +% +% Output parameters: +% Anm - regular spherical expansion coefficients +% +% References: +% + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 1; +nargmax = 1; +narginchk(nargmin,nargmax); +isargvector(Am); +Nce = (length(Am)-1)/2; + +%% ===== Computation ==================================================== + +Anm = zeros((Nce+1).^2,1); +for m=-Nce:Nce + % for theta=0 the legendre polynom is zero if n+m is odd + for n = abs(m):2:Nce + v = sphexp_index(m,n); + Anm(v) = 4*pi.*1j.^(m-n).*sphharmonics(n,-m,0,0).*Am(m+Nce+1); + end +end + +end + From c031dc83d4f5a2ea7f5838f1cbd5229a357e0ca2 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Mon, 15 Jun 2015 19:03:46 +0200 Subject: [PATCH 45/81] fix bug --- .../driving_function_mono_nfchoa_sht_sphexp.m | 19 ++++++---- test_exp_nfchoa.m | 37 +++++++++++++++++-- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m index f87bba61..c7daa486 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m @@ -131,9 +131,9 @@ for m=-Nse:Nse v = sphexp_index(m, abs(m):Nse); % v(1) contains index for n=abs(m) - Dnm(v,:) = Pnm(v(1),:) ./ ... - ( -1i.*repmat(k.*sphbesselh(abs(m),2,kr0), length(v), 1) ... - .* sphharmonics(abs(m),-m, 0, 0) ); + Dnm(v,:) = repmat( Pnm(v(1),:) ./ ( -1i.*k.* ... + sphbesselh(abs(m),2,kr0).*sphharmonics(abs(m),-m, 0, 0) ) ... + , length(v), 1); end else % --- Xref ~= Xc -------------------------------------------------- @@ -149,8 +149,8 @@ end for m=-Nse:Nse - Pm = 0; - Gm = 0; + Pm = zeros(1,length(f)); + Gm = Pm; % for theta=0 the legendre polynom is zero if n+m is odd for n=abs(m):2:Nse factor = jn(n+1,:) .* ... @@ -159,13 +159,16 @@ sqrt( factorial(n-abs(m)) ./ factorial(n+abs(m)) ) .* ... asslegendre(n,abs(m),0); - Pm = Pm + sphexp_access(Pnm, m, n) .* factor; + v = sphexp_index(m,n); + + Pm = Pm + Pnm(v,:) .* factor; - Gm = Gm + (-1i*k) .* hn(n+1) .* sphharmonics(n, -m, 0, 0) .* factor; + Gm = Gm + (-1i*k) .* hn(n+1,:) .* sphharmonics(n, -m, 0, 0) ... + .* factor; end v = sphexp_index(m, abs(m):Nse); - Dnm(v) = Pm ./ Gm; + Dnm(v,:) = repmat( Pm./Gm, length(v), 1 ); end end Dnm = Dnm./(2*pi*r0); diff --git a/test_exp_nfchoa.m b/test_exp_nfchoa.m index af2cd7cb..53d36ebf 100644 --- a/test_exp_nfchoa.m +++ b/test_exp_nfchoa.m @@ -14,7 +14,7 @@ conf.usenormalisation = false; conf.resolution = 400; -xrange = 0; +xrange = [-2 2]; yrange = [-2 2]; zrange = 0; @@ -46,10 +46,11 @@ Apsnm = sphexp_mono_ps(xs,'R',Nse,f,xq+xt,conf); Alsnm = sphexp_mono_ls(xs,'R',Nse,f,xq+xt,conf); % regular-to-regular spherical reexpansion (translatory shift) -% [RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', f, conf); +[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', Nse, f, conf); % shift spherical expansion back to xq -% A1sph_shift = RRsph*sphexp_bandlimit(A1sph,10); -% A2sph_shift = RRsph*sphexp_bandlimit(A2sph,10); +Apwnm_shift = RRsph*sphexp_bandlimit(Apwnm,10); +Apsnm_shift = RRsph*sphexp_bandlimit(Apsnm,10); +Alsnm_shift = RRsph*sphexp_bandlimit(Alsnm,10); %% generic NFCHOA in spatial domain conf.dimension = '2.5D'; @@ -59,10 +60,18 @@ Dpw = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apwnm_original, f, conf); Dps = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apsnm_original, f, conf); Dls = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Alsnm_original, f, conf); +% compute driving functions from shifting fields +Dpw_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apwnm_shift, f, conf); +Dps_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apsnm_shift, f, conf); +Dls_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Alsnm_shift, f, conf); % compute fields Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw,f,conf); Pps = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps,f,conf); Pls = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dps,f,conf); +% compute fields from shifted driving functions +Ppw_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw_shift,f,conf); +Pps_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps_shift,f,conf); +Pls_shift = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dps_shift,f,conf); % plot plot_sound_field(Ppw, x1,y1,z1, [], conf); title('2.5D NFCHOA (spatial domain): plane wave'); @@ -70,6 +79,12 @@ title('2.5D NFCHOA (spatial domain): point source'); plot_sound_field(Pls, x1,y1,z1, [], conf); title('2.5D NFCHOA (spatial domain): line source'); +plot_sound_field(Ppw_shift, x1,y1,z1, [], conf); +title('2.5D NFCHOA (spatial domain): plane wave (shifted expansion)'); +plot_sound_field(Pps_shift, x1,y1,z1, [], conf); +title('2.5D NFCHOA (spatial domain): point source (shifted expansion)'); +plot_sound_field(Pls_shift, x1,y1,z1, [], conf); +title('2.5D NFCHOA (spatial domain): line source (shifted expansion)'); %% generic 2.5D NFCHOA in spherical harmonics domain conf.dimension = '2.5D'; @@ -77,10 +92,18 @@ Dpwnm = driving_function_mono_nfchoa_sht_sphexp(Apwnm_original,f,conf); Dpsnm = driving_function_mono_nfchoa_sht_sphexp(Apsnm_original,f,conf); Dlsnm = driving_function_mono_nfchoa_sht_sphexp(Alsnm_original,f,conf); +% compute driving functions from shifting fields +Dpwnm_shift = driving_function_mono_nfchoa_sht_sphexp(Apwnm_shift, f, conf); +Dpsnm_shift = driving_function_mono_nfchoa_sht_sphexp(Apsnm_shift, f, conf); +Dlsnm_shift = driving_function_mono_nfchoa_sht_sphexp(Alsnm_shift, f, conf); % compute fields Ppw = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpwnm, f, conf); Pps = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpsnm, f, conf); Pls = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dlsnm, f, conf); +% compute fields from shifted driving functions +Ppw_shift = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpwnm_shift, f, conf); +Pps_shift = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpsnm_shift, f, conf); +Pls_shift = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dlsnm_shift, f, conf); % plot plot_sound_field(Ppw, x1,y1,z1, [], conf); title('2.5D NFCHOA (sht domain): plane wave'); @@ -88,6 +111,12 @@ title('2.5D NFCHOA (sht domain): point source'); plot_sound_field(Pls, x1,y1,z1, [], conf); title('2.5D NFCHOA (sht domain): line source'); +plot_sound_field(Ppw_shift, x1,y1,z1, [], conf); +title('2.5D NFCHOA (spatial domain): plane wave (shifted expansion)'); +plot_sound_field(Pps_shift, x1,y1,z1, [], conf); +title('2.5D NFCHOA (spatial domain): point source (shifted expansion)'); +plot_sound_field(Pls_shift, x1,y1,z1, [], conf); +title('2.5D NFCHOA (spatial domain): line source (shifted expansion)'); %% generic 3D NFCHOA in spherical harmonics domain conf.dimension = '3D'; From 65836e198a81094dd8aba4f18b82cf0e748de767 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 16 Jun 2015 14:57:00 +0200 Subject: [PATCH 46/81] add functions to compute truncation order after Kennedy --- .../circexp/circexp_truncation_order.m | 78 +++++++++++++++++++ .../sphexp/sphexp_truncation_order.m | 78 +++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 SFS_monochromatic/circexp/circexp_truncation_order.m create mode 100644 SFS_monochromatic/sphexp/sphexp_truncation_order.m diff --git a/SFS_monochromatic/circexp/circexp_truncation_order.m b/SFS_monochromatic/circexp/circexp_truncation_order.m new file mode 100644 index 00000000..36fb2774 --- /dev/null +++ b/SFS_monochromatic/circexp/circexp_truncation_order.m @@ -0,0 +1,78 @@ +function Nce = circexp_truncation_order(r, f, nmse, conf) +%Truncation order for circular expansion of an arbitrary sound field +% +% Usage: Nce = circexp_truncation_orde(r, f, epsilon, conf) +% +% Input parameters: +% r - max 2D distance from expansion center / m +% f - frequency / Hz +% nmse - maximum bound for normalized mean squared error +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% Nse - Maximum order for circular expansion +% +% CIRCEXP_TRUNCATION_ORDER(r, f, epsilon, conf) yields the order up to which +% a the circular expansion coefficients of an arbitrary sound field have +% be summed up. For a given frequency and maximum radius the normalized +% truncation mean squared error is below the specified error bound (nmse). +% +% References: +% Kennedy et al. (2007) - "Intrinsic Limits of Dimensionality and +% Richness in Random Multipath Fields", +% IEEE Transactions on Signal Processing + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargpositivescalar(f,r,nmse); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargpositivescalar(f,r,nmse); +if nargin Date: Tue, 16 Jun 2015 18:11:51 +0200 Subject: [PATCH 47/81] re-structure circular expansion and nfchoa/wfs stuff related to it --- SFS_general/besselj_derived.m | 62 ++++ SFS_monochromatic/circexp/circexp_mono_ls.m | 21 +- .../circexp/circexp_mono_pw.m | 43 +-- .../circexp/circexp_mono_scatter.m | 47 ++- .../circexp/circexp_mono_timereverse.m | 59 ++++ .../circexp/circexp_truncation_order.m | 4 +- ....m => driving_function_mono_wfs_circexp.m} | 67 ++-- .../driving_function_mono_wfs_sphexp.m | 16 +- .../sphexp/sphexp_mono_scatter.m | 16 +- .../{sphexp_bandlimit.m => sphexp_truncate.m} | 22 +- test_exp_nfchoa.m | 73 +++-- test_exp_wfs.m | 297 ++++++++---------- 12 files changed, 407 insertions(+), 320 deletions(-) create mode 100644 SFS_general/besselj_derived.m rename SFS_scattering/cylexpR_mono_pw.m => SFS_monochromatic/circexp/circexp_mono_pw.m (80%) rename SFS_scattering/cylexpS_mono_scatter.m => SFS_monochromatic/circexp/circexp_mono_scatter.m (62%) create mode 100644 SFS_monochromatic/circexp/circexp_mono_timereverse.m rename SFS_monochromatic/driving_functions_mono/{driving_function_mono_wfs_cylexpS.m => driving_function_mono_wfs_circexp.m} (78%) rename SFS_monochromatic/sphexp/{sphexp_bandlimit.m => sphexp_truncate.m} (84%) diff --git a/SFS_general/besselj_derived.m b/SFS_general/besselj_derived.m new file mode 100644 index 00000000..5337ed53 --- /dev/null +++ b/SFS_general/besselj_derived.m @@ -0,0 +1,62 @@ +function out = besselj_derived(nu,z) +% BESSELJ_DERIVED derivative of cylindrical bessel function of order nu, and argument z +% +% Usage: out = besselh_derived(nu,z) +% +% Input parameters: +% nu - order of bessel function +% z - argument of bessel function +% +% Output parameters: +% out - value of bessel function at point z +% +% BESSELJ_DERIVED(nu,z) derivation of cylindrical bessel function of +% order nu, and argument z +% +% References: +% (4.1-51) in Ziomek (1995) - "Fundamentals of acoustic field theory +% and space-time signal processing" +% +% see also: besselj + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking input parameters ======================================= +nargmin = 2; +nargmax = 2; +narginchk(nargmin,nargmax); +isargscalar(nu) +isargnumeric(z) + +%% ===== Computation ===================================================== +out = 0.5*(besselj(nu-1,z) - besselj(nu+1,z)); \ No newline at end of file diff --git a/SFS_monochromatic/circexp/circexp_mono_ls.m b/SFS_monochromatic/circexp/circexp_mono_ls.m index 0422e77e..d7e05f41 100644 --- a/SFS_monochromatic/circexp/circexp_mono_ls.m +++ b/SFS_monochromatic/circexp/circexp_mono_ls.m @@ -1,20 +1,20 @@ function ABm = circexp_mono_ls(xs, mode, Nce, f, xq, conf) -%Regular/Singular Cylindrical Expansion of Line Source +%regular/singular circular expansion of line source % % Usage: ABm = circexp_mono_ls(xs, mode, Nce, f, xq, conf) % % Input parameters: % xs - position of line source % mode - 'R' for regular, 'S' for singular -% Nse - maximum order of spherical basis functions -% f - frequency -% xq - optional expansion center +% Nce - maximum order of circular basis functions +% f - frequency / Hz [1 x m] or [m x 1] +% xq - optional expansion center / m [1 x 3] % conf - optional configuration struct (see SFS_config) % % Output parameters: % ABm - regular cylindrical Expansion Coefficients % -% circexp_mono_ls(nk,xq,f,conf) computes the regular cylindrical +% CIRCEXP_MONO_LS(xs, mode, Nce, f, xq, conf) computes the regular circular % expansion coefficients for a line source. The expansion will be done % around the expansion coordinate xq: % @@ -75,7 +75,9 @@ nargmax = 6; narginchk(nargmin,nargmax); isargposition(xs); -isargpositivescalar(f, Nce); +isargchar(mode); +isargpositivescalar(Nce); +isargvector(f); if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 1; +nargmax = 1; +narginchk(nargmin,nargmax); +isargmatrix(Pm); +if mod(size(Pm, 1)-1, 2) ~= 0 + error('Number of row of %s has be to odd', inputname(Pm)); +end + +%% ===== Computation ==================================================== +Nce = (size(Pm,1)-1) / 2; + +Pm = conj(Pm(end:-1:1,:)).*(-1).^(-Nce:Nce).'; + +end + diff --git a/SFS_monochromatic/circexp/circexp_truncation_order.m b/SFS_monochromatic/circexp/circexp_truncation_order.m index 36fb2774..806fdf72 100644 --- a/SFS_monochromatic/circexp/circexp_truncation_order.m +++ b/SFS_monochromatic/circexp/circexp_truncation_order.m @@ -1,7 +1,7 @@ function Nce = circexp_truncation_order(r, f, nmse, conf) %Truncation order for circular expansion of an arbitrary sound field % -% Usage: Nce = circexp_truncation_orde(r, f, epsilon, conf) +% Usage: Nce = circexp_truncation_order(r, f, epsilon, conf) % % Input parameters: % r - max 2D distance from expansion center / m @@ -10,7 +10,7 @@ % conf - optional configuration struct (see SFS_config) % % Output parameters: -% Nse - Maximum order for circular expansion +% Nce - Maximum order for circular expansion % % CIRCEXP_TRUNCATION_ORDER(r, f, epsilon, conf) yields the order up to which % a the circular expansion coefficients of an arbitrary sound field have diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m similarity index 78% rename from SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m rename to SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m index 61d0f106..b5a17f20 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_cylexpS.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m @@ -1,21 +1,22 @@ -function D = driving_function_mono_wfs_cylexpS(x0,n0,Bl,f,xq,conf) -%DRIVING_FUNCTION_MONO_WFS_CYLEXPS computes the time reversed wfs driving -%functions for a sound field expressed by singular cylindrical expansion coefficients. +function D = driving_function_mono_wfs_circexp(x0,n0,Pm,mode,f,xq,conf) +%computes the time reversed wfs driving functions for a sound field expressed +%by singular cylindrical expansion coefficients. % -% Usage: D = driving_function_mono_wfs_cylexpS(x0,n0,Bl,f,xq,conf) +% Usage: D = driving_function_mono_wfs_circexp(x0,n0,Pm,mode,f,xq,conf) % % Input parameters: % x0 - position of the secondary sources / m [nx3] % n0 - directions of the secondary sources / m [nx3] -% Bl - singular spherical expansion coefficients of sound field -% f - frequency in Hz +% Pm - circular expansion coefficients of sound field +% mode - 'R' for regular expansion, 'S' for singular expansion +% f - frequency / Hz % xq - optional expansion center coordinates, default: [0, 0, 0] % conf - optional configuration struct (see SFS_config) % % Output parameters: % D - driving function signal [nx1] % -% DRIVING_FUNCTION_MONO_WFS_CYLEXPS(x0,n0,Bl,f,xq,conf) +% DRIVING_FUNCTION_MONO_WFS_CIRCEXP(x0,n0,Pm,mode,f,xq,conf) % % see also: driving_function_mono_wfs_sphexpS % @@ -58,8 +59,8 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 4; -nargmax = 6; +nargmin = 5; +nargmax = 7; narginchk(nargmin,nargmax); isargmatrix(x0,n0); isargpositivescalar(f); @@ -77,26 +78,22 @@ c = conf.c; dimension = conf.dimension; driving_functions = conf.driving_functions; -Nce = conf.scattering.Nce; -showprogress = conf.showprogress; %% ===== Computation ==================================================== -% Calculate the driving function in time-frequency domain - +Nce = (size(Pm, 1)-1)/2; % apply shift to the center of expansion xq x = x0(:,1)-xq(1); y = x0(:,2)-xq(2); -z = x0(:,3)-xq(3); % conversion to cylindrical coordinates -r = sqrt(x.^2 + y.^2); -phi = atan2(y,x); +r0 = sqrt(x.^2 + y.^2); +phi0 = atan2(y,x); % frequency depended stuff omega = 2*pi*f; k = omega/c; -kr = k.*r; +kr0 = k.*r0; % gradient in spherical coordinates Gradr = zeros(size(x0,1),1); @@ -106,17 +103,29 @@ % directional weights for conversion spherical gradient into carthesian % coordinates + point product with normal vector n0 (directional derivative % in cartesian coordinates) -Sn0r = cos(phi).*n0(:,1)... - + sin(phi).*n0(:,2); -Sn0phi = -sin(phi).*n0(:,1)... - + cos(phi).*n0(:,2); +Sn0r = cos(phi0).*n0(:,1)... + + sin(phi0).*n0(:,2); +Sn0phi = -sin(phi0).*n0(:,1)... + + cos(phi0).*n0(:,2); Sn0z = n0(:,3); +% select suitable basis function +if strcmp('R', mode) + circbasis = @besselj; + circbasis_derived = @besselj_derived; +elseif strcmp('S', mode) + circbasis = @(nu,z) besselh(nu,2,z); + circbasis_derived = @(nu,z) besselh_derived(nu,2,z); +else + error('unknown mode:'); +end + +%% ===== Computation ==================================================== +% Calculate the driving function in time-frequency domain + % indexing the expansion coefficients -L = 2*Nce+1; l = 0; - if strcmp('2D',dimension) || strcmp('3D',dimension) % === 2- or 3-Dimensional ============================================ @@ -139,16 +148,14 @@ for n=-Nce:Nce l = l + 1; - h_prime = k.*besselh_derived(n,2,kr); - h = besselh(n, 2, kr); - Yn = exp(1j.*n.*phi); - Gradr = Gradr + ( Bl(l).*h_prime.*Yn ); - Gradphi = Gradphi + 1./r.*( Bl(l).*h.*1j.*n.*Yn ); - if showprogress, progress_bar(l,L); end % progress bar + cn_prime = k.*circbasis_derived(n,kr0); + cn = circbasis(n,kr0); + Yn = exp(1j.*n.*phi0); + Gradr = Gradr + ( Pm(l).*cn_prime.*Yn ); + Gradphi = Gradphi + 1./r0.*( Pm(l).*cn.*1j.*n.*Yn ); end % directional gradient + time reversion (conjugate complex) D = Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0z.*Gradz; - D = -conj(D); else error(['%s: %s, this type of driving function is not implemented ', ... 'for a 2D/3D line source.'],upper(mfilename),driving_functions); diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m index 66a54578..7ca66a8f 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m @@ -1,4 +1,4 @@ -function D = driving_function_mono_wfs_sphexp(x0,n0,ABnm,mode,f,xq,conf) +function D = driving_function_mono_wfs_sphexp(x0,n0,Pnm,mode,f,xq,conf) %computes the wfs driving functions for a sound field expressed by spherical %expansion coefficients. % @@ -7,7 +7,7 @@ % Input parameters: % x0 - position of the secondary sources / m [nx3] % n0 - directions of the secondary sources / m [nx3] -% ABnm - singular spherical expansion coefficients of sound field +% Pnm - singular spherical expansion coefficients of sound field % mode - 'R' for regular expansion, 'S' for singular expansion % f - frequency in Hz % xq - optional expansion center coordinates, default: [0, 0, 0] @@ -63,6 +63,7 @@ nargmax = 7; narginchk(nargmin,nargmax); isargmatrix(x0,n0); +isargvector(Pnm); isargpositivescalar(f); isargchar(mode); if nargin length(Anm) ) +if any( (N^2 + 1) > size(Anm, 1) ) error('%s: order(%d) exceeds size of array',upper(mfilename), N); end %% ===== Computation ==================================================== -v = sphexp_index(+N,N); -Anm(v+1:end) = 0; +v = sphexp_index(+N,N); % last element array is n=N, m=+N +Anm(v+1:end,:) = 0; end diff --git a/test_exp_nfchoa.m b/test_exp_nfchoa.m index 53d36ebf..8a0af8ca 100644 --- a/test_exp_nfchoa.m +++ b/test_exp_nfchoa.m @@ -9,7 +9,7 @@ conf.showprogress = true; % plotting -conf.plot.usedb = true; +conf.plot.usedb = false; conf.plot.useplot = false; conf.usenormalisation = false; conf.resolution = 400; @@ -22,56 +22,63 @@ % secondary sources conf.secondary_sources.geometry = 'circular'; -conf.secondary_sources.number = 200; +conf.secondary_sources.number = 56; conf.secondary_sources.size = 3; conf.secondary_sources.center = [0, 0, 0]; +f = 1000; ns = [0, -1, 0]; % propagation direction of plane wave xs = [0, 2, 0]; % position of point source -f = 300; -Nse = 10; -xq = conf.secondary_sources.center; -xt = [ 0.5, 0.5, 0]; -conf.xref = xq; -r0 = conf.secondary_sources.size / 2; +xq = conf.secondary_sources.center; % expansion center +conf.xref = xq; % reference position + +xt = [ 0.5, 0.5, 0]; % position of the sweet spot +rt = 0.3; % "size" of the sweet spot +Ncet = circexp_truncation_order(norm(xt)+rt, f, 1e-6, conf); % 2.5DHOA order for translation +Nce = circexp_truncation_order(rt, f, 1e-6, conf); % 2.5DHOA order for sweet spot +Nse = sphexp_truncation_order(rt, f, 1e-6, conf); % 3DHOA order for sweet spot %% Spherical Expansion Coefficients % regular spherical expansion at xq -Apwnm_original = sphexp_mono_pw(ns,Nse,f,xq,conf); -Apsnm_original = sphexp_mono_ps(xs,'R',Nse,f,xq,conf); -Alsnm_original = sphexp_mono_ls(xs,'R',Nse,f,xq,conf); +Apwnm_25D = sphexp_mono_pw(ns, Nce,f,xq,conf); +Apsnm_25D = sphexp_mono_ps(xs,'R', Nce,f,xq,conf); +Alsnm_25D = sphexp_mono_ls(xs,'R', Nce,f,xq,conf); +% regular spherical expansion at xq +Apwnm_3D = sphexp_mono_pw(ns, Nse,f,xq,conf); +Apsnm_3D = sphexp_mono_ps(xs,'R', Nse,f,xq,conf); +Alsnm_3D = sphexp_mono_ls(xs,'R', Nse,f,xq,conf); % regular spherical expansion at xq+xt -Apwnm = sphexp_mono_pw(ns,Nse,f,xq+xt,conf); -Apsnm = sphexp_mono_ps(xs,'R',Nse,f,xq+xt,conf); -Alsnm = sphexp_mono_ls(xs,'R',Nse,f,xq+xt,conf); +Apwnm = sphexp_mono_pw(ns,Ncet,f,xq+xt,conf); +Apsnm = sphexp_mono_ps(xs,'R',Ncet,f,xq+xt,conf); +Alsnm = sphexp_mono_ls(xs,'R',Ncet,f,xq+xt,conf); % regular-to-regular spherical reexpansion (translatory shift) -[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', Nse, f, conf); +[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', Ncet, f, conf); % shift spherical expansion back to xq -Apwnm_shift = RRsph*sphexp_bandlimit(Apwnm,10); -Apsnm_shift = RRsph*sphexp_bandlimit(Apsnm,10); -Alsnm_shift = RRsph*sphexp_bandlimit(Alsnm,10); +Apwnm_shift = RRsph*sphexp_truncate(Apwnm, Nce); +Apsnm_shift = RRsph*sphexp_truncate(Apsnm, Nce); +Alsnm_shift = RRsph*sphexp_truncate(Alsnm, Nce); %% generic NFCHOA in spatial domain conf.dimension = '2.5D'; % loudspeakers x0 = secondary_source_positions(conf); % compute driving functions -Dpw = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apwnm_original, f, conf); -Dps = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apsnm_original, f, conf); -Dls = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Alsnm_original, f, conf); -% compute driving functions from shifting fields +Dpw = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apwnm_25D, f, conf); +Dps = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apsnm_25D, f, conf); +Dls = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Alsnm_25D, f, conf); +% compute driving functions from shifted fields Dpw_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apwnm_shift, f, conf); Dps_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apsnm_shift, f, conf); Dls_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Alsnm_shift, f, conf); % compute fields Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw,f,conf); Pps = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps,f,conf); -Pls = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dps,f,conf); +Pls = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dls,f,conf); % compute fields from shifted driving functions Ppw_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw_shift,f,conf); Pps_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps_shift,f,conf); -Pls_shift = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dps_shift,f,conf); +Pls_shift = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dls_shift,f,conf); % plot plot_sound_field(Ppw, x1,y1,z1, [], conf); title('2.5D NFCHOA (spatial domain): plane wave'); @@ -88,11 +95,11 @@ %% generic 2.5D NFCHOA in spherical harmonics domain conf.dimension = '2.5D'; -% compute driving functions -Dpwnm = driving_function_mono_nfchoa_sht_sphexp(Apwnm_original,f,conf); -Dpsnm = driving_function_mono_nfchoa_sht_sphexp(Apsnm_original,f,conf); -Dlsnm = driving_function_mono_nfchoa_sht_sphexp(Alsnm_original,f,conf); -% compute driving functions from shifting fields +% compute sht of driving functions +Dpwnm = driving_function_mono_nfchoa_sht_sphexp(Apwnm_25D,f,conf); +Dpsnm = driving_function_mono_nfchoa_sht_sphexp(Apsnm_25D,f,conf); +Dlsnm = driving_function_mono_nfchoa_sht_sphexp(Alsnm_25D,f,conf); +% compute sht of driving functions from shifted fields Dpwnm_shift = driving_function_mono_nfchoa_sht_sphexp(Apwnm_shift, f, conf); Dpsnm_shift = driving_function_mono_nfchoa_sht_sphexp(Apsnm_shift, f, conf); Dlsnm_shift = driving_function_mono_nfchoa_sht_sphexp(Alsnm_shift, f, conf); @@ -120,10 +127,10 @@ %% generic 3D NFCHOA in spherical harmonics domain conf.dimension = '3D'; -% compute driving functions -Dpwnm = driving_function_mono_nfchoa_sht_sphexp(Apwnm_original,f,conf); -Dpsnm = driving_function_mono_nfchoa_sht_sphexp(Apsnm_original,f,conf); -Dlsnm = driving_function_mono_nfchoa_sht_sphexp(Alsnm_original,f,conf); +% compute sht of driving functions +Dpwnm = driving_function_mono_nfchoa_sht_sphexp(Apwnm_3D,f,conf); +Dpsnm = driving_function_mono_nfchoa_sht_sphexp(Apsnm_3D,f,conf); +Dlsnm = driving_function_mono_nfchoa_sht_sphexp(Alsnm_3D,f,conf); % compute fields Ppw = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpwnm, f, conf); Pps = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpsnm, f, conf); diff --git a/test_exp_wfs.m b/test_exp_wfs.m index 86fff5ef..04fa1ec2 100644 --- a/test_exp_wfs.m +++ b/test_exp_wfs.m @@ -6,196 +6,159 @@ %% Parameters conf = SFS_config_example; - +conf.showprogress = true; conf.dimension = '2.5D'; -conf.secondary_sources.geometry = 'linear'; -conf.secondary_sources.number = 60; -conf.secondary_sources.size = 4; -conf.secondary_sources.center = [0, 0, 0]; +% plotting +conf.plot.usedb = false; conf.plot.useplot = false; +conf.usenormalisation = true; +conf.resolution = 300; -conf.scattering.Nse = 23; -conf.scattering.Nce = 23; - -conf.showprogress = true; -conf.resolution = 400; - -ns = [0, -1, 0]; % propagation direction of plane wave -xs = [0, 1.0, 0]; % position of point source -f = 1200; xrange = [-2 2]; -yrange = [-2 2]; +yrange = [-4 0]; zrange = 0; -% scatterer -sigma = inf; % admittance of scatterer (inf to soft scatterer) -R = 0.3; -xq = [ 0, -1, 0]; -xt = [ 0.5, 0.5, 0]; -conf.xref = xq; - -display(conf.scattering) - -%% Spherical Expansion -% spherical expansion -A1sph = sphexp_mono_pw(ns,f,xq,conf); -A1sph_shift = sphexp_mono_pw(ns,f,xq+xt,conf); -A2sph = sphexp_mono_ps(xs,'R',f,xq,conf); -A2sph_shift = sphexp_mono_ps(xs,'R', f,xq+xt,conf); -% regular-to-regular spherical reexpansion (translatory shift) -[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', f, conf); -A1spht = RRsph*A1sph; -A2spht = RRsph*A2sph; - -% Evaluate spherical basis functions -[Jsphn, Hsphn, Ysphnm] = ... - sphbasis_mono_XYZgrid(xrange,yrange,zrange,f,xq,conf); -% -[Jsphnt, Hsphnt, Ysphnmt] = ... - sphbasis_mono_XYZgrid(xrange,yrange,zrange,f,xq+xt,conf); - -% compute fields -P1sph = sound_field_mono_basis(A1sph, Jsphn, Ysphnm, conf); -P1sph_shift = sound_field_mono_basis(A1sph_shift, Jsphnt, Ysphnmt, conf); -P1spht = sound_field_mono_basis(A1spht, Jsphnt, Ysphnmt, conf); -P2sph = sound_field_mono_basis(A2sph, Jsphn, Ysphnm, conf); -P2sph_shift = sound_field_mono_basis(A2sph_shift, Jsphnt, Ysphnmt, conf); -P2spht = sound_field_mono_basis(A2spht, Jsphnt, Ysphnmt, conf); - -% plot [~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); -plot_sound_field(P1sph ,x1,y1,z1, [], conf); -plot_scatterer(xq,R); -title('plane wave'); -plot_sound_field(P1sph_shift ,x1,y1,z1, [], conf); -plot_scatterer(xq,R); -title('plane wave (shifted expansion)'); -plot_sound_field(P1spht ,x1,y1,z1, [], conf); -plot_scatterer(xq,R); -title('plane wave (shifted reexpansion)'); -plot_sound_field(P2sph ,x1,y1,z1, [], conf); -plot_scatterer(xq,R); -title('point source'); -plot_sound_field(P2sph_shift ,x1,y1,z1, [], conf); -plot_scatterer(xq,R); -title('point source (shifted expansion)'); -plot_sound_field(P2spht ,x1,y1,z1, [], conf); -plot_scatterer(xq,R); -title('point source (shifted reexpansion)'); - -%% Scattering with Sphere -% scatterer is assumed to be located at coordinates origin -B1sph = sphexp_mono_scatter(A1sph, R, sigma, f, conf); -B2sph = sphexp_mono_scatter(A2sph, R, sigma, f, conf); - -% compute fields -P1sph_scatter = sound_field_mono_basis(A1sph, Hsphn, Ysphnm, conf); -P2sph_scatter = sound_field_mono_basis(A2sph, Hsphn, Ysphnm, conf); +% secondary sources +conf.secondary_sources.geometry = 'linear'; +conf.secondary_sources.number = 64; +conf.secondary_sources.size = 4; +conf.secondary_sources.center = [0, 0, 0]; -%% WFS Reproduction of Spherical Expansion -% regular spherical expansion of plane wave and point source -A1sph = sphexp_mono_pw(ns,f,xq,conf); -A2sph = sphexp_mono_ps(xs,'R',f,xq,conf); -% loudspeakers +f = 1000; +ns = [0, -1, 0]; % propagation direction of plane wave +xs = [0, 2, 0]; % position of point source +ls = xs; % position of line source + +xq = [0 -2 0]; % expansion center +conf.xref = xq; % reference position + +xt = [ 0.5, 0.5, 0]; % position of the sweet spot +rt = 1.0; % "size" of the sweet spot +Nce = circexp_truncation_order(rt, f, 1e-6, conf); % 2.5DHOA order for sweet spot + +sigma = inf; % (inf for sound soft scatterer) + +%% Spherical Expansion Coefficients +% regular spherical expansion at xq +Apwnm = sphexp_mono_pw(ns, Nce,f,xq,conf); +Apsnm = sphexp_mono_ps(xs,'R', Nce,f,xq,conf); +Alsnm = sphexp_mono_ls(xs,'R', Nce,f,xq,conf); +% regular spherical expansion at xq+xt +Apwnm_t = sphexp_mono_pw(ns,Nce,f,xq+xt,conf); +Apsnm_t = sphexp_mono_ps(xs,'R',Nce,f,xq+xt,conf); +Alsnm_t = sphexp_mono_ls(xs,'R',Nce,f,xq+xt,conf); +% compute timereversed incident field +Apwnm_rev = sphexp_mono_timereverse(Apwnm); +Apsnm_rev = sphexp_mono_timereverse(Apsnm); +Alsnm_rev = sphexp_mono_timereverse(Alsnm); +% compute timereversed incident field +Apwnm_t_rev = sphexp_mono_timereverse(Apwnm_t); +Apsnm_t_rev = sphexp_mono_timereverse(Apsnm_t); +Alsnm_t_rev = sphexp_mono_timereverse(Alsnm_t); +% scatterer is assumed to be located at the expansion center (i.e. xq) +Bpwnm = sphexp_mono_scatter(Apwnm_rev, rt, sigma, f, conf); +Bpsnm = sphexp_mono_scatter(Apsnm_rev, rt, sigma, f, conf); +Blsnm = sphexp_mono_scatter(Alsnm_rev, rt, sigma, f, conf); +% scatterer is assumed to be located at the expansion center (i.e. xq+xt) +Bpwnm_t = sphexp_mono_scatter(Apwnm_t_rev, rt, sigma, f, conf); +Bpsnm_t = sphexp_mono_scatter(Apsnm_t_rev, rt, sigma, f, conf); +Blsnm_t = sphexp_mono_scatter(Alsnm_t_rev, rt, sigma, f, conf); + +%% Circular Expansion Coefficients +% regular circular expansion at xq +Apwm = circexp_mono_pw(ns, Nce,f,xq,conf); +Alsm = circexp_mono_ls(xs, 'R', Nce,f,xq,conf); +% regular circular expansion at xq+xt +Apwm_t = circexp_mono_pw(ns,Nce,f,xq+xt,conf); +Alsm_t = circexp_mono_ls(xs, 'R', Nce,f,xq+xt,conf); +% compute timereversed incident field +Apwm_rev = circexp_mono_timereverse(Apwm); +Alsm_rev = circexp_mono_timereverse(Alsm); +% compute timereversed incident field +Apwm_t_rev = circexp_mono_timereverse(Apwm_t); +Alsm_t_rev = circexp_mono_timereverse(Alsm_t); +% scatterer is assumed to be located at the expansion center (i.e. xq) +Bpwm = circexp_mono_scatter(Apwm_rev, rt, sigma, f, conf); +Blsm = circexp_mono_scatter(Alsm_rev, rt, sigma, f, conf); +% scatterer is assumed to be located at the expansion center (i.e. xq+xt) +Bpwm_t = circexp_mono_scatter(Apwm_t_rev, rt, sigma, f, conf); +Blsm_t = circexp_mono_scatter(Alsm_t_rev, rt, sigma, f, conf); + +%% generic WFS in spatial domain using Spherical Expansion Coefficients +conf.dimension = '2.5D'; +% loudspeakers (TODO: implicit selection of loudspeakers in driving +% function) x0 = secondary_source_positions(conf); -x0pw = secondary_source_selection(x0,ns,'pw'); -x0ps = secondary_source_selection(x0,xs,'ps'); -% compute driving functions and sound fields -D1sph = driving_function_mono_wfs_sphexp(x0pw(:,1:3),x0pw(:,4:6),A1sph,'R',f,xq,conf); -D2sph = driving_function_mono_wfs_sphexp(x0ps(:,1:3),x0ps(:,4:6),A2sph,'R',f,xq,conf); +% compute driving functions +Dpw = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Apwnm,'R',f,xq,conf); +Dps = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Apsnm,'R',f,xq,conf); +Dls = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Alsnm,'R',f,xq,conf); % compute fields -P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0pw,'ps',D1sph,f,conf); -P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0ps,'ps',D2sph,f,conf); +Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw,f,conf); +Pps = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps,f,conf); +Pls = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dls,f,conf); % plot -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); - -plot_sound_field(P1sphwfs ,x1,y1,z1, x0pw, conf); -title('plane wave'); -plot_sound_field(P2sphwfs ,x1,y1,z1, x0ps, conf); -title('point source'); - -%% WFS Reproduction of focused source using time reversal -% singular spherical expansion of point source -B1sph = sphexp_mono_ps(xs, 'S', f, xs, conf); -% loudspeakers +plot_sound_field(Ppw, x1,y1,z1, [], conf); +title('2.5D WFS with spherical expansion (spatial domain): plane wave'); +plot_sound_field(Pps, x1,y1,z1, [], conf); +title('2.5D WFS with spherical expansion (spatial domain): point source'); +plot_sound_field(Pls, x1,y1,z1, [], conf); +title('2.5D WFS with spherical expansion (spatial domain): line source'); + +%% generic WFS in spatial domain using circular Expansion Coefficients +conf.dimension = '2D'; +% loudspeakers (TODO: implicit selection of loudspeakers in driving +% function) x0 = secondary_source_positions(conf); -x0ps = secondary_source_selection(x0,xs,'ps'); -x0fs = secondary_source_selection(x0,[xs,0 1 0],'fs'); % compute driving functions -D1sph = driving_function_mono_wfs_sphexp(x0ps(:,1:3),x0ps(:,4:6),B1sph,'S',f,xs,conf); -D2sph = driving_function_mono_wfs_sphexp(x0fs(:,1:3),x0fs(:,4:6),B1sph,'S',f,xs,conf); +Dpw = driving_function_mono_wfs_circexp(x0(:,1:3),x0(:,4:6), Apwm,'R',f,xq,conf); +Dls = driving_function_mono_wfs_circexp(x0(:,1:3),x0(:,4:6), Alsm,'R',f,xq,conf); % compute fields -P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sph,f,conf); -P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(D2sph),f,conf); +Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dpw,f,conf); +Pls = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dls,f,conf); % plot -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); +plot_sound_field(Ppw, x1,y1,z1, [], conf); +title('2D WFS with circular expansion (spatial domain): plane wave'); +plot_sound_field(Pls, x1,y1,z1, [], conf); +title('2D WFS with circular expansion (spatial domain): line source'); -plot_sound_field(P1sphwfs,x1,y1,z1, x0, conf); -title('point source'); -plot_sound_field(P2sphwfs,x1,y1,z1, x0, conf); -title('focused source'); - -%% WFS Reproduction using virtual Scatterer and time reversal -% regular spherical expansion of plane wave and point source -A1sph = sphexp_mono_pw(ns,f,xq,conf); -A2sph = sphexp_mono_ps(xs,'R',f,xq,conf); -% compute timereversed incident field -A1sph_timereversed = sphexp_mono_timereverse(A1sph); -A2sph_timereversed = sphexp_mono_timereverse(A2sph); -% compute scattered field -B1sph = sphexp_mono_scatter(A1sph_timereversed, R, sigma, f, conf); -B2sph = sphexp_mono_scatter(A2sph_timereversed, R, sigma, f, conf); -% loudspeakers +%% LWFS in spatial domain using virtual Spherical Scatterer and time reversal +conf.dimension = '2.5D'; +% loudspeakers (TODO: implicit selection of loudspeakers in driving +% function) x0 = secondary_source_positions(conf); -x0pw = secondary_source_selection(x0,ns,'pw'); -x0ps = secondary_source_selection(x0,xs,'ps'); % compute driving functions -D1sph = driving_function_mono_wfs_sphexp(x0pw(:,1:3),x0pw(:,4:6),B1sph,'S',f,xq,conf); -D2sph = driving_function_mono_wfs_sphexp(x0ps(:,1:3),x0ps(:,4:6),B2sph,'S',f,xq,conf); +Dpw = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Bpwnm,'S',f,xq,conf); +Dps = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Bpsnm,'S',f,xq,conf); +Dls = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Blsnm,'S',f,xq,conf); % compute fields -P1sphwfs = sound_field_mono(xrange,yrange,zrange,x0pw,'ps',conj(D1sph),f,conf); -P2sphwfs = sound_field_mono(xrange,yrange,zrange,x0ps,'ps',conj(D2sph),f,conf); +Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(Dpw),f,conf); +Pps = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(Dps),f,conf); +Pls = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(Dls),f,conf); % plot -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); - -plot_sound_field(P1sphwfs ,x1,y1,z1, x0pw, conf); -title('plane wave'); -plot_scatterer(xq,R); -plot_sound_field(P2sphwfs ,x1,y1,z1, x0ps, conf); -title('point source'); -plot_scatterer(xq,R); - -%% generic NFCHOA -% loudspeakers +plot_sound_field(Ppw, x1,y1,z1, [], conf); +title('2.5D local WFS with spherical expansion (spatial domain): plane wave'); +plot_sound_field(Pps, x1,y1,z1, [], conf); +title('2.5D local WFS with spherical expansion (spatial domain): point source'); +plot_sound_field(Pls, x1,y1,z1, [], conf); +title('2.5D local WFS with spherical expansion (spatial domain): line source'); + +%% LWFS in spatial domain using virtual Spherical Scatterer and time reversal +conf.dimension = '2D'; +% loudspeakers (TODO: implicit selection of loudspeakers in driving +% function) x0 = secondary_source_positions(conf); - -A1spht_shift = RRsphm*sphexp_bandlimit(A1sph_shift,10); -A2spht_shift = RRsphm*sphexp_bandlimit(A2sph_shift,10); - % compute driving functions -D1sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1sph, f, conf); -D2sphhoa = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2sph, f, conf); -% compute driving functions for shifted expansions -D1sphhoat = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A1spht_shift, f, conf); -D2sphhoat = driving_function_mono_nfchoa_sphexp(x0(:,1:3), A2spht_shift, f, conf); - -% compute fields -P1sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoa,f,conf); -P2sphhoa = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoa,f,conf); +Dpw = driving_function_mono_wfs_circexp(x0(:,1:3),x0(:,4:6),Bpwm,'S',f,xq,conf); +Dls = driving_function_mono_wfs_circexp(x0(:,1:3),x0(:,4:6),Blsm,'S',f,xq,conf); % compute fields -P1sphhoat = sound_field_mono(xrange,yrange,zrange,x0,'ps',D1sphhoat,f,conf); -P2sphhoat = sound_field_mono(xrange,yrange,zrange,x0,'ps',D2sphhoat,f,conf); - +Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ls',conj(Dpw),f,conf); +Pls = sound_field_mono(xrange,yrange,zrange,x0,'ls',conj(Dls),f,conf); % plot -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); - -plot_sound_field(P1sphhoa, x1,y1,z1, x0, conf); -title('NFCHOA: plane wave'); -plot_sound_field(P2sphhoa ,x1,y1,z1, x0, conf); -title('NFCHOA: point source'); -plot_sound_field(P1sphhoat/5, x1,y1,z1, x0, conf); -title('NFCHOA: plane wave (shifted reexpansion)'); -plot_sound_field(P2sphhoat/5, x1,y1,z1, x0, conf); -title('NFCHOA: point source (shifted reexpansion)'); \ No newline at end of file +plot_sound_field(Ppw, x1,y1,z1, [], conf); +title('2D local WFS with circular expansion (spatial domain): plane wave'); +plot_sound_field(Pls, x1,y1,z1, [], conf); +title('2D local WFS with circular expansion (spatial domain): line source'); \ No newline at end of file From 8dd8900754628b5bcd34ff843d7a02e910ad4269 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 16 Jun 2015 18:57:28 +0200 Subject: [PATCH 48/81] rename soundfield sound for circular expansions --- .../circexp/circbasis_mono.m | 19 ++-- .../circexp/circbasis_mono_grid.m | 92 +++++++++++----- .../circexp/circexp_mono_translation.m | 73 ++++++++----- .../circexp/sound_field_mono_circbasis.m | 51 +++++---- .../circexp/sound_field_mono_circexp.m | 52 +++++---- .../sphexp/sphexp_mono_translation.m | 8 +- SFS_scattering/cylexpSR_mono.m | 94 ---------------- SFS_scattering/sound_field_mono_basis.m | 102 ------------------ 8 files changed, 182 insertions(+), 309 deletions(-) rename SFS_scattering/cylbasis_mono.m => SFS_monochromatic/circexp/circbasis_mono.m (89%) rename SFS_scattering/cylbasis_mono_XYZgrid.m => SFS_monochromatic/circexp/circbasis_mono_grid.m (58%) rename SFS_scattering/cylexpRR_mono.m => SFS_monochromatic/circexp/circexp_mono_translation.m (62%) rename SFS_scattering/sound_field_mono_cylexpR.m => SFS_monochromatic/circexp/sound_field_mono_circbasis.m (73%) rename SFS_scattering/sound_field_mono_cylexpS.m => SFS_monochromatic/circexp/sound_field_mono_circexp.m (68%) delete mode 100644 SFS_scattering/cylexpSR_mono.m delete mode 100644 SFS_scattering/sound_field_mono_basis.m diff --git a/SFS_scattering/cylbasis_mono.m b/SFS_monochromatic/circexp/circbasis_mono.m similarity index 89% rename from SFS_scattering/cylbasis_mono.m rename to SFS_monochromatic/circexp/circbasis_mono.m index 658872aa..67aa2e33 100644 --- a/SFS_scattering/cylbasis_mono.m +++ b/SFS_monochromatic/circexp/circbasis_mono.m @@ -1,7 +1,7 @@ -function [Jn, H2n, Yn] = cylbasis_mono(r,phi,k,conf) -%Evaluate cylindrical basis functions for given input arguments +function [Jn, H2n, Yn] = circbasis_mono(r, phi, Nce, k, conf) +%Evaluate circular basis functions for given input arguments % -% Usage: [Jn, H2n, Yn] = cylbasis_mono(r,phi,k,conf) +% Usage: [Jn, H2n, Yn] = circbasis_mono(r, phi, Nce, k, conf) % % Input parameters: % r - distance from z-axis in cylindrical coordinates @@ -14,10 +14,10 @@ % H2n - cell array of cylindrical hankel functions of 2nd kind % Yn - cell array of cylindrical harmonics % -% CYLBASIS_MONO(r,phi,k,conf) computes cylindrical basis functions for -% the given arguments r and phi. r and phi can be of arbitrary (but same) +% CIRCBASIS_MONO(r, phi, Nce, k, conf) computes cylindrical basis functions +% for the given arguments r and phi. r and phi can be of arbitrary (but same) % size. Output will be stored in cell arrays (one cell entry for each order) -% of length 2*conf.scattering.Nce+1 . Each cell array entry contains a +% of length 2*Nce+1 . Each cell array entry contains a % matrix of the same size as r and phi. % % References: @@ -58,11 +58,12 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 3; -nargmax = 4; +nargmin = 4; +nargmax = 5; narginchk(nargmin,nargmax); isargequalsize(r,phi); isargscalar(k); +isargpositivescalar(Nce); if nargin 2) + 2*(numel(Y) > 2) + 4*(numel(Z) > 2); +switch customGrid + case 1 + isargscalar(Y,Z); + case 2 + isargscalar(X,Z); + case 3 + isargequalsize(X,Y); isargscalar(Z); + case 4 + isargscalar(X,Y); + case 5 + isargequalsize(X,Z); isargscalar(Y); + case 6 + isargequalsize(Y,Z); isargscalar(X); + case 7 + isargequalsize(X,Y,Z); + otherwise + isargvector(X,Y,Z); +end +isargpositivescalar(f,Nce); if nargin (E|F) (t) F (x) +% n /__ l=0 l,n l +% +% where {E,F} = {R,S}. R denotes the regular circular basis function, while +% S symbolizes the singular circular basis function. Note that (S|S) and +% (S|R) are respectively equivalent to (R|R) and (R|S). +% +% see also: circexp_mono_ps, circexp_mono_pw + %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * % Assessment of IP-based Applications * @@ -47,8 +64,8 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 3; -nargmax = 4; +nargmin = 4; +nargmax = 5; narginchk(nargmin,nargmax); isargposition(xq); if nargin. * -% * -% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * -% field synthesis methods like wave field synthesis or higher order * -% ambisonics. * -% * -% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * -%***************************************************************************** - - -%% ===== Checking of input parameters ================================== -nargmin = 3; -nargmax = 4; -narginchk(nargmin,nargmax); -isargposition(xq); -if nargin. * -% * -% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * -% field synthesis methods like wave field synthesis or higher order * -% ambisonics. * -% * -% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * -%***************************************************************************** - -%% ===== Checking of input parameters ================================== -nargmin = 3; -nargmax = 4; -narginchk(nargmin,nargmax); -isargvector(AB); -if nargin Date: Wed, 17 Jun 2015 14:23:40 +0200 Subject: [PATCH 49/81] some modifications on circular translation coefficients --- .../circexp/circexp_mono_translation.m | 28 +++---- .../circexp/sound_field_mono_circbasis.m | 18 ++-- test_exp_circ.m | 83 +++++++++++++++++++ 3 files changed, 106 insertions(+), 23 deletions(-) create mode 100644 test_exp_circ.m diff --git a/SFS_monochromatic/circexp/circexp_mono_translation.m b/SFS_monochromatic/circexp/circexp_mono_translation.m index 1c979bdc..b2088da6 100644 --- a/SFS_monochromatic/circexp/circexp_mono_translation.m +++ b/SFS_monochromatic/circexp/circexp_mono_translation.m @@ -1,10 +1,10 @@ -function [EF, EFm] = circexp_mono_translation(t, mode, Nce, f, conf) +function [EF, EFm] = circexp_mono_translation(xt, mode, Nce, f, conf) % Circular translation coefficients (multipole re-expansion) % % Usage: [EF, EFm] = circexp_mono_translation(t, mode, Nse, f, conf) % % Input parameters: -% t - translatory shift [1x3] / m +% xt - translatory shift [1x3] / m % mode - 'RS' for regular-to-singular reexpansion % 'RR' for regular-to-regular reexpansion % 'SR' for singular-to-regular reexpansion @@ -22,8 +22,8 @@ % coordinate system (x+t) based on the original basis functions for (x). % % \~~ inf -% E (x + t) = > (E|F) (t) F (x) -% n /__ l=0 l,n l +% E (x + t) = > (E|F) (xt) F (x) +% n /__ l=-inf l,n l % % where {E,F} = {R,S}. R denotes the regular circular basis function, while % S symbolizes the singular circular basis function. Note that (S|S) and @@ -67,7 +67,9 @@ nargmin = 4; nargmax = 5; narginchk(nargmin,nargmax); -isargposition(xq); +isargposition(xt); +isargchar(mode); +isargpositivescalar(Nce,f); if nargin Date: Fri, 19 Jun 2015 18:23:01 +0200 Subject: [PATCH 50/81] add possibility to truncate spectra non-symmetrically --- .../sht/sound_field_mono_nfchoa_sht.m | 42 +----- .../sphexp/sound_field_mono_sphbasis.m | 12 +- .../sphexp/sphexp_mono_nfchoa_sht.m | 104 +++++++++++++++ SFS_monochromatic/sphexp/sphexp_truncate.m | 35 +++-- test_exp_nfchoa.m | 125 ++++++++++++------ 5 files changed, 223 insertions(+), 95 deletions(-) create mode 100644 SFS_monochromatic/sphexp/sphexp_mono_nfchoa_sht.m diff --git a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m b/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m index 109dfff3..4bba937a 100644 --- a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m +++ b/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m @@ -88,10 +88,6 @@ %% ===== Configuration ================================================== Xc = conf.secondary_sources.center; r0 = conf.secondary_sources.size / 2; -dimension = conf.dimension; - -%% ===== Variables ====================================================== -Nse = sqrt(length(Dnm)) - 1; %% ===== Computation ==================================================== if customGrid @@ -119,49 +115,15 @@ % find coordinates, which are inside and outside the loudspeaker array select = sqrt((X(:)-Xc(1)).^2 + (Y(:)-Xc(2)).^2 + (Z(:)-Xc(3)).^2) <= r0; -if strcmp('2D',dimension) - % === 2-Dimensional ================================================== - - error('%s: 2D not supported.',upper(mfilename)); - -elseif strcmp('2.5D',dimension) - % === 2.5-Dimensional ================================================ - - % regular expansion for the coordinates inside - GnmR = 2*pi*r0*sphexp_mono_ps([r0, 0, 0], 'R', Nse, f, [0,0,0], conf); - - % singular expansion for the coordinates outside - GnmS = 2*pi*r0*sphexp_mono_ps([r0, 0, 0], 'S', Nse, f, [0,0,0], conf); - -elseif strcmp('3D',dimension) - % === 3-Dimensional ================================================== - - % regular expansion for the coordinates inside - GnmR = sphexp_mono_ps([0, 0, r0], 'R', Nse, f, [0,0,0], conf); - - % singular expansion for the coordinates outside - GnmS = sphexp_mono_ps([0, 0, r0], 'S', Nse, f, [0,0,0], conf); - - for n=0:Nse - v = sphexp_index(-n:n,n); - w = sphexp_index(0,n); - GnmR(v) = 2*pi*r0^2*sqrt(4*pi / (2*n+1))*GnmR(w); - GnmS(v) = 2*pi*r0^2*sqrt(4*pi / (2*n+1))*GnmS(w); - end -else - error('%s: the dimension %s is unknown.',upper(mfilename),dimension); -end - P = zeros(size(X)); - if any(select(:)) - Pnm = GnmR .* Dnm; + Pnm = sphexp_mono_nfchoa_sht(Dnm,'R',f,conf); P(select) = sound_field_mono_sphexp(X(select),Y(select),Z(select), Pnm, ... 'R', f, Xc,conf); end if any(~select(:)) - Pnm = GnmS .* Dnm; + Pnm = sphexp_mono_nfchoa_sht(Dnm,'S',f,conf); P(~select) = sound_field_mono_sphexp(X(~select),Y(~select),Z(~select), ... Pnm, 'S', f, Xc,conf); end diff --git a/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m b/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m index cce23152..f0fce47e 100644 --- a/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m +++ b/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m @@ -54,11 +54,15 @@ nargmax = 3; narginchk(nargmin,nargmax); isargvector(ABnm); -isargequallength(ABnm, Ynm); -Nse = length(jh2n) - 1; -if (length(Ynm) ~= (Nse + 1)^2) - error('%s, length(Y) has to be (length(jhsn)+1).^2!',upper(mfilename)); +if length(Ynm) ~= length(jh2n)^2 + error('%s: length(Y) has to be equal length(jh2n)^2!',upper(mfilename)); end +if length(Ynm) < length(ABnm) + error('%s: length(Y) has to larger equal length(ABnm)!',upper(mfilename)); +end + +%% ===== Variables ====================================================== +Nse = sqrt(size(ABnm,1)) - 1; %% ===== Computation ==================================================== P = zeros(size(jh2n{1})); diff --git a/SFS_monochromatic/sphexp/sphexp_mono_nfchoa_sht.m b/SFS_monochromatic/sphexp/sphexp_mono_nfchoa_sht.m new file mode 100644 index 00000000..b6d7313e --- /dev/null +++ b/SFS_monochromatic/sphexp/sphexp_mono_nfchoa_sht.m @@ -0,0 +1,104 @@ +function Pnm = sphexp_mono_nfchoa_sht(Dnm,mode,f,conf) +%SPHEXP_MONO_NFCHOA_SHT yields spherical expansion coefficients of a sound field +%resulting from of the nfchoa driving function given as a spherical harmonics +%transform +% +% Usage: Pnm = sphexp_mono_nfchoa_sht(Dnm,mode,f,conf) +% +% Input parameters: +% Dnm - spherical harmonics transform of nfchoa driving function +% mode - 'R' for regular, 'S' for singular +% f - frequency in Hz +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% Pnm - spherical expansion coefficients of a sound field +% reproduced by nfchoa driving function +% +% SPHEXP_MONO_NFCHOA_SHT(Dnm,mode,f,conf) + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargmatrix(Dnm); +isargsquaredinteger(size(Dnm,1)); +isargvector(f); +isargchar(mode); +if ~strcmp('R', mode) && ~strcmp('S', mode) + error('%s: unknown mode (%s)!', upper(mfilename), mode); +end +if nargin size(Anm, 1) ) - error('%s: order(%d) exceeds size of array',upper(mfilename), N); +if nargin == nargmin + Nshift = 0; +else + isargscalar(Nshift); end +%% ===== Variable ======================================================= +Nse = sqrt(size(Pnm, 1))-1; %% ===== Computation ==================================================== -v = sphexp_index(+N,N); % last element array is n=N, m=+N -Anm(v+1:end,:) = 0; +Anm = zeros(size(Pnm)); + +for m=max(-N+Nshift,-Nse):min(N+Nshift,Nse) + v = sphexp_index(m,abs(m):Nse); + Anm(v,:) = Pnm(v,:); +end end diff --git a/test_exp_nfchoa.m b/test_exp_nfchoa.m index 8a0af8ca..b67b2c13 100644 --- a/test_exp_nfchoa.m +++ b/test_exp_nfchoa.m @@ -11,33 +11,34 @@ % plotting conf.plot.usedb = false; conf.plot.useplot = false; -conf.usenormalisation = false; -conf.resolution = 400; +conf.usenormalisation = true; +conf.resolution = 200; xrange = [-2 2]; yrange = [-2 2]; zrange = 0; -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); +f = 1000; +ns = [0, -1, 0]; % propagation direction of plane wave +xs = [0, 3, 0]; % position of point source + +xt = [ 0.5, 0.5, 0]; % position of the sweet spot +rt = 0.3; % "size" of the sweet spot +Ncet = circexp_truncation_order(norm(xt)+rt, f, 1e-6, conf); % 2.5DHOA order for translation +Nce = circexp_truncation_order(rt, f, 1e-6, conf); % 2.5DHOA order for sweet spot +Nse = sphexp_truncation_order(rt, f, 1e-6, conf); % 3DHOA order for sweet spot % secondary sources conf.secondary_sources.geometry = 'circular'; -conf.secondary_sources.number = 56; +conf.secondary_sources.number = Nce*2+1; conf.secondary_sources.size = 3; conf.secondary_sources.center = [0, 0, 0]; -f = 1000; -ns = [0, -1, 0]; % propagation direction of plane wave -xs = [0, 2, 0]; % position of point source - xq = conf.secondary_sources.center; % expansion center conf.xref = xq; % reference position -xt = [ 0.5, 0.5, 0]; % position of the sweet spot -rt = 0.3; % "size" of the sweet spot -Ncet = circexp_truncation_order(norm(xt)+rt, f, 1e-6, conf); % 2.5DHOA order for translation -Nce = circexp_truncation_order(rt, f, 1e-6, conf); % 2.5DHOA order for sweet spot -Nse = sphexp_truncation_order(rt, f, 1e-6, conf); % 3DHOA order for sweet spot +%% Spherical Basis Functions +[jn, ~, Ynm, x, y, z] = sphbasis_mono_grid(xrange,yrange,zrange,max(Ncet,Nse),f,xq,conf); %% Spherical Expansion Coefficients % regular spherical expansion at xq @@ -57,7 +58,11 @@ % shift spherical expansion back to xq Apwnm_shift = RRsph*sphexp_truncate(Apwnm, Nce); Apsnm_shift = RRsph*sphexp_truncate(Apsnm, Nce); -Alsnm_shift = RRsph*sphexp_truncate(Alsnm, Nce); +Alsnm_shift = RRsph*sphexp_truncate(Alsnm, Nce); +% computed truncated expansion +Apwnm_shift_trunc = sphexp_truncate(Apwnm_shift, Nce, -round(2*pi*f/conf.c*norm(xt)*sind(90-atan2d(-xt(2),-xt(1))))); +Apsnm_shift_trunc = sphexp_truncate(Apsnm_shift, Nce, -round(2*pi*f/conf.c*norm(xt)*sind(90-atan2d(-xt(2),-xt(1))))); +Alsnm_shift_trunc = sphexp_truncate(Alsnm_shift, Nce, -round(2*pi*f/conf.c*norm(xt)*sind(90-atan2d(-xt(2),-xt(1))))); %% generic NFCHOA in spatial domain conf.dimension = '2.5D'; @@ -71,6 +76,10 @@ Dpw_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apwnm_shift, f, conf); Dps_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apsnm_shift, f, conf); Dls_shift = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Alsnm_shift, f, conf); +% compute driving functions from shifted fields +Dpw_shift_trunc = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apwnm_shift_trunc, f, conf); +Dps_shift_trunc = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apsnm_shift_trunc, f, conf); +Dls_shift_trunc = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Alsnm_shift_trunc, f, conf); % compute fields Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw,f,conf); Pps = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps,f,conf); @@ -79,19 +88,29 @@ Ppw_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw_shift,f,conf); Pps_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps_shift,f,conf); Pls_shift = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dls_shift,f,conf); +% compute fields from shifted + bandlimited driving functions +Ppw_shift_trunc = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw_shift_trunc,f,conf); +Pps_shift_trunc = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps_shift_trunc,f,conf); +Pls_shift_trunc = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dls_shift_trunc,f,conf); % plot -plot_sound_field(Ppw, x1,y1,z1, [], conf); +plot_sound_field(Ppw, x,y,z, [], conf); title('2.5D NFCHOA (spatial domain): plane wave'); -plot_sound_field(Pps, x1,y1,z1, [], conf); +plot_sound_field(Pps, x,y,z, [], conf); title('2.5D NFCHOA (spatial domain): point source'); -plot_sound_field(Pls, x1,y1,z1, [], conf); +plot_sound_field(Pls, x,y,z, [], conf); title('2.5D NFCHOA (spatial domain): line source'); -plot_sound_field(Ppw_shift, x1,y1,z1, [], conf); +plot_sound_field(Ppw_shift, x,y,z, [], conf); title('2.5D NFCHOA (spatial domain): plane wave (shifted expansion)'); -plot_sound_field(Pps_shift, x1,y1,z1, [], conf); +plot_sound_field(Pps_shift, x,y,z, [], conf); title('2.5D NFCHOA (spatial domain): point source (shifted expansion)'); -plot_sound_field(Pls_shift, x1,y1,z1, [], conf); +plot_sound_field(Pls_shift, x,y,z, [], conf); title('2.5D NFCHOA (spatial domain): line source (shifted expansion)'); +plot_sound_field(Ppw_shift_trunc, x,y,z, [], conf); +title('2.5D NFCHOA (spatial domain): plane wave (shifted + truncated expansion)'); +plot_sound_field(Pps_shift_trunc, x,y,z, [], conf); +title('2.5D NFCHOA (spatial domain): point source (shifted + truncated expansion)'); +plot_sound_field(Pls_shift_trunc, x,y,z, [], conf); +title('2.5D NFCHOA (spatial domain): line source (shifted + truncated expansion)'); %% generic 2.5D NFCHOA in spherical harmonics domain conf.dimension = '2.5D'; @@ -103,27 +122,53 @@ Dpwnm_shift = driving_function_mono_nfchoa_sht_sphexp(Apwnm_shift, f, conf); Dpsnm_shift = driving_function_mono_nfchoa_sht_sphexp(Apsnm_shift, f, conf); Dlsnm_shift = driving_function_mono_nfchoa_sht_sphexp(Alsnm_shift, f, conf); +% compute sht of driving functions from shifted fields +Dpwnm_shift_trunc = driving_function_mono_nfchoa_sht_sphexp(Apwnm_shift_trunc, f, conf); +Dpsnm_shift_trunc = driving_function_mono_nfchoa_sht_sphexp(Apsnm_shift_trunc, f, conf); +Dlsnm_shift_trunc = driving_function_mono_nfchoa_sht_sphexp(Alsnm_shift_trunc, f, conf); +% compute spherical expansion of reproduced sound field +Ppwnm = sphexp_mono_nfchoa_sht(Dpwnm,'R',f,conf); +Ppsnm = sphexp_mono_nfchoa_sht(Dpsnm,'R',f,conf); +Plsnm = sphexp_mono_nfchoa_sht(Dlsnm,'R',f,conf); +% compute spherical expansion of reproduced sound field from shifted driving functions +Ppwnm_shift = sphexp_mono_nfchoa_sht(Dpwnm_shift,'R',f,conf); +Ppsnm_shift = sphexp_mono_nfchoa_sht(Dpsnm_shift,'R',f,conf); +Plsnm_shift = sphexp_mono_nfchoa_sht(Dlsnm_shift,'R',f,conf); +% compute spherical expansion of reproduced sound field from shifted and truncated driving functions +Ppwnm_shift_trunc = sphexp_mono_nfchoa_sht(Dpwnm_shift_trunc,'R',f,conf); +Ppsnm_shift_trunc = sphexp_mono_nfchoa_sht(Dpsnm_shift_trunc,'R',f,conf); +Plsnm_shift_trunc = sphexp_mono_nfchoa_sht(Dlsnm_shift_trunc,'R',f,conf); % compute fields -Ppw = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpwnm, f, conf); -Pps = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpsnm, f, conf); -Pls = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dlsnm, f, conf); +Ppw = sound_field_mono_sphbasis(Ppwnm, jn, Ynm); +Pps = sound_field_mono_sphbasis(Ppsnm, jn, Ynm); +Pls = sound_field_mono_sphbasis(Plsnm, jn, Ynm); +% compute fields from shifted driving functions +Ppw_shift = sound_field_mono_sphbasis(Ppwnm_shift, jn, Ynm); +Pps_shift = sound_field_mono_sphbasis(Ppsnm_shift, jn, Ynm); +Pls_shift = sound_field_mono_sphbasis(Plsnm_shift, jn, Ynm); % compute fields from shifted driving functions -Ppw_shift = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpwnm_shift, f, conf); -Pps_shift = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpsnm_shift, f, conf); -Pls_shift = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dlsnm_shift, f, conf); +Ppw_shift_trunc = sound_field_mono_sphbasis(Ppwnm_shift_trunc, jn, Ynm); +Pps_shift_trunc = sound_field_mono_sphbasis(Ppsnm_shift_trunc, jn, Ynm); +Pls_shift_trunc = sound_field_mono_sphbasis(Plsnm_shift_trunc, jn, Ynm); % plot -plot_sound_field(Ppw, x1,y1,z1, [], conf); +plot_sound_field(Ppw, x,y,z, [], conf); title('2.5D NFCHOA (sht domain): plane wave'); -plot_sound_field(Pps, x1,y1,z1, [], conf); +plot_sound_field(Pps, x,y,z, [], conf); title('2.5D NFCHOA (sht domain): point source'); -plot_sound_field(Pls, x1,y1,z1, [], conf); +plot_sound_field(Pls, x,y,z, [], conf); title('2.5D NFCHOA (sht domain): line source'); -plot_sound_field(Ppw_shift, x1,y1,z1, [], conf); +plot_sound_field(Ppw_shift, x,y,z, [], conf); title('2.5D NFCHOA (spatial domain): plane wave (shifted expansion)'); -plot_sound_field(Pps_shift, x1,y1,z1, [], conf); +plot_sound_field(Pps_shift, x,y,z, [], conf); title('2.5D NFCHOA (spatial domain): point source (shifted expansion)'); -plot_sound_field(Pls_shift, x1,y1,z1, [], conf); +plot_sound_field(Pls_shift, x,y,z, [], conf); title('2.5D NFCHOA (spatial domain): line source (shifted expansion)'); +plot_sound_field(Ppw_shift_trunc, x,y,z, [], conf); +title('2.5D NFCHOA (spatial domain): plane wave (shifted + truncated expansion)'); +plot_sound_field(Pps_shift_trunc, x,y,z, [], conf); +title('2.5D NFCHOA (spatial domain): point source (shifted + truncated expansion)'); +plot_sound_field(Pls_shift_trunc, x,y,z, [], conf); +title('2.5D NFCHOA (spatial domain): line source (shifted + truncated expansion)'); %% generic 3D NFCHOA in spherical harmonics domain conf.dimension = '3D'; @@ -131,14 +176,18 @@ Dpwnm = driving_function_mono_nfchoa_sht_sphexp(Apwnm_3D,f,conf); Dpsnm = driving_function_mono_nfchoa_sht_sphexp(Apsnm_3D,f,conf); Dlsnm = driving_function_mono_nfchoa_sht_sphexp(Alsnm_3D,f,conf); +% compute spherical expansion of reproduced sound field +Ppwnm = sphexp_mono_nfchoa_sht(Dpwnm,'R',f,conf); +Ppsnm = sphexp_mono_nfchoa_sht(Dpsnm,'R',f,conf); +Plsnm = sphexp_mono_nfchoa_sht(Dlsnm,'R',f,conf); % compute fields -Ppw = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpwnm, f, conf); -Pps = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dpsnm, f, conf); -Pls = sound_field_mono_nfchoa_sht(xrange,yrange,zrange, Dlsnm, f, conf); +Ppw = sound_field_mono_sphbasis(Ppwnm, jn, Ynm); +Pps = sound_field_mono_sphbasis(Ppsnm, jn, Ynm); +Pls = sound_field_mono_sphbasis(Plsnm, jn, Ynm); % plot -plot_sound_field(Ppw, x1,y1,z1, [], conf); +plot_sound_field(Ppw, x,y,z, [], conf); title('3D NFCHOA (sht domain): plane wave'); -plot_sound_field(Pps, x1,y1,z1, [], conf); +plot_sound_field(Pps, x,y,z, [], conf); title('3D NFCHOA (sht domain): point source'); -plot_sound_field(Pls, x1,y1,z1, [], conf); +plot_sound_field(Pls, x,y,z, [], conf); title('3D NFCHOA (sht domain): line source'); \ No newline at end of file From fb4338270b53eef556d09dbdfa7be082753a2f29 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Mon, 20 Jul 2015 16:07:45 +0200 Subject: [PATCH 51/81] bug fixing and documentation --- .../driving_function_mono_nfchoa_sphexp.m | 2 +- .../sphexp/sphexp_mono_nfchoa_sht.m | 18 ++++---- SFS_monochromatic/sphexp/sphexp_mono_pw.m | 18 ++++---- .../sphexp/sphexp_mono_scatter.m | 31 ++++++------- .../sphexp/sphexp_mono_timereverse.m | 9 ++-- .../sphexp/sphexp_mono_translation.m | 44 ++++++++++--------- .../sphexp/sphexp_translation_auxiliary.m | 22 +++++----- SFS_monochromatic/sphexp/sphexp_truncate.m | 34 ++++++++------ .../sphexp/sphexp_truncation_order.m | 13 +++--- 9 files changed, 101 insertions(+), 90 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index e897d1c4..18edd300 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -82,7 +82,7 @@ % Calculate the driving function in time-frequency domain % secondary source positions -x00 = bsxfun(@minus,x0,Xc); +x00 = bsxfun(@minus,x0(:,1:3),Xc); [phi0, ~,r0] = cart2sph(x00(:,1),x00(:,2),x00(:,3)); % frequency depended stuff diff --git a/SFS_monochromatic/sphexp/sphexp_mono_nfchoa_sht.m b/SFS_monochromatic/sphexp/sphexp_mono_nfchoa_sht.m index b6d7313e..3d432781 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_nfchoa_sht.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_nfchoa_sht.m @@ -1,14 +1,14 @@ function Pnm = sphexp_mono_nfchoa_sht(Dnm,mode,f,conf) %SPHEXP_MONO_NFCHOA_SHT yields spherical expansion coefficients of a sound field -%resulting from of the nfchoa driving function given as a spherical harmonics -%transform +%resulting from of the nfchoa driving function given as a spherical harmonics +%transform % % Usage: Pnm = sphexp_mono_nfchoa_sht(Dnm,mode,f,conf) % % Input parameters: % Dnm - spherical harmonics transform of nfchoa driving function % mode - 'R' for regular, 'S' for singular -% f - frequency in Hz +% f - frequency / Hz [Nf x 1] or [1 x Nf] % conf - optional configuration struct (see SFS_config) % % Output parameters: @@ -76,20 +76,20 @@ %% ===== Computation ==================================================== if strcmp('2D',dimension) % === 2-Dimensional ================================================== - + error('%s: 2D not supported.',upper(mfilename)); elseif strcmp('2.5D',dimension) % === 2.5-Dimensional ================================================ - - % regular/singular expansion + + % regular/singular expansion of 3D Green's function Gnm = 2*pi*r0*sphexp_mono_ps([r0, 0, 0], mode, Nse, f, [0,0,0], conf); elseif strcmp('3D',dimension) % === 3-Dimensional ================================================== - - % regular/singular expansion + + % regular/singular expansion of 3D Green's function Gnm = sphexp_mono_ps([0, 0, r0], mode, Nse, f, [0,0,0], conf); - + for n=0:Nse v = sphexp_index(-n:n,n); w = sphexp_index(0,n); diff --git a/SFS_monochromatic/sphexp/sphexp_mono_pw.m b/SFS_monochromatic/sphexp/sphexp_mono_pw.m index 625b794d..22767578 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_pw.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_pw.m @@ -6,19 +6,19 @@ % Input parameters: % npw - unit vector propagation direction of plane wave % Nse - maximum order of spherical basis functions -% f - frequency [m x 1] or [1 x m] -% xq - optional expansion coordinate +% f - frequency / Hz [Nf x 1] or [1 x Nf] +% xq - optional expansion coordinate % conf - optional configuration struct (see SFS_config) % % Output parameters: -% Anm - regular Spherical Expansion Coefficients [(Nse+1)^2 x m] +% Anm - regular Spherical Expansion Coefficients [(Nse+1)^2 x Nf] % % SPHEXP_MONO_PW(npw,Nse,f,xq,conf) computes the regular Spherical Expansion % Coefficients for a plane wave. The expansion will be done around the % expansion coordinate xq: % % \~~ oo \~~ n m m -% p (x,f) = > > A R (x-x ) +% p (x,f) = > > A R (x-x ) % pw /__ n=0 /__ m=-n n n q % % with the expansion coefficients (Gumerov, p. 74, eq. 2.3.6): @@ -27,16 +27,16 @@ % A = 4pi i Y (theta , phi ) % n n pw pw % -% The coefficients are stored in linear arrays with index l resulting from +% The coefficients are stored in linear arrays with index l resulting from % m and n: -% +% % m 2 % A = A ; with l = (n+1) - (n - m) -% l n +% l n % % References: -% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the -% Helmholtz Equation in three +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three % Dimensions", ELSEVIER % % see also: sphexp_access sphexp_index sphbasis_mono diff --git a/SFS_monochromatic/sphexp/sphexp_mono_scatter.m b/SFS_monochromatic/sphexp/sphexp_mono_scatter.m index dc3337e2..5ebbca4f 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_scatter.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_scatter.m @@ -1,33 +1,33 @@ function Bnm = sphexp_mono_scatter(Anm, R, sigma, f, conf) -%Singular Spherical Expansion of sphere-scattered field +% Singular Spherical Expansion of a sphere-scattered sound field % % Usage: Bl = sphexpS_mono_scatter(Al, R, sigma, f, conf) % % Input parameters: -% Al - regular spherical expansion of incident field -% R - radius of sphere +% Anm - regular spherical expansion of incident sound field +% R - radius of sphere / m % sigma - admittance of sphere (from 0(sound soft) to inf(sound hard)) -% f - frequency in Hz +% f - frequency / Hz [Nf x 1] or [1 x Nf] % % Output parameters: -% Bl - singular spherical expansion coefficients of +% Bnm - singular spherical expansion coefficients of % scattered field % -% SPHEXPS_MONO_SCATTER(Anm, R, sigma, f, conf) computes the singular spherical +% SPHEXPS_MONO_SCATTER(Anm, R, sigma, f, conf) computes the singular spherical % expansion coefficients of a field resulting from a scattering of an incident -% field at a sphere. Incident field is descriped by regular expansion +% field at a sphere. Incident field is descriped by regular expansion % coefficients (expansion center is expected to be at the center of the sphere % xq): % % \~~ oo \~~ n m m -% p (x,f) = > > A R (x-x ) +% P (x,f) = > > A R (x-x ) % ind /__ n=0 /__ m=-n n n q % % The scattered field is descriped by singular expansion coefficients, -% expanded around the center of the sphere xq. +% expanded around the center of the sphere xq. % % \~~ oo \~~ n m m -% p (x,f) = > > B S (x-x ) +% P (x,f) = > > B S (x-x ) % sca /__ n=0 /__ m=-n n n q % % Due to the boundary conditions on the surface of the sphere the @@ -41,14 +41,14 @@ % % where k = 2*pi*f/c. The coefficients are stored in linear arrays with % index l resulting from m and n: -% +% % m m 2 % A = A ; B = B with l = (n+1) - (n - m) % l n l n % % References: -% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the -% Helmholtz Equation in three +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three % Dimensions", ELSEVIER % % see also: sphexp_mono_ps, sphexp_mono_pw @@ -93,7 +93,8 @@ L = length(Anm); isargsquaredinteger(L); isargscalar(sigma); -isargpositivescalar(f,R); +isargpositivescalar(R); +isargvector(f); if nargin > (E|F) (t) F (x) % n /__ l=0 /__ s=-l l,n l % % where {E,F} = {R,S}. R denotes the regular spherical basis function, while -% S symbolizes the singular spherical basis function. Note that (S|S) and -% (S|R) are respectively equivalent to (R|R) and (R|S). -% The reexpansion coefficients can seperated into sectorial +% S symbolizes the singular spherical basis function. Note that (S|S) and +% (S|R) are respectively equivalent to (R|R) and (R|S). +% The reexpansion coefficients can seperated into sectorial % (n = abs|m| and/or l = abs|s|) and tesseral (else) coefficients. Latter will % only be computed, if conf.dimensions == '3D'. % % References: -% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the -% Helmholtz Equation in three +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three % Dimensions", ELSEVIER % % see also: sphexp_mono_ps, sphexp_mono_pw @@ -114,8 +114,8 @@ end %% ===== Sectorial Coefficients ========================================= -% if translation vector's z-coordinate is zero, many coefficients are zero -% this is to save some computation time +% if translation vector's z-coordinate is zero, many coefficients are zero. +% This is to save some computation time if t(3) == 0 inc = 2; else @@ -154,11 +154,12 @@ v = sphexp_index(-s,l); S(v,1) = (-1).^l*Hn.*Ynm; % -s,l, m=0, n=0 - S(1,v) = Hn.*conj(Ynm); % s=0,l=0, -m, n + S(1,v) = Hn.*conj(Ynm); % s=0,l=0, -m, n end if showprogress, progress_bar(v,L); end % progress bar end +%% ===== Sectorial Coefficients ========================================== % for n=|m| (Gumerov2004, eq. 3.2.78) % % -m-1 s,m+1 -s s-1,m s-1 s-1,m @@ -168,12 +169,12 @@ % -m-1 s,-m-1 s s+1,-m -s-1 s+1,-m % b (E|F)(t) = b (E|F)(t) - b (E|F)(t) % m+1 l,|m+1| l l-1,|m| l+1 l+1,|m| -% +% % while {E,F} = {R,S} % for m=0:Nse-1 % NOTE: sphexp_access(b, -m-1) == sphexp_access(b, -m-1, m+1) - bm = 1./sphexp_access(b,-m-1); + bm = 1./sphexp_access(b,-m-1); for l=1:(2*Nse-m-1) for s=-l:inc:l % +m @@ -181,13 +182,13 @@ S(v,w) = bm * ( ... sphexp_access(b,-s ,l) * sphexp_access(S,s-1,l-1,m) - ... sphexp_access(b,s-1,l+1) * sphexp_access(S,s-1,l+1,m)... - ); + ); % -m [v, w] = sphexp_index(s,l,-m-1); S(v,w) = bm * ( ... sphexp_access(b,s ,l) * sphexp_access(S,s+1,l-1,-m) - ... sphexp_access(b,-s-1,l+1) * sphexp_access(S,s+1,l+1,-m)... - ); + ); end end if showprogress, progress_bar(m,Nse); end % progress bar @@ -211,7 +212,8 @@ end %% ===== Tesseral Coefficients ========================================== -if ~strcmp('2.5D', dimension) +% TODO: there is a bug somewhere in here +if strcmp('3D', dimension) for m=-Nse:Nse for s=-Nse:Nse @@ -219,7 +221,7 @@ % left propagation for n=(0:lowerbound-1)+abs(m) amn1 = 1./sphexp_access(a,m,n); - amn2 = sphexp_access(a,m,n-1); + amn2 = sphexp_access(a,m,n-1); for l=(abs(s)-abs(m)+n+1):(2*Nse-n-1) [v, w] = sphexp_index(m, n+1, s, l); S(v,w) = amn1 * ( ... @@ -233,7 +235,7 @@ % up propagation for l=(0:lowerbound-1)+abs(s) asl1 = 1./sphexp_access(a,s,l); - asl2 = sphexp_access(a,s,l-1); + asl2 = sphexp_access(a,s,l-1); for n=(abs(m)-abs(s)+l+2):(2*Nse-l-1) [v, w] = sphexp_index(s,l+1, m, n); S(v,w) = asl1 * ( ... @@ -242,7 +244,7 @@ sphexp_access(a,m,n-1) * sphexp_access(S,s,l ,m,n-1)... ); end - end + end if showprogress, progress_bar(m+Nse,2*Nse); end % progress bar end end @@ -250,11 +252,11 @@ L = (Nse + 1)^2; EF = S(1:L,1:L); % (E|F)(t) % SR(-t) -EFm = zeros(L); +EFm = zeros(L); for n=0:Nse for l=0:Nse m = -n:inc:n; - s = -l:inc:l; + s = -l:inc:l; [v, w] = sphexp_index(s,l,m,n); EFm(v,w) = (-1).^(l+n)*sphexp_access(EF,s,l,m,n); end diff --git a/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m b/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m index b664fa09..66c61169 100644 --- a/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m +++ b/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m @@ -15,13 +15,13 @@ % % SPHEXP_TRANSLATION_AUXILIARY(Nse,conf) % -% Auxiliary coefficients for the calculation of tesseral spherical +% Auxiliary coefficients for the calculation of tesseral spherical % translation coefficients (Gumerov2004, eq. 2.2.8 and 3.2.65): % % +------------------+ % m |(n+1+|m|)(n+1-|m|) _ % a = |------------------ for |m| < n -% n \| (2n+1)(2n+3) +% n \| (2n+1)(2n+3) % % 0 else % @@ -37,10 +37,10 @@ % m |(n-m)(n-m-1) _ % b = - |------------ for -n < m < 0 % n \|(2n-1)(2n+1) -% +% % 0 else % -% The coefficients are stored in linear arrays with index l resulting from +% The coefficients are stored in linear arrays with index l resulting from % m and n: % % m m 2 @@ -48,8 +48,8 @@ % l n l n % % References: -% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the -% Helmholtz Equation in three +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three % Dimensions", ELSEVIER % % see also: sphexp_mono_ps, sphexp_mono_pw @@ -87,17 +87,15 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 0; +nargmin = 1; nargmax = 2; narginchk(nargmin,nargmax); +isargpositivescalar(Nse); if nargin Date: Wed, 22 Jul 2015 10:16:08 +0200 Subject: [PATCH 52/81] compute translation coefficients for various frequencies --- SFS_monochromatic/sphexp/sphexp_access.m | 30 +++++++++---- .../sphexp/sphexp_mono_translation.m | 42 ++++++++++--------- test_exp_nfchoa.m | 8 +++- 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/SFS_monochromatic/sphexp/sphexp_access.m b/SFS_monochromatic/sphexp/sphexp_access.m index f43a08a7..2861ce2a 100644 --- a/SFS_monochromatic/sphexp/sphexp_access.m +++ b/SFS_monochromatic/sphexp/sphexp_access.m @@ -4,7 +4,8 @@ % Usage: a = sphexp_access(A, m1, n1, m2, n2) % % Input parameters: -% A - 1D, 2D array of expansion coefficients +% A - 1D, 2D, 3D array of expansion coefficients (3rd +% dimension for temporal frequency) % m1 - order of 1st dimension % n1 - degree of 1st dimension (optional, default = |m1|) % m2 - order of 2st dimension (optional, default = 0) @@ -50,28 +51,39 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== +L1 = length(m1); if nargin < 3 n1 = abs(m1); +elseif length(n1) < L1 + n1 = repmat(n1, [1 L1]); +elseif length(n1) > L1 + m1 = repmat(m1, [1 length(n2)]); + L1 = length(m2); end + if nargin < 4 m2 = 0; end + +L2 = length(m2); if nargin < 5 n2 = abs(m2); +elseif length(n2) < L2 + n2 = repmat(n2, [1 L2]); +elseif length(n2) > L2 + m2 = repmat(m2, [1 length(n2)]); + L2 = length(m2); end %% ===== Computation ==================================================== -a = zeros(length(m1)*length(n1),length(m2)*length(n2)); - -[m1, n1] = meshgrid(m1, n1); -[m2, n2] = meshgrid(m2, n2); +a = zeros(L1, L2, size(A, 3)); -s1 = abs(m1(:)) <= n1(:); -s2 = abs(m2(:)) <= n2(:); +s1 = abs(m1) <= n1; +s2 = abs(m2) <= n2; if any(s1) && any(s2) - [l1, l2] = sphexp_index(m1(s1), n1(s1), m2(s2), n2(s2)); - a(s1,s2) = A(l1,l2); + [v, w] = sphexp_index(m1(s1), n1(s1), m2(s2), n2(s2)); + a(s1,s2,:) = A(v,w,:); end end diff --git a/SFS_monochromatic/sphexp/sphexp_mono_translation.m b/SFS_monochromatic/sphexp/sphexp_mono_translation.m index 63c7fb1a..ff37c753 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_translation.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_translation.m @@ -9,7 +9,7 @@ % 'RR' for regular-to-regular reexpansion % 'SR' for singular-to-regular reexpansion % 'SS' for singular-to-singular reexpansion -% f - frequency / Hz +% f - frequency [1 x Nf] / Hz % conf - optional configuration struct (see SFS_config) % % Output parameters: @@ -77,7 +77,8 @@ narginchk(nargmin,nargmax); isargposition(t); isargchar(mode); -isargpositivescalar(f, Nse); +isargpositivescalar(Nse); +isargvector(f); if nargin Date: Thu, 30 Jul 2015 11:45:09 +0200 Subject: [PATCH 53/81] remove 2D ccase from nfchoa_sht_sphexp --- .../driving_function_mono_nfchoa_sht_sphexp.m | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m index c7daa486..64e312bc 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m @@ -97,18 +97,7 @@ % initialize empty driving signal Dnm = zeros(size(Pnm)); -if strcmp('2D',dimension) - % === 2-Dimensional ================================================== - - if strcmp('default',driving_functions) - % --- SFS Toolbox ------------------------------------------------ - to_be_implemented; - else - error('%s: %s, this type of driving function is not implemented ', ... - upper(mfilename), driving_functions); - end - -elseif strcmp('2.5D',dimension) +if strcmp('2.5D',dimension) % === 2.5-Dimensional ================================================ if strcmp('default',driving_functions) @@ -197,5 +186,6 @@ upper(mfilename), driving_functions); end else - error('%s: the dimension %s is unknown.',upper(mfilename),dimension); + error('%s: the dimension %s is unknown or not supported.', ... + upper(mfilename),dimension); end From 931c5a3b7b1308531a673a787bae75cfe7c07c3f Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 30 Jul 2015 11:59:38 +0200 Subject: [PATCH 54/81] add sht of nfchoa driving function for point source --- .../sht/driving_function_mono_nfchoa_sht_ps.m | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ps.m diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ps.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ps.m new file mode 100644 index 00000000..17a5ef17 --- /dev/null +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ps.m @@ -0,0 +1,77 @@ +function Dnm = driving_function_mono_nfchoa_sht_ps(xs, Nse, f, conf) +%computes the spherical harmonics transform of nfchoa driving functions +%for a point source. +% +% Usage: D = driving_function_mono_nfchoa_sht_ps(xs, Nse, f, conf) +% +% Input parameters: +% xs - position of point source [1 x 3] / m +% Nse - maximum order of spherical basis functions +% f - frequency [m x 1] or [1 x m] / Hz +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% Dnm - regular spherical expansion coefficients of driving +% function signal [n x m] +% +% DRIVING_FUNCTION_MONO_NFCHOA_SHT_PS(xs, Nse, f, conf) returns regular +% spherical expansion coefficients of the NFCHOA driving function for a +% virtual sound expressed by regular spherical expansion coefficients +% and the frequency f. +% +% see also: driving_function_mono_nfchoa_sphexp + +%***************************************************************************** +% Copyright (c) 2010-2015 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2015 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargposition(xs); +isargpositivescalar(Nse); +isargvector(f); +if nargin Date: Thu, 30 Jul 2015 13:40:47 +0200 Subject: [PATCH 55/81] add functions computing shts of nfchoa driving functions for specific sound source models --- .../sht/driving_function_mono_nfchoa_sht.m | 92 +++++++++++++++++++ .../sht/driving_function_mono_nfchoa_sht_ls.m | 76 +++++++++++++++ .../sht/driving_function_mono_nfchoa_sht_ps.m | 11 +-- .../sht/driving_function_mono_nfchoa_sht_pw.m | 76 +++++++++++++++ .../driving_function_mono_nfchoa_sht_sphexp.m | 15 ++- SFS_monochromatic/sphexp/sphexp_mono_ls.m | 2 +- SFS_monochromatic/sphexp/sphexp_mono_ps.m | 6 +- 7 files changed, 259 insertions(+), 19 deletions(-) create mode 100644 SFS_monochromatic/sht/driving_function_mono_nfchoa_sht.m create mode 100644 SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ls.m create mode 100644 SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_pw.m diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht.m new file mode 100644 index 00000000..790112e8 --- /dev/null +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht.m @@ -0,0 +1,92 @@ +function Dnm = driving_function_mono_nfchoa_sht(xs, src, Nse, f, conf) +%computes the spherical harmonics transform of nfchoa driving functions +%for a specified source model +% +% Usage: D = driving_function_mono_nfchoa_sht(xs, src, Nse, f, conf) +% +% Input parameters: +% xs - position of virtual source or direction of plane +% wave [1 x 3] / m +% Nse - maximum order of spherical basis functions +% f - frequency [m x 1] or [1 x m] / Hz +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% Dnm - regular spherical harmonics transform of driving +% function signal [n x m] +% +% DRIVING_FUNCTION_MONO_NFCHOA_SHT(xs, src, Nse, f, conf) returns spherical +% harmonics transform of the NFCHOA driving function with maximum order Nse +% for a specified source model. +% +% see also: driving_function_mono_nfchoa_sht_sphexp + +%***************************************************************************** +% Copyright (c) 2010-2015 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2015 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 4; +nargmax = 5; +narginchk(nargmin,nargmax); +isargposition(xs); +isargchar(src); +isargpositivescalar(Nse); +isargvector(f); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargposition(xs); +isargpositivescalar(Nse); +isargvector(f); +if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargposition(npw); +isargpositivescalar(Nse); +isargvector(f); +if nargin Date: Mon, 10 Aug 2015 13:43:45 +0200 Subject: [PATCH 56/81] polish doc for sphexp functions --- .../sphexp/sound_field_mono_sphbasis.m | 6 +- .../sphexp/sound_field_mono_sphexp.m | 11 ++-- SFS_monochromatic/sphexp/sphbasis_mono.m | 19 +++--- SFS_monochromatic/sphexp/sphbasis_mono_grid.m | 21 ++++--- SFS_monochromatic/sphexp/sphexp_access.m | 15 +++-- .../sphexp/sphexp_convert_circexp.m | 8 ++- SFS_monochromatic/sphexp/sphexp_index.m | 7 ++- SFS_monochromatic/sphexp/sphexp_mono_ls.m | 42 ++------------ .../sphexp/sphexp_mono_multiscatter.m | 58 ++++++++++++------- .../sphexp/sphexp_mono_nfchoa_sht.m | 9 ++- SFS_monochromatic/sphexp/sphexp_mono_ps.m | 6 +- SFS_monochromatic/sphexp/sphexp_mono_pw.m | 10 ++-- .../sphexp/sphexp_mono_scatter.m | 9 +-- .../sphexp/sphexp_mono_timereverse.m | 2 +- .../sphexp/sphexp_mono_translation.m | 20 ++++--- .../sphexp/sphexp_translation_auxiliary.m | 14 ++--- SFS_monochromatic/sphexp/sphexp_truncate.m | 7 ++- .../sphexp/sphexp_truncation_order.m | 9 ++- 18 files changed, 137 insertions(+), 136 deletions(-) diff --git a/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m b/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m index f0fce47e..fa6b53ba 100644 --- a/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m +++ b/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m @@ -54,6 +54,8 @@ nargmax = 3; narginchk(nargmin,nargmax); isargvector(ABnm); +L = size(ABnm,1); +isargsquaredinteger(L); if length(Ynm) ~= length(jh2n)^2 error('%s: length(Y) has to be equal length(jh2n)^2!',upper(mfilename)); end @@ -62,7 +64,7 @@ end %% ===== Variables ====================================================== -Nse = sqrt(size(ABnm,1)) - 1; +Nse = sqrt(L) - 1; %% ===== Computation ==================================================== P = zeros(size(jh2n{1})); @@ -75,5 +77,3 @@ P = P + ABnm(l)*(jh2n{n+1}.*Ynm{l}); end end - -end \ No newline at end of file diff --git a/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m b/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m index 6ce79177..63ed359a 100644 --- a/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m +++ b/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m @@ -1,6 +1,6 @@ function [P, x, y, z] = sound_field_mono_sphexp(X,Y,Z,ABnm,mode,f,xq,conf) -%SOUND_FIELD_MONO_SPHEXPR simulates a sound field given with -%regular/singular spherical expansion coefficients +%SOUND_FIELD_MONO_SPHEXPR simulates a sound field given with regular/singular +%spherical expansion coefficients % % Usage: [P, x, y, z] = sound_field_mono_sphexp(X,Y,Z,Al,f,x0,conf) % @@ -68,8 +68,9 @@ end if nargin == nargmin xq = [0, 0, 0]; -end -isargposition(xq); +else + isargposition(xq); +end %% ===== Variables ====================================================== Nse = sqrt(length(ABnm)) - 1; @@ -80,7 +81,7 @@ elseif strcmp('S', mode) [~, fn, Ynm, x, y, z] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf); else - error('%s: %s is an unknown mode!',upper(mfilename), mode); + error('%s: %s is an unknown mode!', upper(mfilename), mode); end P = sound_field_mono_sphbasis(ABnm,fn,Ynm); diff --git a/SFS_monochromatic/sphexp/sphbasis_mono.m b/SFS_monochromatic/sphexp/sphbasis_mono.m index 8b4fc4e0..bddc451b 100644 --- a/SFS_monochromatic/sphexp/sphbasis_mono.m +++ b/SFS_monochromatic/sphexp/sphbasis_mono.m @@ -1,5 +1,5 @@ function [jn, h2n, Ynm] = sphbasis_mono(r,theta,phi,Nse,k,conf) -%Evaluate spherical basis functions for given input arguments +%SPHBASIS_MONO evaluates spherical basis functions for given input arguments % % Usage: [jn, h2n, Ynm] = sphbasis_mono(r,theta,phi,Nse,k,conf) % @@ -16,12 +16,13 @@ % h2n - cell array of spherical hankel functions of 2nd kind % Ynm - cell array of spherical harmonics % -% SPHBASIS_MONO(r,theta,phi,k,conf) computes spherical basis functions for -% the given arguments r, theta and phi. r, theta and phi can be of arbitrary -% (but same) size. Output will be stored in cell arrays (one cell entry for -% each order) of length Nse+1 for jn and h2n. For Ynm the lenght is -% (Nse+1).^2. The coefficients of Ynm are stored with the linear index l -% resulting from the order m and the degree n of the spherical harmonics: +% SPHBASIS_MONO(r,theta,phi,Nse,k,conf) computes spherical basis functions +% for the given arguments r, theta and phi. r, theta and phi can be of +% arbitrary (but same) size. Output will be stored in cell arrays (one cell +% entry for each order) of length Nse+1 for jn and h2n. For Ynm the lenght +% is (Nse+1).^2. The coefficients of Ynm are stored with the linear index l +% resulting from the order m and the degree n of the spherical harmonics: +% % m 2 % Y = Y ; with l = (n+1) - (n - m) % l n @@ -68,9 +69,9 @@ isargequalsize(r,phi,theta); isargscalar(k); if nargin A(l1) ; A(n2,m2) => A(l2) +% CAUTION: THIS FUNCTION DOES NOT USE ANY CHECK OF INPUT ARGUMENTS % % see also: sphexp_access @@ -76,14 +79,14 @@ end %% ===== Computation ==================================================== -a = zeros(L1, L2, size(A, 3)); +a = zeros(L1, L2, size(Anm, 3)); s1 = abs(m1) <= n1; s2 = abs(m2) <= n2; if any(s1) && any(s2) [v, w] = sphexp_index(m1(s1), n1(s1), m2(s2), n2(s2)); - a(s1,s2,:) = A(v,w,:); + a(s1,s2,:) = Anm(v,w,:); end end diff --git a/SFS_monochromatic/sphexp/sphexp_convert_circexp.m b/SFS_monochromatic/sphexp/sphexp_convert_circexp.m index c5c0ac5c..982666bc 100644 --- a/SFS_monochromatic/sphexp/sphexp_convert_circexp.m +++ b/SFS_monochromatic/sphexp/sphexp_convert_circexp.m @@ -1,5 +1,6 @@ function Anm = sphexp_convert_circexp(Am) -% compute converts circular expansion into spherical expansion coefficients +%SPHEXP_CONVERT_CIRCEXP compute converts regular circular expansion into +%spherical expansion coefficients % % Usage: Anm = sphexp_convert_circexp(Am) % @@ -10,6 +11,10 @@ % Anm - regular spherical expansion coefficients % % References: +% Hahn, Spors (2015) - "Sound Field Synthesis of Virtual Cylindrical +% Waves using Circular and Spherical Loudspeaker +% Arrays", 138th AES Convention +% % %***************************************************************************** @@ -53,6 +58,7 @@ %% ===== Computation ==================================================== +% Implementation of Hahn2015, Eq. (14) Anm = zeros((Nce+1).^2,1); for m=-Nce:Nce % for theta=0 the legendre polynom is zero if n+m is odd diff --git a/SFS_monochromatic/sphexp/sphexp_index.m b/SFS_monochromatic/sphexp/sphexp_index.m index dd7724cc..3fab9e1d 100644 --- a/SFS_monochromatic/sphexp/sphexp_index.m +++ b/SFS_monochromatic/sphexp/sphexp_index.m @@ -1,5 +1,6 @@ function [l1, l2] = sphexp_index(m1, n1, m2, n2) -%Calculate index(indices) for array of spherical expansion coefficients +%SPHEXP_INDEX calculates index(indices) for the arrays of spherical expansion +%coefficients % % Usage: [l1, l2] = sphexp_index(m1, n1, m2, n2) % @@ -16,6 +17,7 @@ % SPHEXP_INDEX(m1, n1, m2, n2) computes one/two indices for accessing % 1D/2D arrays of spherical expansion coefficients % A(n1,m1) => A(l1) ; A(n2,m2) => A(l2) +% CAUTION: THIS FUNCTION DOES NOT USE ANY CHECK OF INPUT ARGUMENTS % % see also: sphexp_access @@ -63,7 +65,6 @@ end %% ===== Computation ==================================================== + l1 = (n1 + 1).^2 - (n1 - m1); l2 = (n2 + 1).^2 - (n2 - m2); -end - diff --git a/SFS_monochromatic/sphexp/sphexp_mono_ls.m b/SFS_monochromatic/sphexp/sphexp_mono_ls.m index 171e377c..b6406cd0 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_ls.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_ls.m @@ -1,5 +1,5 @@ function Anm = sphexp_mono_ls(xs, mode, Nse, f, xq, conf) -%Regular/Singular Spherical Expansion of Line Source +%SPHEXP_MONO_LS compute the regular/singular spherical expansion of line source % % Usage: Anm = sphexp_mono_ls(xs, mode, Nse, f, xq, conf) % @@ -14,43 +14,11 @@ % Output parameters: % Al - regular Spherical Expansion Coefficients % -% SPHEXP_MONO_PS(xs, mode, f, Nse, xq, conf) computes the regular/singular -% Spherical Expansion Coefficients for a point source at xs. The expansion -% will be done around the expansion coordinate xq: +% SPHEXP_MONO_LS(xs, mode, f, Nse, xq, conf) computes the regular/singular +% spherical expansion coefficients for a point source at xs. The expansion +% will be done around the expansion coordinate xq. % -% Regular Expansion: -% \~~ oo \~~ n m m -% p (x,f) = > > A R (x-x ) -% ps,R /__ n=0 /__ m=-n n n q -% -% with the expansion coefficients (Gumerov2004, eq. 3.2.2): -% m -m -% A = -i . k . S (x - x ) -% n n s q -% -% Singular Expansion: -% \~~ oo \~~ n m m -% p (x,f) = > > B S (x-x ) -% ps,S /__ n=0 /__ m=-n n n q -% -% with the expansion coefficients (Gumerov2004, eq. 3.2.2): -% m -m -% B = -i . k . R (x - x ) -% n n s q -% -% The coefficients are stored in linear arrays with index l resulting from -% m and n: -% -% m m 2 -% A = A ; B = B with l = (n+1) - (n - m) -% l n l n -% -% References: -% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the -% Helmholtz Equation in three -% Dimensions", ELSEVIER -% -% see also: sphexp_access sphexp_index sphbasis_mono +% see also: sphexp_mono_ps sphexp_mono_pw sphexp_convert_circexp %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * diff --git a/SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m b/SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m index 3ea063a2..11ba8420 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m @@ -1,4 +1,22 @@ function B = sphexp_mono_multiscatter(A, xq, R, sigma, f, conf) +%SPHEXP_MONO_MULTISCATTER compute the singular spherical expansion of a sphere- +%scattered sound field +% +% Usage: B = sphexp_mono_multiscatter(A, xq, R, sigma, f, conf) +% +% Input parameters: +% A - regular spherical expansion coefficients of incident +% sound fields arriving at each sphere [n x Nq] +% xq - positions of the sphere / m [Nq x 3] +% R - radii of the spheres / m [Nq x 1] +% sigma - admittances of the sphere / m [Nq x 1] +% f - frequency / Hz +% +% Output parameters: +% B - regular spherical expansion coefficients of sound fields +% scattered at each sphere [n x Nq] +% +% SPHEXP_MONO_MULTISCATTER(A, xq, R, sigma, f, conf) %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * @@ -36,54 +54,52 @@ nargmin = 5; nargmax = 6; narginchk(nargmin,nargmax); -isargmatrix(A,xq); isargpositivescalar(f); isargvector(R, sigma); +isargmatrix(A, xq); if nargin > A R (x-x ) @@ -39,7 +39,7 @@ % Helmholtz Equation in three % Dimensions", ELSEVIER % -% see also: sphexp_access sphexp_index sphbasis_mono +% see also: sphexp_mono_ls sphexp_mono_ps %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * diff --git a/SFS_monochromatic/sphexp/sphexp_mono_scatter.m b/SFS_monochromatic/sphexp/sphexp_mono_scatter.m index 5ebbca4f..c46680b1 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_scatter.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_scatter.m @@ -1,7 +1,8 @@ function Bnm = sphexp_mono_scatter(Anm, R, sigma, f, conf) -% Singular Spherical Expansion of a sphere-scattered sound field +%SPHEXP_MONO_SCATTER compute the singular spherical expansion of a sphere- +%scattered sound field % -% Usage: Bl = sphexpS_mono_scatter(Al, R, sigma, f, conf) +% Usage: Bnm = sphexp_mono_scatter(Anm, R, sigma, f, conf) % % Input parameters: % Anm - regular spherical expansion of incident sound field @@ -13,7 +14,7 @@ % Bnm - singular spherical expansion coefficients of % scattered field % -% SPHEXPS_MONO_SCATTER(Anm, R, sigma, f, conf) computes the singular spherical +% SPHEXP_MONO_SCATTER(Anm, R, sigma, f, conf) computes the singular spherical % expansion coefficients of a field resulting from a scattering of an incident % field at a sphere. Incident field is descriped by regular expansion % coefficients (expansion center is expected to be at the center of the sphere @@ -51,7 +52,7 @@ % Helmholtz Equation in three % Dimensions", ELSEVIER % -% see also: sphexp_mono_ps, sphexp_mono_pw +% see also: sphexp_mono_ps, sphexp_mono_pw, sphexp_mono_timereverse %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * diff --git a/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m b/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m index a68feca5..2f340d39 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m @@ -1,5 +1,5 @@ function ABnm = sphexp_mono_timereverse(ABnm) -% compute coefficients of time reversed sound field +%SPHEXP_MONO_TIMEREVERSE compute coefficients of a time reversed sound field % % Usage: ABnm = sphexp_mono_timereverse(ABnm) % diff --git a/SFS_monochromatic/sphexp/sphexp_mono_translation.m b/SFS_monochromatic/sphexp/sphexp_mono_translation.m index ff37c753..4159b76a 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_translation.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_translation.m @@ -1,5 +1,6 @@ function [EF, EFm] = sphexp_mono_translation(t, mode, Nse, f, conf) -% Spherical translation coefficients (multipole re-expansion) +%SPHEXP_MONO_TRANSLATION computes spherical translation coefficients +%(multipole re-expansion) % % Usage: [EF, EFm] = sphexp_mono_translation(t, mode, Nse, f, conf) % @@ -16,10 +17,11 @@ % EF - spherical re-expansion coefficients for t % EFm - spherical re-expansion coefficients for -t % -% SPHEXP_MONO_TRANSLATION(t, mode, f, conf) computes the spherical re-expansion -% coefficients to perform as translatory shift of spherical basis function. -% Multipole Re-expansion computes the spherical basis function for a shifted -% coordinate system (x+t) based on the original basis functions for (x). +% SPHEXP_MONO_TRANSLATION(t, mode, Nse, f, conf) computes the spherical +% re-expansion coefficients to perform as translatory shift of spherical basis +% function. Multipole Re-expansion computes the spherical basis function for a +% shifted coordinate system (x+t) based on the original basis functions for +% (x). % % m \~~ inf \~~ l s,m s % E (x + t) = > > (E|F) (t) F (x) @@ -27,10 +29,10 @@ % % where {E,F} = {R,S}. R denotes the regular spherical basis function, while % S symbolizes the singular spherical basis function. Note that (S|S) and -% (S|R) are respectively equivalent to (R|R) and (R|S). -% The reexpansion coefficients can seperated into sectorial -% (n = abs|m| and/or l = abs|s|) and tesseral (else) coefficients. Latter will -% only be computed, if conf.dimensions == '3D'. +% (S|R) are respectively equivalent to (R|R) and (R|S). The reexpansion +% coefficients can seperated into sectorial (n = abs|m| and/or l = abs|s|) +% and tesseral (else) coefficients. Latter will only be computed, if +% conf.dimensions == '3D'. % % References: % Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the diff --git a/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m b/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m index 66c61169..3861183a 100644 --- a/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m +++ b/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m @@ -1,5 +1,6 @@ function [a, b] = sphexp_translation_auxiliary(Nse,conf) -%Auxiliary coefficients for the recursive calculation of spherical translation coefficients +%SPHEXP_TRANSLATION_AUXILIARY yields the auxiliary coefficients for the +%recursive calculation of spherical translation coefficients % % Usage: [a, b] = sphexp_translation_auxiliary(Nse,conf) % @@ -13,10 +14,9 @@ % b - auxiliary coefficients for the calculation of sectorial % spherical translation coefficients % -% SPHEXP_TRANSLATION_AUXILIARY(Nse,conf) -% -% Auxiliary coefficients for the calculation of tesseral spherical -% translation coefficients (Gumerov2004, eq. 2.2.8 and 3.2.65): +% SPHEXP_TRANSLATION_AUXILIARY(Nse,conf) computes the auxiliary coefficients +% for the calculation of tesseral spherical translation coefficients +% (Gumerov2004, eq. 2.2.8 and 3.2.65): % % +------------------+ % m |(n+1+|m|)(n+1-|m|) _ @@ -52,8 +52,8 @@ % Helmholtz Equation in three % Dimensions", ELSEVIER % -% see also: sphexp_mono_ps, sphexp_mono_pw -% +% see also: sphexp_mono_translation + %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * % Assessment of IP-based Applications * diff --git a/SFS_monochromatic/sphexp/sphexp_truncate.m b/SFS_monochromatic/sphexp/sphexp_truncate.m index 261ff0b7..209337ad 100644 --- a/SFS_monochromatic/sphexp/sphexp_truncate.m +++ b/SFS_monochromatic/sphexp/sphexp_truncate.m @@ -1,5 +1,6 @@ function Anm = sphexp_truncate(Pnm, N, M, Mshift) -% Truncates spherical expansion by setting remaining coefficients to zero +%SPHEXP_TRUNCATE truncates spherical expansion by setting remaining +%coefficients to zero % % Usage: Anm = sphexp_truncate(Pnm, N, M, Mshift) % @@ -11,10 +12,10 @@ % % Output parameters: % Anm - 1D array of bandlimited spherical expansion -% coefficients [N x Nf] +% coefficients [n x Nf] % % SPHEXP_TRUNCATE(Pnm, N, M, Mshift) sets coefficients belonging to an degree -% n higher than N or an order m exceeding: -M+Mshift to +M+Mshift to zero. +% n higher than N or an order m exceeding (-M+Mshift:+M+Mshift) to zero. % % see also: sphexp_truncation_order diff --git a/SFS_monochromatic/sphexp/sphexp_truncation_order.m b/SFS_monochromatic/sphexp/sphexp_truncation_order.m index c3b89e74..9936edff 100644 --- a/SFS_monochromatic/sphexp/sphexp_truncation_order.m +++ b/SFS_monochromatic/sphexp/sphexp_truncation_order.m @@ -1,7 +1,8 @@ function Nse = sphexp_truncation_order(r, f, nmse, conf) -%Truncation order for spherical expansion of an arbitrary sound field +%SPHEXP_TRUNCATION_ORDER yields the bound of summation for a spherical expansion +%of an arbitrary sound field % -% Usage: Nse = sphexp_truncation_order(r, f, epsilon, conf) +% Usage: Nse = sphexp_truncation_order(r, f, nmse, conf) % % Input parameters: % r - max 3D distance from expansion center / m @@ -10,7 +11,7 @@ % conf - optional configuration struct (see SFS_config) % % Output parameters: -% Nse - Maximum order for spherical expansion +% Nse - maximum order for spherical expansion % % SPHEXP_TRUNCATION_ORDER(r, f, nmse, conf) yields the order up to which % a the spherical expansion coefficients of an arbitrary sound field have @@ -24,6 +25,8 @@ % Kennedy et al. (2007) - "Intrinsic Limits of Dimensionality and % Richness in Random Multipath Fields", % IEEE Transactions on Signal Processing +% +% see also: sphexp_truncation %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * From 4900195b8118b36e6dd25c91b9ca7b37acf237f7 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Mon, 10 Aug 2015 14:12:27 +0200 Subject: [PATCH 57/81] polish doc of sht functions --- .../sht/driving_function_mono_nfchoa_sht.m | 4 +- .../sht/driving_function_mono_nfchoa_sht_ls.m | 4 +- .../sht/driving_function_mono_nfchoa_sht_ps.m | 6 +- .../sht/driving_function_mono_nfchoa_sht_pw.m | 4 +- .../driving_function_mono_nfchoa_sht_sphexp.m | 5 +- .../driving_function_mono_wfs_sht_sphexp.m | 123 ++++++++++++++++++ ...no_nfchoa_sht.m => sound_field_mono_sht.m} | 10 +- 7 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 SFS_monochromatic/sht/driving_function_mono_wfs_sht_sphexp.m rename SFS_monochromatic/sht/{sound_field_mono_nfchoa_sht.m => sound_field_mono_sht.m} (95%) diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht.m index 790112e8..09e93bcf 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht.m @@ -1,6 +1,6 @@ function Dnm = driving_function_mono_nfchoa_sht(xs, src, Nse, f, conf) -%computes the spherical harmonics transform of nfchoa driving functions -%for a specified source model +%DRIVING_FUNCTION_MONO_NFCHOA_SHT computes the spherical harmonics transform of +%nfchoa driving functions for a specified source model % % Usage: D = driving_function_mono_nfchoa_sht(xs, src, Nse, f, conf) % diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ls.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ls.m index ba3e43f9..2309d355 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ls.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ls.m @@ -1,6 +1,6 @@ function Dnm = driving_function_mono_nfchoa_sht_ls(xs, Nse, f, conf) -%computes the spherical harmonics transform of nfchoa driving functions -%for a line source. +%DRIVING_FUNCTION_MONO_NFCHOA_SHT_LS computes the spherical harmonics transform +%of nfchoa driving functions for a line source. % % Usage: D = driving_function_mono_nfchoa_sht_ls(xs, Nse, f, conf) % diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ps.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ps.m index 7fcde5ee..3a038434 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ps.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_ps.m @@ -1,6 +1,6 @@ function Dnm = driving_function_mono_nfchoa_sht_ps(xs, Nse, f, conf) -%computes the spherical harmonics transform of nfchoa driving functions -%for a point source. +%DRIVING_FUNCTION_MONO_NFCHOA_SHT_PS computes the spherical harmonics +%transform of nfchoa driving functions for a point source. % % Usage: D = driving_function_mono_nfchoa_sht_ps(xs, Nse, f, conf) % @@ -14,7 +14,7 @@ % Dnm - regular spherical harmonics transform of driving % function signal [n x m] % -% DRIVING_FUNCTION_MONO_NFCHOA_SHT_LS(xs, Nse, f, conf) returns spherical +% DRIVING_FUNCTION_MONO_NFCHOA_SHT_PS(xs, Nse, f, conf) returns spherical % harmonics transform of the NFCHOA driving function with maximum order Nse % for a virtual point source at xs. % diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_pw.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_pw.m index b3a39df7..2e9fbe88 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_pw.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_pw.m @@ -1,6 +1,6 @@ function Dnm = driving_function_mono_nfchoa_sht_pw(npw, Nse, f, conf) -%computes the spherical harmonics transform of nfchoa driving functions -%for a point source. +%DRIVING_FUNCTION_MONO_NFCHOA_SHT_PW computes the spherical harmonics +%transform of nfchoa driving functions for a point source. % % Usage: D = driving_function_mono_nfchoa_sht_pw(npw, Nse, f, conf) % diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m index 611e4132..da693a50 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m @@ -1,6 +1,7 @@ function Dnm = driving_function_mono_nfchoa_sht_sphexp(Pnm, f, conf) -%computes the spherical harmonics transform of nfchoa driving functions -%for a sound field expressed by regular spherical expansion coefficients. +%DRIVING_FUNCTION_MONO_NFCHOA_SHT_SPHEXP computes the spherical harmonics +%transform of nfchoa driving functions for a sound field expressed by regular +%spherical expansion coefficients. % % Usage: D = driving_function_mono_nfchoa_sht_sphexp(Pnm, f, conf) % diff --git a/SFS_monochromatic/sht/driving_function_mono_wfs_sht_sphexp.m b/SFS_monochromatic/sht/driving_function_mono_wfs_sht_sphexp.m new file mode 100644 index 00000000..fffde934 --- /dev/null +++ b/SFS_monochromatic/sht/driving_function_mono_wfs_sht_sphexp.m @@ -0,0 +1,123 @@ +function Dnm = driving_function_mono_wfs_sht_sphexp(Pnm, mode, f, conf) +%DRIVING_FUNCTION_MONO_WFS_SHT_SPHEXP computes spherical harmonics transform +%the wfs driving functions for a sound field expressed by spherical expansion +%coefficients. +% +% Usage: Dnm = driving_function_mono_wfs_sht_sphexp(Pnm, mode, f, conf) +% +% Input parameters: +% Pnm - regular/singular spherical expansion coefficients of +% sound field +% mode - 'R' for regular expansion, 'S' for singular expansion +% f - frequency / Hz +% conf - optional configuration struct (see SFS_config) +% +% Output parameters: +% Dnm - regular spherical harmonics transform of driving +% function signal [n x m] +% +% DRIVING_FUNCTION_MONO_WFS_SHT_SPHEXP(Pnm, mode, f, conf) + +%***************************************************************************** +% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 4; +narginchk(nargmin,nargmax); +isargmatrix(Pnm); +isargvector(f); +isargchar(mode); +if nargin > B F (x) + % /__ n=0 /__ m=-n n n + % + % where F = {R,S}. + % + % regular spherical basis functions: + % m m + % R (x) = j (kr) . Y (theta, phi) + % n n n + % singular spherical basis functions: + % m (2) m + % S (x) = h (kr) . Y (theta, phi) + % n n n + + Dnm = zeros( size(Pnm) ); + for n=0:Nse + v = sphexp_index(-n:n, n); % m=-n:n + + Dnm(v,:) = Pnm(v,:) .* repmat( sphbasis_derived(n), 2*n+1, 1); + end + Dnm = -2.*Dnm; + +else + error(['%s: %s, this type of driving function is not implemented ', ... + 'for a 2.5D point source.'], upper(mfilename), driving_functions); +end diff --git a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m b/SFS_monochromatic/sht/sound_field_mono_sht.m similarity index 95% rename from SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m rename to SFS_monochromatic/sht/sound_field_mono_sht.m index 4bba937a..b1e68c8d 100644 --- a/SFS_monochromatic/sht/sound_field_mono_nfchoa_sht.m +++ b/SFS_monochromatic/sht/sound_field_mono_sht.m @@ -1,6 +1,6 @@ -function [P, x, y, z] = sound_field_mono_nfchoa_sht(X,Y,Z,Dnm,f,conf) -%SOUND_FIELD_MONO_NFCHOA_SHT simulates a sound field given with the -%spherical harmonics transform of the nfchoa driving function +function [P, x, y, z] = sound_field_mono_sht(X,Y,Z,Dnm,f,conf) +%SOUND_FIELD_MONO_SHT simulates a sound field given with the spherical +%harmonics transform of the driving function % % Usage: [P, x, y, z] = sound_field_mono_sht(X,Y,Z,Dnm,f,conf) % @@ -15,7 +15,7 @@ % Output parameters: % P - resulting soundfield % -% SOUND_FIELD_MONO_NFCHOA_SHT(X,Y,Z,ABnm,mode,f,conf) +% SOUND_FIELD_MONO_SHT(X,Y,Z,Dnm,f,conf) % % see also: sphbasis_mono_grid, sound_field_mono_sphexp @@ -58,6 +58,7 @@ isargvector(Dnm); isargsquaredinteger(length(Dnm)); isargnumeric(X,Y,Z); + % unique index encoding which dimension is an nd-array customGrid = (numel(X) > 2) + 2*(numel(Y) > 2) + 4*(numel(Z) > 2); switch customGrid @@ -78,6 +79,7 @@ otherwise isargvector(X,Y,Z); end + isargpositivescalar(f); if nargin Date: Mon, 10 Aug 2015 14:32:23 +0200 Subject: [PATCH 58/81] polish doc for circexp functions --- SFS_monochromatic/circexp/circbasis_mono.m | 2 +- .../circexp/circbasis_mono_grid.m | 4 ++-- SFS_monochromatic/circexp/circexp_mono_ls.m | 4 +++- SFS_monochromatic/circexp/circexp_mono_pw.m | 18 +++++++++--------- .../circexp/circexp_mono_scatter.m | 7 ++++--- .../circexp/circexp_mono_timereverse.m | 4 +++- .../circexp/circexp_mono_translation.m | 11 ++++++----- .../circexp/circexp_truncation_order.m | 5 +++-- .../circexp/sound_field_mono_circbasis.m | 6 ++++-- .../circexp/sound_field_mono_circexp.m | 17 ++++++++++------- 10 files changed, 45 insertions(+), 33 deletions(-) diff --git a/SFS_monochromatic/circexp/circbasis_mono.m b/SFS_monochromatic/circexp/circbasis_mono.m index 67aa2e33..29a9c02f 100644 --- a/SFS_monochromatic/circexp/circbasis_mono.m +++ b/SFS_monochromatic/circexp/circbasis_mono.m @@ -1,5 +1,5 @@ function [Jn, H2n, Yn] = circbasis_mono(r, phi, Nce, k, conf) -%Evaluate circular basis functions for given input arguments +%CIRCBASIS_MONO evaluates circular basis functions for given input arguments % % Usage: [Jn, H2n, Yn] = circbasis_mono(r, phi, Nce, k, conf) % diff --git a/SFS_monochromatic/circexp/circbasis_mono_grid.m b/SFS_monochromatic/circexp/circbasis_mono_grid.m index aa2546f2..da8ed029 100644 --- a/SFS_monochromatic/circexp/circbasis_mono_grid.m +++ b/SFS_monochromatic/circexp/circbasis_mono_grid.m @@ -1,6 +1,6 @@ function [jn, h2n, Ynm, x, y, z] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf) -%Evaluate spherical basis functions for given grid in cartesian coordinates -% +%CIRCBASIS_MONO_GRID evaluate spherical basis functions for given grid in +%cartesian coordinates % % Usage: [jn, h2n, Ynm, x, y, z] = circbasis_mono_grid(X,Y,Z,f,xq,conf) % diff --git a/SFS_monochromatic/circexp/circexp_mono_ls.m b/SFS_monochromatic/circexp/circexp_mono_ls.m index d7e05f41..a9cdbb69 100644 --- a/SFS_monochromatic/circexp/circexp_mono_ls.m +++ b/SFS_monochromatic/circexp/circexp_mono_ls.m @@ -1,5 +1,5 @@ function ABm = circexp_mono_ls(xs, mode, Nce, f, xq, conf) -%regular/singular circular expansion of line source +%CIRCEXP_MONO_LS computes the regular/singular circular expansion of line source % % Usage: ABm = circexp_mono_ls(xs, mode, Nce, f, xq, conf) % @@ -37,6 +37,8 @@ % m -i % A = --- R (x -x ) % n 4 n s q +% +% see also: circexp_mono_pw circexp_mono_scatter %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * diff --git a/SFS_monochromatic/circexp/circexp_mono_pw.m b/SFS_monochromatic/circexp/circexp_mono_pw.m index 03bf577a..b15610c8 100644 --- a/SFS_monochromatic/circexp/circexp_mono_pw.m +++ b/SFS_monochromatic/circexp/circexp_mono_pw.m @@ -1,7 +1,7 @@ -function Am = circexp_mono_pw(nk, Nce, f, xq, conf) -%regular circular expansion of plane wave +function Am = circexp_mono_pw(npw, Nce, f, xq, conf) +%CIRCEXP_MONO_PW computes regular circular expansion coefficients of plane wave % -% Usage: Am = circexp_mono_pw(nk, Nce, f, xq, conf) +% Usage: Am = circexp_mono_pw(npw, Nce, f, xq, conf) % % Input parameters: % nk - propagation direction of plane wave @@ -13,7 +13,7 @@ % Output parameters: % Am - regular cylindrical Expansion Coefficients % -% CIRCEXP_MONO_PW(nk, Nce, f, xq, conf) computes the regular circular +% CIRCEXP_MONO_PW(npw, Nce, f, xq, conf) computes the regular circular % expansion coefficients for a plane wave. The expansion will be done a % round the expansion coordinate xq: % @@ -27,7 +27,7 @@ % A = 4pi i exp (-i*n*phi ) % n pw % -% see also: eval_cylbasis_mono +% see also: circexp_mono_ls circexp_mono_scatter %***************************************************************************** % Copyright (c) 2010-2014 Quality & Usability Lab, together with * @@ -65,7 +65,7 @@ nargmin = 3; nargmax = 5; narginchk(nargmin,nargmax); -isargposition(nk); +isargposition(npw); isargpositivescalar(f); if nargin Date: Wed, 4 Nov 2015 17:47:01 +0100 Subject: [PATCH 59/81] adjust functions to new plotting routines --- .../circexp/circbasis_mono_grid.m | 17 ++--- SFS_monochromatic/sphexp/sphbasis_mono_grid.m | 16 +---- test_exp_circ.m | 23 +++--- test_exp_nfchoa.m | 71 +++++++++---------- test_exp_wfs.m | 48 ++++++------- test_sphexp.m | 29 ++++---- 6 files changed, 88 insertions(+), 116 deletions(-) diff --git a/SFS_monochromatic/circexp/circbasis_mono_grid.m b/SFS_monochromatic/circexp/circbasis_mono_grid.m index da8ed029..a940ff83 100644 --- a/SFS_monochromatic/circexp/circbasis_mono_grid.m +++ b/SFS_monochromatic/circexp/circbasis_mono_grid.m @@ -1,8 +1,8 @@ -function [jn, h2n, Ynm, x, y, z] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf) +function [jn, h2n, Ynm] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf) %CIRCBASIS_MONO_GRID evaluate spherical basis functions for given grid in %cartesian coordinates % -% Usage: [jn, h2n, Ynm, x, y, z] = circbasis_mono_grid(X,Y,Z,f,xq,conf) +% Usage: [jn, h2n, Ynm] = circbasis_mono_grid(X,Y,Z,f,xq,conf) % % Input parameters: % X - x-axis / m; single value or [xmin,xmax] or nD-array @@ -17,9 +17,6 @@ % jn - cell array of cylindrical bessel functions % h2n - cell array of cylindrical hankel functions of 2nd kind % Ynm - cell array of cylindrical harmonics -% x - corresponding x axis / m -% y - corresponding y axis / m -% z - corresponding z axis / m % % CIRCBASIS_MONO_GRID(X,Y,Z,f,xq,conf) computes circular basis functions % for given grid in cartesian coordinates. This is a wrapper function for @@ -108,14 +105,8 @@ isargposition(xq); %% ===== Computation ==================================================== -if customGrid - % just copy everything - xx = X; yy = Y; - x = X; y = Y; z = Z; -else - % Create a x-y-grid - [xx,yy,~,x,y,z] = xyz_grid(X,Y,Z,conf); -end +% Create a x-y-grid +[xx,yy] = xyz_grid(X,Y,Z,conf); k = 2*pi*f/conf.c; % wavenumber diff --git a/SFS_monochromatic/sphexp/sphbasis_mono_grid.m b/SFS_monochromatic/sphexp/sphbasis_mono_grid.m index 2096f801..1b3519c3 100644 --- a/SFS_monochromatic/sphexp/sphbasis_mono_grid.m +++ b/SFS_monochromatic/sphexp/sphbasis_mono_grid.m @@ -1,8 +1,8 @@ -function [jn, h2n, Ynm, x, y, z] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf) +function [jn, h2n, Ynm] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf) %SPHBASIS_MONO_GRID(X,Y,Z,f,xq,conf) evaluates spherical basis functions for %given grid in cartesian coordinates % -% Usage: [jn, h2n, Ynm, x, y, z] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf) +% Usage: [jn, h2n, Ynm] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf) % % Input parameters: % X - x-axis / m; single value or [xmin,xmax] or nD-array @@ -17,9 +17,6 @@ % jn - cell array of spherical bessel functions % h2n - cell array of spherical hankel functions of 2nd kind % Ynm - cell array of spherical harmonics -% x - corresponding x axis / m -% y - corresponding y axis / m -% z - corresponding z axis / m % % SPHBASIS_MONO_GRID(X,Y,Z,Nse,f,xq,conf) computes spherical basis functions % for given grid in cartesian coordinates. This is a wrapper function for @@ -109,14 +106,7 @@ isargposition(xq); %% ===== Computation ==================================================== -if customGrid - % just copy everything - xx = X; yy = Y; zz = Z; - x = X; y = Y; z = Z; -else - % Create a x-y-grid - [xx, yy, zz, x, y, z] = xyz_grid(X, Y, Z, conf); -end +[xx, yy, zz] = xyz_grid(X, Y, Z, conf); k = 2*pi*f/conf.c; % wavenumber diff --git a/test_exp_circ.m b/test_exp_circ.m index 6d351189..99025c90 100644 --- a/test_exp_circ.m +++ b/test_exp_circ.m @@ -17,9 +17,9 @@ ns = [0, -1, 0]; % propagation direction of plane wave xs = [0, 3.0, 0]; % position of line source -xrange = [-2 2]; -yrange = [-2 2]; -zrange = 0; +X = [-2 2]; +Y = [-2 2]; +Z = 0; f = 1000; @@ -47,10 +47,10 @@ %% Sound Fields % Evaluate spherical basis functions on regular grid [Jm, H2m, Ym] = ... - circbasis_mono_grid(xrange,yrange,zrange,Nce,f,xq,conf); + circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf); % [Jm_t, H2m_t, Ym_t] = ... - circbasis_mono_grid(xrange,yrange,zrange,Nce,f,xq+xt,conf); + circbasis_mono_grid(X,Y,Z,Nce,f,xq+xt,conf); % compute fields for expansion at xq Ppwm = sound_field_mono_circbasis(Apwm, Jm, Ym); Plsm = sound_field_mono_circbasis(Alsm, Jm, Ym); @@ -61,23 +61,22 @@ Ppwm_re = sound_field_mono_circbasis(Apwm_re, Jm, Ym_t); Plsm_re = sound_field_mono_circbasis(Alsm_re, Jm, Ym_t); % plot -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); -plot_sound_field(Ppwm ,x1,y1,z1, [], conf); +plot_sound_field(Ppwm ,X, Y, Z, [], conf); plot_scatterer(xq,rt); title('plane wave'); -plot_sound_field(Ppwm_t ,x1,y1,z1, [], conf); +plot_sound_field(Ppwm_t ,X, Y, Z, [], conf); plot_scatterer(xq,rt); title('plane wave (shifted expansion)'); -plot_sound_field(Ppwm_re ,x1,y1,z1, [], conf); +plot_sound_field(Ppwm_re ,X, Y, Z, [], conf); plot_scatterer(xq,rt); title('plane wave (re-expansion)'); -plot_sound_field(Plsm ,x1,y1,z1, [], conf); +plot_sound_field(Plsm ,X, Y, Z, [], conf); plot_scatterer(xq,rt); title('line source'); -plot_sound_field(Plsm_t,x1,y1,z1, [], conf); +plot_sound_field(Plsm_t,X, Y, Z, [], conf); plot_scatterer(xq,rt); title('line source (shifted expansion)'); -plot_sound_field(Plsm_re ,x1,y1,z1, [], conf); +plot_sound_field(Plsm_re ,X, Y, Z, [], conf); plot_scatterer(xq,rt); title('line source (reexpansion)'); \ No newline at end of file diff --git a/test_exp_nfchoa.m b/test_exp_nfchoa.m index 9d2d089b..d977ff87 100644 --- a/test_exp_nfchoa.m +++ b/test_exp_nfchoa.m @@ -14,9 +14,9 @@ conf.usenormalisation = true; conf.resolution = 200; -xrange = [-2 2]; -yrange = [-2 2]; -zrange = 0; +X = [-2 2]; +Y = [-2 2]; +Z = 0; f = 1000; ns = [0, -1, 0]; % propagation direction of plane wave @@ -38,7 +38,7 @@ conf.xref = xq; % reference position %% Spherical Basis Functions -[jn, ~, Ynm] = sphbasis_mono_grid(xrange,yrange,zrange,max(Ncet,Nse),f,xq,conf); +[jn, ~, Ynm] = sphbasis_mono_grid(X,Y,Z,max(Ncet,Nse),f,xq,conf); %% Spherical Expansion Coefficients % regular spherical expansion at xq @@ -81,37 +81,36 @@ Dps_shift_trunc = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Apsnm_shift_trunc, f, conf); Dls_shift_trunc = driving_function_mono_nfchoa_sphexp(x0(:,1:3), Alsnm_shift_trunc, f, conf); % compute fields -Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw,f,conf); -Pps = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps,f,conf); -Pls = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dls,f,conf); +Ppw = sound_field_mono(X,Y,Z,x0,'ps',Dpw,f,conf); +Pps = sound_field_mono(X,Y,Z,x0,'ps',Dps,f,conf); +Pls = sound_field_mono(X,Y,Z,x0,'ls',Dls,f,conf); % compute fields from shifted driving functions -Ppw_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw_shift,f,conf); -Pps_shift = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps_shift,f,conf); -Pls_shift = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dls_shift,f,conf); +Ppw_shift = sound_field_mono(X,Y,Z,x0,'ps',Dpw_shift,f,conf); +Pps_shift = sound_field_mono(X,Y,Z,x0,'ps',Dps_shift,f,conf); +Pls_shift = sound_field_mono(X,Y,Z,x0,'ls',Dls_shift,f,conf); % compute fields from shifted + bandlimited driving functions -Ppw_shift_trunc = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw_shift_trunc,f,conf); -Pps_shift_trunc = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps_shift_trunc,f,conf); -Pls_shift_trunc = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dls_shift_trunc,f,conf); +Ppw_shift_trunc = sound_field_mono(X,Y,Z,x0,'ps',Dpw_shift_trunc,f,conf); +Pps_shift_trunc = sound_field_mono(X,Y,Z,x0,'ps',Dps_shift_trunc,f,conf); +Pls_shift_trunc = sound_field_mono(X,Y,Z,x0,'ls',Dls_shift_trunc,f,conf); % plot -[~,~,~,x,y,z] = xyz_grid(xrange,yrange,zrange,conf); -plot_sound_field(Ppw, x,y,z, [], conf); +plot_sound_field(Ppw, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): plane wave'); -plot_sound_field(Pps, x,y,z, [], conf); +plot_sound_field(Pps, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): point source'); -plot_sound_field(Pls, x,y,z, [], conf); +plot_sound_field(Pls, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): line source'); -plot_sound_field(Ppw_shift, x,y,z, [], conf); +plot_sound_field(Ppw_shift, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): plane wave (shifted expansion)'); -plot_sound_field(Pps_shift, x,y,z, [], conf); +plot_sound_field(Pps_shift, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): point source (shifted expansion)'); -plot_sound_field(Pls_shift, x,y,z, [], conf); +plot_sound_field(Pls_shift, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): line source (shifted expansion)'); -plot_sound_field(Ppw_shift_trunc, x,y,z, [], conf); +plot_sound_field(Ppw_shift_trunc, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): plane wave (shifted + truncated expansion)'); -plot_sound_field(Pps_shift_trunc, x,y,z, [], conf); +plot_sound_field(Pps_shift_trunc, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): point source (shifted + truncated expansion)'); -plot_sound_field(Pls_shift_trunc, x,y,z, [], conf); +plot_sound_field(Pls_shift_trunc, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): line source (shifted + truncated expansion)'); %% generic 2.5D NFCHOA in spherical harmonics domain @@ -153,25 +152,24 @@ Pps_shift_trunc = sound_field_mono_sphbasis(Ppsnm_shift_trunc, jn, Ynm); Pls_shift_trunc = sound_field_mono_sphbasis(Plsnm_shift_trunc, jn, Ynm); % plot -[~,~,~,x,y,z] = xyz_grid(xrange,yrange,zrange,conf); -plot_sound_field(Ppw, x,y,z, [], conf); +plot_sound_field(Ppw, X, Y, Z, [], conf); title('2.5D NFCHOA (sht domain): plane wave'); -plot_sound_field(Pps, x,y,z, [], conf); +plot_sound_field(Pps, X, Y, Z, [], conf); title('2.5D NFCHOA (sht domain): point source'); -plot_sound_field(Pls, x,y,z, [], conf); +plot_sound_field(Pls, X, Y, Z, [], conf); title('2.5D NFCHOA (sht domain): line source'); -plot_sound_field(Ppw_shift, x,y,z, [], conf); +plot_sound_field(Ppw_shift, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): plane wave (shifted expansion)'); -plot_sound_field(Pps_shift, x,y,z, [], conf); +plot_sound_field(Pps_shift, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): point source (shifted expansion)'); -plot_sound_field(Pls_shift, x,y,z, [], conf); +plot_sound_field(Pls_shift, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): line source (shifted expansion)'); -plot_sound_field(Ppw_shift_trunc, x,y,z, [], conf); +plot_sound_field(Ppw_shift_trunc, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): plane wave (shifted + truncated expansion)'); -plot_sound_field(Pps_shift_trunc, x,y,z, [], conf); +plot_sound_field(Pps_shift_trunc, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): point source (shifted + truncated expansion)'); -plot_sound_field(Pls_shift_trunc, x,y,z, [], conf); +plot_sound_field(Pls_shift_trunc, X, Y, Z, [], conf); title('2.5D NFCHOA (spatial domain): line source (shifted + truncated expansion)'); %% generic 3D NFCHOA in spherical harmonics domain @@ -189,11 +187,10 @@ Pps = sound_field_mono_sphbasis(Ppsnm, jn, Ynm); Pls = sound_field_mono_sphbasis(Plsnm, jn, Ynm); % plot -[~,~,~,x,y,z] = xyz_grid(xrange,yrange,zrange,conf); -plot_sound_field(Ppw, x,y,z, [], conf); +plot_sound_field(Ppw, X, Y, Z, [], conf); title('3D NFCHOA (sht domain): plane wave'); -plot_sound_field(Pps, x,y,z, [], conf); +plot_sound_field(Pps, X, Y, Z, [], conf); title('3D NFCHOA (sht domain): point source'); -plot_sound_field(Pls, x,y,z, [], conf); +plot_sound_field(Pls, X, Y, Z, [], conf); title('3D NFCHOA (sht domain): line source'); \ No newline at end of file diff --git a/test_exp_wfs.m b/test_exp_wfs.m index 04fa1ec2..3a13016a 100644 --- a/test_exp_wfs.m +++ b/test_exp_wfs.m @@ -15,11 +15,9 @@ conf.usenormalisation = true; conf.resolution = 300; -xrange = [-2 2]; -yrange = [-4 0]; -zrange = 0; - -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); +X = [-2 2]; +Y = [-4 0]; +Z = 0; % secondary sources conf.secondary_sources.geometry = 'linear'; @@ -97,15 +95,15 @@ Dps = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Apsnm,'R',f,xq,conf); Dls = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Alsnm,'R',f,xq,conf); % compute fields -Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dpw,f,conf); -Pps = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dps,f,conf); -Pls = sound_field_mono(xrange,yrange,zrange,x0,'ps',Dls,f,conf); +Ppw = sound_field_mono(X,Y,Z,x0,'ps',Dpw,f,conf); +Pps = sound_field_mono(X,Y,Z,x0,'ps',Dps,f,conf); +Pls = sound_field_mono(X,Y,Z,x0,'ps',Dls,f,conf); % plot -plot_sound_field(Ppw, x1,y1,z1, [], conf); +plot_sound_field(Ppw, X, Y, Z, [], conf); title('2.5D WFS with spherical expansion (spatial domain): plane wave'); -plot_sound_field(Pps, x1,y1,z1, [], conf); +plot_sound_field(Pps, X, Y, Z, [], conf); title('2.5D WFS with spherical expansion (spatial domain): point source'); -plot_sound_field(Pls, x1,y1,z1, [], conf); +plot_sound_field(Pls, X, Y, Z, [], conf); title('2.5D WFS with spherical expansion (spatial domain): line source'); %% generic WFS in spatial domain using circular Expansion Coefficients @@ -117,12 +115,12 @@ Dpw = driving_function_mono_wfs_circexp(x0(:,1:3),x0(:,4:6), Apwm,'R',f,xq,conf); Dls = driving_function_mono_wfs_circexp(x0(:,1:3),x0(:,4:6), Alsm,'R',f,xq,conf); % compute fields -Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dpw,f,conf); -Pls = sound_field_mono(xrange,yrange,zrange,x0,'ls',Dls,f,conf); +Ppw = sound_field_mono(X,Y,Z,x0,'ls',Dpw,f,conf); +Pls = sound_field_mono(X,Y,Z,x0,'ls',Dls,f,conf); % plot -plot_sound_field(Ppw, x1,y1,z1, [], conf); +plot_sound_field(Ppw, X, Y, Z, [], conf); title('2D WFS with circular expansion (spatial domain): plane wave'); -plot_sound_field(Pls, x1,y1,z1, [], conf); +plot_sound_field(Pls, X, Y, Z, [], conf); title('2D WFS with circular expansion (spatial domain): line source'); %% LWFS in spatial domain using virtual Spherical Scatterer and time reversal @@ -135,15 +133,15 @@ Dps = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Bpsnm,'S',f,xq,conf); Dls = driving_function_mono_wfs_sphexp(x0(:,1:3),x0(:,4:6), Blsnm,'S',f,xq,conf); % compute fields -Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(Dpw),f,conf); -Pps = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(Dps),f,conf); -Pls = sound_field_mono(xrange,yrange,zrange,x0,'ps',conj(Dls),f,conf); +Ppw = sound_field_mono(X,Y,Z,x0,'ps',conj(Dpw),f,conf); +Pps = sound_field_mono(X,Y,Z,x0,'ps',conj(Dps),f,conf); +Pls = sound_field_mono(X,Y,Z,x0,'ps',conj(Dls),f,conf); % plot -plot_sound_field(Ppw, x1,y1,z1, [], conf); +plot_sound_field(Ppw, X, Y, Z, [], conf); title('2.5D local WFS with spherical expansion (spatial domain): plane wave'); -plot_sound_field(Pps, x1,y1,z1, [], conf); +plot_sound_field(Pps, X, Y, Z, [], conf); title('2.5D local WFS with spherical expansion (spatial domain): point source'); -plot_sound_field(Pls, x1,y1,z1, [], conf); +plot_sound_field(Pls, X, Y, Z, [], conf); title('2.5D local WFS with spherical expansion (spatial domain): line source'); %% LWFS in spatial domain using virtual Spherical Scatterer and time reversal @@ -155,10 +153,10 @@ Dpw = driving_function_mono_wfs_circexp(x0(:,1:3),x0(:,4:6),Bpwm,'S',f,xq,conf); Dls = driving_function_mono_wfs_circexp(x0(:,1:3),x0(:,4:6),Blsm,'S',f,xq,conf); % compute fields -Ppw = sound_field_mono(xrange,yrange,zrange,x0,'ls',conj(Dpw),f,conf); -Pls = sound_field_mono(xrange,yrange,zrange,x0,'ls',conj(Dls),f,conf); +Ppw = sound_field_mono(X,Y,Z,x0,'ls',conj(Dpw),f,conf); +Pls = sound_field_mono(X,Y,Z,x0,'ls',conj(Dls),f,conf); % plot -plot_sound_field(Ppw, x1,y1,z1, [], conf); +plot_sound_field(Ppw, X, Y, Z, [], conf); title('2D local WFS with circular expansion (spatial domain): plane wave'); -plot_sound_field(Pls, x1,y1,z1, [], conf); +plot_sound_field(Pls, X, Y, Z, [], conf); title('2D local WFS with circular expansion (spatial domain): line source'); \ No newline at end of file diff --git a/test_sphexp.m b/test_sphexp.m index a11bac26..a1f648e0 100644 --- a/test_sphexp.m +++ b/test_sphexp.m @@ -17,11 +17,11 @@ ns = [0, -1, 0]; % propagation direction of plane wave xs = [0, 2.0, 0]; % position of point source -xrange = [-2 2]; -yrange = [-2 2]; -zrange = 0; +X = [-2 2]; +Y = [-2 2]; +Z = 0; -f = 300; +f = 500; Nse = 10; % scatterer @@ -38,16 +38,16 @@ A2sph = sphexp_mono_ps(xs,'R',Nse, f,xq,conf); A2sph_shift = sphexp_mono_ps(xs,'R', Nse, f,xq+xt,conf); % regular-to-regular spherical reexpansion (translatory shift) -[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', Nse, f, conf); +[RRsph, RRsphm] = sphexp_mono_translation(xt, 'RR', Nse, f, conf); A1spht = RRsph*A1sph; A2spht = RRsph*A2sph; % Evaluate spherical basis functions [jn, h2n, Ynm] = ... - sphbasis_mono_grid(xrange,yrange,zrange,Nse,f,xq,conf); + sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf); % [jnt, ~, Ynmt] = ... - sphbasis_mono_grid(xrange,yrange,zrange,Nse,f,xq+xt,conf); + sphbasis_mono_grid(X, Y, Z,Nse,f,xq+xt,conf); % compute fields P1sph = sound_field_mono_sphbasis(A1sph, jn, Ynm); @@ -57,25 +57,22 @@ P2sph_shift = sound_field_mono_sphbasis(A2sph_shift, jnt, Ynmt); P2spht = sound_field_mono_sphbasis(A2spht, jnt, Ynmt); -% plot -[~,~,~,x1,y1,z1] = xyz_grid(xrange,yrange,zrange,conf); - -plot_sound_field(P1sph ,x1,y1,z1, [], conf); +plot_sound_field(P1sph ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('plane wave'); -plot_sound_field(P1sph_shift ,x1,y1,z1, [], conf); +plot_sound_field(P1sph_shift ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('plane wave (shifted expansion)'); -plot_sound_field(P1spht ,x1,y1,z1, [], conf); +plot_sound_field(P1spht ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('plane wave (shifted reexpansion)'); -plot_sound_field(P2sph ,x1,y1,z1, [], conf); +plot_sound_field(P2sph ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('point source'); -plot_sound_field(P2sph_shift ,x1,y1,z1, [], conf); +plot_sound_field(P2sph_shift ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('point source (shifted expansion)'); -plot_sound_field(P2spht ,x1,y1,z1, [], conf); +plot_sound_field(P2spht ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('point source (shifted reexpansion)'); From c8eaaa8490f028df8edc89e26556731b1cb6e9b9 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 26 Nov 2015 16:28:02 +0100 Subject: [PATCH 60/81] fix comments --- .../driving_function_mono_wfs_circexp.m | 33 ++++---- .../driving_function_mono_wfs_sphexp.m | 78 ++++++++++--------- test_exp_wfs.m | 6 +- 3 files changed, 64 insertions(+), 53 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m index b5a17f20..e3eaf434 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m @@ -1,6 +1,6 @@ function D = driving_function_mono_wfs_circexp(x0,n0,Pm,mode,f,xq,conf) -%computes the time reversed wfs driving functions for a sound field expressed -%by singular cylindrical expansion coefficients. +%computes the wfs driving functions for a sound field expressed by cylindrical +%expansion coefficients. % % Usage: D = driving_function_mono_wfs_circexp(x0,n0,Pm,mode,f,xq,conf) % @@ -132,20 +132,25 @@ if (strcmp('default',driving_functions)) % --- SFS Toolbox ------------------------------------------------ - % D using a line source - % - % d - % D(x0, w) = --- conj(-Ps(x0,w)) - % d n - % with singular cylindrical expansion of the sound field: + % d + % D(x0, w) = -2 --- P(x0,w) + % d n + % with cylindrical expansion of the sound field: % \~~ oo - % Ps(x,w) = > B S (x-xq) + % P(x,w) = > B F (x-xq) % /__ n=-oo n n + % + % where F = {R,S}. + % + % regular cylindrical basis functions: + % + % R (x) = J (kr) . exp(j n phi)) + % n n % singular cylindrical basis functions % (2) % S (x) = H (kr) . exp(j n phi) - % n n - + % n n + for n=-Nce:Nce l = l + 1; cn_prime = k.*circbasis_derived(n,kr0); @@ -154,11 +159,11 @@ Gradr = Gradr + ( Pm(l).*cn_prime.*Yn ); Gradphi = Gradphi + 1./r0.*( Pm(l).*cn.*1j.*n.*Yn ); end - % directional gradient + time reversion (conjugate complex) - D = Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0z.*Gradz; + % directional gradient + D = -2*( Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0z.*Gradz ); else error(['%s: %s, this type of driving function is not implemented ', ... - 'for a 2D/3D line source.'],upper(mfilename),driving_functions); + 'for 2D/3D.'],upper(mfilename),driving_functions); end else error('%s: the dimension %s is unknown.',upper(mfilename),dimension); diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m index 7ca66a8f..ae324b2e 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m @@ -2,7 +2,7 @@ %computes the wfs driving functions for a sound field expressed by spherical %expansion coefficients. % -% Usage: D = driving_function_mono_wfs_sphexp(x0,n0,Bl,mode,f,xq,conf) +% Usage: D = driving_function_mono_wfs_sphexp(x0,n0,Pnm,mode,f,xq,conf) % % Input parameters: % x0 - position of the secondary sources / m [nx3] @@ -16,7 +16,7 @@ % Output parameters: % D - driving function signal [nx1] % -% DRIVING_FUNCTION_MONO_WFS_SPHEXP(x0,n0,Bl,mode,f,xq,conf) +% DRIVING_FUNCTION_MONO_WFS_SPHEXP(x0,n0,Pnm,mode,f,xq,conf) % % see also: driving_function_mono_wfs_cylexp % @@ -79,6 +79,7 @@ %% ===== Configuration ================================================== c = conf.c; +dimension = conf.dimension; driving_functions = conf.driving_functions; %% ===== Variables ====================================================== @@ -133,42 +134,47 @@ % indexing the expansion coefficients l = 0; -if (strcmp('default',driving_functions)) - % --- SFS Toolbox ------------------------------------------------ - % - % d - % D(x0, w) = ---- Ps(x0,w) - % d n0 - % with regular/singular spherical expansion of the sound field: - % \~~ N \~~ n m m - % P(x,w) = > > B F (x-xq) - % /__ n=0 /__ m=-n n n - % - % where F = {R,S}. - % - % regular spherical basis functions: - % m m - % R (x) = j (kr) . Y (theta, phi) - % n n n - % singular spherical basis functions: - % m (2) m - % S (x) = h (kr) . Y (theta, phi) - % n n n +if strcmp('2D',dimension) || strcmp('3D',dimension) - for n=0:Nse - cn_prime = k.*sphbasis_derived(n,kr); - cn = sphbasis(n, kr); - for m=-n:n - l = l + 1; - Ynm = sphharmonics(n,m, theta0, phi0); - Gradr = Gradr + ( Pnm(l).*cn_prime.*Ynm); - Gradphi = Gradphi + 1./r0.*( Pnm(l).*cn.*1j.*m.*Ynm ); - %Gradtheta = 0; TODO + if (strcmp('default',driving_functions)) + % --- SFS Toolbox ------------------------------------------------ + % + % d + % D(x0, w) = -2 ------ P(x0,w) + % d n0 + % with regular/singular spherical expansion of the sound field: + % \~~ N \~~ n m m + % P(x,w) = > > B F (x-xq) + % /__ n=0 /__ m=-n n n + % + % where F = {R,S}. + % + % regular spherical basis functions: + % m m + % R (x) = j (kr) . Y (theta, phi) + % n n n + % singular spherical basis functions: + % m (2) m + % S (x) = h (kr) . Y (theta, phi) + % n n n + + for n=0:Nse + cn_prime = k.*sphbasis_derived(n,kr); + cn = sphbasis(n, kr); + for m=-n:n + l = l + 1; + Ynm = sphharmonics(n,m, theta0, phi0); + Gradr = Gradr + ( Pnm(l).*cn_prime.*Ynm); + Gradphi = Gradphi + 1./r0.*( Pnm(l).*cn.*1j.*m.*Ynm ); + %Gradtheta = 0; TODO + end end + % directional gradient + D = -2*( Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0theta.*Gradtheta ); + else + error(['%s: %s, this type of driving function is not implemented ', ... + 'for 2D/3D'],upper(mfilename),driving_functions); end - % directional gradient - D = Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0theta.*Gradtheta; else - error(['%s: %s, this type of driving function is not implemented ', ... - 'for a 2.5D point source.'],upper(mfilename),driving_functions); + error('%s: the dimension %s is unknown.',upper(mfilename),dimension); end diff --git a/test_exp_wfs.m b/test_exp_wfs.m index 3a13016a..ac55cd21 100644 --- a/test_exp_wfs.m +++ b/test_exp_wfs.m @@ -7,7 +7,7 @@ %% Parameters conf = SFS_config_example; conf.showprogress = true; -conf.dimension = '2.5D'; +conf.dimension = '2D'; % plotting conf.plot.usedb = false; @@ -86,7 +86,7 @@ Blsm_t = circexp_mono_scatter(Alsm_t_rev, rt, sigma, f, conf); %% generic WFS in spatial domain using Spherical Expansion Coefficients -conf.dimension = '2.5D'; +conf.dimension = '2D'; % loudspeakers (TODO: implicit selection of loudspeakers in driving % function) x0 = secondary_source_positions(conf); @@ -124,7 +124,7 @@ title('2D WFS with circular expansion (spatial domain): line source'); %% LWFS in spatial domain using virtual Spherical Scatterer and time reversal -conf.dimension = '2.5D'; +conf.dimension = '2D'; % loudspeakers (TODO: implicit selection of loudspeakers in driving % function) x0 = secondary_source_positions(conf); From d3c9b05a7c2ae7949b374b670305f31603e8e826 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Wed, 2 Dec 2015 14:27:43 +0100 Subject: [PATCH 61/81] fix normalization for 2.5D NFC-HOA driving function for spherically expanded Sound Field --- .../driving_function_mono_nfchoa_sphexp.m | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index 18edd300..fb1de4d9 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -142,7 +142,18 @@ % --- Xref ~= Xc ---------------------------------------------------- % % if the reference position is not in the middle of the array, things - % get a 'little' more complicated + % get a 'little' more complicated + % + % __ + % \ m m + % __ /__ P j (k rref) Y (pi/2, 0) + % 1 \ n=|m| n n n + % D(phi0,w) = ------ /__ ------------------------------ e^(i m phi0) + % 2pi r0 m=-N..N __ + % \ m m + % /__ G j (k rref) Y (pi/2, 0) + % n=|m| n n n + % hn = zeros(size(x0,1),1,Nse+1); jn = hn; @@ -171,7 +182,7 @@ end end - D = D/N0; % normalization due to angular sampling + D = D./(2*pi*r0); % normalization due to size of circular array elseif strcmp('3D',dimension) % === 3-Dimensional ================================================== From e3a945a4e678cb44958136828e8b0893c8508357 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Tue, 9 Feb 2016 15:51:55 +0100 Subject: [PATCH 62/81] fix some dimension issues --- .../driving_function_mono_nfchoa_sht_sphexp.m | 6 +- SFS_monochromatic/sht/sound_field_mono_sht.m | 68 ++++--------------- SFS_monochromatic/sphexp/sphbasis_mono_grid.m | 58 ++++------------ 3 files changed, 30 insertions(+), 102 deletions(-) diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m index da693a50..97396ca2 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m @@ -75,7 +75,9 @@ Xc = conf.secondary_sources.center; r0 = conf.secondary_sources.size / 2; -rref = norm( conf.xref - Xc ); % reference radius +xref = conf.xref - Xc; +rref = norm( xref ); % reference radius +thetaref = asin( norm(xref(3))/rref); % reference elevation angle %% ===== Variables ====================================================== Nse = sqrt(size(Pnm,1))-1; @@ -144,7 +146,7 @@ (-1).^(m) .* ... sqrt( (2*n+1) ./ (4*pi) ) .* ... sqrt( factorial(n-abs(m)) ./ factorial(n+abs(m)) ) .* ... - asslegendre(n,abs(m),0); + asslegendre(n,abs(m), thetaref); v = sphexp_index(m,n); diff --git a/SFS_monochromatic/sht/sound_field_mono_sht.m b/SFS_monochromatic/sht/sound_field_mono_sht.m index b1e68c8d..34b88de5 100644 --- a/SFS_monochromatic/sht/sound_field_mono_sht.m +++ b/SFS_monochromatic/sht/sound_field_mono_sht.m @@ -10,7 +10,7 @@ % Z - z-axis / m; single value or [zmin,zmax] or nD-array % Dnm - spherical harmonics transform of nfchoa driving function % f - frequency in Hz -% conf - optional configuration struct (see SFS_config) +% conf - configuration struct (see SFS_config) % % Output parameters: % P - resulting soundfield @@ -52,81 +52,37 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 5; +nargmin = 6; nargmax = 6; narginchk(nargmin,nargmax); isargvector(Dnm); isargsquaredinteger(length(Dnm)); isargnumeric(X,Y,Z); - -% unique index encoding which dimension is an nd-array -customGrid = (numel(X) > 2) + 2*(numel(Y) > 2) + 4*(numel(Z) > 2); -switch customGrid - case 1 - isargscalar(Y,Z); - case 2 - isargscalar(X,Z); - case 3 - isargequalsize(X,Y); isargscalar(Z); - case 4 - isargscalar(X,Y); - case 5 - isargequalsize(X,Z); isargscalar(Y); - case 6 - isargequalsize(Y,Z); isargscalar(X); - case 7 - isargequalsize(X,Y,Z); - otherwise - isargvector(X,Y,Z); -end - isargpositivescalar(f); -if nargin 2) + 2*(numel(Y) > 2) + 4*(numel(Z) > 2); -switch customGrid - case 1 - isargscalar(Y,Z); - case 2 - isargscalar(X,Z); - case 3 - isargequalsize(X,Y); isargscalar(Z); - case 4 - isargscalar(X,Y); - case 5 - isargequalsize(X,Z); isargscalar(Y); - case 6 - isargequalsize(Y,Z); isargscalar(X); - case 7 - isargequalsize(X,Y,Z); - otherwise - isargvector(X,Y,Z); -end - -isargpositivescalar(f,Nse); -if nargin Date: Wed, 10 Feb 2016 14:38:08 +0100 Subject: [PATCH 63/81] review code for circexp --- SFS_monochromatic/circexp/circbasis_mono.m | 15 ++---- .../circexp/circbasis_mono_grid.m | 46 +++---------------- SFS_monochromatic/circexp/circexp_mono_ls.m | 23 +++------- SFS_monochromatic/circexp/circexp_mono_pw.m | 25 ++++------ .../circexp/circexp_mono_scatter.m | 44 ++++++++++++++---- .../circexp/circexp_mono_timereverse.m | 10 ++-- .../circexp/circexp_mono_translation.m | 17 +++---- .../circexp/circexp_truncation_order.m | 11 ++--- .../circexp/sound_field_mono_circbasis.m | 9 ++-- .../circexp/sound_field_mono_circexp.m | 42 +++++++---------- test_exp_circ.m | 2 +- 11 files changed, 96 insertions(+), 148 deletions(-) diff --git a/SFS_monochromatic/circexp/circbasis_mono.m b/SFS_monochromatic/circexp/circbasis_mono.m index 29a9c02f..be298ca1 100644 --- a/SFS_monochromatic/circexp/circbasis_mono.m +++ b/SFS_monochromatic/circexp/circbasis_mono.m @@ -17,8 +17,8 @@ % CIRCBASIS_MONO(r, phi, Nce, k, conf) computes cylindrical basis functions % for the given arguments r and phi. r and phi can be of arbitrary (but same) % size. Output will be stored in cell arrays (one cell entry for each order) -% of length 2*Nce+1 . Each cell array entry contains a -% matrix of the same size as r and phi. +% of length 2*Nce+1 . Each cell array entry contains a matrix of the same +% size as r and phi. % % References: % Williams (1999) - "Fourier Acoustics", ACADEMIC PRESS @@ -26,12 +26,12 @@ % see also: cylbasis_mono_XYZgrid besselj besselh %***************************************************************************** -% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * % Assessment of IP-based Applications * % Telekom Innovation Laboratories, TU Berlin * % Ernst-Reuter-Platz 7, 10587 Berlin, Germany * % * -% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * % Universitaet Rostock * % Richard-Wagner-Strasse 31, 18119 Rostock * % * @@ -58,17 +58,12 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 4; +nargmin = 5; nargmax = 5; narginchk(nargmin,nargmax); isargequalsize(r,phi); isargscalar(k); isargpositivescalar(Nce); -if nargin 2) + 2*(numel(Y) > 2) + 4*(numel(Z) > 2); -switch customGrid - case 1 - isargscalar(Y,Z); - case 2 - isargscalar(X,Z); - case 3 - isargequalsize(X,Y); isargscalar(Z); - case 4 - isargscalar(X,Y); - case 5 - isargequalsize(X,Z); isargscalar(Y); - case 6 - isargequalsize(Y,Z); isargscalar(X); - case 7 - isargequalsize(X,Y,Z); - otherwise - isargvector(X,Y,Z); -end isargpositivescalar(f,Nce); -if nargin. * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 4; +nargmin = 5; nargmax = 5; narginchk(nargmin,nargmax); isargmatrix(Am); isargscalar(sigma); isargpositivescalar(R); isargvector(f); -if nargin (E|F) (xt) F (x) -% n /__ l=-inf l,n l +% n /__ l=-inf l,n l % % where {E,F} = {R,S}. R denotes the regular circular basis function, while % S symbolizes the singular circular basis function. Note that (S|S) and -% (S|R) are respectively equivalent to (R|R) and (R|S). +% (S|R) are equivalent to (R|R) and (R|S), respectively. % % see also: circexp_mono_ps, circexp_mono_pw %***************************************************************************** -% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * % Assessment of IP-based Applications * % Telekom Innovation Laboratories, TU Berlin * % Ernst-Reuter-Platz 7, 10587 Berlin, Germany * % * -% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * % Universitaet Rostock * % Richard-Wagner-Strasse 31, 18119 Rostock * % * @@ -65,17 +65,12 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 4; +nargmin = 5; nargmax = 5; narginchk(nargmin,nargmax); isargposition(xt); isargchar(mode); isargpositivescalar(Nce,f); -if nargin Date: Wed, 10 Feb 2016 16:13:40 +0100 Subject: [PATCH 64/81] review code for sphexp --- SFS_monochromatic/sht/sound_field_mono_sht.m | 8 +++--- .../sphexp/sound_field_mono_sphbasis.m | 9 +++---- .../sphexp/sound_field_mono_sphexp.m | 26 ++++++------------- SFS_monochromatic/sphexp/sphbasis_mono.m | 7 ++--- SFS_monochromatic/sphexp/sphbasis_mono_grid.m | 4 +-- SFS_monochromatic/sphexp/sphexp_access.m | 6 ++--- .../sphexp/sphexp_convert_circexp.m | 9 ++----- SFS_monochromatic/sphexp/sphexp_index.m | 9 +++---- SFS_monochromatic/sphexp/sphexp_mono_ls.m | 22 +++++----------- .../sphexp/sphexp_mono_multiscatter.m | 12 +++------ SFS_monochromatic/sphexp/sphexp_mono_ps.m | 21 ++++----------- SFS_monochromatic/sphexp/sphexp_mono_pw.m | 21 ++++----------- .../sphexp/sphexp_mono_scatter.m | 19 +++++--------- ...xp_mono_nfchoa_sht.m => sphexp_mono_sht.m} | 18 +++++-------- .../sphexp/sphexp_mono_timereverse.m | 7 ++--- .../sphexp/sphexp_mono_translation.m | 17 +++++------- .../sphexp/sphexp_translation_auxiliary.m | 14 ++++------ SFS_monochromatic/sphexp/sphexp_truncate.m | 10 +++---- .../sphexp/sphexp_truncation_order.m | 17 ++++-------- test_exp_nfchoa.m | 26 +++++++++---------- 20 files changed, 99 insertions(+), 183 deletions(-) rename SFS_monochromatic/sphexp/{sphexp_mono_nfchoa_sht.m => sphexp_mono_sht.m} (92%) diff --git a/SFS_monochromatic/sht/sound_field_mono_sht.m b/SFS_monochromatic/sht/sound_field_mono_sht.m index 34b88de5..b308eb70 100644 --- a/SFS_monochromatic/sht/sound_field_mono_sht.m +++ b/SFS_monochromatic/sht/sound_field_mono_sht.m @@ -20,12 +20,12 @@ % see also: sphbasis_mono_grid, sound_field_mono_sphexp %***************************************************************************** -% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * % Assessment of IP-based Applications * % Telekom Innovation Laboratories, TU Berlin * % Ernst-Reuter-Platz 7, 10587 Berlin, Germany * % * -% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * % Universitaet Rostock * % Richard-Wagner-Strasse 31, 18119 Rostock * % * @@ -76,12 +76,12 @@ P = zeros(size(x)); if any(select(:)) - Pnm = sphexp_mono_nfchoa_sht(Dnm,'R',f,conf); + Pnm = sphexp_mono_sht(Dnm,'R',f,conf); P(select) = sound_field_mono_sphexp(x(select), y(select), z(select), ... Pnm, 'R', f, Xc,conf); end if any(~select(:)) - Pnm = sphexp_mono_nfchoa_sht(Dnm,'S',f,conf); + Pnm = sphexp_mono_sht(Dnm,'S',f,conf); P(~select) = sound_field_mono_sphexp(x(~select), y(~select), z(~select), ... Pnm, 'S', f, Xc,conf); end diff --git a/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m b/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m index fa6b53ba..f5c960d6 100644 --- a/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m +++ b/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m @@ -1,6 +1,6 @@ function P = sound_field_mono_sphbasis(ABnm, jh2n, Ynm) -%SOUND_FIELD_MONO_SPHBASIS simulates a sound field with spherical basis -%functions +%SOUND_FIELD_MONO_SPHBASIS simulates a sound field expressed with spherical +%basis functions % % Usage: P = sound_field_mono_sphbasis(AB, jh2n, Ynm) % @@ -8,7 +8,6 @@ % ABnm - regular/singular spherical expansion coefficients % jh2n - cell array of spherical bessel/hankel(2nd kind) functions % Ynm - cell array of spherical harmonics -% conf - optional configuration struct (see SFS_config) % % Output parameters: % P - resulting soundfield @@ -18,12 +17,12 @@ % see also: sphbasis_mono_grid sound_field_mono_sphexp %***************************************************************************** -% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * % Assessment of IP-based Applications * % Telekom Innovation Laboratories, TU Berlin * % Ernst-Reuter-Platz 7, 10587 Berlin, Germany * % * -% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * % Universitaet Rostock * % Richard-Wagner-Strasse 31, 18119 Rostock * % * diff --git a/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m b/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m index 63ed359a..fcf5cf39 100644 --- a/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m +++ b/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m @@ -2,7 +2,7 @@ %SOUND_FIELD_MONO_SPHEXPR simulates a sound field given with regular/singular %spherical expansion coefficients % -% Usage: [P, x, y, z] = sound_field_mono_sphexp(X,Y,Z,Al,f,x0,conf) +% Usage: [P, x, y, z] = sound_field_mono_sphexp(X,Y,Z,ABnm,mode,f,xq,conf) % % Input parameters: % X - x-axis / m; single value or [xmin,xmax] or nD-array @@ -11,8 +11,8 @@ % ABnm - regular/singular spherical expansion coefficients % mode - 'R' for regular, 'S' for singular % f - frequency in Hz -% xq - optional expansion center coordinates, default: [0, 0, 0] -% conf - optional configuration struct (see SFS_config) +% xq - expansion center coordinates, default: [0, 0, 0] +% conf - configuration struct (see SFS_config) % % Output parameters: % P - resulting soundfield @@ -22,12 +22,12 @@ % see also: sphbasis_mono_grid, sound_field_mono_sphbasis %***************************************************************************** -% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * % Assessment of IP-based Applications * % Telekom Innovation Laboratories, TU Berlin * % Ernst-Reuter-Platz 7, 10587 Berlin, Germany * % * -% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * % Universitaet Rostock * % Richard-Wagner-Strasse 31, 18119 Rostock * % * @@ -54,23 +54,15 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 6; +nargmin = 8; nargmax = 8; narginchk(nargmin,nargmax); isargvector(ABnm); isargsquaredinteger(length(ABnm)); isargnumeric(X,Y,Z); isargpositivescalar(f); -if nargin Date: Fri, 12 Feb 2016 11:38:00 +0100 Subject: [PATCH 65/81] review driving functions --- .../driving_function_mono_nfchoa_sphexp.m | 19 +++++++-------- .../driving_function_mono_wfs_circexp.m | 19 +++++---------- .../driving_function_mono_wfs_sphexp.m | 24 +++++++------------ .../sht/driving_function_mono_nfchoa_sht.m | 15 ++++-------- .../sht/driving_function_mono_nfchoa_sht_ls.m | 15 ++++-------- .../sht/driving_function_mono_nfchoa_sht_ps.m | 15 ++++-------- .../sht/driving_function_mono_nfchoa_sht_pw.m | 15 ++++-------- .../driving_function_mono_nfchoa_sht_sphexp.m | 18 ++++++-------- .../driving_function_mono_wfs_sht_sphexp.m | 14 ++++------- SFS_monochromatic/sht/sound_field_mono_sht.m | 1 + 10 files changed, 55 insertions(+), 100 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index fb1de4d9..c37a4698 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -8,7 +8,7 @@ % x0 - position of the secondary sources / m [nx3] % Pnm - regular spherical expansion coefficients of sound field % f - frequency in Hz -% conf - optional configuration struct (see SFS_config) +% conf - configuration struct (see SFS_config) % % Output parameters: % D - driving function signal [nx1] @@ -20,12 +20,12 @@ % see also: driving_function_mono_wfs_sphexp %***************************************************************************** -% Copyright (c) 2010-2014 Quality & Usability Lab, together with * +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * % Assessment of IP-based Applications * % Telekom Innovation Laboratories, TU Berlin * % Ernst-Reuter-Platz 7, 10587 Berlin, Germany * % * -% Copyright (c) 2013-2014 Institut fuer Nachrichtentechnik * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * % Universitaet Rostock * % Richard-Wagner-Strasse 31, 18119 Rostock * % * @@ -52,17 +52,13 @@ %***************************************************************************** %% ===== Checking of input parameters ================================== -nargmin = 3; +nargmin = 4; nargmax = 4; narginchk(nargmin,nargmax); isargmatrix(x0); isargvector(Pnm); isargpositivescalar(f); -if nargin Date: Wed, 17 Feb 2016 14:37:52 +0100 Subject: [PATCH 66/81] fix bug related to interpretation of xyz grids --- SFS_monochromatic/sht/sound_field_mono_sht.m | 26 +++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/SFS_monochromatic/sht/sound_field_mono_sht.m b/SFS_monochromatic/sht/sound_field_mono_sht.m index 7030c178..ded3ee99 100644 --- a/SFS_monochromatic/sht/sound_field_mono_sht.m +++ b/SFS_monochromatic/sht/sound_field_mono_sht.m @@ -64,11 +64,12 @@ %% ===== Configuration ================================================== Xc = conf.secondary_sources.center; r0 = conf.secondary_sources.size / 2; +useplot = conf.plot.useplot; %% ===== Computation ==================================================== [x,y,z] = xyz_grid(X,Y,Z,conf); % find coordinates, which are inside and outside the loudspeaker array -select = sqrt((x(:)-Xc(1)).^2 + (y(:)-Xc(2)).^2 + (z(:)-Xc(3)).^2) <= r0; +select = sqrt((x-Xc(1)).^2 + (y-Xc(2)).^2 + (z-Xc(3)).^2) <= r0; if (numel(x) == 1) x = repmat(x, size(select)); end if (numel(y) == 1) y = repmat(y, size(select)); end @@ -81,10 +82,29 @@ P(select) = sound_field_mono_sphexp(x(select), y(select), z(select), ... Pnm, 'R', f, Xc,conf); end + if any(~select(:)) Pnm = sphexp_mono_sht(Dnm,'S',f,conf); - P(~select) = sound_field_mono_sphexp(x(~select), y(~select), z(~select), ... - Pnm, 'S', f, Xc,conf); + if sum( ~select(:) ) == 2 + % this handle cases, where x(~select) would only contain 2 entries, which + % would be interpreted as a range by the sound_field_... function + xtmp = x(~select); + ytmp = y(~select); + ztmp = z(~select); + Ptmp(1) = sound_field_mono_sphexp(xtmp(1), ytmp(1), ztmp(1), ... + Pnm, 'S', f, Xc,conf); + Ptmp(2) = sound_field_mono_sphexp(xtmp(2), ytmp(2), ztmp(2), ... + Pnm, 'S', f, Xc,conf); + P(~select) = [Ptmp(1); Ptmp(2)]; + else + P(~select) = sound_field_mono_sphexp(x(~select), y(~select), z(~select), ... + Pnm, 'S', f, Xc,conf); + end +end + +%% ===== Plotting ======================================================= +if (nargout==0 || useplot) + plot_sound_field(P,X,Y,Z,[],conf); end end \ No newline at end of file From 90d5026077876882e4c8f4c017e9371cfdcde36e Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 18 Feb 2016 18:21:17 +0100 Subject: [PATCH 67/81] support vectors for temporal frequency in nfchoa_sphexp driving function --- .../driving_function_mono_nfchoa_sphexp.m | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index c37a4698..da071f49 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -5,9 +5,10 @@ % Usage: D = driving_function_mono_nfchoa_sphexp(x0,Pnm,f,conf) % % Input parameters: -% x0 - position of the secondary sources / m [nx3] +% x0 - position of the secondary sources / m [N0x3] % Pnm - regular spherical expansion coefficients of sound field -% f - frequency in Hz +% [N x Nf] +% f - frequency / Hz [Nf x 1] or [1 x Nf] % conf - configuration struct (see SFS_config) % % Output parameters: @@ -55,9 +56,9 @@ nargmin = 4; nargmax = 4; narginchk(nargmin,nargmax); -isargmatrix(x0); -isargvector(Pnm); -isargpositivescalar(f); +isargsecondarysource(x0); +isargmatrix(Pnm); +isargvector(f); isargstruct(conf); if mod(sqrt(size(Pnm, 1)),1) ~= 0 error(['%s: number of columns of Pnm (%s) is not the square of an', ... @@ -83,16 +84,16 @@ [phi0, ~,r0] = cart2sph(x00(:,1),x00(:,2),x00(:,3)); % frequency depended stuff -omega = 2*pi*f; -k = omega/c; -kr0 = k.*r0; +omega = 2*pi*row_vector(f); % [1 x Nf] +k = omega./c; % [1 x Nf] +kr0 = r0 * k; % [N0 x Nf] % reference radius [~, ~, rref] = cart2sph(xref(1),xref(2),xref(3)); -krref = k.*rref; +krref = k.*rref; % [1 x Nf] % initialize empty driving signal -D = zeros(size(x0,1),1); +D = zeros(size(kr0)); % [N0 x Nf] %% ===== Computation ==================================================== % Calculate the driving function in time-frequency domain @@ -130,11 +131,12 @@ % n n n for m=-Nse:Nse - D = D + sphexp_access(Pnm, m) ./ ... - (sphbesselh(abs(m),2,kr0) .* sphharmonics(abs(m),-m, 0, 0) ) ... - .* exp(1i.*m.*phi0); + v = sphexp_index(m); + D = D + bsxfun(@times, Pnm(v,:), exp(1i.*m.*phi0)) ./ ... + ( sphbesselh(abs(m),2,kr0) .* sphharmonics(abs(m),-m, 0, 0) ); end - D = D./(-1i*k); % factor from expansion of 3D free field Green's Function + % factor from expansion of 3D free field Green's Function + D = bsxfun(@rdivide, D, -1i*k); else % --- Xref ~= Xc ---------------------------------------------------- % @@ -143,17 +145,17 @@ % % __ % \ m m - % __ /__ P j (k rref) Y (pi/2, 0) + % __ /__ P j (k rref) Y (thetaref, 0) % 1 \ n=|m| n n n - % D(phi0,w) = ------ /__ ------------------------------ e^(i m phi0) + % D(phi0,w) = ------ /__ --------------------------------- e^(i m phi0) % 2pi r0 m=-N..N __ % \ m m - % /__ G j (k rref) Y (pi/2, 0) + % /__ G j (k rref) Y (thetaref, 0) % n=|m| n n n % - hn = zeros(size(x0,1),1,Nse+1); - jn = hn; + hn = zeros(size(x0,1),length(omega),Nse+1); + jn = zeros(1,length(omega),Nse+1); for n=0:Nse hn(:,:,n+1) = sphbesselh(n,2,kr0); jn(:,:,n+1) = sphbesselj(n,krref); @@ -162,24 +164,26 @@ for m=-Nse:Nse Pm = 0; Gm = 0; - % for theta=0 the legendre polynom is zero if n+m is odd - for n=abs(m):2:Nse + for n=abs(m):Nse factor = jn(:,:,n+1) .* ... (-1).^(m) .* ... sqrt( (2*n+1) ./ (4*pi) ) .* ... sqrt( factorial(n-abs(m)) ./ factorial(n+abs(m)) ) .* ... - asslegendre(n,abs(m), sin(thetaref)); + asslegendre(n,abs(m), sin(thetaref)); % [1 x Nf] - Pm = Pm + sphexp_access(Pnm, m, n) .* factor; + v = sphexp_index(m, n); - Gm = Gm + (-1i*k) .* hn(:,:,n+1) .* sphharmonics(n, -m, 0, 0) .* factor; + Pm = Pm + Pnm(v,:) .* factor; % [1 x Nf] + + Gm = Gm + sphharmonics(n, -m, 0, 0) .* ... + bsxfun(@times, hn(:,:,n+1), (-1i*k).*factor); % [N0 x Nf] end - D = D + Pm ./ Gm .* exp(1i.*m.*phi0); + D = D + (exp(1i.*m.*phi0) * Pm) ./ Gm; % [N0 x Nf] end end - - D = D./(2*pi*r0); % normalization due to size of circular array + % normalization due to size of circular array + D = bsxfun(@rdivide, D, 2*pi*r0); elseif strcmp('3D',dimension) % === 3-Dimensional ================================================== From f14513a43aa59e4fbbe10f96fe1f737470beb96e Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 19 Feb 2016 14:08:33 +0100 Subject: [PATCH 68/81] fix SFS_config call --- test_exp_wfs.m | 2 +- test_sphexp.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test_exp_wfs.m b/test_exp_wfs.m index ac55cd21..892c53f6 100644 --- a/test_exp_wfs.m +++ b/test_exp_wfs.m @@ -5,7 +5,7 @@ SFS_start; %% Parameters -conf = SFS_config_example; +conf = SFS_config; conf.showprogress = true; conf.dimension = '2D'; diff --git a/test_sphexp.m b/test_sphexp.m index a1f648e0..1bf7c44b 100644 --- a/test_sphexp.m +++ b/test_sphexp.m @@ -5,7 +5,7 @@ SFS_start; %% Parameters -conf = SFS_config_example; +conf = SFS_config; conf.dimension = '2.5D'; From 36a557d4b8847b945b2e658f97a139928a103b35 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 23 Jun 2016 12:23:49 +0200 Subject: [PATCH 69/81] fix bug in circular translation coefficients --- .../circexp/circexp_mono_translation.m | 4 ++-- test_exp_circ.m | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/SFS_monochromatic/circexp/circexp_mono_translation.m b/SFS_monochromatic/circexp/circexp_mono_translation.m index 700202cd..c352997c 100644 --- a/SFS_monochromatic/circexp/circexp_mono_translation.m +++ b/SFS_monochromatic/circexp/circexp_mono_translation.m @@ -104,8 +104,8 @@ l = 0; for m=-Nce:Nce l = l+1; - EF(s,l) = circbasis(n-m) .* exp(-1j.*(n-m).*phit); - EFm(s,l) = EF(s,l) .* (-1)^(n-m); + EFm(s,l) = circbasis(n-m) .* exp(-1j.*(n-m).*phit); + EF(s,l) = EFm(s,l) .* (-1)^(n-m); end end diff --git a/test_exp_circ.m b/test_exp_circ.m index 0cb920dc..d48b9b85 100644 --- a/test_exp_circ.m +++ b/test_exp_circ.m @@ -23,7 +23,7 @@ f = 1000; -xq = [ 0, 0, 0]; +xq = [0, 0, 0]; conf.xref = xq; @@ -36,13 +36,13 @@ % regular circular expansion at xq Apwm = circexp_mono_pw(ns, Nce,f,xq,conf); Alsm = circexp_mono_ls(xs, 'R', Nce,f,xq,conf); -% regular circular expansion at xq+xt +% regular circular expansion at xq+xt (x' = x - xt) Apwm_t = circexp_mono_pw(ns,Nce,f,xq+xt,conf); Alsm_t = circexp_mono_ls(xs, 'R', Nce,f,xq+xt,conf); -% regular-to-regular cylindrical reexpansion (translatory shift) -[RR, RRm] = circexp_mono_translation(xt,'RR',Nce,f,conf); -Apwm_re = RRm*Apwm; -Alsm_re = RRm*Alsm; +% regular-to-regular cylindrical reexpansion (translatory shift of -xt) +[RR, RRm] = circexp_mono_translation(-xt,'RR',Nce,f,conf); +Apwm_re = RR*Apwm_t; +Alsm_re = RR*Alsm_t; %% Sound Fields % Evaluate spherical basis functions on regular grid @@ -58,8 +58,8 @@ Ppwm_t = sound_field_mono_circbasis(Apwm_t, Jm_t, Ym_t); Plsm_t = sound_field_mono_circbasis(Alsm_t, Jm_t, Ym_t); % compute field for cylindrical reexpansion (translatory shift) -Ppwm_re = sound_field_mono_circbasis(Apwm_re, Jm, Ym_t); -Plsm_re = sound_field_mono_circbasis(Alsm_re, Jm, Ym_t); +Ppwm_re = sound_field_mono_circbasis(Apwm_re, Jm, Ym); +Plsm_re = sound_field_mono_circbasis(Alsm_re, Jm, Ym); % plot plot_sound_field(Ppwm ,X, Y, Z, [], conf); From c9bf9330d89bd236863826fde6d36a43ee6f361c Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 23 Jun 2016 19:34:57 +0200 Subject: [PATCH 70/81] simplify circular translation further --- SFS_monochromatic/circexp/circexp_mono_translation.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SFS_monochromatic/circexp/circexp_mono_translation.m b/SFS_monochromatic/circexp/circexp_mono_translation.m index c352997c..d27c1928 100644 --- a/SFS_monochromatic/circexp/circexp_mono_translation.m +++ b/SFS_monochromatic/circexp/circexp_mono_translation.m @@ -104,8 +104,8 @@ l = 0; for m=-Nce:Nce l = l+1; - EFm(s,l) = circbasis(n-m) .* exp(-1j.*(n-m).*phit); - EF(s,l) = EFm(s,l) .* (-1)^(n-m); + EF(s,l) = circbasis(m-n) .* exp(+1j.*(m-n).*phit); + EFm(s,l) = EF(s,l) .* (-1)^(n-m); end end From a56e6d25654aae151821ed31f96bedd1a18e60c5 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 23 Jun 2016 19:35:23 +0200 Subject: [PATCH 71/81] rename some variables in test script for spherical expansions --- test_sphexp.m | 60 ++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/test_sphexp.m b/test_sphexp.m index 1bf7c44b..63a3242f 100644 --- a/test_sphexp.m +++ b/test_sphexp.m @@ -21,26 +21,28 @@ Y = [-2 2]; Z = 0; -f = 500; -Nse = 10; +f = 1000; +Nse = 20; % scatterer sigma = inf; % admittance of scatterer (inf to soft scatterer) R = 0.3; -xq = [ 0, -1, 0]; -xt = [ 0.5, 0.5, 0]; +xq = [ 0, 0, 0]; +xt = [ 0.5, 0, 0]; conf.xref = xq; + %% Spherical Expansion -% spherical expansion -A1sph = sphexp_mono_pw(ns,Nse,f,xq,conf); -A1sph_shift = sphexp_mono_pw(ns,Nse,f,xq+xt,conf); -A2sph = sphexp_mono_ps(xs,'R',Nse, f,xq,conf); -A2sph_shift = sphexp_mono_ps(xs,'R', Nse, f,xq+xt,conf); -% regular-to-regular spherical reexpansion (translatory shift) -[RRsph, RRsphm] = sphexp_mono_translation(xt, 'RR', Nse, f, conf); -A1spht = RRsph*A1sph; -A2spht = RRsph*A2sph; +% regular spherical expansion at xq +Apwsph = sphexp_mono_pw(ns,Nse,f,xq,conf); +Apssph = sphexp_mono_ps(xs,'R',Nse, f,xq,conf); +% regular spherical expansion at xq+xt (x' = x - xt) +Apwsph_t = sphexp_mono_pw(ns,Nse,f,xq+xt,conf); +Apssph_t = sphexp_mono_ps(xs,'R', Nse, f,xq+xt,conf); +% regular-to-regular spherical reexpansion (translatory shift of -xt) +[RRsph, RRsphm] = sphexp_mono_translation(-xt, 'RR', Nse, f, conf); +A1sph_re = RRsph*Apwsph_t; +A2sph_re = RRsph*Apssph_t; % Evaluate spherical basis functions [jn, h2n, Ynm] = ... @@ -50,37 +52,37 @@ sphbasis_mono_grid(X, Y, Z,Nse,f,xq+xt,conf); % compute fields -P1sph = sound_field_mono_sphbasis(A1sph, jn, Ynm); -P1sph_shift = sound_field_mono_sphbasis(A1sph_shift, jnt, Ynmt); -P1spht = sound_field_mono_sphbasis(A1spht, jnt, Ynmt); -P2sph = sound_field_mono_sphbasis(A2sph, jn, Ynm); -P2sph_shift = sound_field_mono_sphbasis(A2sph_shift, jnt, Ynmt); -P2spht = sound_field_mono_sphbasis(A2spht, jnt, Ynmt); +Ppwsph = sound_field_mono_sphbasis(Apwsph, jn, Ynm); +Ppwsph_t = sound_field_mono_sphbasis(Apwsph_t, jnt, Ynmt); +Ppwsph_re = sound_field_mono_sphbasis(A1sph_re, jn, Ynm); +Ppssph = sound_field_mono_sphbasis(Apssph, jn, Ynm); +Ppssph_t = sound_field_mono_sphbasis(Apssph_t, jnt, Ynmt); +Ppssph_re = sound_field_mono_sphbasis(A2sph_re, jn, Ynm); -plot_sound_field(P1sph ,X, Y, Z, [], conf); +plot_sound_field(Ppwsph ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('plane wave'); -plot_sound_field(P1sph_shift ,X, Y, Z, [], conf); +plot_sound_field(Ppwsph_t ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('plane wave (shifted expansion)'); -plot_sound_field(P1spht ,X, Y, Z, [], conf); +plot_sound_field(Ppwsph_re ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('plane wave (shifted reexpansion)'); -plot_sound_field(P2sph ,X, Y, Z, [], conf); +plot_sound_field(Ppssph ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('point source'); -plot_sound_field(P2sph_shift ,X, Y, Z, [], conf); +plot_sound_field(Ppssph_t ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('point source (shifted expansion)'); -plot_sound_field(P2spht ,X, Y, Z, [], conf); +plot_sound_field(Ppssph_re ,X, Y, Z, [], conf); plot_scatterer(xq,R); title('point source (shifted reexpansion)'); %% Scattering with Sphere % scatterer is assumed to be located at coordinates origin -B1sph = sphexp_mono_scatter(A1sph, R, sigma, f, conf); -B2sph = sphexp_mono_scatter(A2sph, R, sigma, f, conf); +B1sph = sphexp_mono_scatter(Apwsph, R, sigma, f, conf); +B2sph = sphexp_mono_scatter(Apssph, R, sigma, f, conf); % compute fields -P1sph_scatter = sound_field_mono_sphbasis(B1sph, h2n, Ynm); -P2sph_scatter = sound_field_mono_sphbasis(B2sph, h2n, Ynm); \ No newline at end of file +Ppwsph_scatter = sound_field_mono_sphbasis(B1sph, h2n, Ynm); +Ppssph_scatter = sound_field_mono_sphbasis(B2sph, h2n, Ynm); \ No newline at end of file From 5e762fb2b22a73aea8d5714f7ee8b6104b2c2cb7 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Wed, 29 Jun 2016 16:17:36 +0200 Subject: [PATCH 72/81] add 2.5D driving functions for wfs and validation routine --- .../circexp/circexp_convert_sphexp.m | 64 ++++++++ .../driving_function_mono_wfs_circexp.m | 99 ++++++------ .../driving_function_mono_wfs_sphexp.m | 113 ++++++++------ validation/test_wfs_exp.m | 145 ++++++++++++++++++ 4 files changed, 327 insertions(+), 94 deletions(-) create mode 100644 SFS_monochromatic/circexp/circexp_convert_sphexp.m create mode 100644 validation/test_wfs_exp.m diff --git a/SFS_monochromatic/circexp/circexp_convert_sphexp.m b/SFS_monochromatic/circexp/circexp_convert_sphexp.m new file mode 100644 index 00000000..a95a95a5 --- /dev/null +++ b/SFS_monochromatic/circexp/circexp_convert_sphexp.m @@ -0,0 +1,64 @@ +function Am = circexp_convert_sphexp(Anm) +%CIRCEXP_CONVERT_SPHEXP converts regular spherical expansion coefficients into +%regular circular expansion coefficients +% +% Usage: Am = circexp_convert_sphexp(Anm) +% +% Input parameters: +% Anm - regular spherical expansion coefficients +% +% Output parameters: +% Am - regular circular expansion coefficients +% +% References: +% Hahn, Winter, Spors (2016) - +% "Local Wave Field Synthesis by Spatial Band-limitation in the +% Circular/Spherical Harmonics Domain", 140th AES Convention + +%***************************************************************************** +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 1; +nargmax = 1; +narginchk(nargmin,nargmax); +isargvector(Anm); +Nse = sqrt(size(Anm, 1))-1; + +%% ===== Computation ==================================================== + +% Implementation of Hahn2016, Eq. (32) +Am = zeros(2*Nse+1,size(Anm, 2)); +for m=-Nse:Nse + v = sphexp_index(m); % (n,m) = (abs(m),m); + Am(m+Nse+1,:) = Anm(v,:)./(4*pi.*1j.^(m-abs(m))*sphharmonics(abs(m),-m,0,0)); +end diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m index ba155c49..c03a7fc1 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m @@ -1,5 +1,5 @@ function D = driving_function_mono_wfs_circexp(x0,n0,Pm,mode,f,xq,conf) -%computes the wfs driving functions for a sound field expressed by cylindrical +%computes the wfs driving functions for a sound field expressed by cylindrical %expansion coefficients. % % Usage: D = driving_function_mono_wfs_circexp(x0,n0,Pm,mode,f,xq,conf) @@ -68,6 +68,7 @@ isargposition(xq); %% ===== Configuration ================================================== +xref = conf.xref; c = conf.c; dimension = conf.dimension; driving_functions = conf.driving_functions; @@ -93,13 +94,13 @@ Gradphi = zeros(size(x0,1),1); Gradz = zeros(size(x0,1),1); -% directional weights for conversion spherical gradient into carthesian -% coordinates + point product with normal vector n0 (directional derivative +% directional weights for conversion spherical gradient into carthesian +% coordinates + point product with normal vector n0 (directional derivative % in cartesian coordinates) Sn0r = cos(phi0).*n0(:,1)... - + sin(phi0).*n0(:,2); + + sin(phi0).*n0(:,2); Sn0phi = -sin(phi0).*n0(:,1)... - + cos(phi0).*n0(:,2); + + cos(phi0).*n0(:,2); Sn0z = n0(:,3); % select suitable basis function @@ -119,45 +120,53 @@ % indexing the expansion coefficients l = 0; -if strcmp('2D',dimension) || strcmp('3D',dimension) - - % === 2- or 3-Dimensional ============================================ - - if (strcmp('default',driving_functions)) - % --- SFS Toolbox ------------------------------------------------ - % d - % D(x0, w) = -2 --- P(x0,w) - % d n - % with cylindrical expansion of the sound field: - % \~~ oo - % P(x,w) = > B F (x-xq) - % /__ n=-oo n n - % - % where F = {R,S}. - % - % regular cylindrical basis functions: - % - % R (x) = J (kr) . exp(j n phi)) - % n n - % singular cylindrical basis functions - % (2) - % S (x) = H (kr) . exp(j n phi) - % n n - - for n=-Nce:Nce - l = l + 1; - cn_prime = k.*circbasis_derived(n,kr0); - cn = circbasis(n,kr0); - Yn = exp(1j.*n.*phi0); - Gradr = Gradr + ( Pm(l).*cn_prime.*Yn ); - Gradphi = Gradphi + 1./r0.*( Pm(l).*cn.*1j.*n.*Yn ); +switch dimension + case {'2D', '2.5D', '3D'} + + % === 2- or 3-Dimensional ============================================ + + if (strcmp('default',driving_functions)) + % --- SFS Toolbox ------------------------------------------------ + % d + % D(x0, w) = -2 --- P(x0,w) + % d n + % with cylindrical expansion of the sound field: + % \~~ oo + % P(x,w) = > B F (x-xq) + % /__ n=-oo n n + % + % where F = {R,S}. + % + % regular cylindrical basis functions: + % + % R (x) = J (kr) . exp(j n phi)) + % n n + % singular cylindrical basis functions + % (2) + % S (x) = H (kr) . exp(j n phi) + % n n + + for n=-Nce:Nce + l = l + 1; + cn_prime = k.*circbasis_derived(n,kr0); + cn = circbasis(n,kr0); + Yn = exp(1j.*n.*phi0); + Gradr = Gradr + ( Pm(l).*cn_prime.*Yn ); + Gradphi = Gradphi + 1./r0.*( Pm(l).*cn.*1j.*n.*Yn ); + end + % directional gradient + D = -2*( Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0z.*Gradz ); + + % 2.5D correction factor + if strcmp('2.5D', dimension) + xref = repmat(xref,[size(x0,1) 1]); + g0 = sqrt( 2*pi*vector_norm(xref-x0, 2)./(1j.*k)); + D = D.*g0; + end + else + error(['%s: %s, this type of driving function is not implemented ', ... + 'for 2D/3D.'],upper(mfilename),driving_functions); end - % directional gradient - D = -2*( Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0z.*Gradz ); - else - error(['%s: %s, this type of driving function is not implemented ', ... - 'for 2D/3D.'],upper(mfilename),driving_functions); - end -else - error('%s: the dimension %s is unknown.',upper(mfilename),dimension); + otherwise + error('%s: the dimension %s is unknown.',upper(mfilename),dimension); end diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m index 92c97982..432a2320 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m @@ -1,5 +1,5 @@ function D = driving_function_mono_wfs_sphexp(x0,n0,Pnm,mode,f,xq,conf) -%computes the wfs driving functions for a sound field expressed by spherical +%computes the wfs driving functions for a sound field expressed by spherical %expansion coefficients. % % Usage: D = driving_function_mono_wfs_sphexp(x0,n0,Pnm,mode,f,xq,conf) @@ -66,7 +66,7 @@ isargvector(Pnm); isargpositivescalar(f); isargchar(mode); -isargposition(xq); +isargposition(xq); isargstruct(conf); %% ===== Configuration ================================================== @@ -101,14 +101,14 @@ % coordinates + point product with normal vector n0 (directional derivative % in cartesian coordinates) Sn0r = cos(theta0).*cos(phi0).*n0(:,1)... - + cos(theta0).*sin(phi0).*n0(:,2)... - + sin(theta0) .*n0(:,3); + + cos(theta0).*sin(phi0).*n0(:,2)... + + sin(theta0) .*n0(:,3); Sn0phi = -sin(phi0) .*n0(:,1)... - + cos(phi0) .*n0(:,2); + + cos(phi0) .*n0(:,2); Sn0theta = sin(theta0).*cos(phi0).*n0(:,1)... - + sin(theta0).*sin(phi0).*n0(:,2)... - - cos(theta0) .*n0(:,3); - + + sin(theta0).*sin(phi0).*n0(:,2)... + - cos(theta0) .*n0(:,3); + % select suitable basis function if strcmp('R', mode) sphbasis = @sphbesselj; @@ -126,47 +126,62 @@ % indexing the expansion coefficients l = 0; -if strcmp('2D',dimension) || strcmp('3D',dimension) - - if (strcmp('default',driving_functions)) - % --- SFS Toolbox ------------------------------------------------ - % - % d - % D(x0, w) = -2 ------ P(x0,w) - % d n0 - % with regular/singular spherical expansion of the sound field: - % \~~ N \~~ n m m - % P(x,w) = > > B F (x-xq) - % /__ n=0 /__ m=-n n n - % - % where F = {R,S}. - % - % regular spherical basis functions: - % m m - % R (x) = j (kr) . Y (theta, phi) - % n n n - % singular spherical basis functions: - % m (2) m - % S (x) = h (kr) . Y (theta, phi) - % n n n - - for n=0:Nse - cn_prime = k.*sphbasis_derived(n,kr); - cn = sphbasis(n, kr); - for m=-n:n - l = l + 1; - Ynm = sphharmonics(n,m, theta0, phi0); - Gradr = Gradr + ( Pnm(l).*cn_prime.*Ynm); - Gradphi = Gradphi + 1./r0.*( Pnm(l).*cn.*1j.*m.*Ynm ); - %Gradtheta = 0; TODO +switch dimension + case {'3D'} + + if (strcmp('default',driving_functions)) + % --- SFS Toolbox ------------------------------------------------ + % + % d + % D(x0, w) = -2 ------ P(x0,w) + % d n0 + % with regular/singular spherical expansion of the sound field: + % \~~ N \~~ n m m + % P(x,w) = > > B F (x-xq) + % /__ n=0 /__ m=-n n n + % + % where F = {R,S}. + % + % regular spherical basis functions: + % m m + % R (x) = j (kr) . Y (theta, phi) + % n n n + % singular spherical basis functions: + % m (2) m + % S (x) = h (kr) . Y (theta, phi) + % n n n + + for n=0:Nse + cn_prime = k.*sphbasis_derived(n,kr); + cn = sphbasis(n, kr); + for m=-n:n + l = l + 1; + Ynm = sphharmonics(n,m, theta0, phi0); + Gradr = Gradr + Pnm(l).*cn_prime.*Ynm; + Gradphi = Gradphi + 1./r0.*Pnm(l).*cn.*1j.*m.*Ynm; + Gradtheta = Gradtheta + 1./(r0.*cos(theta0).^2).*cn.*Pnm(l).*... + ( (n+1).*sin(theta0).*Ynm - ... + sqrt((2*n+1)./(2*n+3).*((n+1).^2-m^2)).* ... + sphharmonics(n+1,m, theta0, phi0) ); + end end + % directional gradient + D = -2*( Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0theta.*Gradtheta ); + else + error(['%s: %s, this type of driving function is not implemented ', ... + 'for 3D'],upper(mfilename),driving_functions); end - % directional gradient - D = -2*( Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0theta.*Gradtheta ); - else - error(['%s: %s, this type of driving function is not implemented ', ... - 'for 2D/3D'],upper(mfilename),driving_functions); - end -else - error('%s: the dimension %s is unknown.',upper(mfilename),dimension); + + case {'2D', '2.5D'} + if (strcmp('default',driving_functions)) + % approximate spherical expansion with circular expansion + Pm = circexp_convert_sphexp(Pnm); + % compute driving function for circular expansion + D = driving_function_mono_wfs_circexp(x0,n0,Pm,mode,f,xq,conf); + else + error(['%s: %s, this type of driving function is not implemented ', ... + 'for 2D/2.5D'],upper(mfilename),driving_functions); + end + otherwise + error('%s: the dimension %s is unknown.',upper(mfilename),dimension); end diff --git a/validation/test_wfs_exp.m b/validation/test_wfs_exp.m new file mode 100644 index 00000000..6301478a --- /dev/null +++ b/validation/test_wfs_exp.m @@ -0,0 +1,145 @@ +function boolean = test_wfs_exp +%TEST_WFS_EXP tests the correctness of the driving functions + +%***************************************************************************** +% The MIT License (MIT) * +% * +% Copyright (c) 2010-2016 SFS Toolbox Developers * +% * +% Permission is hereby granted, free of charge, to any person obtaining a * +% copy of this software and associated documentation files (the "Software"), * +% to deal in the Software without restriction, including without limitation * +% the rights to use, copy, modify, merge, publish, distribute, sublicense, * +% and/or sell copies of the Software, and to permit persons to whom the * +% Software is furnished to do so, subject to the following conditions: * +% * +% The above copyright notice and this permission notice shall be included in * +% all copies or substantial portions of the Software. * +% * +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * +% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * +% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * +% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * +% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * +% DEALINGS IN THE SOFTWARE. * +% * +% The SFS Toolbox allows to simulate and investigate sound field synthesis * +% methods like wave field synthesis or higher order ambisonics. * +% * +% http://sfstoolbox.org sfstoolbox@gmail.com * +%***************************************************************************** + +% TODO: add mode to save data as reference data + + +%% ===== Checking of input parameters =================================== +nargmin = 0; +nargmax = 0; +narginchk(nargmin,nargmax); + + +%% ===== Configuration =================================================== +conf = SFS_config; +conf.secondary_sources.size = 3; +f = 1000; +conf.plot.useplot = false; +conf.plot.usenormalisation = true; +conf.plot.normalisation = 'center'; +conf.driving_functions = 'default'; +conf.usetapwin = false; +Nce = 15; + +% test scenarios +scenarios = { ... + 'WFS', '2D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'WFS', '2D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'WFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'WFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'WFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'WFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'WFS', '2.5D', 'circular', 'ps', [ 0.0 2.5 0.0], 'sph'; ... + 'WFS', '3D', 'sphere', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'WFS', '3D', 'sphere', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'WFS', '3D', 'sphere', 'ps', [ 0.0 2.5 0.0], 'sph'; ... +}; + +% Start testing +for ii=1:size(scenarios) + + % get current dimension + conf.dimension = scenarios{ii,2}; + + % get source type and position + src = scenarios{ii,4}; + xs = scenarios{ii,5}; + + % get secondary source type + switch conf.dimension + case '2D' + secsrc = 'ls'; + case {'2.5D', '3D'} + secsrc = 'ps'; + end + + % get secondary source distribution + conf.secondary_sources.geometry = scenarios{ii,3}; + switch conf.secondary_sources.geometry + case 'linear' + X = [-2 2]; + Y = [-3 0.15]; + Z = 0; + conf.xref = [0 -1.5 0]; + conf.secondary_sources.number = 20; + case 'circular' + X = [-2 2]; + Y = [-2 2]; + Z = 0; + conf.xref = [0 0 0]; + conf.secondary_sources.number = 56; + case 'box' + X = [-2 2]; + Y = [-2 2]; + Z = 0; + conf.xref = [0 0 0]; + conf.secondary_sources.number = 80; + case 'sphere' + X = [-2 2]; + Y = [-2 2]; + Z = 0; + conf.xref = [0 0 0]; + conf.secondary_sources.number = 900; + end + x0 = secondary_source_positions(conf); + + % get expansion coefficients + xq = conf.xref; + fname = [scenarios{ii,6}, 'exp_mono_', src]; + expfunc = str2func(fname); + switch src + case 'pw' + A = expfunc(xs, Nce,f,xq,conf); + case 'ls' + A = expfunc(xs,'R', Nce,f,xq,conf); + case 'ps' + A = expfunc(xs,'R', Nce,f,xq,conf); + end + + % get method + method = scenarios{ii,1}; + + % ===== WFS ========================================================== + if strcmp('WFS',method) + x0 = secondary_source_selection(x0,xs,src); + x0 = secondary_source_tapering(x0,conf); + + Dfunc = str2func(['driving_function_mono_wfs_', scenarios{ii,6}, 'exp']); + + D = Dfunc(x0(:,1:3),x0(:,4:6),A,'R',f,xq,conf); + P = sound_field_mono(X,Y,Z,x0,secsrc,D,f,conf); + plot_sound_field(P, X, Y, Z, x0, conf); + end + + title(sprintf('%s %s of %s. exp. of %s', conf.dimension, method, ... + scenarios{ii,6}, src), 'Interpreter', 'None'); +end From f3c9cd5e02aec9c939aa2d4542e99a3c2894d478 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Wed, 29 Jun 2016 16:32:52 +0200 Subject: [PATCH 73/81] add LWFS with virtual scatterer to validation function --- validation/test_wfs_exp.m | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/validation/test_wfs_exp.m b/validation/test_wfs_exp.m index 6301478a..230bc21d 100644 --- a/validation/test_wfs_exp.m +++ b/validation/test_wfs_exp.m @@ -48,7 +48,9 @@ conf.plot.normalisation = 'center'; conf.driving_functions = 'default'; conf.usetapwin = false; -Nce = 15; + +rt = 1.0; % "size" of the sweet spot +Nce = circexp_truncation_order(rt, f, 1e-6, conf); % order for sweet spot % test scenarios scenarios = { ... @@ -62,6 +64,16 @@ 'WFS', '3D', 'sphere', 'pw', [ 0.5 0.5 0.0], 'sph'; ... 'WFS', '3D', 'sphere', 'ls', [ 0.0 2.5 0.0], 'sph'; ... 'WFS', '3D', 'sphere', 'ps', [ 0.0 2.5 0.0], 'sph'; ... + 'LWFS', '2D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'LWFS', '2D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'LWFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'LWFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'LWFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'LWFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'LWFS', '2.5D', 'circular', 'ps', [ 0.0 2.5 0.0], 'sph'; ... + 'LWFS', '3D', 'sphere', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'LWFS', '3D', 'sphere', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'LWFS', '3D', 'sphere', 'ps', [ 0.0 2.5 0.0], 'sph'; ... }; % Start testing @@ -138,7 +150,27 @@ D = Dfunc(x0(:,1:3),x0(:,4:6),A,'R',f,xq,conf); P = sound_field_mono(X,Y,Z,x0,secsrc,D,f,conf); plot_sound_field(P, X, Y, Z, x0, conf); + % ===== local WFS ==================================================== + elseif strcmp('LWFS',method) + x0 = secondary_source_selection(x0,xs,src); + x0 = secondary_source_tapering(x0,conf); + + % compute timereversed incident field + Tfunc = str2func([scenarios{ii,6}, 'exp_mono_timereverse']); + A_rev = Tfunc(A); + + % compute scattered, timereversed field + Sfunc = str2func([scenarios{ii,6}, 'exp_mono_scatter']); + B = Sfunc(A_rev, rt, inf, f, conf); + + % compute driving function + Dfunc = str2func(['driving_function_mono_wfs_', scenarios{ii,6}, 'exp']); + D = Dfunc(x0(:,1:3),x0(:,4:6),B,'S',f,xq,conf); + + P = sound_field_mono(X,Y,Z,x0,secsrc,conj(D),f,conf); + plot_sound_field(P, X, Y, Z, x0, conf); end + title(sprintf('%s %s of %s. exp. of %s', conf.dimension, method, ... scenarios{ii,6}, src), 'Interpreter', 'None'); From d42c91d34c9d4a2003356fc0f04ed14213647c77 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 30 Jun 2016 11:21:38 +0200 Subject: [PATCH 74/81] add NFCHOA for circexp and shpexp to validation function --- .../driving_function_mono_nfchoa_circexp.m | 129 +++++++++++ .../driving_function_mono_nfchoa_sphexp.m | 57 +++-- .../driving_function_mono_wfs_circexp.m | 88 ++++---- .../driving_function_mono_wfs_sphexp.m | 2 +- validation/test_sfs_exp.m | 203 ++++++++++++++++++ validation/test_wfs_exp.m | 177 --------------- 6 files changed, 412 insertions(+), 244 deletions(-) create mode 100644 SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_circexp.m create mode 100644 validation/test_sfs_exp.m delete mode 100644 validation/test_wfs_exp.m diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_circexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_circexp.m new file mode 100644 index 00000000..ffed1a9e --- /dev/null +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_circexp.m @@ -0,0 +1,129 @@ +function D = driving_function_mono_nfchoa_circexp(x0, Pm,f,conf) +%computes the nfchoa driving functions for a sound field expressed by regular +%spherical expansion coefficients. +% +% Usage: D = driving_function_mono_nfchoa_circexp(x0,Pm,f,conf) +% +% Input parameters: +% x0 - position of the secondary sources / m [N0x3] +% Pm - regular circular expansion coefficients of sound field +% [N x Nf] +% f - frequency / Hz [Nf x 1] or [1 x Nf] +% conf - configuration struct (see SFS_config) +% +% Output parameters: +% D - driving function signal [nx1] +% +% DRIVING_FUNCTION_MONO_NFCHOA_CIRCEXP(x0,Pm,f,conf) returns the NFCHOA +% driving signals for the given secondary sources x0, the virtual sound ex- +% pressed by regular circular expansion coefficients Pm, and the frequency f. +% +% see also: driving_function_mono_wfs_circexp +% driving_function_mono_nfchoa_sphexp + +%***************************************************************************** +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 4; +nargmax = 4; +narginchk(nargmin,nargmax); +isargmatrix(Pm,x0); +isargvector(f); +isargstruct(conf); + +%% ===== Configuration ================================================== +c = conf.c; +dimension = conf.dimension; +Xc = conf.secondary_sources.center; + +%% ===== Computation ==================================================== +Nce = (size(Pm, 1)-1)/2; +% Calculate the driving function in time-frequency domain + +% secondary source positions +x00 = bsxfun(@minus,x0(:,1:3),Xc); +[phi0, ~,r0] = cart2sph(x00(:,1),x00(:,2),x00(:,3)); + +% frequency depended stuff +omega = 2*pi*row_vector(f); % [1 x Nf] +k = omega./c; % [1 x Nf] +kr0 = r0 * k; % [N0 x Nf] + +% initialize empty driving signal +D = zeros(size(kr0)); % [N0 x Nf] + +% indexing the expansion coefficients +l = 0; + +% Calculate the driving function in time-frequency domain + +switch dimension + case '2D' + % === 2-Dimensional ================================================== + % + % __ P + % 1 \ m + % D(phi0,w) = ------ /__ -------- e^(i m phi0) + % 2pi r0 m=-N..N G + % m + % + % with regular circular expansion of the sound field: + % \~~ oo + % P(x,w) = > P J (kr) . e^(+j m phi) + % /__ m=-oo m m + % + % and 3D free field Green's Function: + % \~~ oo + % G (x,w) = > G J (kr) . e^(+j m phi) + % ls /__ m=-oo m m + % + % with the regular expansion coefficients: + % m -i (2) + % G = ----- . H (kr0) + % n 4 m + for m=-Nce:Nce + l = l+1; + D = D + bsxfun(@times, Pm(l,:), exp(1i.*m.*phi0))./ besselh(m,2,kr0); + end + % factor from expansion of 2D free field Green's Function + D = D./(-1j/4); + % normalization due to size of circular array + D = bsxfun(@rdivide, D, 2*pi*r0); + case {'2.5D', '3D'} + % convert circular expansion to spherical expansion + Pmn = sphexp_convert_circexp(Pm); + % compute driving function for spherical expansion + D = driving_function_mono_nfchoa_sphexp(x0,Pmn,f,conf); + otherwise + error('%s: the dimension %s is unknown.',upper(mfilename),dimension); +end diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index da071f49..2be19362 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -56,8 +56,7 @@ nargmin = 4; nargmax = 4; narginchk(nargmin,nargmax); -isargsecondarysource(x0); -isargmatrix(Pnm); +isargmatrix(Pnm,x0); isargvector(f); isargstruct(conf); if mod(sqrt(size(Pnm, 1)),1) ~= 0 @@ -81,7 +80,7 @@ % secondary source positions x00 = bsxfun(@minus,x0(:,1:3),Xc); -[phi0, ~,r0] = cart2sph(x00(:,1),x00(:,2),x00(:,3)); +[phi0, theta0, r0] = cart2sph(x00(:,1),x00(:,2),x00(:,3)); % frequency depended stuff omega = 2*pi*row_vector(f); % [1 x Nf] @@ -98,6 +97,22 @@ %% ===== Computation ==================================================== % Calculate the driving function in time-frequency domain +% Regular spherical expansion of the sound field: +% \~~ N \~~ n m m +% P(x,w) = > > P j (kr) . Y (theta, phi) +% /__ n=0 /__ m=-n n n n +% +% and 3D free field Green's Function: +% \~~ oo \~~ n m m +% G (x0,f) = > > G . j (kr) . Y (theta, phi) +% ps /__ n=0 /__ m=-n n n n +% +% with the regular expansion coefficients of reen's Function +% (see Gumerov2004, eq. 3.2.2): +% m (2) -m +% G = -i . k . h (kr0) Y (pi/2, 0) +% n n n + if strcmp('2D',dimension) % === 2-Dimensional ================================================== to_be_implemented; @@ -114,22 +129,6 @@ % 2pi r0 m=-N..N m % G % |m| - % - % with regular spherical expansion of the sound field: - % \~~ N \~~ n m m - % P(x,w) = > > P j (kr) . Y (theta, phi) - % /__ n=0 /__ m=-n n n n - % - % and 3D free field Green's Function: - % \~~ oo \~~ n m m - % G (x0,f) = > > G . j (kr) . Y (theta, phi) - % ps /__ n=0 /__ m=-n n n n - % - % with the regular expansion coefficients (Gumerov2004, eq. 3.2.2): - % m (2) -m - % G = -i . k . h (kr0) Y (pi/2, 0) - % n n n - for m=-Nse:Nse v = sphexp_index(m); D = D + bsxfun(@times, Pnm(v,:), exp(1i.*m.*phi0)) ./ ... @@ -154,6 +153,7 @@ % n=|m| n n n % + % save some intermediate results hn = zeros(size(x0,1),length(omega),Nse+1); jn = zeros(1,length(omega),Nse+1); for n=0:Nse @@ -187,8 +187,23 @@ elseif strcmp('3D',dimension) % === 3-Dimensional ================================================== - - to_be_implemented; + % m + % __ __ P + % 1j \ \ n m + % D(x0,w) = --------- /__ /__ ----------- Y (theta0, phi0) + % k r0^2 n=0..oo m=-N..N (2) n + % h (k r0) + % n + for n=0:Nse + Pm = 0; + for m=-n:n + v = sphexp_index(m, n); + Pm = Pm + Pnm(v,:).*sphharmonics(n,m,theta0,phi0); + end + D = D + bsxfun(@rdivide, Pm, sphbesselh(n,2,kr0)); + end + % order independent factor + D = D./(-1j.*(r0.^2)*k); else error('%s: the dimension %s is unknown.',upper(mfilename),dimension); end diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m index c03a7fc1..3c94697c 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_circexp.m @@ -101,7 +101,6 @@ + sin(phi0).*n0(:,2); Sn0phi = -sin(phi0).*n0(:,1)... + cos(phi0).*n0(:,2); -Sn0z = n0(:,3); % select suitable basis function if strcmp('R', mode) @@ -114,7 +113,6 @@ error('unknown mode:'); end -%% ===== Computation ==================================================== % Calculate the driving function in time-frequency domain % indexing the expansion coefficients @@ -123,49 +121,49 @@ switch dimension case {'2D', '2.5D', '3D'} - % === 2- or 3-Dimensional ============================================ - - if (strcmp('default',driving_functions)) - % --- SFS Toolbox ------------------------------------------------ - % d - % D(x0, w) = -2 --- P(x0,w) - % d n - % with cylindrical expansion of the sound field: - % \~~ oo - % P(x,w) = > B F (x-xq) - % /__ n=-oo n n - % - % where F = {R,S}. - % - % regular cylindrical basis functions: - % - % R (x) = J (kr) . exp(j n phi)) - % n n - % singular cylindrical basis functions - % (2) - % S (x) = H (kr) . exp(j n phi) - % n n - - for n=-Nce:Nce - l = l + 1; - cn_prime = k.*circbasis_derived(n,kr0); - cn = circbasis(n,kr0); - Yn = exp(1j.*n.*phi0); - Gradr = Gradr + ( Pm(l).*cn_prime.*Yn ); - Gradphi = Gradphi + 1./r0.*( Pm(l).*cn.*1j.*n.*Yn ); - end - % directional gradient - D = -2*( Sn0r.*Gradr + Sn0phi.*Gradphi + Sn0z.*Gradz ); - - % 2.5D correction factor - if strcmp('2.5D', dimension) - xref = repmat(xref,[size(x0,1) 1]); - g0 = sqrt( 2*pi*vector_norm(xref-x0, 2)./(1j.*k)); - D = D.*g0; - end - else - error(['%s: %s, this type of driving function is not implemented ', ... - 'for 2D/3D.'],upper(mfilename),driving_functions); + % === 2-,2.5-,3-Dimensional ============================================ + switch driving_functions + case 'default' + % --- SFS Toolbox ------------------------------------------------ + % d + % D(x0, w) = -2 --- P(x0,w) + % d n + % with cylindrical expansion of the sound field: + % \~~ oo + % P(x,w) = > B F (x-xq) + % /__ n=-oo n n + % + % where F = {R,S}. + % + % regular cylindrical basis functions: + % + % R (x) = J (kr) . exp(j n phi)) + % n n + % singular cylindrical basis functions + % (2) + % S (x) = H (kr) . exp(j n phi) + % n n + + for n=-Nce:Nce + l = l + 1; + cn_prime = k.*circbasis_derived(n,kr0); + cn = circbasis(n,kr0); + Yn = exp(1j.*n.*phi0); + Gradr = Gradr + ( Pm(l).*cn_prime.*Yn ); + Gradphi = Gradphi + 1./r0.*( Pm(l).*cn.*1j.*n.*Yn ); + end + % directional gradient + D = -2*( Sn0r.*Gradr + Sn0phi.*Gradphi); + + % 2.5D correction factor + if strcmp('2.5D', dimension) + xref = repmat(xref,[size(x0,1) 1]); + g0 = sqrt( 2*pi*vector_norm(xref-x0, 2)./(1j.*k)); + D = D.*g0; + end + otherwise + error(['%s: %s, this type of driving function is not implemented ', ... + 'for 2D/2.5D/3D.'],upper(mfilename),driving_functions); end otherwise error('%s: the dimension %s is unknown.',upper(mfilename),dimension); diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m index 432a2320..f1692f66 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_wfs_sphexp.m @@ -177,7 +177,7 @@ % approximate spherical expansion with circular expansion Pm = circexp_convert_sphexp(Pnm); % compute driving function for circular expansion - D = driving_function_mono_wfs_circexp(x0,n0,Pm,mode,f,xq,conf); + D = driving_function_mono_wfs_circexp(x0,n0,Pm,mode,f,xq,conf); else error(['%s: %s, this type of driving function is not implemented ', ... 'for 2D/2.5D'],upper(mfilename),driving_functions); diff --git a/validation/test_sfs_exp.m b/validation/test_sfs_exp.m new file mode 100644 index 00000000..011b326e --- /dev/null +++ b/validation/test_sfs_exp.m @@ -0,0 +1,203 @@ +function boolean = test_wfs_exp +%TEST_WFS_EXP tests the correctness of the driving functions + +%***************************************************************************** +% The MIT License (MIT) * +% * +% Copyright (c) 2010-2016 SFS Toolbox Developers * +% * +% Permission is hereby granted, free of charge, to any person obtaining a * +% copy of this software and associated documentation files (the "Software"), * +% to deal in the Software without restriction, including without limitation * +% the rights to use, copy, modify, merge, publish, distribute, sublicense, * +% and/or sell copies of the Software, and to permit persons to whom the * +% Software is furnished to do so, subject to the following conditions: * +% * +% The above copyright notice and this permission notice shall be included in * +% all copies or substantial portions of the Software. * +% * +% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * +% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * +% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * +% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * +% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * +% DEALINGS IN THE SOFTWARE. * +% * +% The SFS Toolbox allows to simulate and investigate sound field synthesis * +% methods like wave field synthesis or higher order ambisonics. * +% * +% http://sfstoolbox.org sfstoolbox@gmail.com * +%***************************************************************************** + +% TODO: add mode to save data as reference data + + +%% ===== Checking of input parameters =================================== +nargmin = 0; +nargmax = 0; +narginchk(nargmin,nargmax); + + +%% ===== Configuration =================================================== +conf = SFS_config; +conf.secondary_sources.size = 3; +f = 1000; +conf.plot.useplot = false; +conf.plot.usenormalisation = true; +conf.plot.normalisation = 'center'; +conf.driving_functions = 'default'; +conf.usetapwin = false; + +rt = 1.0; % "size" of the sweet spot + +% test scenarios +scenarios = { ... + 'WFS', '2D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'WFS', '2D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'WFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'WFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'WFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'WFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'WFS', '2.5D', 'circular', 'ps', [ 0.0 2.5 0.0], 'sph'; ... + 'WFS', '3D', 'sphere', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'WFS', '3D', 'sphere', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'WFS', '3D', 'sphere', 'ps', [ 0.0 2.5 0.0], 'sph'; ... + 'LWFS', '2D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'LWFS', '2D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'LWFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'LWFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'LWFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'LWFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'LWFS', '2.5D', 'circular', 'ps', [ 0.0 2.5 0.0], 'sph'; ... + 'LWFS', '3D', 'sphere', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'LWFS', '3D', 'sphere', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'LWFS', '3D', 'sphere', 'ps', [ 0.0 2.5 0.0], 'sph'; ... + 'NFCHOA', '2D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'NFCHOA', '2D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'NFCHOA', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... + 'NFCHOA', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'NFCHOA', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... + 'NFCHOA', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'NFCHOA', '2.5D', 'circular', 'ps', [ 0.0 2.5 0.0], 'sph'; ... + 'NFCHOA', '3D', 'sphere', 'pw', [ 0.5 0.5 0.0], 'sph'; ... + 'NFCHOA', '3D', 'sphere', 'ls', [ 0.0 2.5 0.0], 'sph'; ... + 'NFCHOA', '3D', 'sphere', 'ps', [ 0.0 2.5 0.0], 'sph'; ... + }; + +% Start testing +for ii=1:size(scenarios) + + % get current dimension + conf.dimension = scenarios{ii,2}; + + % get source type and position + src = scenarios{ii,4}; + xs = scenarios{ii,5}; + + % get secondary source type + switch conf.dimension + case '2D' + secsrc = 'ls'; + case {'2.5D', '3D'} + secsrc = 'ps'; + end + + % get secondary source distribution + conf.secondary_sources.geometry = scenarios{ii,3}; + switch conf.secondary_sources.geometry + case 'linear' + X = [-2 2]; + Y = [-3 0.15]; + Z = 0; + conf.xref = [0 -1.5 0]; + conf.secondary_sources.number = 20; + case 'circular' + X = [-2 2]; + Y = [-2 2]; + Z = 0; + conf.xref = [0 0 0]; + conf.secondary_sources.number = 56; + case 'box' + X = [-2 2]; + Y = [-2 2]; + Z = 0; + conf.xref = [0 0 0]; + conf.secondary_sources.number = 80; + case 'sphere' + X = [-2 2]; + Y = [-2 2]; + Z = 0; + conf.xref = [0 0 0]; + conf.secondary_sources.number = 900; + end + x0 = secondary_source_positions(conf); + + % get expansion order + switch scenarios{ii,6} + case 'sph' + % spherical expansion order for sweet spot + Nexp = sphexp_truncation_order(rt, f, 1e-6, conf); + case 'circ' + % circular expansion order for sweet spot + Nexp = circexp_truncation_order(rt, f, 1e-6, conf); + end + + % get expansion coefficients + xq = conf.xref; + fname = [scenarios{ii,6}, 'exp_mono_', src]; + expfunc = str2func(fname); + switch src + case 'pw' + A = expfunc(xs, Nexp,f,xq,conf); + case 'ls' + A = expfunc(xs,'R', Nexp,f,xq,conf); + case 'ps' + A = expfunc(xs,'R', Nexp,f,xq,conf); + end + + % get method + method = scenarios{ii,1}; + + + if strcmp('WFS',method) + % ===== WFS ========================================================== + x0 = secondary_source_selection(x0,xs,src); + x0 = secondary_source_tapering(x0,conf); + + % compute driving function + Dfunc = str2func(['driving_function_mono_wfs_', scenarios{ii,6}, 'exp']); + D = Dfunc(x0(:,1:3),x0(:,4:6),A,'R',f,xq,conf); + + elseif strcmp('LWFS',method) + % ===== local WFS ==================================================== + x0 = secondary_source_selection(x0,xs,src); + x0 = secondary_source_tapering(x0,conf); + + % compute timereversed incident field + Tfunc = str2func([scenarios{ii,6}, 'exp_mono_timereverse']); + A_rev = Tfunc(A); + + % compute scattered, timereversed field + Sfunc = str2func([scenarios{ii,6}, 'exp_mono_scatter']); + B = Sfunc(A_rev, rt, inf, f, conf); + + % compute driving function + Dfunc = str2func(['driving_function_mono_wfs_', scenarios{ii,6}, 'exp']); + D = Dfunc(x0(:,1:3),x0(:,4:6),B,'S',f,xq,conf); + D = conj(D); + + elseif strcmp('NFCHOA', method) + % ===== NFCHOA ==================================================== + + % compute driving function + Dfunc = str2func(['driving_function_mono_nfchoa_', scenarios{ii,6}, 'exp']); + D = Dfunc(x0(:,1:3), A, f, conf); + + end + + P = sound_field_mono(X,Y,Z,x0,secsrc,D,f,conf); + plot_sound_field(P, X, Y, Z, x0, conf); + title(sprintf('%s %s of %s. exp. of %s', conf.dimension, method, ... + scenarios{ii,6}, src), 'Interpreter', 'None'); +end diff --git a/validation/test_wfs_exp.m b/validation/test_wfs_exp.m deleted file mode 100644 index 230bc21d..00000000 --- a/validation/test_wfs_exp.m +++ /dev/null @@ -1,177 +0,0 @@ -function boolean = test_wfs_exp -%TEST_WFS_EXP tests the correctness of the driving functions - -%***************************************************************************** -% The MIT License (MIT) * -% * -% Copyright (c) 2010-2016 SFS Toolbox Developers * -% * -% Permission is hereby granted, free of charge, to any person obtaining a * -% copy of this software and associated documentation files (the "Software"), * -% to deal in the Software without restriction, including without limitation * -% the rights to use, copy, modify, merge, publish, distribute, sublicense, * -% and/or sell copies of the Software, and to permit persons to whom the * -% Software is furnished to do so, subject to the following conditions: * -% * -% The above copyright notice and this permission notice shall be included in * -% all copies or substantial portions of the Software. * -% * -% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * -% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * -% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * -% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * -% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * -% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * -% DEALINGS IN THE SOFTWARE. * -% * -% The SFS Toolbox allows to simulate and investigate sound field synthesis * -% methods like wave field synthesis or higher order ambisonics. * -% * -% http://sfstoolbox.org sfstoolbox@gmail.com * -%***************************************************************************** - -% TODO: add mode to save data as reference data - - -%% ===== Checking of input parameters =================================== -nargmin = 0; -nargmax = 0; -narginchk(nargmin,nargmax); - - -%% ===== Configuration =================================================== -conf = SFS_config; -conf.secondary_sources.size = 3; -f = 1000; -conf.plot.useplot = false; -conf.plot.usenormalisation = true; -conf.plot.normalisation = 'center'; -conf.driving_functions = 'default'; -conf.usetapwin = false; - -rt = 1.0; % "size" of the sweet spot -Nce = circexp_truncation_order(rt, f, 1e-6, conf); % order for sweet spot - -% test scenarios -scenarios = { ... - 'WFS', '2D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... - 'WFS', '2D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... - 'WFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... - 'WFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'sph'; ... - 'WFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... - 'WFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'sph'; ... - 'WFS', '2.5D', 'circular', 'ps', [ 0.0 2.5 0.0], 'sph'; ... - 'WFS', '3D', 'sphere', 'pw', [ 0.5 0.5 0.0], 'sph'; ... - 'WFS', '3D', 'sphere', 'ls', [ 0.0 2.5 0.0], 'sph'; ... - 'WFS', '3D', 'sphere', 'ps', [ 0.0 2.5 0.0], 'sph'; ... - 'LWFS', '2D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... - 'LWFS', '2D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... - 'LWFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'circ'; ... - 'LWFS', '2.5D', 'circular', 'pw', [ 0.5 0.5 0.0], 'sph'; ... - 'LWFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'circ'; ... - 'LWFS', '2.5D', 'circular', 'ls', [ 0.0 2.5 0.0], 'sph'; ... - 'LWFS', '2.5D', 'circular', 'ps', [ 0.0 2.5 0.0], 'sph'; ... - 'LWFS', '3D', 'sphere', 'pw', [ 0.5 0.5 0.0], 'sph'; ... - 'LWFS', '3D', 'sphere', 'ls', [ 0.0 2.5 0.0], 'sph'; ... - 'LWFS', '3D', 'sphere', 'ps', [ 0.0 2.5 0.0], 'sph'; ... -}; - -% Start testing -for ii=1:size(scenarios) - - % get current dimension - conf.dimension = scenarios{ii,2}; - - % get source type and position - src = scenarios{ii,4}; - xs = scenarios{ii,5}; - - % get secondary source type - switch conf.dimension - case '2D' - secsrc = 'ls'; - case {'2.5D', '3D'} - secsrc = 'ps'; - end - - % get secondary source distribution - conf.secondary_sources.geometry = scenarios{ii,3}; - switch conf.secondary_sources.geometry - case 'linear' - X = [-2 2]; - Y = [-3 0.15]; - Z = 0; - conf.xref = [0 -1.5 0]; - conf.secondary_sources.number = 20; - case 'circular' - X = [-2 2]; - Y = [-2 2]; - Z = 0; - conf.xref = [0 0 0]; - conf.secondary_sources.number = 56; - case 'box' - X = [-2 2]; - Y = [-2 2]; - Z = 0; - conf.xref = [0 0 0]; - conf.secondary_sources.number = 80; - case 'sphere' - X = [-2 2]; - Y = [-2 2]; - Z = 0; - conf.xref = [0 0 0]; - conf.secondary_sources.number = 900; - end - x0 = secondary_source_positions(conf); - - % get expansion coefficients - xq = conf.xref; - fname = [scenarios{ii,6}, 'exp_mono_', src]; - expfunc = str2func(fname); - switch src - case 'pw' - A = expfunc(xs, Nce,f,xq,conf); - case 'ls' - A = expfunc(xs,'R', Nce,f,xq,conf); - case 'ps' - A = expfunc(xs,'R', Nce,f,xq,conf); - end - - % get method - method = scenarios{ii,1}; - - % ===== WFS ========================================================== - if strcmp('WFS',method) - x0 = secondary_source_selection(x0,xs,src); - x0 = secondary_source_tapering(x0,conf); - - Dfunc = str2func(['driving_function_mono_wfs_', scenarios{ii,6}, 'exp']); - - D = Dfunc(x0(:,1:3),x0(:,4:6),A,'R',f,xq,conf); - P = sound_field_mono(X,Y,Z,x0,secsrc,D,f,conf); - plot_sound_field(P, X, Y, Z, x0, conf); - % ===== local WFS ==================================================== - elseif strcmp('LWFS',method) - x0 = secondary_source_selection(x0,xs,src); - x0 = secondary_source_tapering(x0,conf); - - % compute timereversed incident field - Tfunc = str2func([scenarios{ii,6}, 'exp_mono_timereverse']); - A_rev = Tfunc(A); - - % compute scattered, timereversed field - Sfunc = str2func([scenarios{ii,6}, 'exp_mono_scatter']); - B = Sfunc(A_rev, rt, inf, f, conf); - - % compute driving function - Dfunc = str2func(['driving_function_mono_wfs_', scenarios{ii,6}, 'exp']); - D = Dfunc(x0(:,1:3),x0(:,4:6),B,'S',f,xq,conf); - - P = sound_field_mono(X,Y,Z,x0,secsrc,conj(D),f,conf); - plot_sound_field(P, X, Y, Z, x0, conf); - end - - - title(sprintf('%s %s of %s. exp. of %s', conf.dimension, method, ... - scenarios{ii,6}, src), 'Interpreter', 'None'); -end From ccb56b6b14d3feddf02a40811f487cf6f64ddd32 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Thu, 30 Jun 2016 18:29:29 +0200 Subject: [PATCH 75/81] some minor fixes for validation script --- validation/test_sfs_exp.m | 56 ++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/validation/test_sfs_exp.m b/validation/test_sfs_exp.m index 011b326e..5f677f99 100644 --- a/validation/test_sfs_exp.m +++ b/validation/test_sfs_exp.m @@ -1,5 +1,15 @@ -function boolean = test_wfs_exp -%TEST_WFS_EXP tests the correctness of the driving functions +function boolean = test_sfs_exp(modus) +%TEST_SFS_EXP tests the correctness of the driving functions for sound fields +%expressed as circular or spherical expansions + +% Usage: boolean = test_sfs_exp(modus) +% +% Input parameters: +% modus - 0: numerical +% 1: visual +% +% Output parameters: +% boolean - true or false %***************************************************************************** % The MIT License (MIT) * @@ -30,12 +40,9 @@ % http://sfstoolbox.org sfstoolbox@gmail.com * %***************************************************************************** -% TODO: add mode to save data as reference data - - %% ===== Checking of input parameters =================================== -nargmin = 0; -nargmax = 0; +nargmin = 1; +nargmax = 1; narginchk(nargmin,nargmax); @@ -49,7 +56,7 @@ conf.driving_functions = 'default'; conf.usetapwin = false; -rt = 1.0; % "size" of the sweet spot +rt = 0.3; % "size" of the sweet spot % test scenarios scenarios = { ... @@ -95,12 +102,20 @@ src = scenarios{ii,4}; xs = scenarios{ii,5}; - % get secondary source type + % get secondary source type and expansion order switch conf.dimension case '2D' secsrc = 'ls'; - case {'2.5D', '3D'} + % circular expansion order + Nexp = circexp_truncation_order(rt, f, 1e-6, conf); + case '2.5D' + secsrc = 'ps'; + % circular expansion order + Nexp = circexp_truncation_order(rt, f, 1e-6, conf); + case '3D' secsrc = 'ps'; + % spherical expansion order + Nexp = sphexp_truncation_order(rt, f, 1e-6, conf); end % get secondary source distribution @@ -133,16 +148,6 @@ end x0 = secondary_source_positions(conf); - % get expansion order - switch scenarios{ii,6} - case 'sph' - % spherical expansion order for sweet spot - Nexp = sphexp_truncation_order(rt, f, 1e-6, conf); - case 'circ' - % circular expansion order for sweet spot - Nexp = circexp_truncation_order(rt, f, 1e-6, conf); - end - % get expansion coefficients xq = conf.xref; fname = [scenarios{ii,6}, 'exp_mono_', src]; @@ -195,9 +200,12 @@ D = Dfunc(x0(:,1:3), A, f, conf); end - + P = sound_field_mono(X,Y,Z,x0,secsrc,D,f,conf); - plot_sound_field(P, X, Y, Z, x0, conf); - title(sprintf('%s %s of %s. exp. of %s', conf.dimension, method, ... - scenarios{ii,6}, src), 'Interpreter', 'None'); + if modus + plot_sound_field(P, X, Y, Z, x0, conf); + plot_scatterer(xq,rt); + title(sprintf('%s %s of %s. exp. (N=%d) of %s', conf.dimension, method, ... + scenarios{ii,6}, Nexp, src), 'Interpreter', 'None'); + end end From 438a58b19f8db6b62cb62bd3a6b905e3a0b10d90 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 1 Jul 2016 14:44:41 +0200 Subject: [PATCH 76/81] remove doubled code by re-using harmonics transform of driving functions --- ...driving_function_mono_nfchoa_cht_circexp.m | 112 ++++++++++++ .../driving_function_mono_nfchoa_cht_sphexp.m | 163 ++++++++++++++++++ .../driving_function_mono_nfchoa_circexp.m | 40 +---- .../driving_function_mono_nfchoa_sphexp.m | 124 ++++--------- .../driving_function_mono_nfchoa_sht_sphexp.m | 149 ++++------------ 5 files changed, 351 insertions(+), 237 deletions(-) create mode 100644 SFS_monochromatic/cht/driving_function_mono_nfchoa_cht_circexp.m create mode 100644 SFS_monochromatic/cht/driving_function_mono_nfchoa_cht_sphexp.m diff --git a/SFS_monochromatic/cht/driving_function_mono_nfchoa_cht_circexp.m b/SFS_monochromatic/cht/driving_function_mono_nfchoa_cht_circexp.m new file mode 100644 index 00000000..3b23045e --- /dev/null +++ b/SFS_monochromatic/cht/driving_function_mono_nfchoa_cht_circexp.m @@ -0,0 +1,112 @@ +function Dm = driving_function_mono_nfchoa_cht_circexp(Pm, f, conf) +%DRIVING_FUNCTION_MONO_NFCHOA_CHT_CIRCEXP computes the circular harmonics +%transform of nfchoa driving functions for a sound field expressed by regular +%circular expansion coefficients. +% +% Usage: D = driving_function_mono_nfchoa_cht_circexp(Pm, f, conf) +% +% Input parameters: +% Pm - regular circular expansion coefficients of virtual +% sound field [n x m] +% f - frequency in Hz [m x 1] or [1 x m] +% conf - configuration struct (see SFS_config) +% +% Output parameters: +% Dm - circular harmonics transform of driving function signal +% [n x m] +% +% DRIVING_FUNCTION_MONO_NFCHOA_CHT_CIRCEXP(Pm, f, conf) returns circular +% harmonics transform of the NFCHOA driving function for a virtual sound +% expressed by regular circular expansion coefficients and the frequency f. + +%***************************************************************************** +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 3; +narginchk(nargmin,nargmax); +isargmatrix(Pm); +isargvector(f); +isargstruct(conf); +if size(Pm,2) ~= length(f) + error( '%s:number of rows in %s have to match length of %s', ... + upper(mfilename), inputname(1), inputname(2) ); +end + +%% ===== Configuration ================================================== +c = conf.c; +R0 = conf.secondary_sources.size / 2; + +%% ===== Variables ====================================================== +Nce = (size(Pm, 1)-1)/2; + +% frequency depended stuff +omega = 2*pi*row_vector(f); % [1 x Nf] +k = omega./c; % [1 x Nf] +kR0 = k.*R0; % [1 x Nf] + +%% ===== Computation ==================================================== +% Calculate the circular harmonics of driving function +% +% Regular circular expansion of the sound field: +% \~~ oo +% P(x,w) = > P J (kr) . e^(+j m phi) +% /__ m=-oo m m +% +% and 3D free field Green's Function: +% \~~ oo +% G (x,w) = > G J (kr) . e^(+j m phi) +% ls /__ m=-oo m m +% +% with the regular expansion coefficients of Green's Function +% (see Gumerov2004, eq. 3.2.2): +% m -i (2) +% G = ----- . H (kr0) +% n 4 m + +% P +% 1 m +% D = ------ -------- +% m 2pi r0 G +% m + +Dm = zeros(size(Pm)); +l = 0; +for m=-Nce:Nce + l = l+1; + Dm(l,:) = Pm(l,:) ./ besselh(m,2,kR0); +end +% factor from expansion of 2D free field Green's Function +Dm = Dm./(-1j/4); +% normalization due to size of circular array +Dm = Dm./2*pi*R0; diff --git a/SFS_monochromatic/cht/driving_function_mono_nfchoa_cht_sphexp.m b/SFS_monochromatic/cht/driving_function_mono_nfchoa_cht_sphexp.m new file mode 100644 index 00000000..ca0761f2 --- /dev/null +++ b/SFS_monochromatic/cht/driving_function_mono_nfchoa_cht_sphexp.m @@ -0,0 +1,163 @@ +function Dm = driving_function_mono_nfchoa_cht_sphexp(Pnm, f, conf) +%DRIVING_FUNCTION_MONO_NFCHOA_CHT_SPHEXP computes the circular harmonics +%transform of nfchoa driving functions for a sound field expressed by regular +%spherical expansion coefficients. +% +% Usage: D = driving_function_mono_nfchoa_cht_sphexp(Pnm, f, conf) +% +% Input parameters: +% Pnm - regular spherical expansion coefficients of virtual +% sound field [nxm] +% f - frequency in Hz [m x 1] or [1 x m] +% conf - configuration struct (see SFS_config) +% +% Output parameters: +% Dm - regular circular harmonics transform of driving +% function signal +% +% DRIVING_FUNCTION_MONO_NFCHOA_CHT_SPHEXP(Pnm, f, conf) returns circular +% harmonics transform of the NFCHOA driving function for a virtual sound +% expressed by regular spherical expansion coefficients and the frequency f. + +%***************************************************************************** +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 3; +nargmax = 3; +narginchk(nargmin,nargmax); +isargmatrix(Pnm); +isargsquaredinteger(size(Pnm,1)); +isargvector(f); +isargstruct(conf); +if size(Pnm,2) ~= length(f) + error( '%s:number of rows in %s have to match length of %s', ... + upper(mfilename), inputname(1), inputname(2) ); +end + +%% ===== Configuration ================================================== +c = conf.c; +Xc = conf.secondary_sources.center; +R0 = conf.secondary_sources.size / 2; +xref = conf.xref - Xc; +rref = norm( xref ); % reference radius +thetaref = asin( xref(3)./rref); % reference elevation angle + +%% ===== Variables ====================================================== +Nse = sqrt(size(Pnm,1))-1; + +% frequency depended stuff +omega = 2*pi*row_vector(f); % [1 x Nf] +k = omega./c; % [1 x Nf] +kR0 = k.*R0; % [1 x Nf] +krref = k.*rref; % [1 x Nf] + +%% ===== Computation ==================================================== +% Calculate the circular harmonics of driving function +% +% Regular spherical expansion of the sound field: +% \~~ N \~~ n m m +% P(x,w) = > > P j (kr) . Y (theta, phi) +% /__ n=0 /__ m=-n n n n +% +% and 3D free field Green's Function: +% \~~ oo \~~ n m m +% G (x0,f) = > > G . j (kr) . Y (theta, phi) +% ps /__ n=0 /__ m=-n n n n +% +% with the regular expansion coefficients of Green's Function +% (see Gumerov2004, eq. 3.2.2): +% m (2) -m +% G = -i . k . h (kr0) Y (pi/2, 0) +% n n n + +% initialize empty driving signal +Dm = zeros(2*Nse+1, size(Pnm,2)); +l = 0; +if (rref == 0) + % --- Xref == Xc ------------------------------------------------- + % m + % P + % 1 |m| + % D = ------ -------- + % m 2pi r0 m + % G + % |m| + for m=-Nse:Nse + l = l+1; + v = sphexp_index(m); % n = abs(m) + + Dm(l,:) = Pnm(v,:) ./ ... + ( -1i.*k.* sphbesselh(abs(m),2,kR0).*sphharmonics(abs(m),-m, 0, 0) ); + end +else + % --- Xref ~= Xc -------------------------------------------------- + % + % if the reference position is not in the middle of the array, + % things get a 'little' more complicated + % __ + % \ m m + % /__ P j (k rref) Y (thetaref, 0) + % n 1 l=|m| l l l + % D = ------- ------------------------------------ + % m 2pi r0 __ + % \ m m + % /__ G j (k rref) Y (thetaref, 0) + % l=|m| n l l + % + + % save some intermediate results + hn = zeros(size(Pnm)); + jn = hn; + for n=0:Nse + hn(n+1,:) = sphbesselh(n,2,kR0); % [1 x Nf] + jn(n+1,:) = sphbesselj(n,krref); % [1 x Nf] + end + + for m=-Nse:Nse + Pm = zeros(1,length(f)); + Gm = Pm; + for n=abs(m):Nse + v = sphexp_index(m,n); + % + factor = jn(n+1,:) .* sphharmonics(n, -m, thetaref, 0); + % numerator + Pm = Pm + Pnm(v,:) .* factor; + % denominator + Gm = Gm + (-1i*k) .* hn(n+1,:) .* sphharmonics(n, -m, 0, 0) .* factor; + end + l = l+1; + Dm(v,:) = Pm./Gm; + end +end +% normalization due to size of circular array +Dm = Dm./(2*pi*R0); \ No newline at end of file diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_circexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_circexp.m index ffed1a9e..43a38840 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_circexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_circexp.m @@ -65,6 +65,7 @@ c = conf.c; dimension = conf.dimension; Xc = conf.secondary_sources.center; +R0 = conf.secondary_sources.size/2; % radius of SSD %% ===== Computation ==================================================== Nce = (size(Pm, 1)-1)/2; @@ -72,7 +73,7 @@ % secondary source positions x00 = bsxfun(@minus,x0(:,1:3),Xc); -[phi0, ~,r0] = cart2sph(x00(:,1),x00(:,2),x00(:,3)); +[phi0, r0] = cart2pol(x00(:,1),x00(:,2)); % frequency depended stuff omega = 2*pi*row_vector(f); % [1 x Nf] @@ -82,43 +83,20 @@ % initialize empty driving signal D = zeros(size(kr0)); % [N0 x Nf] -% indexing the expansion coefficients -l = 0; - % Calculate the driving function in time-frequency domain - switch dimension case '2D' % === 2-Dimensional ================================================== - % - % __ P - % 1 \ m - % D(phi0,w) = ------ /__ -------- e^(i m phi0) - % 2pi r0 m=-N..N G - % m - % - % with regular circular expansion of the sound field: - % \~~ oo - % P(x,w) = > P J (kr) . e^(+j m phi) - % /__ m=-oo m m - % - % and 3D free field Green's Function: - % \~~ oo - % G (x,w) = > G J (kr) . e^(+j m phi) - % ls /__ m=-oo m m - % - % with the regular expansion coefficients: - % m -i (2) - % G = ----- . H (kr0) - % n 4 m + % Circular Harmonics of Driving Function + Dm = driving_function_mono_nfchoa_cht_circexp(Pm,f,conf); + + l = 0; for m=-Nce:Nce l = l+1; - D = D + bsxfun(@times, Pm(l,:), exp(1i.*m.*phi0))./ besselh(m,2,kr0); + % second line is for compensating difference between r0 and R0 + D = D + bsxfun(@times, Dm(l,:), exp(1i.*m.*phi0)).* ... + bsxfun(@rdivide, besselh(m,2,kr0), besselh(m,2,k*R0)); end - % factor from expansion of 2D free field Green's Function - D = D./(-1j/4); - % normalization due to size of circular array - D = bsxfun(@rdivide, D, 2*pi*r0); case {'2.5D', '3D'} % convert circular expansion to spherical expansion Pmn = sphexp_convert_circexp(Pm); diff --git a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m index 2be19362..6186dba1 100644 --- a/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m +++ b/SFS_monochromatic/driving_functions_mono/driving_function_mono_nfchoa_sphexp.m @@ -1,5 +1,5 @@ function D = driving_function_mono_nfchoa_sphexp(x0, Pnm,f,conf) -%computes the nfchoa driving functions for a sound field expressed by regular +%computes the nfchoa driving functions for a sound field expressed by regular %spherical expansion coefficients. % % Usage: D = driving_function_mono_nfchoa_sphexp(x0,Pnm,f,conf) @@ -68,16 +68,11 @@ c = conf.c; dimension = conf.dimension; Xc = conf.secondary_sources.center; -xref = conf.xref - Xc; -rref = norm( xref ); % reference radius -thetaref = asin( xref(3)./rref); % reference elevation angle +R0 = conf.secondary_sources.size/2; %% ===== Variables ====================================================== Nse = sqrt(size(Pnm, 1))-1; -%% ===== Computation ==================================================== -% Calculate the driving function in time-frequency domain - % secondary source positions x00 = bsxfun(@minus,x0(:,1:3),Xc); [phi0, theta0, r0] = cart2sph(x00(:,1),x00(:,2),x00(:,3)); @@ -87,10 +82,6 @@ k = omega./c; % [1 x Nf] kr0 = r0 * k; % [N0 x Nf] -% reference radius -[~, ~, rref] = cart2sph(xref(1),xref(2),xref(3)); -krref = k.*rref; % [1 x Nf] - % initialize empty driving signal D = zeros(size(kr0)); % [N0 x Nf] @@ -100,7 +91,7 @@ % Regular spherical expansion of the sound field: % \~~ N \~~ n m m % P(x,w) = > > P j (kr) . Y (theta, phi) -% /__ n=0 /__ m=-n n n n +% /__ n=0 /__ m=-n n n n % % and 3D free field Green's Function: % \~~ oo \~~ n m m @@ -115,95 +106,40 @@ if strcmp('2D',dimension) % === 2-Dimensional ================================================== - to_be_implemented; - + % Convert spherical Expansion to circular expansion (approximation) + Pm = circexp_convert_sphexp(Pnm); + % Compute driving function for circular expansion + D = driving_function_mono_nfchoa_circexp(x0,Pm,f,conf); + % elseif strcmp('2.5D',dimension) % === 2.5-Dimensional ================================================ + % Spherical Harmonics of Driving Function + Dm = driving_function_mono_nfchoa_cht_sphexp(Pnm,f,conf); - if (rref == 0) - % --- Xref == Xc ---------------------------------------------------- - % m - % __ P - % 1 \ |m| - % D(phi0,w) = ------ /__ -------- e^(i m (phi0)) - % 2pi r0 m=-N..N m - % G - % |m| - for m=-Nse:Nse - v = sphexp_index(m); - D = D + bsxfun(@times, Pnm(v,:), exp(1i.*m.*phi0)) ./ ... - ( sphbesselh(abs(m),2,kr0) .* sphharmonics(abs(m),-m, 0, 0) ); - end - % factor from expansion of 3D free field Green's Function - D = bsxfun(@rdivide, D, -1i*k); - else - % --- Xref ~= Xc ---------------------------------------------------- - % - % if the reference position is not in the middle of the array, things - % get a 'little' more complicated - % - % __ - % \ m m - % __ /__ P j (k rref) Y (thetaref, 0) - % 1 \ n=|m| n n n - % D(phi0,w) = ------ /__ --------------------------------- e^(i m phi0) - % 2pi r0 m=-N..N __ - % \ m m - % /__ G j (k rref) Y (thetaref, 0) - % n=|m| n n n - % - - % save some intermediate results - hn = zeros(size(x0,1),length(omega),Nse+1); - jn = zeros(1,length(omega),Nse+1); - for n=0:Nse - hn(:,:,n+1) = sphbesselh(n,2,kr0); - jn(:,:,n+1) = sphbesselj(n,krref); - end - - for m=-Nse:Nse - Pm = 0; - Gm = 0; - for n=abs(m):Nse - factor = jn(:,:,n+1) .* ... - (-1).^(m) .* ... - sqrt( (2*n+1) ./ (4*pi) ) .* ... - sqrt( factorial(n-abs(m)) ./ factorial(n+abs(m)) ) .* ... - asslegendre(n,abs(m), sin(thetaref)); % [1 x Nf] - - v = sphexp_index(m, n); - - Pm = Pm + Pnm(v,:) .* factor; % [1 x Nf] - - Gm = Gm + sphharmonics(n, -m, 0, 0) .* ... - bsxfun(@times, hn(:,:,n+1), (-1i*k).*factor); % [N0 x Nf] - end - - D = D + (exp(1i.*m.*phi0) * Pm) ./ Gm; % [N0 x Nf] - end + l = 0; + for m=-Nse:Nse + l=l+1; + % second line is for compensating possible difference between r0 and R0 + D = D + bsxfun(@times, Dm(l,:), exp(1i.*m.*phi0)).* ... + bsxfun(@rdivide, sphbesselh(abs(m),2,kr0), sphbesselh(abs(m),2,k*R0)); end - % normalization due to size of circular array - D = bsxfun(@rdivide, D, 2*pi*r0); - + % elseif strcmp('3D',dimension) % === 3-Dimensional ================================================== - % m - % __ __ P - % 1j \ \ n m - % D(x0,w) = --------- /__ /__ ----------- Y (theta0, phi0) - % k r0^2 n=0..oo m=-N..N (2) n - % h (k r0) - % n - for n=0:Nse - Pm = 0; + % Spherical Harmonics of Driving Function + Dnm = driving_function_mono_nfchoa_sht_sphexp(Pnm,f,conf); + + % Inverse Spherical Harmonics Transform + for n=0:Nse + Dn = 0; for m=-n:n - v = sphexp_index(m, n); - Pm = Pm + Pnm(v,:).*sphharmonics(n,m,theta0,phi0); - end - D = D + bsxfun(@rdivide, Pm, sphbesselh(n,2,kr0)); + v = sphexp_index(m, n); + Dn = Dn + bsxfun(@times, Dnm(v,:), sphharmonics(n,m,theta0,phi0)); + end + % compensating possible difference between r0 and R0 + D = D + Dn .* bsxfun(@rdivide, sphbesselh(n,2,kr0), sphbesselh(n,2,k*R0)); end - % order independent factor - D = D./(-1j.*(r0.^2)*k); + % else - error('%s: the dimension %s is unknown.',upper(mfilename),dimension); + error('%s: the dimension %s is unknown.',upper(mfilename),dimension); end diff --git a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m index 5e5a195a..e67b109a 100644 --- a/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m +++ b/SFS_monochromatic/sht/driving_function_mono_nfchoa_sht_sphexp.m @@ -1,6 +1,6 @@ function Dnm = driving_function_mono_nfchoa_sht_sphexp(Pnm, f, conf) -%DRIVING_FUNCTION_MONO_NFCHOA_SHT_SPHEXP computes the spherical harmonics -%transform of nfchoa driving functions for a sound field expressed by regular +%DRIVING_FUNCTION_MONO_NFCHOA_SHT_SPHEXP computes the spherical harmonics +%transform of nfchoa driving functions for a sound field expressed by regular %spherical expansion coefficients. % % Usage: D = driving_function_mono_nfchoa_sht_sphexp(Pnm, f, conf) @@ -16,7 +16,7 @@ % function signal [n x m] % % DRIVING_FUNCTION_MONO_NFCHOA_SHT_SPHEXP(Pnm, f, conf) returns spherical -% harmonics transform of the NFCHOA driving function for a virtual sound +% harmonics transform of the NFCHOA driving function for a virtual sound % expressed by regular spherical expansion coefficients and the frequency f. %***************************************************************************** @@ -66,122 +66,47 @@ %% ===== Configuration ================================================== c = conf.c; -dimension = conf.dimension; -driving_functions = conf.driving_functions; - -Xc = conf.secondary_sources.center; -r0 = conf.secondary_sources.size / 2; -xref = conf.xref - Xc; -rref = norm( xref ); % reference radius -thetaref = asin( xref(3)./rref); % reference elevation angle +R0 = conf.secondary_sources.size / 2; %% ===== Variables ====================================================== Nse = sqrt(size(Pnm,1))-1; -%% ===== Computation ==================================================== -% Calculate the driving function in time-frequency domain - % frequency depended stuff -omega = 2*pi*row_vector(f); -k = omega./c; -kr0 = k.*r0; -krref = k.*rref; +omega = 2*pi*row_vector(f); % [1 x Nf] +k = omega./c; % [1 x Nf] +kR0 = k.*R0; % [1 x Nf] %% ===== Computation ==================================================== -% Calculate the driving function in time-frequency domain - -% initialize empty driving signal -Dnm = zeros(size(Pnm)); - -if strcmp('2.5D',dimension) - % === 2.5-Dimensional ================================================ - - if strcmp('default',driving_functions) - - if (rref == 0) - % --- Xref == Xc ------------------------------------------------- - % m - % P - % n 1 |m| - % D = ------ -------- - % m 2pi r0 m - % G - % |m| - % - % with the regular expansion coefficients (Gumerov2004, eq. 3.2.2): - % m (2) -m - % G = -i . k . h (kr0) Y (pi/2, 0) - % n n n - - for m=-Nse:Nse - v = sphexp_index(m, abs(m):Nse); % v(1) contains index for n=abs(m) - - Dnm(v,:) = repmat( Pnm(v(1),:) ./ ( -1i.*k.* ... - sphbesselh(abs(m),2,kr0).*sphharmonics(abs(m),-m, 0, 0) ) ... - , length(v), 1); - end - else - % --- Xref ~= Xc -------------------------------------------------- - % - % if the reference position is not in the middle of the array, - % things get a 'little' more complicated - - hn = zeros(size(Pnm)); - jn = hn; - for n=0:Nse - hn(n+1,:) = sphbesselh(n,2,kr0); - jn(n+1,:) = sphbesselj(n,krref); - end - - for m=-Nse:Nse - Pm = zeros(1,length(f)); - Gm = Pm; - % for theta=0 the legendre polynom is zero if n+m is odd - for n=abs(m):2:Nse - factor = jn(n+1,:) .* ... - (-1).^(m) .* ... - sqrt( (2*n+1) ./ (4*pi) ) .* ... - sqrt( factorial(n-abs(m)) ./ factorial(n+abs(m)) ) .* ... - asslegendre(n,abs(m), sin(thetaref)); - - v = sphexp_index(m,n); - - Pm = Pm + Pnm(v,:) .* factor; - - Gm = Gm + (-1i*k) .* hn(n+1,:) .* sphharmonics(n, -m, 0, 0) ... - .* factor; - end +% Calculate the spherical harmonics of driving function +% +% Regular spherical expansion of the sound field: +% \~~ N \~~ n m m +% P(x,w) = > > P j (kr) . Y (theta, phi) +% /__ n=0 /__ m=-n n n n +% +% and 3D free field Green's Function: +% \~~ oo \~~ n m m +% G (x0,f) = > > G . j (kr) . Y (theta, phi) +% ps /__ n=0 /__ m=-n n n n +% +% with the regular expansion coefficients of Green's Function +% (see Gumerov2004, eq. 3.2.2): +% m (2) -m +% G = -i . k . h (kr0) Y (pi/2, 0) +% n n n - v = sphexp_index(m, abs(m):Nse); - Dnm(v,:) = repmat( Pm./Gm, length(v), 1 ); - end - end - Dnm = Dnm./(2*pi*r0); - - else - error('%s: %s, this type of driving function is not implemented ', ... - upper(mfilename), driving_functions); - end - -elseif strcmp('3D',dimension) - % === 3-Dimensional ================================================== +% m +% P +% m n +% D = --------------------- +% n (2) +% -j k r0^2 h (k r0) +% n - if strcmp('default',driving_functions) - - for n=0:Nse - Gn0 = (-1i*k) .* sphbesselh(n,2,kr0) .* sphharmonics(n, 0, pi/2, 0); - - v = sphexp_index(-n:n, n); - Dnm(v,:) = sqrt( (2*n+1) ./ (4*pi) ) .* Pnm(v,:) ./ ... - repmat(Gn0,length(v),1); - end - - Dnm = Dnm./(2*pi*r0.^2); - else - error('%s: %s, this type of driving function is not implemented ', ... - upper(mfilename), driving_functions); - end -else - error('%s: the dimension %s is unknown or not supported.', ... - upper(mfilename),dimension); +Dnm = zeros(size(Pnm)); +for n=0:Nse + v = sphexp_index(-n:n, n); % m=-n:n + Dnm(v,:) = bsxfun(@rdivide, Pnm(v,:), sphbesselh(n,2,kR0)); end +% order independent factor +Dnm = bsxfun(@rdivide, Dnm, -1j.*(R0.^2)*k); From 9adc1fbbf0e4329110fe8c0340a7d80a99e6b24f Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 1 Jul 2016 14:46:19 +0200 Subject: [PATCH 77/81] make modus argument optional --- validation/test_sfs_exp.m | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/validation/test_sfs_exp.m b/validation/test_sfs_exp.m index 5f677f99..726c017c 100644 --- a/validation/test_sfs_exp.m +++ b/validation/test_sfs_exp.m @@ -2,11 +2,11 @@ %TEST_SFS_EXP tests the correctness of the driving functions for sound fields %expressed as circular or spherical expansions -% Usage: boolean = test_sfs_exp(modus) +% Usage: boolean = test_sfs_exp([modus]) % % Input parameters: % modus - 0: numerical -% 1: visual +% 1: visual [default] % % Output parameters: % boolean - true or false @@ -41,11 +41,13 @@ %***************************************************************************** %% ===== Checking of input parameters =================================== -nargmin = 1; +nargmin = 0; nargmax = 1; narginchk(nargmin,nargmax); - - +if nargin == nargmin + modus = 1; +end + %% ===== Configuration =================================================== conf = SFS_config; conf.secondary_sources.size = 3; From d026963a1481dfc5a219ef47bf607d4f9743c602 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 1 Jul 2016 14:48:00 +0200 Subject: [PATCH 78/81] fix startup script --- SFS_start.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SFS_start.m b/SFS_start.m index 9d1bca11..ed5c873d 100644 --- a/SFS_start.m +++ b/SFS_start.m @@ -73,6 +73,8 @@ function SFS_start(printbanner) addpath([basepath,'/SFS_monochromatic/driving_functions_mono']); addpath([basepath,'/SFS_monochromatic/sphexp']); addpath([basepath,'/SFS_monochromatic/sht']); + addpath([basepath,'/SFS_monochromatic/cht']); + addpath([basepath,'/SFS_monochromatic/kx']); addpath([basepath,'/SFS_plotting']); addpath([basepath,'/SFS_scattering']); addpath([basepath,'/SFS_plotting/colormaps']); From f35cb60b649ef6790927d8aa037ad8d76c16ebb2 Mon Sep 17 00:00:00 2001 From: Fiete Winter Date: Fri, 1 Jul 2016 16:13:43 +0200 Subject: [PATCH 79/81] compute soundfield from circular harmonics driving function --- SFS_monochromatic/cht/sound_field_mono_cht.m | 124 ++++++++++++++++++ .../circexp/sound_field_mono_circexp.m | 4 +- SFS_monochromatic/sht/sound_field_mono_sht.m | 4 +- SFS_monochromatic/sphexp/sphexp_mono_cht.m | 82 ++++++++++++ 4 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 SFS_monochromatic/cht/sound_field_mono_cht.m create mode 100644 SFS_monochromatic/sphexp/sphexp_mono_cht.m diff --git a/SFS_monochromatic/cht/sound_field_mono_cht.m b/SFS_monochromatic/cht/sound_field_mono_cht.m new file mode 100644 index 00000000..cfded76c --- /dev/null +++ b/SFS_monochromatic/cht/sound_field_mono_cht.m @@ -0,0 +1,124 @@ +function [P, x, y, z] = sound_field_mono_cht(X,Y,Z,Dm,f,conf) +%SOUND_FIELD_MONO_CHT simulates a sound field reproduced by a circular +%secondary source distribution given with the circular harmonics transform +%of the driving function +% +% Usage: [P, x, y, z] = sound_field_mono_cht(X,Y,Z,Dm,f,conf) +% +% Input parameters: +% X - x-axis / m; single value or [xmin,xmax] or nD-array +% Y - y-axis / m; single value or [ymin,ymax] or nD-array +% Z - z-axis / m; single value or [zmin,zmax] or nD-array +% Dm - circular harmonics transform of nfchoa driving function +% f - frequency in Hz +% conf - configuration struct (see SFS_config) +% +% Output parameters: +% P - resulting soundfield +% +% SOUND_FIELD_MONO_CHT(X,Y,Z,Dm,f,conf) computes the sound field reproduced +% by a continuous, circular secondary source distribution driven by a driving +% function whose circular harmonics transform is given as Dm. +% +% see also: circbasis_mono_grid, sound_field_mono_circexp + +%***************************************************************************** +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 6; +nargmax = 6; +narginchk(nargmin,nargmax); +isargvector(Dm); +isargnumeric(X,Y,Z); +isargpositivescalar(f); +isargstruct(conf); + +%% ===== Configuration ================================================== +Xc = conf.secondary_sources.center; +R0 = conf.secondary_sources.size / 2; +useplot = conf.plot.useplot; +dimension = conf.dimension; + +%% ===== Variables ====================================================== +% select secondary source type (line source or point source) +switch dimension + case '2D' + exp_func = @(mo) circexp_mono_cht(Dm,mo,f,conf); + sound_field_func = @(x,y,z,Am,mo) sound_field_mono_circexp(x, y, z, Am, ... + mo, f, Xc, conf); + case '2.5D' + exp_func = @(mo) sphexp_mono_cht(Dm,mo,f,conf); + sound_field_func = @(x,y,z,Amn,mo) sound_field_mono_sphexp(x, y, z, Amn, ... + mo, f, Xc, conf); +end + +%% ===== Computation ==================================================== +[x,y,z] = xyz_grid(X,Y,Z,conf); +% find coordinates, which are inside and outside the loudspeaker array +select = sqrt((x-Xc(1)).^2 + (y-Xc(2)).^2 + (z-Xc(3)).^2) <= R0; + +if (numel(x) == 1) x = repmat(x, size(select)); end +if (numel(y) == 1) y = repmat(y, size(select)); end +if (numel(z) == 1) z = repmat(z, size(select)); end + +P = zeros(size(x)); + +% regular (interior) domain inside the loudspeaker array +if any(select(:)) + Pnm = exp_func('R'); + P(select) = sound_field_func(x(select), y(select), z(select), Pnm, 'R'); +end + +% singular (exterior) domain outside the loudspeaker array +if any(~select(:)) + Pnm = exp_func('S'); + if sum( ~select(:) ) == 2 + % this handle cases, where x(~select) would only contain 2 entries, which + % would be interpreted as a range by the sound_field_... function + xtmp = x(~select); + ytmp = y(~select); + ztmp = z(~select); + Ptmp(1) = sound_field_func(xtmp(1), ytmp(1), ztmp(1), Pnm, 'S'); + Ptmp(2) = sound_field_func(xtmp(2), ytmp(2), ztmp(2), Pnm, 'S'); + P(~select) = [Ptmp(1); Ptmp(2)]; + else + P(~select) = sound_field_func(x(~select), y(~select), z(~select), Pnm, 'S'); + end +end + +%% ===== Plotting ======================================================= +if (nargout==0 || useplot) + plot_sound_field(P,X,Y,Z,[],conf); +end + +end \ No newline at end of file diff --git a/SFS_monochromatic/circexp/sound_field_mono_circexp.m b/SFS_monochromatic/circexp/sound_field_mono_circexp.m index 74b99f65..6997b643 100644 --- a/SFS_monochromatic/circexp/sound_field_mono_circexp.m +++ b/SFS_monochromatic/circexp/sound_field_mono_circexp.m @@ -58,9 +58,9 @@ nargmax = 8; narginchk(nargmin,nargmax); isargvector(Pm); -if mod(size(Pm, 1)-1, 2) ~= 0 +if mod(size(Pm, 1), 2) ~= 0 error('%s: Number of rows of %s has be to odd', upper(mfilename), ... - inputname(Pm)); + inputname(4)); end isargnumeric(X,Y,Z); isargpositivescalar(f); diff --git a/SFS_monochromatic/sht/sound_field_mono_sht.m b/SFS_monochromatic/sht/sound_field_mono_sht.m index ded3ee99..1aa4e6b8 100644 --- a/SFS_monochromatic/sht/sound_field_mono_sht.m +++ b/SFS_monochromatic/sht/sound_field_mono_sht.m @@ -77,12 +77,14 @@ P = zeros(size(x)); +% regular (interior) domain inside the loudspeaker array if any(select(:)) Pnm = sphexp_mono_sht(Dnm,'R',f,conf); P(select) = sound_field_mono_sphexp(x(select), y(select), z(select), ... Pnm, 'R', f, Xc,conf); end - + +% singular (exterior) domain outside the loudspeaker array if any(~select(:)) Pnm = sphexp_mono_sht(Dnm,'S',f,conf); if sum( ~select(:) ) == 2 diff --git a/SFS_monochromatic/sphexp/sphexp_mono_cht.m b/SFS_monochromatic/sphexp/sphexp_mono_cht.m new file mode 100644 index 00000000..a7520700 --- /dev/null +++ b/SFS_monochromatic/sphexp/sphexp_mono_cht.m @@ -0,0 +1,82 @@ +function Pnm = sphexp_mono_cht(Dm, mode, f, conf) +%SPHEXP_MONO_CHT yields spherical expansion coefficients of a sound field +%resulting from of a driving function given as a circular harmonics transform +% +% Usage: Pnm = sphexp_mono_cht(Dm, mode, f, conf) +% +% Input parameters: +% Dm - circular harmonics transform of driving function +% mode - 'R' for regular, 'S' for singular +% f - frequency / Hz [Nf x 1] or [1 x Nf] +% conf - configuration struct (see SFS_config) +% +% Output parameters: +% Pnm - spherical expansion coefficients of a synthesized +% sound field reproduced by nfchoa driving function +% +% SPHEXP_MONO_CHT(Dm, mode, f, conf) computes the spherical expansion +% coefficients of sound field reproduced by a circular secondary source +% distribution consisting of SPHERICAL monopoles. The driving function is +% given as its circular harmonics transform. + +%***************************************************************************** +% Copyright (c) 2010-2016 Quality & Usability Lab, together with * +% Assessment of IP-based Applications * +% Telekom Innovation Laboratories, TU Berlin * +% Ernst-Reuter-Platz 7, 10587 Berlin, Germany * +% * +% Copyright (c) 2013-2016 Institut fuer Nachrichtentechnik * +% Universitaet Rostock * +% Richard-Wagner-Strasse 31, 18119 Rostock * +% * +% This file is part of the Sound Field Synthesis-Toolbox (SFS). * +% * +% The SFS 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 3 of the License, or (at your option) * +% any later version. * +% * +% The SFS 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, see . * +% * +% The SFS is a toolbox for Matlab/Octave to simulate and investigate sound * +% field synthesis methods like wave field synthesis or higher order * +% ambisonics. * +% * +% http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * +%***************************************************************************** + +%% ===== Checking of input parameters ================================== +nargmin = 4; +nargmax = 4; +narginchk(nargmin,nargmax); +isargmatrix(Dm); +isargvector(f); +isargchar(mode); +if ~strcmp('R', mode) && ~strcmp('S', mode) + error('%s: unknown mode (%s)!', upper(mfilename), mode); +end +isargstruct(conf); + +%% ===== Configuration ================================================== +R0 = conf.secondary_sources.size / 2; + +%% ===== Variables ====================================================== +Nse = (size(Dm, 1)-1)/2; + +%% ===== Computation ==================================================== +% regular/singular spherical expansion of 3D Green's function +Gnm = sphexp_mono_ps([R0, 0, 0], mode, Nse, f, [0,0,0], conf); +% regular/singular spherical expansion of synthesised sound field +Pnm = zeros(size(Gnm)); +for n=0:Nse + v = sphexp_index(-n:n,n); + Pnm(v,:) = 2*pi*R0*Gnm(v,:).*Dm((-n:n)+Nse+1,:); +end + +end \ No newline at end of file From 9d158a847cd77a7607e42ede81d2a87777fea5e3 Mon Sep 17 00:00:00 2001 From: Chris Hold Date: Thu, 15 Dec 2016 15:37:30 +0100 Subject: [PATCH 80/81] Update style in circexp --- SFS_monochromatic/circexp/circbasis_mono.m | 27 ++++++------ .../circexp/circbasis_mono_grid.m | 10 ++--- .../circexp/circexp_convert_sphexp.m | 17 +++---- SFS_monochromatic/circexp/circexp_mono_ls.m | 37 ++++++++-------- SFS_monochromatic/circexp/circexp_mono_pw.m | 17 ++++--- .../circexp/circexp_mono_scatter.m | 39 ++++++++-------- .../circexp/circexp_mono_timereverse.m | 7 ++- .../circexp/circexp_mono_translation.m | 44 +++++++++---------- .../circexp/circexp_truncation_order.m | 13 +++--- .../circexp/sound_field_mono_circbasis.m | 20 ++++----- .../circexp/sound_field_mono_circexp.m | 24 +++++----- 11 files changed, 125 insertions(+), 130 deletions(-) diff --git a/SFS_monochromatic/circexp/circbasis_mono.m b/SFS_monochromatic/circexp/circbasis_mono.m index be298ca1..f1ca4094 100644 --- a/SFS_monochromatic/circexp/circbasis_mono.m +++ b/SFS_monochromatic/circexp/circbasis_mono.m @@ -1,10 +1,10 @@ -function [Jn, H2n, Yn] = circbasis_mono(r, phi, Nce, k, conf) +function [Jn,H2n,Yn] = circbasis_mono(r,phi,Nce,k,conf) %CIRCBASIS_MONO evaluates circular basis functions for given input arguments % -% Usage: [Jn, H2n, Yn] = circbasis_mono(r, phi, Nce, k, conf) +% Usage: [Jn,H2n,Yn] = circbasis_mono(r,phi,Nce,k,conf) % % Input parameters: -% r - distance from z-axis in cylindrical coordinates +% r - distance from z-axis in cylindrical coordinates % phi - azimuth angle in cylindrical coordinates % k - wave number % conf - optional configuration struct (see SFS_config) @@ -78,17 +78,16 @@ l = 0; for n=-Nce:0 - % negative n - l = l + 1; - Jn{l} = besselj(n,kr); - H2n{l} = Jn{l} - 1j*bessely(n,kr); - Yn{l} = exp(1j*n*phi); - % positive n - Jn{L-l+1} = (-1)^n*Jn{l}; - H2n{L-l+1} = (-1)^n*H2n{l}; - Yn{L-l+1} = conj(Yn{l}); - if showprogress, progress_bar(n+Nce,Nce); end % progress bar + % negative n + l = l + 1; + Jn{l} = besselj(n,kr); + H2n{l} = Jn{l} - 1j*bessely(n,kr); + Yn{l} = exp(1j*n*phi); + % positive n + Jn{L-l+1} = (-1)^n*Jn{l}; + H2n{L-l+1} = (-1)^n*H2n{l}; + Yn{L-l+1} = conj(Yn{l}); + if showprogress, progress_bar(n+Nce,Nce); end % progress bar end end - diff --git a/SFS_monochromatic/circexp/circbasis_mono_grid.m b/SFS_monochromatic/circexp/circbasis_mono_grid.m index 871ab4d8..3450be88 100644 --- a/SFS_monochromatic/circexp/circbasis_mono_grid.m +++ b/SFS_monochromatic/circexp/circbasis_mono_grid.m @@ -1,8 +1,8 @@ -function [jn, h2n, Ynm] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf) -%CIRCBASIS_MONO_GRID evaluate spherical basis functions for given grid in +function [jn,h2n,Ynm] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf) +%CIRCBASIS_MONO_GRID evaluate spherical basis functions for given grid in %cartesian coordinates % -% Usage: [jn, h2n, Ynm] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf) +% Usage: [jn,h2n,Ynm] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf) % % Input parameters: % X - x-axis / m; single value or [xmin,xmax] or nD-array @@ -67,7 +67,7 @@ % http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * %***************************************************************************** -%% ===== Checking of input parameters ================================== +%% ===== Checking of input parameters ================================== nargmin = 7; nargmax = 7; narginchk(nargmin,nargmax); @@ -88,4 +88,4 @@ r = sqrt(xx.^2 + yy.^2); phi = atan2(yy,xx); -[jn, h2n, Ynm] = circbasis_mono(r, phi, Nce, k, conf); \ No newline at end of file +[jn,h2n,Ynm] = circbasis_mono(r,phi,Nce,k,conf); diff --git a/SFS_monochromatic/circexp/circexp_convert_sphexp.m b/SFS_monochromatic/circexp/circexp_convert_sphexp.m index a95a95a5..747874b0 100644 --- a/SFS_monochromatic/circexp/circexp_convert_sphexp.m +++ b/SFS_monochromatic/circexp/circexp_convert_sphexp.m @@ -1,5 +1,5 @@ function Am = circexp_convert_sphexp(Anm) -%CIRCEXP_CONVERT_SPHEXP converts regular spherical expansion coefficients into +%CIRCEXP_CONVERT_SPHEXP converts regular spherical expansion coefficients into %regular circular expansion coefficients % % Usage: Am = circexp_convert_sphexp(Anm) @@ -11,8 +11,8 @@ % Am - regular circular expansion coefficients % % References: -% Hahn, Winter, Spors (2016) - -% "Local Wave Field Synthesis by Spatial Band-limitation in the +% Hahn, Winter, Spors (2016) - +% "Local Wave Field Synthesis by Spatial Band-limitation in the % Circular/Spherical Harmonics Domain", 140th AES Convention %***************************************************************************** @@ -47,18 +47,19 @@ % http://github.com/sfstoolbox/sfs sfstoolbox@gmail.com * %***************************************************************************** -%% ===== Checking of input parameters ================================== +%% ===== Checking of input parameters ================================== nargmin = 1; nargmax = 1; narginchk(nargmin,nargmax); isargvector(Anm); -Nse = sqrt(size(Anm, 1))-1; +Nse = sqrt(size(Anm,1))-1; %% ===== Computation ==================================================== % Implementation of Hahn2016, Eq. (32) -Am = zeros(2*Nse+1,size(Anm, 2)); +Am = zeros(2*Nse+1,size(Anm,2)); for m=-Nse:Nse - v = sphexp_index(m); % (n,m) = (abs(m),m); - Am(m+Nse+1,:) = Anm(v,:)./(4*pi.*1j.^(m-abs(m))*sphharmonics(abs(m),-m,0,0)); + v = sphexp_index(m); % (n,m) = (abs(m),m); + Am(m+Nse+1,:) = Anm(v,:)./(4*pi.*1j.^(m-abs(m))* ... + sphharmonics(abs(m),-m,0,0)); end diff --git a/SFS_monochromatic/circexp/circexp_mono_ls.m b/SFS_monochromatic/circexp/circexp_mono_ls.m index ffecb083..cac46a90 100644 --- a/SFS_monochromatic/circexp/circexp_mono_ls.m +++ b/SFS_monochromatic/circexp/circexp_mono_ls.m @@ -1,7 +1,7 @@ -function ABm = circexp_mono_ls(xs, mode, Nce, f, xq, conf) +function ABm = circexp_mono_ls(xs,mode,Nce,f,xq,conf) %CIRCEXP_MONO_LS computes the regular/singular circular expansion of line source % -% Usage: ABm = circexp_mono_ls(xs, mode, Nce, f, xq, conf) +% Usage: ABm = circexp_mono_ls(xs,mode,Nce,f,xq,conf) % % Input parameters: % xs - position of line source @@ -14,28 +14,28 @@ % Output parameters: % ABm - regular cylindrical expansion coefficients [2*Nce+1 x Nf] % -% CIRCEXP_MONO_LS(xs, mode, Nce, f, xq, conf) computes the regular circular -% expansion coefficients for a line source. The expansion will be done +% CIRCEXP_MONO_LS(xs,mode,Nce,f,xq,conf) computes the regular circular +% expansion coefficients for a line source. The expansion will be done % around the expansion coordinate xq: % % Regular Expansion: -% \~~ oo -% p (x,f) = > A R (x-x ) +% \~~ oo +% p (x,f) = > A R (x-x ) % ls,R /__ n=-oo n n q % % with the expansion coefficients: -% m -i -% A = --- S (x -x ) -% n 4 n s q +% m -i +% A = --- S (x -x ) +% n 4 n s q % % Singular Expansion: -% \~~ oo m -% p (x,f) = > B S (x-x ) +% \~~ oo m +% p (x,f) = > B S (x-x ) % ls,R /__ n=-oo n n q % % with the expansion coefficients): -% m -i -% B = --- R (x -x ) +% m -i +% B = --- R (x -x ) % n 4 n s q % % see also: circexp_mono_pw circexp_mono_scatter @@ -96,11 +96,11 @@ % select suitable basis function if strcmp('R', mode) - circbasis = @(nu,z) besselh(nu,2,z); + circbasis = @(nu,z) besselh(nu,2,z); elseif strcmp('S', mode) - circbasis = @besselj; + circbasis = @besselj; else - error('unknown mode:'); + error('unknown mode:'); end %% ===== Computation ==================================================== @@ -109,9 +109,8 @@ ABm = zeros(L,Nf); l = 0; for n=-Nce:Nce - l = l+1; - ABm(l,:) = -1j/4*circbasis(n,kr).*exp(-1j*n*phi); + l = l+1; + ABm(l,:) = -1j/4*circbasis(n,kr).*exp(-1j*n*phi); end end - diff --git a/SFS_monochromatic/circexp/circexp_mono_pw.m b/SFS_monochromatic/circexp/circexp_mono_pw.m index 7ebd3d81..b4c31e0a 100644 --- a/SFS_monochromatic/circexp/circexp_mono_pw.m +++ b/SFS_monochromatic/circexp/circexp_mono_pw.m @@ -1,10 +1,10 @@ -function Am = circexp_mono_pw(npw, Nce, f, xq, conf) +function Am = circexp_mono_pw(npw,Nce,f,xq,conf) %CIRCEXP_MONO_PW computes regular circular expansion coefficients of plane wave % -% Usage: Am = circexp_mono_pw(npw, Nce, f, xq, conf) +% Usage: Am = circexp_mono_pw(npw,Nce,f,xq,conf) % % Input parameters: -% nk - propagation direction of plane wave +% nk - propagation direction of plane wave % Nce - maximum order of circular basis functions % f - frequency / Hz [1 x Nf] or [Nf x 1] % xq - expansion center @@ -13,12 +13,12 @@ % Output parameters: % Am - regular cylindrical expansion coefficients [2*Nce+1 x Nf] % -% CIRCEXP_MONO_PW(npw, Nce, f, xq, conf) computes the regular circular +% CIRCEXP_MONO_PW(npw,Nce,f,xq,conf) computes the regular circular % expansion coefficients for a plane wave. The expansion will be done a % round the expansion coordinate xq: % -% \~~ oo -% p (x,f) = > A R (x-x ) +% \~~ oo +% p (x,f) = > A R (x-x ) % pw /__ n=-oo n n q % % with the cylyndrical expansion coefficients: @@ -85,9 +85,8 @@ Am = zeros(L,Nf); l = 0; for n=-Nce:Nce - l = l+1; - Am(l,:) = (1j)^(-n).*exp(-1j*n*phi).*exp(-1j*delay); + l = l+1; + Am(l,:) = (1j)^(-n).*exp(-1j*n*phi).*exp(-1j*delay); end end - diff --git a/SFS_monochromatic/circexp/circexp_mono_scatter.m b/SFS_monochromatic/circexp/circexp_mono_scatter.m index f1d68205..0fe1cb10 100644 --- a/SFS_monochromatic/circexp/circexp_mono_scatter.m +++ b/SFS_monochromatic/circexp/circexp_mono_scatter.m @@ -1,11 +1,11 @@ -function Bm = circexp_mono_scatter(Am, R, sigma, f, conf) +function Bm = circexp_mono_scatter(Am,R,sigma,f,conf) %CIRCEXP_MONO_SCATTER computes the singular circular expansion coefficients of %cylinder-scattered field % -% Usage: Bm = circexp_mono_scatter(Al, R, sigma, f, conf) +% Usage: Bm = circexp_mono_scatter(Al,R,sigma,f,conf) % % Input parameters: -% Am - regular circular expansion of incident field [n x Nf] +% Am - regular circular expansion of incident field [n x Nf] % R - radius of cylinder / m % sigma - complex admittance of scatterer % f - frequency / Hz [1 x Nf] or [Nf x 1] @@ -15,28 +15,28 @@ % Bm - singular circular expansion coefficients of % scattered field [n x Nf] % -% CIRCEXP_MONO_SCATTER(Am, R, sigma, f, conf) computes the singular -% cylindrical expansion coefficients of a field resulting from a scattering -% of an incident field at a cylindrical. Incident field is descriped by -% regular expansion coefficients (expansion center is expected to be at the +% CIRCEXP_MONO_SCATTER(Am,R,sigma,f,conf) computes the singular +% cylindrical expansion coefficients of a field resulting from a scattering +% of an incident field at a cylindrical. Incident field is descriped by +% regular expansion coefficients (expansion center is expected to be at the % center of the cylinder xq): % -% \~~ oo -% p (x,f) = > A R (x-x ) +% \~~ oo +% p (x,f) = > A R (x-x ) % ind /__ n=0 n n q % % The scattered field is descriped by singular expansion coefficients, -% expanded around the center of the cylinder x0. +% expanded around the center of the cylinder x0. % -% \~~ oo -% p (x,f) = > B S (x-x ) +% \~~ oo +% p (x,f) = > B S (x-x ) % sca /__ n=0 n n q % % Due to the boundary conditions on the surface of the cylinder the % coefficients are related by: % % k . J' (kR) + sigma . H (kR) -% n n +% n n % B = - ------------------------------ . A % n k . H' (kR) + sigma . H (kR) n % n n @@ -95,12 +95,12 @@ kR = k.*R; % select suitable transformation function if isinf(sigma) - T = @(x) -besselj(x,kR)./besselh(x,2,kR); + T = @(x) -besselj(x,kR)./besselh(x,2,kR); elseif sigma == 0 - T = @(x) -besselj_derived(x,kR)./besselh_derived(x,2,kR); + T = @(x) -besselj_derived(x,kR)./besselh_derived(x,2,kR); else - T = @(x) -(k.*besselj_derived(x,kR)+sigma.*besselj(x,kR)) ... - ./(k.*besselh_derived(x,2,kR)+sigma.*besselh(x,2,kR)); + T = @(x) -(k.*besselj_derived(x,kR)+sigma.*besselj(x,kR)) ... + ./(k.*besselh_derived(x,2,kR)+sigma.*besselh(x,2,kR)); end %% ===== Computation ==================================================== @@ -108,9 +108,8 @@ Bm = zeros(size(Am)); l = 0; for n=-Nce:Nce - l = l+1; - Bm(l,:) = T(n).*Am(l,:); + l = l+1; + Bm(l,:) = T(n).*Am(l,:); end end - diff --git a/SFS_monochromatic/circexp/circexp_mono_timereverse.m b/SFS_monochromatic/circexp/circexp_mono_timereverse.m index 74731942..d3cfddd0 100644 --- a/SFS_monochromatic/circexp/circexp_mono_timereverse.m +++ b/SFS_monochromatic/circexp/circexp_mono_timereverse.m @@ -48,9 +48,9 @@ nargmax = 1; narginchk(nargmin,nargmax); isargmatrix(Pm); -if mod(size(Pm, 1)-1, 2) ~= 0 - error('%s: Number of rows of %s has be to odd', upper(mfilename), ... - inputname(Pm)); +if mod(size(Pm,1)-1,2) ~= 0 + error('%s: Number of rows of %s has be to odd',upper(mfilename), ... + inputname(Pm)); end %% ===== Computation ==================================================== @@ -58,4 +58,3 @@ Pm = conj(Pm(end:-1:1,:)).*(-1).^(-Nce:Nce).'; end - diff --git a/SFS_monochromatic/circexp/circexp_mono_translation.m b/SFS_monochromatic/circexp/circexp_mono_translation.m index d27c1928..0231e578 100644 --- a/SFS_monochromatic/circexp/circexp_mono_translation.m +++ b/SFS_monochromatic/circexp/circexp_mono_translation.m @@ -1,11 +1,11 @@ -function [EF, EFm] = circexp_mono_translation(xt, mode, Nce, f, conf) -%CIRCEXP_MONO_TRANSLATION compute circular translation coefficients +function [EF,EFm] = circexp_mono_translation(xt,mode,Nce,f,conf) +%CIRCEXP_MONO_TRANSLATION compute circular translation coefficients %(multipole re-expansion) % -% Usage: [EF, EFm] = circexp_mono_translation(xt, mode, Nce, f, conf) +% Usage: [EF,EFm] = circexp_mono_translation(xt,mode,Nce,f,conf) % % Input parameters: -% xt - translatory shift [1x3] / m +% xt - translatory shift [1x3] / m % mode - 'RS' for regular-to-singular reexpansion % 'RR' for regular-to-regular reexpansion % 'SR' for singular-to-regular reexpansion @@ -16,22 +16,22 @@ % Output parameters: % EF - circular re-expansion coefficients for t % EFm - circular re-expansion coefficients for -t -% -% CIRCEXP_MONO_TRANSLATION(t, mode, f, conf) computes the circular re-expansion +% +% CIRCEXP_MONO_TRANSLATION(t,mode,f,conf) computes the circular re-expansion % coefficients to perform as translatory shift of circular basis function. % Multipole Re-expansion computes the circular basis function for a shifted -% coordinate system (x+t) based on the original basis functions for (x). +% coordinate system (x+t) based on the original basis functions for (x). % % \~~ inf % E (x + t) = > (E|F) (xt) F (x) % n /__ l=-inf l,n l % % where {E,F} = {R,S}. R denotes the regular circular basis function, while -% S symbolizes the singular circular basis function. Note that (S|S) and +% S symbolizes the singular circular basis function. Note that (S|S) and % (S|R) are equivalent to (R|R) and (R|S), respectively. % % see also: circexp_mono_ps, circexp_mono_pw - + %***************************************************************************** % Copyright (c) 2010-2016 Quality & Usability Lab, together with * % Assessment of IP-based Applications * @@ -89,24 +89,24 @@ EFm = EF; % select suitable basis function -if strcmp('RR', mode) || strcmp('SS', mode) - circbasis = @(nu) besselj(nu, kr); -elseif strcmp('SR', mode) || strcmp('RS', mode) - circbasis = @(nu) besselh(nu, 2, kr); +if strcmp('RR',mode) || strcmp('SS',mode) + circbasis = @(nu) besselj(nu,kr); +elseif strcmp('SR',mode) || strcmp('RS',mode) + circbasis = @(nu) besselh(nu,2,kr); else - error('unknown mode:'); + error('unknown mode:'); end %% ===== Computation ==================================================== s = 0; for n=-Nce:Nce - s = s+1; - l = 0; - for m=-Nce:Nce - l = l+1; - EF(s,l) = circbasis(m-n) .* exp(+1j.*(m-n).*phit); - EFm(s,l) = EF(s,l) .* (-1)^(n-m); - end + s = s+1; + l = 0; + for m=-Nce:Nce + l = l+1; + EF(s,l) = circbasis(m-n) .* exp(+1j.*(m-n).*phit); + EFm(s,l) = EF(s,l) .* (-1)^(n-m); + end end -end \ No newline at end of file +end diff --git a/SFS_monochromatic/circexp/circexp_truncation_order.m b/SFS_monochromatic/circexp/circexp_truncation_order.m index d4da0537..5e29a94f 100644 --- a/SFS_monochromatic/circexp/circexp_truncation_order.m +++ b/SFS_monochromatic/circexp/circexp_truncation_order.m @@ -1,8 +1,8 @@ -function Nce = circexp_truncation_order(r, f, nmse, conf) -%CIRCEXP_TRUNCATION_ORDER computes truncation order for circular expansion +function Nce = circexp_truncation_order(r,f,nmse,conf) +%CIRCEXP_TRUNCATION_ORDER computes truncation order for circular expansion %coefficients of an arbitrary sound field % -% Usage: Nce = circexp_truncation_order(r, f, nmse, conf) +% Usage: Nce = circexp_truncation_order(r,f,nmse,conf) % % Input parameters: % r - max 2D distance from expansion center / m @@ -13,13 +13,13 @@ % Output parameters: % Nce - Maximum order for circular expansion % -% CIRCEXP_TRUNCATION_ORDER(r, f, epsilon, conf) yields the order up to which +% CIRCEXP_TRUNCATION_ORDER(r,f,epsilon,conf) yields the order up to which % a the circular expansion coefficients of an arbitrary sound field have -% be summed up. For a given frequency and maximum radius the normalized +% be summed up. For a given frequency and maximum radius the normalized % truncation mean squared error is below the specified error bound (nmse). % % References: -% Kennedy et al. (2007) - "Intrinsic Limits of Dimensionality and +% Kennedy et al. (2007) - "Intrinsic Limits of Dimensionality and % Richness in Random Multipath Fields", % IEEE Transactions on Signal Processing @@ -71,4 +71,3 @@ Nce = ceil(pi*r*exp(1)/lambda) + delta; end - diff --git a/SFS_monochromatic/circexp/sound_field_mono_circbasis.m b/SFS_monochromatic/circexp/sound_field_mono_circbasis.m index 3129ef54..904e620b 100644 --- a/SFS_monochromatic/circexp/sound_field_mono_circbasis.m +++ b/SFS_monochromatic/circexp/sound_field_mono_circbasis.m @@ -1,12 +1,12 @@ -function P = sound_field_mono_circbasis(Pm, JH2m, Ym) -%SOUND_FIELD_MONO_CIRCBASIS simulates a sound field expressed with +function P = sound_field_mono_circbasis(Pm,JH2m,Ym) +%SOUND_FIELD_MONO_CIRCBASIS simulates a sound field expressed with %circular basis functions % -% Usage: P = sound_field_mono_circbasis(Pm, JH2m, Ym) +% Usage: P = sound_field_mono_circbasis(Pm,JH2m,Ym) % % Input parameters: % Pm - regular/singular circular expansion coefficients -% JH2m - cell array of cylindrical bessel/hankel(2nd kind) +% JH2m - cell array of cylindrical bessel/hankel(2nd kind) % functions % Ym - cell array of cylindrical harmonics (exponential % functions) @@ -14,7 +14,7 @@ % Output parameters: % P - resulting soundfield % -% SOUND_FIELD_MONO_CIRCBASIS(Pm, JH2m, Ym) +% SOUND_FIELD_MONO_CIRCBASIS(Pm,JH2m,Ym) % % see also: circbasis_mono_grid sound_field_mono_circexp @@ -57,8 +57,8 @@ isargvector(Pm); isargequallength(Pm, Ym); if length(Ym) ~= length(JH2m) - error('%s, length(%s) has to be length(%s)!', upper(mfilename), ... - inputname(2), inputname(3)); + error('%s, length(%s) has to be length(%s)!',upper(mfilename), ... + inputname(2),inputname(3)); end %% ===== Variables ====================================================== @@ -69,8 +69,8 @@ l = 0; for n=0:Nce - l=l+1; - P = P + Pm(l).*(JH2m{l}.*Ym{l}); + l=l+1; + P = P + Pm(l).*(JH2m{l}.*Ym{l}); end -end \ No newline at end of file +end diff --git a/SFS_monochromatic/circexp/sound_field_mono_circexp.m b/SFS_monochromatic/circexp/sound_field_mono_circexp.m index 6997b643..405abbc8 100644 --- a/SFS_monochromatic/circexp/sound_field_mono_circexp.m +++ b/SFS_monochromatic/circexp/sound_field_mono_circexp.m @@ -1,8 +1,8 @@ -function [P, x, y, z] = sound_field_mono_circexp(X,Y,Z,Pm,mode,f,xq,conf) +function [P,x,y,z] = sound_field_mono_circexp(X,Y,Z,Pm,mode,f,xq,conf) %SOUND_FIELD_MONO_CIRCEXP yields a sound field given with regular/singular %spherical expansion coefficients % -% Usage: [P, x, y, z] = sound_field_mono_circexp(X,Y,Z,Pm,mode,f,xq,conf) +% Usage: [P,x,y,z] = sound_field_mono_circexp(X,Y,Z,Pm,mode,f,xq,conf) % % Input parameters: % X - x-axis / m; single value or [xmin,xmax] or nD-array @@ -58,9 +58,9 @@ nargmax = 8; narginchk(nargmin,nargmax); isargvector(Pm); -if mod(size(Pm, 1), 2) ~= 0 - error('%s: Number of rows of %s has be to odd', upper(mfilename), ... - inputname(4)); +if mod(size(Pm,1),2) ~= 0 + error('%s: Number of rows of %s has be to odd',upper(mfilename), ... + inputname(4)); end isargnumeric(X,Y,Z); isargpositivescalar(f); @@ -71,13 +71,13 @@ %% ===== Computation ==================================================== switch mode - case 'R' - [fn, ~, Ym, x, y, z] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf); - case 'S' - [~, fn, Ym, x, y, z] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf); - otherwise - error('%s: %s is an unknown mode!',upper(mfilename), mode); + case 'R' + [fn,~,Ym,x,y,z] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf); + case 'S' + [~,fn,Ym,x,y,z] = circbasis_mono_grid(X,Y,Z,Nce,f,xq,conf); + otherwise + error('%s: %s is an unknown mode!',upper(mfilename),mode); end P = sound_field_mono_circbasis(Pm,fn,Ym); -end \ No newline at end of file +end From d6c8886b5b9e2fd58273703353d95e353be8bcd4 Mon Sep 17 00:00:00 2001 From: Chris Hold Date: Thu, 15 Dec 2016 16:23:50 +0100 Subject: [PATCH 81/81] Update style in sphexp --- .../sphexp/sound_field_mono_sphbasis.m | 18 +-- .../sphexp/sound_field_mono_sphexp.m | 22 ++-- SFS_monochromatic/sphexp/sphbasis_mono.m | 36 +++--- SFS_monochromatic/sphexp/sphbasis_mono_grid.m | 12 +- SFS_monochromatic/sphexp/sphexp_access.m | 28 ++--- .../sphexp/sphexp_convert_circexp.m | 14 +-- SFS_monochromatic/sphexp/sphexp_index.m | 16 +-- SFS_monochromatic/sphexp/sphexp_mono_cht.m | 20 +-- SFS_monochromatic/sphexp/sphexp_mono_ls.m | 25 ++-- .../sphexp/sphexp_mono_multiscatter.m | 40 +++--- SFS_monochromatic/sphexp/sphexp_mono_ps.m | 58 ++++----- SFS_monochromatic/sphexp/sphexp_mono_pw.m | 30 ++--- .../sphexp/sphexp_mono_scatter.m | 18 +-- SFS_monochromatic/sphexp/sphexp_mono_sht.m | 40 +++--- .../sphexp/sphexp_mono_timereverse.m | 4 +- .../sphexp/sphexp_mono_translation.m | 118 +++++++++--------- .../sphexp/sphexp_translation_auxiliary.m | 22 ++-- SFS_monochromatic/sphexp/sphexp_truncate.m | 32 ++--- .../sphexp/sphexp_truncation_order.m | 8 +- 19 files changed, 280 insertions(+), 281 deletions(-) diff --git a/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m b/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m index f5c960d6..1ae8bc77 100644 --- a/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m +++ b/SFS_monochromatic/sphexp/sound_field_mono_sphbasis.m @@ -1,8 +1,8 @@ -function P = sound_field_mono_sphbasis(ABnm, jh2n, Ynm) +function P = sound_field_mono_sphbasis(ABnm,jh2n,Ynm) %SOUND_FIELD_MONO_SPHBASIS simulates a sound field expressed with spherical %basis functions % -% Usage: P = sound_field_mono_sphbasis(AB, jh2n, Ynm) +% Usage: P = sound_field_mono_sphbasis(AB,jh2n,Ynm) % % Input parameters: % ABnm - regular/singular spherical expansion coefficients @@ -12,7 +12,7 @@ % Output parameters: % P - resulting soundfield % -% SOUND_FIELD_MONO_SPHBASIS(ABnm, jh2n, Ynm) +% SOUND_FIELD_MONO_SPHBASIS(ABnm,jh2n,Ynm) % % see also: sphbasis_mono_grid sound_field_mono_sphexp @@ -56,10 +56,10 @@ L = size(ABnm,1); isargsquaredinteger(L); if length(Ynm) ~= length(jh2n)^2 - error('%s: length(Y) has to be equal length(jh2n)^2!',upper(mfilename)); + error('%s: length(Y) has to be equal length(jh2n)^2!',upper(mfilename)); end if length(Ynm) < length(ABnm) - error('%s: length(Y) has to larger equal length(ABnm)!',upper(mfilename)); + error('%s: length(Y) has to larger equal length(ABnm)!',upper(mfilename)); end %% ===== Variables ====================================================== @@ -71,8 +71,8 @@ % spherical basic functions l = 0; for n=0:Nse - for m=-n:n - l=l+1; - P = P + ABnm(l)*(jh2n{n+1}.*Ynm{l}); - end + for m=-n:n + l=l+1; + P = P + ABnm(l)*(jh2n{n+1}.*Ynm{l}); + end end diff --git a/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m b/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m index fcf5cf39..76302c48 100644 --- a/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m +++ b/SFS_monochromatic/sphexp/sound_field_mono_sphexp.m @@ -1,17 +1,17 @@ -function [P, x, y, z] = sound_field_mono_sphexp(X,Y,Z,ABnm,mode,f,xq,conf) +function [P,x,y,z] = sound_field_mono_sphexp(X,Y,Z,ABnm,mode,f,xq,conf) %SOUND_FIELD_MONO_SPHEXPR simulates a sound field given with regular/singular %spherical expansion coefficients % -% Usage: [P, x, y, z] = sound_field_mono_sphexp(X,Y,Z,ABnm,mode,f,xq,conf) +% Usage: [P,x,y,z] = sound_field_mono_sphexp(X,Y,Z,ABnm,mode,f,xq,conf) % % Input parameters: % X - x-axis / m; single value or [xmin,xmax] or nD-array % Y - y-axis / m; single value or [ymin,ymax] or nD-array % Z - z-axis / m; single value or [zmin,zmax] or nD-array % ABnm - regular/singular spherical expansion coefficients -% mode - 'R' for regular, 'S' for singular +% mode - 'R' for regular,'S' for singular % f - frequency in Hz -% xq - expansion center coordinates, default: [0, 0, 0] +% xq - expansion center coordinates,default: [0,0,0] % conf - configuration struct (see SFS_config) % % Output parameters: @@ -19,7 +19,7 @@ % % SOUND_FIELD_MONO_SPHEXPR(X,Y,Z,ABnm,mode,f,xq,conf) % -% see also: sphbasis_mono_grid, sound_field_mono_sphbasis +% see also: sphbasis_mono_grid,sound_field_mono_sphbasis %***************************************************************************** % Copyright (c) 2010-2016 Quality & Usability Lab, together with * @@ -61,19 +61,19 @@ isargsquaredinteger(length(ABnm)); isargnumeric(X,Y,Z); isargpositivescalar(f); -isargposition(xq); +isargposition(xq); isargstruct(conf); %% ===== Variables ====================================================== Nse = sqrt(length(ABnm)) - 1; %% ===== Computation ==================================================== -if strcmp('R', mode) - [fn, ~, Ynm, x, y, z] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf); -elseif strcmp('S', mode) - [~, fn, Ynm, x, y, z] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf); +if strcmp('R',mode) + [fn,~,Ynm,x,y,z] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf); +elseif strcmp('S',mode) + [~,fn,Ynm,x,y,z] = sphbasis_mono_grid(X,Y,Z,Nse,f,xq,conf); else - error('%s: %s is an unknown mode!', upper(mfilename), mode); + error('%s: %s is an unknown mode!',upper(mfilename),mode); end P = sound_field_mono_sphbasis(ABnm,fn,Ynm); diff --git a/SFS_monochromatic/sphexp/sphbasis_mono.m b/SFS_monochromatic/sphexp/sphbasis_mono.m index 488d4f73..40c42c68 100644 --- a/SFS_monochromatic/sphexp/sphbasis_mono.m +++ b/SFS_monochromatic/sphexp/sphbasis_mono.m @@ -1,7 +1,7 @@ -function [jn, h2n, Ynm] = sphbasis_mono(r,theta,phi,Nse,k,conf) +function [jn,h2n,Ynm] = sphbasis_mono(r,theta,phi,Nse,k,conf) %SPHBASIS_MONO evaluates spherical basis functions for given input arguments % -% Usage: [jn, h2n, Ynm] = sphbasis_mono(r,theta,phi,Nse,k,conf) +% Usage: [jn,h2n,Ynm] = sphbasis_mono(r,theta,phi,Nse,k,conf) % % Input parameters: % r - distance from origin / m [n1 x n2 x ...] @@ -16,11 +16,11 @@ % h2n - cell array of spherical hankel functions of 2nd kind % Ynm - cell array of spherical harmonics % -% SPHBASIS_MONO(r,theta,phi,Nse,k,conf) computes spherical basis functions -% for the given arguments r, theta and phi. r, theta and phi can be of +% SPHBASIS_MONO(r,theta,phi,Nse,k,conf) computes spherical basis functions +% for the given arguments r, theta and phi. r, theta and phi can be of % arbitrary (but same) size. Output will be stored in cell arrays (one cell -% entry for each order) of length Nse+1 for jn and h2n. For Ynm the lenght -% is (Nse+1).^2. The coefficients of Ynm are stored with the linear index l +% entry for each order) of length Nse+1 for jn and h2n. For Ynm the lenght +% is (Nse+1).^2. The coefficients of Ynm are stored with the linear index l % resulting from the order m and the degree n of the spherical harmonics: % % m 2 @@ -69,9 +69,9 @@ isargequalsize(r,phi,theta); isargscalar(k); if nargin A(l1) ; A(n2,m2) => A(l2) % CAUTION: THIS FUNCTION DOES NOT USE ANY CHECK OF INPUT ARGUMENTS @@ -56,36 +56,36 @@ %% ===== Checking of input parameters =================================== L1 = length(m1); if nargin < 3 - n1 = abs(m1); + n1 = abs(m1); elseif length(n1) < L1 - n1 = repmat(n1, [1 L1]); + n1 = repmat(n1,[1 L1]); elseif length(n1) > L1 - m1 = repmat(m1, [1 length(n2)]); - L1 = length(m2); + m1 = repmat(m1,[1 length(n2)]); + L1 = length(m2); end if nargin < 4 - m2 = 0; + m2 = 0; end L2 = length(m2); if nargin < 5 - n2 = abs(m2); + n2 = abs(m2); elseif length(n2) < L2 - n2 = repmat(n2, [1 L2]); + n2 = repmat(n2,[1 L2]); elseif length(n2) > L2 - m2 = repmat(m2, [1 length(n2)]); - L2 = length(m2); + m2 = repmat(m2,[1 length(n2)]); + L2 = length(m2); end %% ===== Computation ==================================================== -a = zeros(L1, L2, size(Anm, 3)); +a = zeros(L1,L2,size(Anm,3)); s1 = abs(m1) <= n1; s2 = abs(m2) <= n2; if any(s1) && any(s2) - [v, w] = sphexp_index(m1(s1), n1(s1), m2(s2), n2(s2)); + [v,w] = sphexp_index(m1(s1),n1(s1),m2(s2),n2(s2)); a(s1,s2,:) = Anm(v,w,:); end diff --git a/SFS_monochromatic/sphexp/sphexp_convert_circexp.m b/SFS_monochromatic/sphexp/sphexp_convert_circexp.m index cc917388..9333a12a 100644 --- a/SFS_monochromatic/sphexp/sphexp_convert_circexp.m +++ b/SFS_monochromatic/sphexp/sphexp_convert_circexp.m @@ -1,5 +1,5 @@ function Anm = sphexp_convert_circexp(Am) -%SPHEXP_CONVERT_CIRCEXP compute converts regular circular expansion into +%SPHEXP_CONVERT_CIRCEXP compute converts regular circular expansion into %spherical expansion coefficients % % Usage: Anm = sphexp_convert_circexp(Am) @@ -12,7 +12,7 @@ % % References: % Hahn, Spors (2015) - "Sound Field Synthesis of Virtual Cylindrical -% Waves using Circular and Spherical Loudspeaker +% Waves using Circular and Spherical Loudspeaker % Arrays", 138th AES Convention %***************************************************************************** @@ -59,9 +59,9 @@ % Implementation of Hahn2015, Eq. (14) Anm = zeros((Nce+1).^2,1); for m=-Nce:Nce - % for theta=0 the legendre polynom is zero if n+m is odd - for n = abs(m):2:Nce - v = sphexp_index(m,n); - Anm(v) = 4*pi.*1j.^(m-n).*sphharmonics(n,-m,0,0).*Am(m+Nce+1); - end + % for theta=0 the legendre polynom is zero if n+m is odd + for n = abs(m):2:Nce + v = sphexp_index(m,n); + Anm(v) = 4*pi.*1j.^(m-n).*sphharmonics(n,-m,0,0).*Am(m+Nce+1); + end end diff --git a/SFS_monochromatic/sphexp/sphexp_index.m b/SFS_monochromatic/sphexp/sphexp_index.m index 621c689d..3b7eb9cf 100644 --- a/SFS_monochromatic/sphexp/sphexp_index.m +++ b/SFS_monochromatic/sphexp/sphexp_index.m @@ -1,8 +1,8 @@ -function [l1, l2] = sphexp_index(m1, n1, m2, n2) -%SPHEXP_INDEX calculates index(indices) for the arrays of spherical expansion +function [l1,l2] = sphexp_index(m1,n1,m2,n2) +%SPHEXP_INDEX calculates index(indices) for the arrays of spherical expansion %coefficients % -% Usage: [l1, l2] = sphexp_index(m1, n1, m2, n2) +% Usage: [l1,l2] = sphexp_index(m1,n1,m2,n2) % % Input parameters: % m1 - order of 1st dimension @@ -14,7 +14,7 @@ % l1 - index for 1st dimension % l2 - index for 2st dimension % -% SPHEXP_INDEX(m1, n1, m2, n2) computes one/two indices for accessing +% SPHEXP_INDEX(m1,n1,m2,n2) computes one/two indices for accessing % 1D/2D arrays of spherical expansion coefficients % A(n1,m1) => A(l1) ; A(n2,m2) => A(l2) % CAUTION: THIS FUNCTION DOES NOT USE ANY CHECK OF INPUT ARGUMENTS @@ -55,13 +55,13 @@ %% ===== Checking of input parameters ================================== if nargin < 2 - n1 = abs(m1); + n1 = abs(m1); end if nargin < 3 - m2 = 0; + m2 = 0; end -if nargin < 4 - n2 = abs(m2); +if nargin < 4 + n2 = abs(m2); end %% ===== Computation ==================================================== diff --git a/SFS_monochromatic/sphexp/sphexp_mono_cht.m b/SFS_monochromatic/sphexp/sphexp_mono_cht.m index a7520700..17fafddf 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_cht.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_cht.m @@ -1,8 +1,8 @@ -function Pnm = sphexp_mono_cht(Dm, mode, f, conf) +function Pnm = sphexp_mono_cht(Dm,mode,f,conf) %SPHEXP_MONO_CHT yields spherical expansion coefficients of a sound field %resulting from of a driving function given as a circular harmonics transform % -% Usage: Pnm = sphexp_mono_cht(Dm, mode, f, conf) +% Usage: Pnm = sphexp_mono_cht(Dm,mode,f,conf) % % Input parameters: % Dm - circular harmonics transform of driving function @@ -14,7 +14,7 @@ % Pnm - spherical expansion coefficients of a synthesized % sound field reproduced by nfchoa driving function % -% SPHEXP_MONO_CHT(Dm, mode, f, conf) computes the spherical expansion +% SPHEXP_MONO_CHT(Dm,mode,f,conf) computes the spherical expansion % coefficients of sound field reproduced by a circular secondary source % distribution consisting of SPHERICAL monopoles. The driving function is % given as its circular harmonics transform. @@ -58,8 +58,8 @@ isargmatrix(Dm); isargvector(f); isargchar(mode); -if ~strcmp('R', mode) && ~strcmp('S', mode) - error('%s: unknown mode (%s)!', upper(mfilename), mode); +if ~strcmp('R',mode) && ~strcmp('S',mode) + error('%s: unknown mode (%s)!',upper(mfilename),mode); end isargstruct(conf); @@ -67,16 +67,16 @@ R0 = conf.secondary_sources.size / 2; %% ===== Variables ====================================================== -Nse = (size(Dm, 1)-1)/2; +Nse = (size(Dm,1)-1)/2; %% ===== Computation ==================================================== % regular/singular spherical expansion of 3D Green's function -Gnm = sphexp_mono_ps([R0, 0, 0], mode, Nse, f, [0,0,0], conf); +Gnm = sphexp_mono_ps([R0,0,0],mode,Nse,f,[0,0,0],conf); % regular/singular spherical expansion of synthesised sound field Pnm = zeros(size(Gnm)); for n=0:Nse - v = sphexp_index(-n:n,n); - Pnm(v,:) = 2*pi*R0*Gnm(v,:).*Dm((-n:n)+Nse+1,:); + v = sphexp_index(-n:n,n); + Pnm(v,:) = 2*pi*R0*Gnm(v,:).*Dm((-n:n)+Nse+1,:); end -end \ No newline at end of file +end diff --git a/SFS_monochromatic/sphexp/sphexp_mono_ls.m b/SFS_monochromatic/sphexp/sphexp_mono_ls.m index 383704a4..3e6bfd93 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_ls.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_ls.m @@ -1,21 +1,21 @@ -function Anm = sphexp_mono_ls(xs, mode, Nse, f, xq, conf) +function Anm = sphexp_mono_ls(xs,mode,Nse,f,xq,conf) %SPHEXP_MONO_LS computes the regular/singular spherical expansion of line source % -% Usage: Anm = sphexp_mono_ls(xs, mode, Nse, f, xq, conf) +% Usage: Anm = sphexp_mono_ls(xs,mode,Nse,f,xq,conf) % % Input parameters: % xs - position of line source % mode - 'R' for regular, 'S' for singular % Nse - maximum order of spherical basis functions % f - frequency -% xq - optional expansion center coordinate +% xq - optional expansion center coordinate % conf - optional configuration struct (see SFS_config) % % Output parameters: % Al - regular Spherical Expansion Coefficients % -% SPHEXP_MONO_LS(xs, mode, Nse, f, xq, conf) computes the regular/singular -% spherical expansion coefficients for a point source at xs. The expansion +% SPHEXP_MONO_LS(xs,mode,Nse,f,xq,conf) computes the regular/singular +% spherical expansion coefficients for a point source at xs. The expansion % will be done around the expansion coordinate xq. % % see also: sphexp_mono_ps sphexp_mono_pw sphexp_convert_circexp @@ -57,20 +57,19 @@ nargmax = 6; narginchk(nargmin,nargmax); isargposition(xs); -isargpositivescalar(f, Nse); +isargpositivescalar(f,Nse); isargposition(xq); isargstruct(conf); %% ===== Computation ==================================================== % select suitable basis function -if strcmp('R', mode) - Am = circexp_mono_ls(xs, mode, Nse, f, xq, conf); - Anm = sphexp_convert_circexp(Am); -elseif strcmp('S', mode) - to_be_implemented; +if strcmp('R',mode) + Am = circexp_mono_ls(xs,mode,Nse,f,xq,conf); + Anm = sphexp_convert_circexp(Am); +elseif strcmp('S',mode) + to_be_implemented; else - error('%s: %s, unknown mode', upper(mfilename), mode); + error('%s: %s, unknown mode',upper(mfilename),mode); end end - diff --git a/SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m b/SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m index 9e4b249c..da6d11e7 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_multiscatter.m @@ -1,11 +1,11 @@ -function B = sphexp_mono_multiscatter(A, xq, R, sigma, f, conf) +function B = sphexp_mono_multiscatter(A,xq,R,sigma,f,conf) %SPHEXP_MONO_MULTISCATTER compute the singular spherical expansion of a sphere- %scattered sound field % -% Usage: B = sphexp_mono_multiscatter(A, xq, R, sigma, f, conf) +% Usage: B = sphexp_mono_multiscatter(A,xq,R,sigma,f,conf) % % Input parameters: -% A - regular spherical expansion coefficients of incident +% A - regular spherical expansion coefficients of incident % sound fields arriving at each sphere [n x Nq] % xq - positions of the sphere / m [Nq x 3] % R - radii of the spheres / m [Nq x 1] @@ -16,7 +16,7 @@ % B - regular spherical expansion coefficients of sound fields % scattered at each sphere [n x Nq] % -% SPHEXP_MONO_MULTISCATTER(A, xq, R, sigma, f, conf) +% SPHEXP_MONO_MULTISCATTER(A,xq,R,sigma,f,conf) %***************************************************************************** % Copyright (c) 2010-2016 Quality & Usability Lab, together with * @@ -55,23 +55,23 @@ nargmax = 6; narginchk(nargmin,nargmax); isargpositivescalar(f); -isargvector(R, sigma); -isargmatrix(A, xq); +isargvector(R,sigma); +isargmatrix(A,xq); isargstruct(conf); L = size(A,1); isargsquaredinteger(L); if length(R) == 1 - R = repmat( R, [1, size(A,2)] ); + R = repmat( R,[1,size(A,2)] ); elseif length(R) ~= size(A,2) - error('%s: Length of R does not match size of A',upper(mfilename)); + error('%s: Length of R does not match size of A',upper(mfilename)); end if length(sigma) == 1 - sigma = repmat( sigma, [1, size(A,2)] ); + sigma = repmat( sigma,[1,size(A,2)] ); elseif length(sigma) ~= size(A,2) - error('%s: Length of R does not match size of A',upper(mfilename)); + error('%s: Length of R does not match size of A',upper(mfilename)); end %% ===== Computation ==================================================== @@ -80,19 +80,19 @@ E = ones(L,1); for qdx=1:Nq - selectq = ((qdx-1)*L+1):(qdx*L); - AB(selectq,selectq) = ... - diag(1./sphexp_mono_scatter(E, R(qdx), sigma(qdx), f, conf)); + selectq = ((qdx-1)*L+1):(qdx*L); + AB(selectq,selectq) = ... + diag(1./sphexp_mono_scatter(E,R(qdx),sigma(qdx),f,conf)); end for qdx=1:Nq - selectq = ((qdx-1)*L+1):(qdx*L); - for pdx=(qdx+1):Nq - selectp = ((pdx-1)*L+1):(pdx*L); - [SRpq, SRqp] = sphexp_mono_translation(xq(qdx,:)-xq(pdx,:), 'SR', f, conf); - AB(selectp,selectq) = -SRpq; - AB(selectq,selectp) = -SRqp; - end + selectq = ((qdx-1)*L+1):(qdx*L); + for pdx=(qdx+1):Nq + selectp = ((pdx-1)*L+1):(pdx*L); + [SRpq,SRqp] = sphexp_mono_translation(xq(qdx,:)-xq(pdx,:),'SR',f,conf); + AB(selectp,selectq) = -SRpq; + AB(selectq,selectp) = -SRqp; + end end A = reshape(A,[],1); diff --git a/SFS_monochromatic/sphexp/sphexp_mono_ps.m b/SFS_monochromatic/sphexp/sphexp_mono_ps.m index 2f3e6d79..60698a3d 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_ps.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_ps.m @@ -1,26 +1,26 @@ -function Anm = sphexp_mono_ps(xs, mode, Nse, f, xq, conf) +function Anm = sphexp_mono_ps(xs,mode,Nse,f,xq,conf) %SPHEXP_MONO_PS computes regular/singular spherical expansion of point source % -% Usage: Anm = sphexp_mono_ps(xs, mode, Nse, f, xq, conf) +% Usage: Anm = sphexp_mono_ps(xs,mode,Nse,f,xq,conf) % % Input parameters: % xs - position of point source % mode - 'R' for regular, 'S' for singular % Nse - maximum order of spherical basis functions % f - frequency [Nf x 1] or [1 x Nf] -% xq - optional expansion center coordinate +% xq - optional expansion center coordinate % conf - optional configuration struct (see SFS_config) % % Output parameters: % Anm - regular Spherical Expansion Coefficients [(Nse+1)^2 x m] % -% SPHEXP_MONO_PS(xs, mode, f, Nse, xq, conf) computes the regular/singular -% Spherical Expansion Coefficients for a point source at xs. The expansion +% SPHEXP_MONO_PS(xs,mode,f,Nse,xq,conf) computes the regular/singular +% Spherical Expansion Coefficients for a point source at xs. The expansion % will be done around the expansion coordinate xq: % % Regular Expansion: % \~~ oo \~~ n m m -% p (x,f) = > > A R (x-x ) +% p (x,f) = > > A R (x-x ) % ps,R /__ n=0 /__ m=-n n n q % % with the expansion coefficients (Gumerov2004, eq. 3.2.2): @@ -30,24 +30,24 @@ % % Singular Expansion: % \~~ oo \~~ n m m -% p (x,f) = > > B S (x-x ) +% p (x,f) = > > B S (x-x ) % ps,S /__ n=0 /__ m=-n n n q -% +% % with the expansion coefficients (Gumerov2004, eq. 3.2.2): % m -m % B = -i . k . R (x - x ) % n n s q % -% The coefficients are stored in linear arrays with index l resulting from +% The coefficients are stored in linear arrays with index l resulting from % m and n: -% +% % m m 2 % A = A ; B = B with l = (n+1) - (n - m) % l n l n % % References: -% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the -% Helmholtz Equation in three +% Gumerov,Duraiswami (2004) - "Fast Multipole Methods for the +% Helmholtz Equation in three % Dimensions", ELSEVIER % % see also: sphexp_mono_ls sphexp_mono_pw @@ -109,26 +109,26 @@ Nf = length(kr); % select suitable basis function -if strcmp('R', mode) - sphbasis = @(nu) sphbesselh(nu,2,kr); -elseif strcmp('S', mode) - sphbasis = @(nu) sphbesselj(nu, kr); +if strcmp('R',mode) + sphbasis = @(nu) sphbesselh(nu,2,kr); +elseif strcmp('S',mode) + sphbasis = @(nu) sphbesselj(nu,kr); else - error('unknown mode:'); + error('unknown mode:'); end %% ===== Computation ==================================================== -Anm = zeros( (Nse + 1).^2 , Nf); +Anm = zeros((Nse + 1).^2,Nf); for n=0:Nse - cn = -1j.*k.*sphbasis(n); - for m=0:n - % spherical harmonics: conj(Y_n^m) = Y_n^-m (Gumerov2004, eq. 2.1.59) - Ynm = sphharmonics(n,m, theta, phi); - % -m - v = sphexp_index(-m,n); - Anm(v,:) = cn.*Ynm; - % +m - v = sphexp_index(m,n); - Anm(v,:) = cn.*conj(Ynm); - end + cn = -1j.*k.*sphbasis(n); + for m=0:n + % spherical harmonics: conj(Y_n^m) = Y_n^-m (Gumerov2004, eq. 2.1.59) + Ynm = sphharmonics(n,m,theta,phi); + % -m + v = sphexp_index(-m,n); + Anm(v,:) = cn.*Ynm; + % +m + v = sphexp_index(m,n); + Anm(v,:) = cn.*conj(Ynm); + end end diff --git a/SFS_monochromatic/sphexp/sphexp_mono_pw.m b/SFS_monochromatic/sphexp/sphexp_mono_pw.m index eeb385d8..b346463f 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_pw.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_pw.m @@ -1,7 +1,7 @@ -function Anm = sphexp_mono_pw(npw, Nse, f, xq, conf) +function Anm = sphexp_mono_pw(npw,Nse,f,xq,conf) %SPHEXP_MONO_PW computes the regular spherical expansion of plane wave % -% Usage: Anm = sphexp_mono_pw(npw, Nse, f, xq, conf) +% Usage: Anm = sphexp_mono_pw(npw,Nse,f,xq,conf) % % Input parameters: % npw - unit vector propagation direction of plane wave @@ -13,7 +13,7 @@ % Output parameters: % Anm - regular Spherical Expansion Coefficients [(Nse+1)^2 x Nf] % -% SPHEXP_MONO_PW(npw, Nse, f, xq, conf) computes the regular spherical +% SPHEXP_MONO_PW(npw,Nse,f,xq,conf) computes the regular spherical % expansion coefficients for a plane wave. The expansion will be done around % the expansion coordinate xq: % @@ -95,17 +95,17 @@ phase = exp(-1j*2*pi*row_vector(f)/c*(npw*xq.')); Nf = length(phase); -Anm = zeros((Nse + 1).^2, Nf); +Anm = zeros((Nse + 1).^2,Nf); for n=0:Nse - cn = 4*pi*(1j)^(-n); - for m=0:n - % spherical harmonics: conj(Y_n^m) = Y_n^-m (Gumerov2004, eq. 2.1.59) - Ynm = sphharmonics(n,m, theta, phi); - % -m - v = sphexp_index(-m,n); - Anm(v,:) = cn.*Ynm.*phase; - % +m - v = sphexp_index(m,n); - Anm(v,:) = cn.*conj(Ynm).*phase; - end + cn = 4*pi*(1j)^(-n); + for m=0:n + % spherical harmonics: conj(Y_n^m) = Y_n^-m (Gumerov2004, eq. 2.1.59) + Ynm = sphharmonics(n,m,theta,phi); + % -m + v = sphexp_index(-m,n); + Anm(v,:) = cn.*Ynm.*phase; + % +m + v = sphexp_index(m,n); + Anm(v,:) = cn.*conj(Ynm).*phase; + end end diff --git a/SFS_monochromatic/sphexp/sphexp_mono_scatter.m b/SFS_monochromatic/sphexp/sphexp_mono_scatter.m index 52c260ab..0abf739f 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_scatter.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_scatter.m @@ -1,8 +1,8 @@ -function Bnm = sphexp_mono_scatter(Anm, R, sigma, f, conf) +function Bnm = sphexp_mono_scatter(Anm,R,sigma,f,conf) %SPHEXP_MONO_SCATTER compute the singular spherical expansion of a sphere- %scattered sound field % -% Usage: Bnm = sphexp_mono_scatter(Anm, R, sigma, f, conf) +% Usage: Bnm = sphexp_mono_scatter(Anm,R,sigma,f,conf) % % Input parameters: % Anm - regular spherical expansion of incident sound field @@ -14,7 +14,7 @@ % Bnm - singular spherical expansion coefficients of scattered % field % -% SPHEXP_MONO_SCATTER(Anm, R, sigma, f, conf) computes the singular spherical +% SPHEXP_MONO_SCATTER(Anm,R,sigma,f,conf) computes the singular spherical % expansion coefficients of a field resulting from a scattering of an incident % field at a sphere. Incident field is descriped by regular expansion % coefficients (expansion center is expected to be at the center of the sphere @@ -108,17 +108,17 @@ % select suitable transformation function if isinf(sigma) - T = @(x) -sphbesselj(x,kR)./sphbesselh(x,2,kR); + T = @(x) -sphbesselj(x,kR)./sphbesselh(x,2,kR); elseif sigma == 0 - T = @(x) -sphbesselj_derived(x,kR)./sphbesselh_derived(x,2,kR); + T = @(x) -sphbesselj_derived(x,kR)./sphbesselh_derived(x,2,kR); else - T = @(x) -(k.*sphbesselj_derived(x,kR)+sigma.*sphbesselj(x,kR)) ... - ./(k.*sphbesselh_derived(x,2,kR)+sigma.*sphbesselh(x,2,kR)); + T = @(x) -(k.*sphbesselj_derived(x,kR)+sigma.*sphbesselj(x,kR)) ... + ./(k.*sphbesselh_derived(x,2,kR)+sigma.*sphbesselh(x,2,kR)); end %% ===== Computation ==================================================== Bnm = zeros(size(Anm)); for n=0:(sqrt(L) - 1) - v = sphexp_index(-n:n,n); - Bnm(v,:) = T(n).*Anm(v,:); + v = sphexp_index(-n:n,n); + Bnm(v,:) = T(n).*Anm(v,:); end diff --git a/SFS_monochromatic/sphexp/sphexp_mono_sht.m b/SFS_monochromatic/sphexp/sphexp_mono_sht.m index 5ce31485..89751155 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_sht.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_sht.m @@ -1,8 +1,8 @@ -function Pnm = sphexp_mono_sht(Dnm, mode, f, conf) +function Pnm = sphexp_mono_sht(Dnm,mode,f,conf) %SPHEXP_MONO_NFCHOA_SHT yields spherical expansion coefficients of a sound field %resulting from of a driving function given as a spherical harmonics transform % -% Usage: Pnm = sphexp_mono_sht(Dnm, mode, f, conf) +% Usage: Pnm = sphexp_mono_sht(Dnm,mode,f,conf) % % Input parameters: % Dnm - spherical harmonics transform of nfchoa driving function @@ -14,7 +14,7 @@ % Pnm - spherical expansion coefficients of a sound field % reproduced by nfchoa driving function % -% SPHEXP_MONO_SHT(Dnm, mode, f, conf) +% SPHEXP_MONO_SHT(Dnm,mode,f,conf) %***************************************************************************** % Copyright (c) 2010-2016 Quality & Usability Lab, together with * @@ -56,8 +56,8 @@ isargsquaredinteger(size(Dnm,1)); isargvector(f); isargchar(mode); -if ~strcmp('R', mode) && ~strcmp('S', mode) - error('%s: unknown mode (%s)!', upper(mfilename), mode); +if ~strcmp('R',mode) && ~strcmp('S',mode) + error('%s: unknown mode (%s)!',upper(mfilename),mode); end isargstruct(conf); @@ -70,30 +70,30 @@ %% ===== Computation ==================================================== if strcmp('2D',dimension) - % === 2-Dimensional ================================================== + % === 2-Dimensional ================================================== - error('%s: 2D not supported.',upper(mfilename)); + error('%s: 2D not supported.',upper(mfilename)); elseif strcmp('2.5D',dimension) - % === 2.5-Dimensional ================================================ + % === 2.5-Dimensional ================================================ - % regular/singular expansion of 3D Green's function - Gnm = 2*pi*r0*sphexp_mono_ps([r0, 0, 0], mode, Nse, f, [0,0,0], conf); + % regular/singular expansion of 3D Green's function + Gnm = 2*pi*r0*sphexp_mono_ps([r0,0,0],mode,Nse,f,[0,0,0],conf); elseif strcmp('3D',dimension) - % === 3-Dimensional ================================================== + % === 3-Dimensional ================================================== - % regular/singular expansion of 3D Green's function - Gnm = sphexp_mono_ps([0, 0, r0], mode, Nse, f, [0,0,0], conf); + % regular/singular expansion of 3D Green's function + Gnm = sphexp_mono_ps([0,0,r0],mode,Nse,f,[0,0,0],conf); - for n=0:Nse - v = sphexp_index(-n:n,n); - w = sphexp_index(0,n); - Gnm(v,:) = 2*pi*r0^2*sqrt(4*pi / (2*n+1))*Gnm(w,:); - end + for n=0:Nse + v = sphexp_index(-n:n,n); + w = sphexp_index(0,n); + Gnm(v,:) = 2*pi*r0^2*sqrt(4*pi / (2*n+1))*Gnm(w,:); + end else - error('%s: the dimension %s is unknown.',upper(mfilename),dimension); + error('%s: the dimension %s is unknown.',upper(mfilename),dimension); end Pnm = Gnm .* Dnm; -end \ No newline at end of file +end diff --git a/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m b/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m index 9276d9ca..2fb1949c 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_timereverse.m @@ -53,6 +53,6 @@ %% ===== Computation ==================================================== for n=0:(sqrt(L)-1) - v = sphexp_index(-n:n,n); - ABnm(v) = conj(sphexp_access(ABnm,n:-1:-n,n)); + v = sphexp_index(-n:n,n); + ABnm(v) = conj(sphexp_access(ABnm,n:-1:-n,n)); end diff --git a/SFS_monochromatic/sphexp/sphexp_mono_translation.m b/SFS_monochromatic/sphexp/sphexp_mono_translation.m index 9088a0d2..1a3f01cb 100644 --- a/SFS_monochromatic/sphexp/sphexp_mono_translation.m +++ b/SFS_monochromatic/sphexp/sphexp_mono_translation.m @@ -1,8 +1,8 @@ -function [EF, EFm] = sphexp_mono_translation(t, mode, Nse, f, conf) -%SPHEXP_MONO_TRANSLATION computes spherical translation coefficients +function [EF,EFm] = sphexp_mono_translation(t,mode,Nse,f,conf) +%SPHEXP_MONO_TRANSLATION computes spherical translation coefficients %(multipole re-expansion) % -% Usage: [EF, EFm] = sphexp_mono_translation(t, mode, Nse, f, conf) +% Usage: [EF,EFm] = sphexp_mono_translation(t,mode,Nse,f,conf) % % Input parameters: % t - translatory shift [1x3] / m @@ -18,7 +18,7 @@ % EF - spherical re-expansion coefficients for t % EFm - spherical re-expansion coefficients for -t % -% SPHEXP_MONO_TRANSLATION(t, mode, Nse, f, conf) computes the spherical +% SPHEXP_MONO_TRANSLATION(t,mode,Nse,f,conf) computes the spherical % re-expansion coefficients to perform as translatory shift of spherical basis % function. Multipole Re-expansion computes the spherical basis function for a % shifted coordinate system (x+t) based on the original basis functions for @@ -30,9 +30,9 @@ % % where {E,F} = {R,S}. R denotes the regular spherical basis function, while % S symbolizes the singular spherical basis function. Note that (S|S) and -% (S|R) are respectively equivalent to (R|R) and (R|S). The reexpansion -% coefficients can seperated into sectorial (n = abs|m| and/or l = abs|s|) -% and tesseral (else) coefficients. Latter will only be computed, if +% (S|R) are respectively equivalent to (R|R) and (R|S). The reexpansion +% coefficients can seperated into sectorial (n = abs|m| and/or l = abs|s|) +% and tesseral (else) coefficients. Latter will only be computed, if % conf.dimensions == '3D'. % % References: @@ -97,30 +97,30 @@ % frequency Nf = length(f); k = 2*pi*f/conf.c; -kr = reshape(k, 1, 1, Nf)*r; +kr = reshape(k,1,1,Nf)*r; L = (2*Nse + 1).^2; -S = zeros(L, L, Nf); +S = zeros(L,L,Nf); % Auxilary Coefficients for Computations -[a, b] = sphexp_translation_auxiliary(2*Nse,conf); +[a,b] = sphexp_translation_auxiliary(2*Nse,conf); % select suitable basis function -if strcmp('RR', mode) || strcmp('SS', mode) - sphbasis = @(nu) sphbesselj(nu, kr); -elseif strcmp('SR', mode) || strcmp('RS', mode) - sphbasis = @(nu) sphbesselh(nu, 2, kr); +if strcmp('RR',mode) || strcmp('SS',mode) + sphbasis = @(nu) sphbesselj(nu,kr); +elseif strcmp('SR',mode) || strcmp('RS',mode) + sphbasis = @(nu) sphbesselh(nu,2,kr); else - error('unknown mode:'); + error('unknown mode:'); end %% ===== Sectorial Coefficients ========================================= % if translation vector's z-coordinate is zero, many coefficients are zero. % This is to save some computation time if t(3) == 0 - inc = 2; + inc = 2; else - inc = 1; + inc = 1; end % for n=0, m=0 (Gumerov2004, eq. 3.2.5) @@ -144,20 +144,20 @@ % 0, m 0, n n % for l=0:2*Nse % n=l - Hn = sqrt(4*pi)*sphbasis(l); % radial basis function (see Variables) - for s=l:-inc:0 % m=s - % spherical harmonics: conj(Y_n^m) = Y_n^-m (Gumerov2004, eq. 2.1.59) - Ynm = sphharmonics(l,s, theta, phi); + Hn = sqrt(4*pi)*sphbasis(l); % radial basis function (see Variables) + for s=l:-inc:0 % m=s + % spherical harmonics: conj(Y_n^m) = Y_n^-m (Gumerov2004, eq. 2.1.59) + Ynm = sphharmonics(l,s,theta,phi); - v = sphexp_index(s,l); - S(v,1,:) = (-1).^l*Hn.*conj(Ynm); % s,l, m=0, n=0 - S(1,v,:) = Hn.*Ynm; % s=0,l=0, m, n + v = sphexp_index(s,l); + S(v,1,:) = (-1).^l*Hn.*conj(Ynm); % s,l, m=0, n=0 + S(1,v,:) = Hn.*Ynm; % s=0,l=0, m, n - v = sphexp_index(-s,l); - S(v,1,:) = (-1).^l*Hn.*Ynm; % -s,l, m=0, n=0 - S(1,v,:) = Hn.*conj(Ynm); % s=0,l=0, -m, n - end - if showprogress, progress_bar(v,L); end % progress bar + v = sphexp_index(-s,l); + S(v,1,:) = (-1).^l*Hn.*Ynm; % -s,l, m=0, n=0 + S(1,v,:) = Hn.*conj(Ynm); % s=0,l=0, -m, n + end + if showprogress, progress_bar(v,L); end % progress bar end %% ===== Sectorial Coefficients ========================================== @@ -174,25 +174,25 @@ % while {E,F} = {R,S} % for m=0:Nse-1 - % NOTE: sphexp_access(b, -m-1) == sphexp_access(b, -m-1, m+1) - bm = 1./sphexp_access(b,-m-1); - for l=1:(2*Nse-m-1) - for s=-l:inc:l - % +m - [v, w] = sphexp_index(s,l,m+1); - S(v,w,:) = bm * ( ... - sphexp_access(b,-s ,l) * sphexp_access(S,s-1,l-1,m) - ... - sphexp_access(b,s-1,l+1) * sphexp_access(S,s-1,l+1,m)... - ); - % -m - [v, w] = sphexp_index(s,l,-m-1); - S(v,w,:) = bm * ( ... - sphexp_access(b,s ,l) * sphexp_access(S,s+1,l-1,-m) - ... - sphexp_access(b,-s-1,l+1) * sphexp_access(S,s+1,l+1,-m)... - ); + % NOTE: sphexp_access(b, -m-1) == sphexp_access(b, -m-1, m+1) + bm = 1./sphexp_access(b,-m-1); + for l=1:(2*Nse-m-1) + for s=-l:inc:l + % +m + [v,w] = sphexp_index(s,l,m+1); + S(v,w,:) = bm * ( ... + sphexp_access(b,-s ,l) * sphexp_access(S,s-1,l-1,m) - ... + sphexp_access(b,s-1,l+1) * sphexp_access(S,s-1,l+1,m)... + ); + % -m + [v,w] = sphexp_index(s,l,-m-1); + S(v,w,:) = bm * ( ... + sphexp_access(b,s ,l) * sphexp_access(S,s+1,l-1,-m) - ... + sphexp_access(b,-s-1,l+1) * sphexp_access(S,s+1,l+1,-m)... + ); + end end - end - if showprogress, progress_bar(m,Nse); end % progress bar + if showprogress, progress_bar(m,Nse); end % progress bar end % for l=|s| using symmetry relation (Gumerov2004, eq. 3.2.49 @@ -204,12 +204,12 @@ % while {E,F} = {R,S} % for l=1:Nse - for n=inc:(2*Nse-l) - s = [-l,l]; - m = (-n+inc):inc:(n-inc); - [v, w] = sphexp_index( s, l, m, n); - S(v,w,:) = (-1).^(l+n)*sphexp_access(S,-m,n,-s, l).'; - end + for n=inc:(2*Nse-l) + s = [-l,l]; + m = (-n+inc):inc:(n-inc); + [v,w] = sphexp_index( s,l,m,n); + S(v,w,:) = (-1).^(l+n)*sphexp_access(S,-m,n,-s,l).'; + end end %% ===== Tesseral Coefficients ========================================== @@ -255,10 +255,10 @@ % SR(-t) EFm = zeros(L,L,Nf); for n=0:Nse - for l=0:Nse - m = -n:inc:n; - s = -l:inc:l; - [v, w] = sphexp_index(s,l,m,n); - EFm(v,w,:) = (-1).^(l+n)*sphexp_access(EF,s,l,m,n); - end + for l=0:Nse + m = -n:inc:n; + s = -l:inc:l; + [v,w] = sphexp_index(s,l,m,n); + EFm(v,w,:) = (-1).^(l+n)*sphexp_access(EF,s,l,m,n); + end end diff --git a/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m b/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m index 914ef42c..ca85a7b1 100644 --- a/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m +++ b/SFS_monochromatic/sphexp/sphexp_translation_auxiliary.m @@ -1,8 +1,8 @@ -function [a, b] = sphexp_translation_auxiliary(Nse,conf) -%SPHEXP_TRANSLATION_AUXILIARY yields the auxiliary coefficients for the +function [a,b] = sphexp_translation_auxiliary(Nse,conf) +%SPHEXP_TRANSLATION_AUXILIARY yields the auxiliary coefficients for the %recursive calculation of spherical translation coefficients % -% Usage: [a, b] = sphexp_translation_auxiliary(Nse,conf) +% Usage: [a,b] = sphexp_translation_auxiliary(Nse,conf) % % Input parameters: % Nse - maximum degree of the auxiliary functions (optional) @@ -15,7 +15,7 @@ % spherical translation coefficients % % SPHEXP_TRANSLATION_AUXILIARY(Nse,conf) computes the auxiliary coefficients -% for the calculation of tesseral spherical translation coefficients +% for the calculation of tesseral spherical translation coefficients % (Gumerov2004, eq. 2.2.8 and 3.2.65): % % +------------------+ @@ -101,14 +101,14 @@ a = zeros(L,1); b = zeros(L,1); for n=0:Nse - a_denum = (2*n+1)*(2*n+3); - b_denum = (2*n-1)*(2*n+1); + a_denum = (2*n+1)*(2*n+3); + b_denum = (2*n-1)*(2*n+1); - m = -n:n; - v = sphexp_index(m,n); + m = -n:n; + v = sphexp_index(m,n); - a(v) = sqrt( (n+1+abs(m)).*(n+1-abs(m))./a_denum ); - b(v) = ( 1-(m<0)*2 ) .* sqrt( (n-m-1).*(n-m)./b_denum ); + a(v) = sqrt( (n+1+abs(m)).*(n+1-abs(m))./a_denum ); + b(v) = ( 1-(m<0)*2 ) .* sqrt( (n-m-1).*(n-m)./b_denum ); - if showprogress, progress_bar(v(end),L); end % progress bar + if showprogress, progress_bar(v(end),L); end % progress bar end diff --git a/SFS_monochromatic/sphexp/sphexp_truncate.m b/SFS_monochromatic/sphexp/sphexp_truncate.m index 873df7a4..6721dde3 100644 --- a/SFS_monochromatic/sphexp/sphexp_truncate.m +++ b/SFS_monochromatic/sphexp/sphexp_truncate.m @@ -1,21 +1,21 @@ -function Anm = sphexp_truncate(Pnm, N, M, Mshift) -%SPHEXP_TRUNCATE truncates spherical expansion by setting remaining +function Anm = sphexp_truncate(Pnm,N,M,Mshift) +%SPHEXP_TRUNCATE truncates spherical expansion by setting remaining %coefficients to zero % -% Usage: Anm = sphexp_truncate(Pnm, N, M, Mshift) +% Usage: Anm = sphexp_truncate(Pnm,N,M,Mshift) % % Input parameters: % Pnm - 1D array of spherical expansion coefficients [n x Nf] % N - maximum degree of spherical expansion % M - maximum order of spherical expansion, default: N % Mshift - shift for asymmetric trunction with respect to order, -% default: 0 +% default: 0 % % Output parameters: % Anm - 1D array of bandlimited spherical expansion % coefficients [n x Nf] % -% SPHEXP_TRUNCATE(Pnm, N, M, Mshift) sets coefficients belonging to an degree +% SPHEXP_TRUNCATE(Pnm,N,M,Mshift) sets coefficients belonging to an degree % n higher than N or an order m exceeding (-M+Mshift:+M+Mshift) to zero. % % see also: sphexp_truncation_order @@ -59,24 +59,24 @@ isargmatrix(Pnm); isargpositivescalar(N); switch nargin - case 2 - M = N; - Mshift = 0; - case 3 - isargpositivescalar(M); - Mshift = 0; - case 4 - isargscalar(Mshift); + case 2 + M = N; + Mshift = 0; + case 3 + isargpositivescalar(M); + Mshift = 0; + case 4 + isargscalar(Mshift); end %% ===== Variable ======================================================= -Nse = min(sqrt(size(Pnm, 1))-1, N); +Nse = min(sqrt(size(Pnm,1))-1,N); %% ===== Computation ==================================================== Anm = zeros(size(Pnm)); for m=max(-M+Mshift,-Nse):min(M+Mshift,Nse) - v = sphexp_index(m,abs(m):Nse); - Anm(v,:) = Pnm(v,:); + v = sphexp_index(m,abs(m):Nse); + Anm(v,:) = Pnm(v,:); end end diff --git a/SFS_monochromatic/sphexp/sphexp_truncation_order.m b/SFS_monochromatic/sphexp/sphexp_truncation_order.m index befc2881..7e874274 100644 --- a/SFS_monochromatic/sphexp/sphexp_truncation_order.m +++ b/SFS_monochromatic/sphexp/sphexp_truncation_order.m @@ -1,8 +1,8 @@ -function Nse = sphexp_truncation_order(r, f, nmse, conf) +function Nse = sphexp_truncation_order(r,f,nmse,conf) %SPHEXP_TRUNCATION_ORDER yields the bound of summation for a spherical expansion %of an arbitrary sound field % -% Usage: Nse = sphexp_truncation_order(r, f, nmse, conf) +% Usage: Nse = sphexp_truncation_order(r,f,nmse,conf) % % Input parameters: % r - max 3D distance from expansion center / m @@ -13,7 +13,7 @@ % Output parameters: % Nse - maximum order for spherical expansion % -% SPHEXP_TRUNCATION_ORDER(r, f, nmse, conf) yields the order up to which +% SPHEXP_TRUNCATION_ORDER(r,f,nmse,conf) yields the order up to which % a the spherical expansion coefficients of an arbitrary sound field have % be summed up. For a given frequency (f) the normalized truncation mean % squared error is below the specified error bound (nmse) at any point inside @@ -73,5 +73,5 @@ %% ===== Computation ==================================================== % See Kennedy et al. (eq. 42/43) lambda = c/f; % wave length -delta = max(0, ceil(log(0.67848/nmse))); % nmse dependent term +delta = max(0,ceil(log(0.67848/nmse))); % nmse dependent term Nse = ceil(pi*r*exp(1)/lambda) + delta;