Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New NFC-HOA line source driving function for the mono-chromatic case #54

Merged
merged 24 commits into from
Feb 17, 2016

Conversation

hagenw
Copy link
Member

@hagenw hagenw commented Jan 25, 2016

Hi Nara.

This is the code I implemented after your 138th AES Convention paper: http://spatialaudio.net/virtual-cylindrical-waves/
We talked about it some time ago, but I'm not 100% sure about the current status. Could you check if it is ok and merge it into master.

* master: (25 commits)
  Update NEWS
  Fix coding style
  Update NEWS
  Fix comments
  Add validation function for secondary source selection
  An odd prefilter order now raises an error in wfs_fir_prefilter. Rounding therefore no longer required in sound_field_imp_*wfs. (fixed another error message in wfs_fir_prefilter)
  Small coding style fix
  Delay Compensation of FIR prefilter for local WFS
  Delay compensation for FIR prefilter (IIR should be minimum phase anyway)
  WFS FIR filter of arbitrary even order (-> odd length) Note: Filter length is no longer a power of 2. If this is desired e.g. in convolution(), it's possibly better done there.
  WFS prefilter order added to config struct
  fix missing idx for vss
  fix recursive call of selection function and remove time consuming vector product
  Update NEWS
  Change Ambisonics order for even loudspeaker numbers
  Update NEWS
  Cleanup code
  fix problem with zero fractional delay due to implementation of sinus cardinalis
  Update NEWS and set version to 2.1.0
  Add extra space for Windows banner
  ...
@narahahn
Copy link
Member

Great. I think the driving functions are implemented correctly. So far, there is nothing new.
One thing I want to discuss is how to treat the line source position. Currently, we are considering line sources that are vertically aligned. For 2D and 2.5D, this is not a big deal since we do not use the z coordinate component. But in 3D cases, the driving function includes the azimuth angle alpha, so the result will be wrong if a line source is defined off the xy-plane. There are some possibilities to avoid this.

  1. Check the position of xs. If it's not on the horizontal plane,
    (a) return error.
    (b) project xs onto the xy-plane and then convert it to spherical coordinate.
  2. Use the polar angle phi in the cylindrical coordinate instead of alpha. The result will be the same as 1(b). But we do not need to check the z component. Also no need for cart2sph. Though it may look strange as phi and alpha0 appear together.

Once this is resolved, I think we are good to merge.

@hagenw
Copy link
Member Author

hagenw commented Jan 25, 2016

The 3D case is indeed interesting. A few more questions from my side, before proposing a solution:

  1. 3D case means also in this case that we have a spherical array with point source characteristics of the secondary sources?
  2. If this is the case then we should be able to align the desired line source to every orientation we would like? But when I have a look at (20) from your paper it seems indeed to be the case that a line source in the horizontal plane is considered at position (r, alpha, 0)?

It's always a little bit confusing when talking about virtual sources that have characteristics that are not compatible with the underlying secondary sources ;)

@narahahn
Copy link
Member

YES and YES. The current driving function can be used for 3D NFC-HOA (using spherical distribution of secondary point sources), only if the line source is parallel to the z-axis.

In order to specify an arbitrarily oriented line source, we need a position vector and an orientation vector. The degree of freedom is 5. Would it be OK to allow xs to have higher dimension? If yes, I think the driving functions can be obtained by applying a rotational operation on the sphere.

@hagenw
Copy link
Member Author

hagenw commented Jan 26, 2016

In principle it is possible to have xs with higher dimensions. The focused source uses xs with 6 entries, first 3 for its position and the last 3 for its traveling direction. At the moment we check xs to have a length of 3 or 6, see isargxs().

In the case of 3D NFC-HOA and the line source we should ask if it would be of advantage to have the possibility to orient the line source to arbitrary directions. If you have only one line source, then it is not needed as the array is completely symmetrical and you can adjust the axis accordingly. The only case where it might be of interest is when you want to use more than one line source simultaneously and they should have different orientations (for whatever reasons).
Is the implementation/formula a lot more complicated by allowing free orientations?

As I have not really an opinion on this, you can decide what you would prefer.

@fietew
Copy link
Member

fietew commented Jan 26, 2016

If think, the degrees of freedom for the position + orientation of an infinitely long line source in 4. Its orientation can be defined by two angles or a unit vector (2 DOFs) and its position is given by any point being part of the line (2 DOFs). However, I think that we should stick to the nomenclature of 6 entries, i.e. orientation vector + position vector, as Hagen mentioned.

@fietew
Copy link
Member

fietew commented Jan 26, 2016

Maybe we should just rotate the coordinate system, i.e. the position of the secondary sources and the line source, such that the line source is always aligned with the z-axis. This could be done inherently within the function, which computes the driving function.

@trettberg
Copy link
Contributor

If you have only one line source, then it is not needed as the array is completely symmetrical

