00001 /* 00002 00003 HOA_Utilities.h -- Higher Order Ambisonic utility classes 00004 See the copyright notice and acknowledgment of authors in the file COPYRIGHT 00005 Higher Order Ambisonic classes written by Jorge Castellanos, Graham Wakefield, Florian Hollerweger, 2005 00006 00007 Utility classes used by HOA_Encoder, MOA_Encoder, HOA_Rotator, MOA_Rotator, HOA_Decoder 00008 00009 */ 00010 00011 #ifndef HOA_UTILITIES_H 00012 #define HOA_UTILITIES_H 00013 00014 #include "CSL_Core.h" 00015 00016 #define AMBI_INVSQRT2 (1/1.414213562) 00017 00018 namespace csl { 00019 00020 /* 00021 00022 CONVENTIONS USED IN THIS CODE: 00023 ------------------------------ 00024 00025 ***coordinate system*** 00026 Left oriented 00027 Azimuth = 0 on the x/z plane and increasing towards the positive y direction 00028 Elevation = 0 on x/y plane and increasing towards the positive z direction 00029 Internal angle representation: spherical radians 00030 00031 ***encoding convention*** 00032 following the Furse-Malham set (Ambisonic channel weighting for uniform energy distribution) 00033 00034 ***abbreviations used in code and comments*** 00035 M ... Ambisonic order (in uniform order system) 00036 M_h ... horizontal Ambisonic order (in hybrid order systems) 00037 M_v ... horizontal Ambisonic order (in hybrid order systems) 00038 N ... total number of Ambisonic encoded channels (horizontal and vertical) 00039 N_h ... number of horizontal Ambisonic channels (in hybrid order systems) 00040 N_v ... number of vertical Ambisonic channels (in hybrid order systems) 00041 L ... number of available loudspeakers 00042 00043 ***ordering and naming of Ambisonic channels = spherical harmonics*** 00044 These conventions follow the ones used in the thesis by Jerome Daniel. 00045 The 3rd order naming convention (which Daniel doesn't provide) follows the one used in the thesis of David Malham. 00046 Watch out for different conventions in other papers! 00047 index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 00048 M (order) 0 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 00049 m (=M) 0 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 00050 n 0 1 1 0 2 2 1 1 0 3 3 2 2 1 1 0 00051 sigma '1' 1 -1 '1' 1 -1 1 -1 '1' 1 -1 1 -1 1 -1 '1' 00052 name W X Y Z U V S T R P Q N O L M K 00053 hor/vert/omni om h h v h h v v v h h v v v v v 00054 00055 */ 00056 00057 // Ambisonic order structure (separate definition of horizontal and vertical order): 00058 typedef struct { 00059 unsigned horizontalOrder, verticalOrder, greaterOrder; 00060 bool isUniform; 00061 } ambisonicOrder; 00062 00063 // returns the Ambisonic order from the number of Ambisonic channels: M = floor(sqrt(N) - 1) 00064 // NOTE - only works for uniform horizontal and vertical order (whereas ambiguity occurs in hybrid order systems)! 00065 unsigned int channelsToUniformOrder(const unsigned int channels); 00066 00067 // compares the horizontal and vertical Ambisonic order of a hybrid order system and returns the greater one 00068 unsigned int getGreaterOrder(const ambisonicOrder order); 00069 00070 // returns the number of Ambisonic channels from a hybrid Ambisonic order: N = 2*M_h + 1 + (M_v + 1)^2 - (2*M_v + 1) 00071 unsigned int orderToChannels(const ambisonicOrder order); 00072 00073 // returns the number of Ambisonic channels from a uniform Ambisonic order: N = (M+1)^2 00074 unsigned int orderToChannels(unsigned int order); 00075 00076 // returns the number of horizontal Ambisonic channels from a hybrid Ambisonic order: N_h = 2*M_h + 1 00077 unsigned int orderToHorizontalChannels(const ambisonicOrder order); 00078 00079 // returns the number of vertical Ambisonic channels from a hybrid Ambisonic order: N_v = (M_v + 1)^2 - (2*M_v + 1) 00080 unsigned int orderToVerticalChannels(const ambisonicOrder order); 00081 00082 // returns a lookup table to map Ambisonic channel index to actually used Framestream channel 00083 unsigned int *channelIndexer(const ambisonicOrder order); 00084 00085 // returns a lookup table to map actually used Framestream channel to Ambisonic channel index 00086 unsigned int *invChannelIndexer(const ambisonicOrder order); 00087 00088 // utility function used in calculating the inverse of a matrix, used in HOA_Decoder for the pseudoinverse method 00089 void SingularValueDecomposition(sample** a, int m, int n, sample* w, sample** v); 00090 00091 // utility function that calculates fuma encoding weights for a given order, azimuth and elevation. 00092 void fumaEncodingWeights(sample *weights, const ambisonicOrder &order, sample &azimuth, sample &elevation); 00093 00094 // utility function that calculates fuma encoding weights for a given order, azimuth and elevation. 00095 void fumaIndexedEncodingWeights(sample *weights, const ambisonicOrder &order, sample &azimuth, sample &elevation); 00096 00097 } 00098 00099 #endif
1.4.5-20051010