SAF
Loading...
Searching...
No Matches
dirass_internal.c
Go to the documentation of this file.
1/*
2 * Copyright 2019 Leo McCormack
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
37#include "dirass.h"
38#include "dirass_internal.h"
39
40void dirass_setCodecStatus(void* const hDir, CODEC_STATUS newStatus)
41{
42 dirass_data *pData = (dirass_data*)(hDir);
43 if(newStatus==CODEC_STATUS_NOT_INITIALISED){
44 /* Pause until current initialisation is complete */
46 SAF_SLEEP(10);
47 }
48 pData->codecStatus = newStatus;
49}
50
51void dirass_initAna(void* const hDir)
52{
53 dirass_data *pData = (dirass_data*)(hDir);
54 dirass_codecPars* pars = pData->pars;
55 int i, j, N_azi, N_ele, nSH_order, order, nSH_sec, order_sec, order_up, nSH_up, geosphere_ico_freq, td_degree;
56 float hfov, vfov, fi, aspectRatio;
57 float *grid_x_axis, *grid_y_axis, *c_n;
58 float_complex* A_xyz;
59
60 order = pData->new_inputOrder;
61 order_up = pData->new_upscaleOrder;
62 nSH_order = (order+1)*(order+1);
63 nSH_up = (order_up+1)*(order_up+1);
64
65 strcpy(pData->progressBarText,"Preparing scanning grid");
66 pData->progressBar0_1 = 0.4f;
67
68 /* Determine scanning grid */
69 switch(pData->gridOption){
70 case T_DESIGN_3: /* 6 points */
71 td_degree = 3;
72 pars->grid_dirs_deg = (float*)__HANDLES_Tdesign_dirs_deg[td_degree-1];
73 pars->grid_nDirs = __Tdesign_nPoints_per_degree[td_degree-1];
74 break;
75 case T_DESIGN_4: /* 12 points */
76 td_degree = 4;
77 pars->grid_dirs_deg = (float*)__HANDLES_Tdesign_dirs_deg[td_degree-1];
78 pars->grid_nDirs = __Tdesign_nPoints_per_degree[td_degree-1];
79 break;
80 case T_DESIGN_6: /* 24 points */
81 td_degree = 6;
82 pars->grid_dirs_deg = (float*)__HANDLES_Tdesign_dirs_deg[td_degree-1];
83 pars->grid_nDirs = __Tdesign_nPoints_per_degree[td_degree-1];
84 break;
85 case T_DESIGN_9: /* 48 points */
86 td_degree = 9;
87 pars->grid_dirs_deg = (float*)__HANDLES_Tdesign_dirs_deg[td_degree-1];
88 pars->grid_nDirs = __Tdesign_nPoints_per_degree[td_degree-1];
89 break;
90 case T_DESIGN_13: /* 94 points */
91 td_degree = 13;
92 pars->grid_dirs_deg = (float*)__HANDLES_Tdesign_dirs_deg[td_degree-1];
93 pars->grid_nDirs = __Tdesign_nPoints_per_degree[td_degree-1];
94 break;
95 case T_DESIGN_18: /* 180 points */
96 td_degree = 18;
97 pars->grid_dirs_deg = (float*)__HANDLES_Tdesign_dirs_deg[td_degree-1];
98 pars->grid_nDirs = __Tdesign_nPoints_per_degree[td_degree-1];
99 break;
100 case GRID_GEOSPHERE_6: /* 362 points */
101 geosphere_ico_freq = 6;
102 pars->grid_dirs_deg = (float*)__HANDLES_geosphere_ico_dirs_deg[geosphere_ico_freq];
103 pars->grid_nDirs = __geosphere_ico_nPoints[geosphere_ico_freq];
104 break;
105 case T_DESIGN_30: /* 480 points */
107 pars->grid_nDirs = 480;
108 break;
109 case GRID_GEOSPHERE_8: /* 642 points */
110 geosphere_ico_freq = 8;
111 pars->grid_dirs_deg = (float*)__HANDLES_geosphere_ico_dirs_deg[geosphere_ico_freq];
112 pars->grid_nDirs = __geosphere_ico_nPoints[geosphere_ico_freq];
113 break;
114 case GRID_GEOSPHERE_9: /* 812 points */
115 geosphere_ico_freq = 9;
116 pars->grid_dirs_deg = (float*)__HANDLES_geosphere_ico_dirs_deg[geosphere_ico_freq];
117 pars->grid_nDirs = __geosphere_ico_nPoints[geosphere_ico_freq];
118 break;
119 case GRID_GEOSPHERE_10: /* 1002 points */
120 geosphere_ico_freq = 10;
121 pars->grid_dirs_deg = (float*)__HANDLES_geosphere_ico_dirs_deg[geosphere_ico_freq];
122 pars->grid_nDirs = __geosphere_ico_nPoints[geosphere_ico_freq];
123 break;
124 case GRID_GEOSPHERE_12: /* 1442 points */
125 geosphere_ico_freq = 12;
126 pars->grid_dirs_deg = (float*)__HANDLES_geosphere_ico_dirs_deg[geosphere_ico_freq];
127 pars->grid_nDirs = __geosphere_ico_nPoints[geosphere_ico_freq];
128 break;
129 }
130
131 /* generate interpolation table for current display config */
132 switch(pData->HFOVoption){
133 default:
134 case HFOV_360: hfov = 360.0f; break;
135 case HFOV_180: hfov = 180.0f; break;
136 case HFOV_90: hfov = 90.0f; break;
137 case HFOV_60: hfov = 60.0f; break;
138 }
139 switch(pData->aspectRatioOption){
140 default:
141 case ASPECT_RATIO_2_1: aspectRatio = 2.0f; break;
142 case ASPECT_RATIO_16_9: aspectRatio = 16.0f/9.0f; break;
143 case ASPECT_RATIO_4_3: aspectRatio = 4.0f/3.0f; break;
144 }
145 N_azi = pData->dispWidth;
146 N_ele = (int)((float)pData->dispWidth/aspectRatio + 0.5f);
147 grid_x_axis = malloc1d(N_azi * sizeof(float));
148 grid_y_axis = malloc1d(N_ele * sizeof(float));
149 vfov = hfov/aspectRatio;
150 for(fi = -hfov/2.0f, i = 0; i<N_azi; fi+=hfov/N_azi, i++)
151 grid_x_axis[i] = fi;
152 for(fi = -vfov/2.0f, i = 0; i<N_ele; fi+=vfov/N_ele, i++)
153 grid_y_axis[i] = fi;
154 pars->interp_dirs_deg = realloc1d(pars->interp_dirs_deg, N_azi*N_ele*2*sizeof(float));
155 pars->interp_dirs_rad = realloc1d(pars->interp_dirs_rad, N_azi*N_ele*2*sizeof(float));
156 for(i = 0; i<N_ele; i++){
157 for(j=0; j<N_azi; j++){
158 pars->interp_dirs_deg[(i*N_azi + j)*2] = grid_x_axis[j];
159 pars->interp_dirs_deg[(i*N_azi + j)*2+1] = grid_y_axis[i];
160 pars->interp_dirs_rad[(i*N_azi + j)*2] = grid_x_axis[j] * SAF_PI/180.0f;
161 pars->interp_dirs_rad[(i*N_azi + j)*2+1] = grid_y_axis[i] * SAF_PI/180.0f;
162 }
163 }
164 free(pars->interp_table);
165 generateVBAPgainTable3D_srcs(pars->interp_dirs_deg, N_azi*N_ele, pars->grid_dirs_deg, pars->grid_nDirs, 0, 0, 0.0f, &(pars->interp_table), &(pars->interp_nDirs), &(pars->interp_nTri));
167
168 strcpy(pData->progressBarText,"Computing Sector coefficients");
169 pData->progressBar0_1 = 0.85f;
170
171 /* get beamforming matrices for sector velocity and sector patterns */
172 order_sec = order-1;
173 nSH_sec = (order_sec+1)*(order_sec+1);
174 A_xyz = malloc1d(nSH_order*nSH_sec*3*sizeof(float_complex));
175 c_n = malloc1d((order_sec+1)*sizeof(float));
176 computeVelCoeffsMtx(order_sec, A_xyz);
177 switch(pData->beamType){
178 case STATIC_BEAM_TYPE_CARDIOID: beamWeightsCardioid2Spherical(order_sec, c_n); break;
180 case STATIC_BEAM_TYPE_MAX_EV: beamWeightsMaxEV(order_sec, c_n); break;
181 }
182 pars->Cxyz = realloc1d(pars->Cxyz, pars->grid_nDirs * nSH_order * 3 * sizeof(float));
183 pars->Cw = realloc1d(pars->Cw, pars->grid_nDirs * nSH_sec * sizeof(float));
184 for(i=0; i<pars->grid_nDirs; i++){
185 beamWeightsVelocityPatternsReal(order_sec, c_n, pars->grid_dirs_deg[i*2]*SAF_PI/180.0f,
186 pars->grid_dirs_deg[i*2+1]*SAF_PI/180.0f, A_xyz, &(pars->Cxyz[i*nSH_order*3]));
187 rotateAxisCoeffsReal(order_sec, c_n, SAF_PI/2.0f - pars->grid_dirs_deg[i*2+1]*SAF_PI/180.0f,
188 pars->grid_dirs_deg[i*2]*SAF_PI/180.0f, &(pars->Cw[i*nSH_sec]));
189 }
190 free(A_xyz);
191 free(c_n);
192
193 /* get regular beamforming weights */
194 c_n = malloc1d((order+1)*sizeof(float));
195 switch(pData->beamType){
198 case STATIC_BEAM_TYPE_MAX_EV: beamWeightsMaxEV(order, c_n); break;
199 }
200 pars->w = realloc1d(pars->w, pars->grid_nDirs * nSH_order * sizeof(float));
201 for(i=0; i<pars->grid_nDirs; i++){
202 rotateAxisCoeffsReal(order, c_n, SAF_PI/2.0f - pars->grid_dirs_deg[i*2+1]*SAF_PI/180.0f,
203 pars->grid_dirs_deg[i*2]*SAF_PI/180.0f, &(pars->w[i*nSH_order]));
204 }
205 free(c_n);
206
207 /* beamforming weights for upscaled */
208 c_n = malloc1d((order_up+1)*sizeof(float));
209 switch(pData->beamType){
212 case STATIC_BEAM_TYPE_MAX_EV: beamWeightsMaxEV(order_up, c_n); break;
213 }
214 pars->Uw = realloc1d(pars->Uw, pars->grid_nDirs * nSH_up * sizeof(float));
215 for(i=0; i<pars->grid_nDirs; i++){
216 rotateAxisCoeffsReal(order_up, c_n, SAF_PI/2.0f - pars->grid_dirs_deg[i*2+1]*SAF_PI/180.0f,
217 pars->grid_dirs_deg[i*2]*SAF_PI/180.0f, &(pars->Uw[i*nSH_up]));
218 }
219 free(c_n);
220
221 /* reallocate memory */
222 pars->Y_up = realloc1d(pars->Y_up, nSH_up * (pars->grid_nDirs)*sizeof(float));
223 pars->est_dirs = realloc1d(pars->est_dirs, pars->grid_nDirs * 2 * sizeof(float));
224 pars->ss = realloc1d(pars->ss, pars->grid_nDirs * DIRASS_FRAME_SIZE * sizeof(float));
225 pars->ssxyz = realloc1d(pars->ssxyz, 3 * DIRASS_FRAME_SIZE * sizeof(float));
226 pData->pmap = realloc1d(pData->pmap, pars->grid_nDirs*sizeof(float));
227 pars->est_dirs_idx = realloc1d(pars->est_dirs_idx, pars->grid_nDirs*sizeof(int));
228 pars->prev_intensity = realloc1d(pars->prev_intensity, pars->grid_nDirs*3*sizeof(float));
229 pars->prev_energy = realloc1d(pars->prev_energy, pars->grid_nDirs*sizeof(float));
230 memset(pars->prev_intensity, 0, pars->grid_nDirs*3*sizeof(float));
231 memset(pars->prev_energy, 0, pars->grid_nDirs*sizeof(float));
232 for(i=0; i<NUM_DISP_SLOTS; i++){
233 pData->pmap_grid[i] = realloc1d(pData->pmap_grid[i], pars->interp_nDirs*sizeof(float));
234 memset(pData->pmap_grid[i], 0, pars->interp_nDirs*sizeof(float));
235 }
236
237 pData->inputOrder = order;
238 pData->upscaleOrder = order_up;
239
240 free(grid_x_axis);
241 free(grid_y_axis);
242}
@ STATIC_BEAM_TYPE_MAX_EV
hyper-cardioid with max_rE weighting
Definition _common.h:171
@ STATIC_BEAM_TYPE_HYPERCARDIOID
hyper-cardioid
Definition _common.h:170
@ STATIC_BEAM_TYPE_CARDIOID
cardioid
Definition _common.h:169
@ HFOV_60
60 degrees
Definition _common.h:183
@ HFOV_360
360 degrees
Definition _common.h:180
@ HFOV_180
180 degrees
Definition _common.h:181
@ HFOV_90
90 degrees
Definition _common.h:182
CODEC_STATUS
Current status of the codec.
Definition _common.h:201
@ CODEC_STATUS_NOT_INITIALISED
Codec has not yet been initialised, or the codec configuration has changed.
Definition _common.h:204
@ CODEC_STATUS_INITIALISING
Codec is currently being initialised, input audio should not be processed.
Definition _common.h:207
@ ASPECT_RATIO_4_3
ASPECT_RATIO_4_3 - 4:3.
Definition _common.h:191
@ ASPECT_RATIO_16_9
ASPECT_RATIO_16_9 - 16:9.
Definition _common.h:190
@ ASPECT_RATIO_2_1
ASPECT_RATIO_2_1 - 2:1.
Definition _common.h:189
A sound-field visualiser based on the directional re-assignment of beamformer energy based on local D...
@ GRID_GEOSPHERE_10
GRID_GEOSPHERE_10 - 1002 points.
Definition dirass.h:97
@ T_DESIGN_9
T_DESIGN_9 - 48 points.
Definition dirass.h:90
@ T_DESIGN_3
T_DESIGN_3 - 6 points.
Definition dirass.h:87
@ T_DESIGN_13
T_DESIGN_13 - 94 points.
Definition dirass.h:91
@ T_DESIGN_6
T_DESIGN_6 - 24 points.
Definition dirass.h:89
@ GRID_GEOSPHERE_9
GRID_GEOSPHERE_9 - 812 points.
Definition dirass.h:96
@ GRID_GEOSPHERE_8
GRID_GEOSPHERE_8 - 642 points.
Definition dirass.h:95
@ GRID_GEOSPHERE_6
GRID_GEOSPHERE_6 - 362 points.
Definition dirass.h:93
@ T_DESIGN_30
T_DESIGN_30 - 480 points.
Definition dirass.h:94
@ T_DESIGN_18
T_DESIGN_18 - 180 points.
Definition dirass.h:92
@ T_DESIGN_4
T_DESIGN_4 - 12 points.
Definition dirass.h:88
@ GRID_GEOSPHERE_12
GRID_GEOSPHERE_12 - 1442 points.
Definition dirass.h:98
void dirass_setCodecStatus(void *const hDir, CODEC_STATUS newStatus)
Sets codec status (see CODEC_STATUS enum)
void dirass_initAna(void *const hDir)
Intialises the codec variables, based on current global/user parameters.
A sound-field visualiser based on the directional re-assignment of beamformer energy based on local D...
#define DIRASS_FRAME_SIZE
Framesize, in time-domain samples.
#define NUM_DISP_SLOTS
Number of display slots.
void beamWeightsVelocityPatternsReal(int order, float *b_n, float azi_rad, float elev_rad, float_complex *A_xyz, float *velCoeffs)
Generates beamforming coefficients for velocity patterns (REAL)
Definition saf_sh.c:885
void beamWeightsCardioid2Spherical(int N, float *b_n)
Generates spherical coefficients for generating cardioid beampatterns.
Definition saf_sh.c:823
void beamWeightsMaxEV(int N, float *b_n)
Generates beamweights in the SHD for maximum energy-vector beampatterns.
Definition saf_sh.c:858
void rotateAxisCoeffsReal(int order, float *c_n, float theta_0, float phi_0, float *c_nm)
Generates spherical coefficients for a rotated axisymmetric pattern (REAL)
Definition saf_sh.c:946
void beamWeightsHypercardioid2Spherical(int N, float *b_n)
Generates beamweights in the SHD for hypercardioid beampatterns.
Definition saf_sh.c:840
void computeVelCoeffsMtx(int sectorOrder, float_complex *A_xyz)
Computes the matrices which generate the coefficients of a beampattern of order (sectorOrder+1) that ...
Definition saf_sh.c:672
#define SAF_PI
pi constant (single precision)
const float * __HANDLES_Tdesign_dirs_deg[21]
minimum T-design HANDLES (up to degree 21 only).
const int __geosphere_ico_nPoints[17]
3LD geosphere number of points (freq = [0 0], [1 0],..., [16 0])
const float __Tdesign_degree_30_dirs_deg[480][2]
Directions [azimuth, Elevation] in degrees, for minimum Tdesign degree: 30.
const int __Tdesign_nPoints_per_degree[21]
Number of points in each t-design (up to degree 21 only).
const float * __HANDLES_geosphere_ico_dirs_deg[17]
3LD geosphere HANDLES (freq = [0 0], [1 0],..., [16 0])
void generateVBAPgainTable3D_srcs(float *src_dirs_deg, int S, float *ls_dirs_deg, int L, int omitLargeTriangles, int enableDummies, float spread, float **gtable, int *N_gtable, int *nTriangles)
Generates a 3-D VBAP [1] gain table based on specified source and loudspeaker directions,...
Definition saf_vbap.c:53
void VBAPgainTable2InterpTable(float *vbap_gtable, int nTable, int nDirs)
Renormalises a VBAP gain table (in-place) so it may be utilised for interpolation of data (for exampl...
Definition saf_vbap.c:370
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
Definition md_malloc.c:59
void * realloc1d(void *ptr, size_t dim1_data_size)
1-D realloc (same as realloc, but with error checking)
Definition md_malloc.c:79
Contains variables for scanning grids, and sector beamforming.
float * ss
beamformer sector signals; FLAT: grid_nDirs x DIRASS_FRAME_SIZE
float * interp_table
interpolation table (spherical->rectangular grid); FLAT: interp_nDirs x grid_nDirs
float * interp_dirs_deg
interpolation directions, in degrees; FLAT: interp_nDirs x 2
float * grid_dirs_deg
scanning grid directions; FLAT: grid_nDirs x 2
float * est_dirs
estimated DoA per grid direction; grid_nDirs x 2
float * Cxyz
beamforming weights for velocity patterns; FLAT: nDirs x (order+1)^2 x 3
int interp_nTri
number of triangles in the spherical scanning grid mesh
float * prev_energy
previous energy (for averaging); FLAT: grid_nDirs x 1
int * est_dirs_idx
DoA indices, into the interpolation directions; grid_nDirs x 1.
float * prev_intensity
previous intensity vectors (for averaging); FLAT: grid_nDirs x 3
float * w
beamforming weights; FLAT: nDirs x (order+1)^2
float * Cw
beamforming weights; FLAT: nDirs x (order)^2
int grid_nDirs
number of grid directions
float * Uw
beamforming weights; FLAT: nDirs x (upscaleOrder+1)^2
int interp_nDirs
number of interpolation directions
float * interp_dirs_rad
interpolation directions, in radians; FLAT: interp_nDirs x 2
float * ssxyz
beamformer velocity signals; FLAT: 3 x DIRASS_FRAME_SIZE
float * Y_up
real SH weights for upscaling; FLAT: (upscaleOrder+1)^2 x grid_nDirs
Main structure for dirass.
int inputOrder
Current input/analysis order.
float * pmap
grid_nDirs x 1
int upscaleOrder
Current target upscale order.
STATIC_BEAM_TYPES beamType
beamformer type mode
float progressBar0_1
Current (re)initialisation progress, between [0..1].
float * pmap_grid[NUM_DISP_SLOTS]
dirass interpolated to grid; interp_nDirs x 1
int new_upscaleOrder
New target upscale order.
ASPECT_RATIO_OPTIONS aspectRatioOption
aspect ratio option
int new_inputOrder
New input/analysis order.
CODEC_STATUS codecStatus
see CODEC_STATUS
DIRASS_GRID_OPTIONS gridOption
grid option
int dispWidth
number of interpolation points on the horizontal
dirass_codecPars * pars
codec parameters
char * progressBarText
Current (re)initialisation step, string.
HFOV_OPTIONS HFOVoption
horizontal field-of-view option