I think this does not hold for discrete arrays.

@hagenw
Copy link
Member Author

hagenw commented Jan 27, 2016

At the starting point of this discussion we were talking about 3D spherical arrays only, so I guess in infinite array is not really considered here.
But I agree that due to the sampling process of the sphere the symmetry might be lost in the discrete case.

@trettberg
Copy link
Contributor

I think a 3-entry xs that restricts line sources to the z-direction is cumbersome: For a different orientation, the array would have to be rotated manually.

Since all xs use cartesian coordinates up to to now, a line source definition in terms of a point xs(1:3) and a vector along the line xs(4:6) seems most reasonable to me.

The question remains what to do in the 2D case if something else than xs = [x,y,0, 0,0,z] is requested. Projection or error?

It now works with xs of size [1x6]
@hagenw
Copy link
Member Author

hagenw commented Feb 1, 2016

I would say we use now xs for line sources with 6 entries, the first three for the position and the last three for the orientation as proposed.

I prepared the WFS monochromatic driving functions for this. @trettberg could you start implementing the proposed solution for WFS in driving_function_mono_wfs_ls(). Everything is prepared and the driving function is expecting a xs with 6 entries (but it is not checked for the correct size yet). For the 2D and 2.5D case I propose that we do an automatic projection and raise a warning if we had to do this.
There remains only one question for the 2D and 2.5D case where I'm not sure what are the consequences. The secondary source selection happens independently from the driving functions and in the 2D and 2.5D case the xs vector with the first three entries without projection is used. So I guess we have to integrate the projection there too, or maybe all together at an earlier stage. It's too late now to think clearly ;)

@narahahn could you implement your proposed solution for NFC-HOA?

@narahahn
Copy link
Member

narahahn commented Feb 2, 2016

Yes, I will implement the NFC-HOA driving function for arbitrary line sources.

Till Rettberg and others added 3 commits February 3, 2016 10:45
@trettberg
Copy link
Contributor

WFS line source should be okay now.
(To avoid code duplication, it might be desirable to handle the 2D case with the 3D case. But for now they are left separated.)

For easier visual inspection, here's a planar array:

conf = SFS_config();

%% construct a square array in the y=0.5 plane
conf.secondary_sources.geometry = 'line';
conf.secondary_sources.number = 31;
x0_line = secondary_source_positions(conf);
M = size(x0_line,1);
dx = abs(x0_line(2,1) - x0_line(1,1))
x0 = repmat(x0_line,[M,1]);
for z = 1:M
    x0((z-1)*M+1:z*M,3) = (z-1)*dx;
end
x0(:,2) = 0.5;
conf.secondary_sources.x0 = x0;
conf.secondary_sources.geometry = 'custom';
conf.secondary_sources.number = 31^2;

%%
conf.dimension = '3D';
conf.usetapwin = 0;
xs = [0,2,0,0,0,1];
f = 1000;
sound_field_mono_wfs([-2,2],[-3,1],0,xs,'ls',f,conf);
sound_field_mono_wfs(0,[-3,1],[-0.5,3.5],xs,'ls',f,conf); 

vls_top
vls_side

- rotation matrix R computed from nxs
- rotation of virtual source and secondary sources
- line source aligend parallel to the z-axis
@narahahn
Copy link
Member

narahahn commented Feb 9, 2016

Now virtual line sources with arbitrary alignment can be synthesized using NFC-HOA.

  • As for the WFS case, xs should have 6 entries: xs(1:3) any point on the line source and xs(4:6) orientation of the line source.
  • Rotation matrix R is computed that rotates the line source position xs(1:3) and the secondary sources x0, in such a way that the line source is parallel to the z-axis in the new coordinate system.
  • Since xs is [nx3] and R is [3x3], it is convenient to apply a right multiplication xs*R rather than R*xs. Azimuth alphan and elevation betan is obtained from nxs and the rotation matrix R is computed which rotates the coordinate system by -alphan and -betan.
  • The rotation matrix R is applied to the line source position xs(1:3) and to the secondary sources x0.
  • Finally, the NFC-HOA driving function is computed.
SFS_start;
conf = SFS_config;
conf.dimension = '3D';
conf.secondary_sources.number = 169;
conf.secondary_sources.geometry = 'sphere';
conf.resolution = 100;
conf.plot.normalisation = 'center';
X = randi([-1000 1000],125000,1)/2000;
Y = randi([-1000 1000],125000,1)/2000;
Z = randi([-1000 1000],125000,1)/2000;

% vertical line source
xs = [0 1.7 0, ...  % position
      0 0 1];       % orientation
src = 'ls';
f = 750;
sound_field_mono_nfchoa(X,Y,Z,xs,src,f,conf);
% print('-dpng','linesource_vertical')

% horizontal line source
xs = [1.7 0 0, ...  % position
       0 1 0];      % orientation
src = 'ls';
f = 750;
sound_field_mono_nfchoa(X,Y,Z,xs,src,f,conf);
% print('-dpng','linesource_horizontal')

% tilted line source
xs = [-2 -2 0, ...  % position
       1 1 1];      % orientation
src = 'ls';
f = 750;
sound_field_mono_nfchoa(X,Y,Z,xs,src,f,conf);
% print('-dpng','linesource_tilted')

linesource_vertical
linesource_horizontal
linesource_tilted

* 'nfchoa_ls' of github.com:sfstoolbox/sfs:
  virtual line sources with arbitrary orientations
  Remove over-eager checks of requested xs fo 2D and 2.5D -> works with proper 2D array -> No guarantees otherwise
  Fix Secondary Source Selection for 3D Line Source
  fix WFS 3D Driving function line source, secondary source selection still WIP
  Add WFS 3D ls case to test_driving_functions()
  3D WFS Line Source Driving function
  Update monochromatic WFS driving functions for ls
@hagenw
Copy link
Member Author

hagenw commented Feb 9, 2016

Nice!
I started testing it and the first obvious difference I encountered between WFS and NFC-HOA is the following:

In WFS for 2D and 2.5D we restrict the orientation of the line source to be [0 0 1] for all cases.
For NFC-HOA you are allowed to use arbitrary orientations. Are the calculations for these orientations correct in NFC-HOA? And if so, would be nice to have that also for WFS?
Here are a few examples:

conf = SFS_config;
conf.plot.normalisation = 'center';
sound_field_mono_wfs([-2 2],[-2 2],0,[0 2.5 0 0 0 1],'ls',1000,conf);

wfs_ls

sound_field_mono_nfchoa([-2 2],[-2 2],0,[0 2.5 0 0 1 1],'ls',1000,conf);

nfchoa_ls_yz

sound_field_mono_nfchoa([-2 2],[-2 2],0,[0 2.5 0 1 0 1],'ls',1000,conf);

nfchoa_ls_xz

sound_field_mono_nfchoa([-2 2],[-2 2],0,[0 2.5 0 1 1 0],'ls',1000,conf);

nfchoa_ls_xy

@narahahn
Copy link
Member

To be honest, I was concentrating too much on 3D cases and forgot to take
care of 2D and 2.5D synthesis. I would say a virtual line source always has
to be parallel to the z-axis in 2D and 2.5D NFC-HOA. I will take care of
this problem.

@hagenw
Copy link
Member Author

hagenw commented Feb 10, 2016

No problem, you could do it exactly like @trettberg did for the WFS line source

2D and 2.5D configurations ignores nxs and the z-component of xs.
@narahahn
Copy link
Member

2D and 2.5D NFC-HOA now use cylindrical coordinate representation of line source position xs and secondary source positions x00. Only 3D NFC-HOA uses the spherical coordinate system, and applies rotation to xs and x00.

@hagenw
Copy link
Member Author

hagenw commented Feb 10, 2016

Perfect, now we have the same behavior for WFS and NFC-HOA.
I made a few more updates:

  1. You can now use a [1x3] position vector in the 2D or 2.5D case
  2. I implemented an additional function get_position_and_orientation_ls(xs,conf) that handles all this and returns warning messages if you use a xs with the wrong size.
  3. I cleaned up driving_function_mono_wfs_ls and driving_function_mono_nfchoa_ls to use only 5 input args as all the other driving functions (the splitting of xs is performed inside the driving functions)

There is only one position in the code left that is not so nice yet, see secondary_source_selection.
If we want to use get_position_and_orientation_ls there we would have to add conf as additional parameter to secondary_source_selection. I'm not sure if we should do that.

Beside this small question everything should be fine now.

@trettberg
Copy link
Contributor

This raises a somewhat abstruse issue for the 2D and 2.5D case:

The secondary source selection uses xs as is, while the driving function uses only the z component.
This is not a problem unless the array itself has "wrong" normal vectors, that is x0(:,6) ~= 0.
The result is most likely wrong anyway, but in this case it is "inconsistently wrong".

Personally I don't think that's an issue and would leave it this way.

But if this is undesirable, conf could be passed to secondary_source_selection.

@hagenw
Copy link
Member Author

hagenw commented Feb 17, 2016

I also don't think that this is an issue. I added a NOTE to the corresponding section in the secondary_source_selection() function, that is stating what you are saying, so if someone really has a problem, that might be a hint what could be wrong.

I'm going to merge this pull request now.

hagenw added a commit that referenced this pull request Feb 17, 2016
New NFC-HOA line source driving function for the mono-chromatic case
@hagenw hagenw merged commit fda0f55 into master Feb 17, 2016
@hagenw hagenw deleted the nfchoa_ls branch February 17, 2016 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants