SAF
Loading...
Searching...
No Matches
rotator.c
Go to the documentation of this file.
1/*
2 * Copyright 2017-2018 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
33
34#include "rotator.h"
35#include "rotator_internal.h"
36
38(
39 void ** const phRot
40)
41{
43 *phRot = (void*)pData;
44
46 pData->fs = 48000.0f;
47
48 /* Default user parameters */
49 pData->Q.w = 1.0f;
50 pData->Q.x = 0.0f;
51 pData->Q.y = 0.0f;
52 pData->Q.z = 0.0f;
53 pData->bFlipQuaternion = 0;
54 pData->yaw = 0.0f;
55 pData->pitch = 0.0f;
56 pData->roll = 0.0f;
57 pData->bFlipYaw = 0;
58 pData->bFlipPitch = 0;
59 pData->bFlipRoll = 0;
60 pData->chOrdering = CH_ACN;
61 pData->norm = NORM_SN3D;
62 pData->useRollPitchYawFlag = 0;
64}
65
67(
68 void ** const phRot
69)
70{
71 rotator_data *pData = (rotator_data*)(*phRot);
72
73 if (pData != NULL) {
74 free(pData);
75 pData = NULL;
76 }
77}
78
80(
81 void * const hRot,
82 int sampleRate
83)
84{
85 rotator_data *pData = (rotator_data*)(hRot);
86 int i;
87
88 pData->fs = sampleRate;
89
90 /* starting values */
91 for(i=1; i<=ROTATOR_FRAME_SIZE; i++){
92 pData->interpolator_fadeIn[i-1] = (float)i*1.0f/(float)ROTATOR_FRAME_SIZE;
93 pData->interpolator_fadeOut[i-1] = 1.0f-pData->interpolator_fadeIn[i-1];
94 }
95 memset(pData->M_rot, 0, MAX_NUM_SH_SIGNALS*MAX_NUM_SH_SIGNALS*sizeof(float));
96 memset(pData->prev_M_rot, 0, MAX_NUM_SH_SIGNALS*MAX_NUM_SH_SIGNALS*sizeof(float));
97 pData->M_rot_status = M_ROT_RECOMPUTE_EULER;//M_ROT_RECOMPUTE_QUATERNION;
98}
99
101(
102 void * const hRot,
103 const float *const * inputs,
104 float* const* const outputs,
105 int nInputs,
106 int nOutputs,
107 int nSamples
108)
109{
110 rotator_data *pData = (rotator_data*)(hRot);
111 int i, j, order, nSH, mixWithPreviousFLAG;
112 float Rxyz[3][3], yaw_temp, pitch_temp, roll_temp;
113 float M_rot_tmp[MAX_NUM_SH_SIGNALS*MAX_NUM_SH_SIGNALS];
114 CH_ORDER chOrdering;
115
116 /* locals */
117 chOrdering = pData->chOrdering;
118 order = (int)pData->inputOrder;
119 nSH = ORDER2NSH(order);
120
121 if (nSamples == ROTATOR_FRAME_SIZE) {
122
123 /* Load time-domain data */
124 for(i=0; i < SAF_MIN(nSH, nInputs); i++)
125 utility_svvcopy(inputs[i], ROTATOR_FRAME_SIZE, pData->inputFrameTD[i]);
126 for(; i<MAX_NUM_SH_SIGNALS; i++)
127 memset(pData->inputFrameTD[i], 0, ROTATOR_FRAME_SIZE * sizeof(float)); /* fill remaining channels with zeros */
128
129 /* account for channel order */
130 switch(chOrdering){
131 case CH_ACN: /* already ACN */ break; /* Otherwise, convert to ACN... */
133 }
134
135 if (order>0){
136 /* calculate rotation matrix */
137 mixWithPreviousFLAG = 0;
138 if(pData->M_rot_status != M_ROT_READY){
139 memset(pData->M_rot, 0, MAX_NUM_SH_SIGNALS*MAX_NUM_SH_SIGNALS*sizeof(float));
141 yawPitchRoll2Rzyx (pData->yaw, pData->pitch, pData->roll, pData->useRollPitchYawFlag, Rxyz);
142 euler2Quaternion(pData->yaw, pData->pitch, pData->roll, 0,
144 }
145 else {/* M_ROT_RECOMPUTE_QUATERNION */
146 quaternion2rotationMatrix(&(pData->Q), Rxyz);
148 &yaw_temp, &pitch_temp, &roll_temp);
149 pData->yaw = yaw_temp;
150 pData->pitch = pitch_temp;
151 pData->roll = roll_temp;
152 }
153 getSHrotMtxReal(Rxyz, (float*)M_rot_tmp, order);
154 for(i=0; i<nSH; i++)
155 for(j=0; j<nSH; j++)
156 pData->M_rot[i][j] = M_rot_tmp[i*nSH+j];
157 mixWithPreviousFLAG = 1;
158 pData->M_rot_status = M_ROT_READY;
159 }
160
161 /* apply rotation */
162 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, ROTATOR_FRAME_SIZE, nSH, 1.0f,
163 (float*)(pData->M_rot), MAX_NUM_SH_SIGNALS,
164 (float*)pData->inputFrameTD, ROTATOR_FRAME_SIZE, 0.0f,
165 (float*)pData->outputFrameTD, ROTATOR_FRAME_SIZE);
166
167 /* Fade between (linearly inerpolate) the new rotation matrix and the previous rotation matrix (only if the new rotation matrix is different) */
168 if(mixWithPreviousFLAG){
169 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, ROTATOR_FRAME_SIZE, nSH, 1.0f,
170 (float*)pData->prev_M_rot, MAX_NUM_SH_SIGNALS,
171 (float*)pData->inputFrameTD, ROTATOR_FRAME_SIZE, 0.0f,
172 (float*)pData->tempFrame, ROTATOR_FRAME_SIZE);
173
174 /* Apply the linear interpolation */
175 for (i=0; i < nSH; i++){
176 utility_svvmul((float*)pData->interpolator_fadeIn, (float*)pData->outputFrameTD[i], ROTATOR_FRAME_SIZE, (float*)pData->outputFrameTD_fadeIn[i]);
177 utility_svvmul((float*)pData->interpolator_fadeOut, (float*)pData->tempFrame[i], ROTATOR_FRAME_SIZE, (float*)pData->tempFrame_fadeOut[i]);
178 }
179 cblas_scopy(nSH*ROTATOR_FRAME_SIZE, (float*)pData->outputFrameTD_fadeIn, 1, (float*)pData->outputFrameTD, 1);
180 cblas_saxpy(nSH*ROTATOR_FRAME_SIZE, 1.0f, (float*)pData->tempFrame_fadeOut, 1, (float*)pData->outputFrameTD, 1);
181
182 /* for next frame */
183 utility_svvcopy((const float*)pData->M_rot, MAX_NUM_SH_SIGNALS*MAX_NUM_SH_SIGNALS, (float*)pData->prev_M_rot);
184 }
185 }
186 else /* Pass-through the omni (cannot be rotated...) */
187 utility_svvcopy((const float*)pData->inputFrameTD[0], ROTATOR_FRAME_SIZE, (float*)pData->outputFrameTD[0]);
188
189 /* account for channel order */
190 switch(chOrdering){
191 case CH_ACN: /* do nothing */ break;
193 }
194
195 /* Copy to output */
196 for (i = 0; i < SAF_MIN(nSH, nOutputs); i++)
197 utility_svvcopy(pData->outputFrameTD[i], ROTATOR_FRAME_SIZE, outputs[i]);
198 for (; i < nOutputs; i++)
199 memset(outputs[i], 0, ROTATOR_FRAME_SIZE*sizeof(float));
200 }
201 else{
202 for (i = 0; i < nOutputs; i++)
203 memset(outputs[i], 0, ROTATOR_FRAME_SIZE*sizeof(float));
204 }
205}
206
207
208/*sets*/
209
210void rotator_setYaw(void* const hRot, float newYaw)
211{
212 rotator_data *pData = (rotator_data*)(hRot);
213 pData->yaw = pData->bFlipYaw == 1 ? -DEG2RAD(newYaw) : DEG2RAD(newYaw);
215}
216
217void rotator_setPitch(void* const hRot, float newPitch)
218{
219 rotator_data *pData = (rotator_data*)(hRot);
220 pData->pitch = pData->bFlipPitch == 1 ? -DEG2RAD(newPitch) : DEG2RAD(newPitch);
222}
223
224void rotator_setRoll(void* const hRot, float newRoll)
225{
226 rotator_data *pData = (rotator_data*)(hRot);
227 pData->roll = pData->bFlipRoll == 1 ? -DEG2RAD(newRoll) : DEG2RAD(newRoll);
229}
230
231void rotator_setQuaternionW(void* const hRot, float newValue)
232{
233 rotator_data *pData = (rotator_data*)(hRot);
234 pData->Q.w = newValue;
236}
237
238void rotator_setQuaternionX(void* const hRot, float newValue)
239{
240 rotator_data *pData = (rotator_data*)(hRot);
241 pData->Q.x = pData->bFlipQuaternion == 1 ? -newValue : newValue;
243}
244
245void rotator_setQuaternionY(void* const hRot, float newValue)
246{
247 rotator_data *pData = (rotator_data*)(hRot);
248 pData->Q.y = pData->bFlipQuaternion == 1 ? -newValue : newValue;
250}
251
252void rotator_setQuaternionZ(void* const hRot, float newValue)
253{
254 rotator_data *pData = (rotator_data*)(hRot);
255 pData->Q.z = pData->bFlipQuaternion == 1 ? -newValue : newValue;
257}
258
259void rotator_setFlipYaw(void* const hRot, int newState)
260{
261 rotator_data *pData = (rotator_data*)(hRot);
262 if(newState !=pData->bFlipYaw ){
263 pData->bFlipYaw = newState;
264 rotator_setYaw(hRot, -rotator_getYaw(hRot));
265 }
266}
267
268void rotator_setFlipPitch(void* const hRot, int newState)
269{
270 rotator_data *pData = (rotator_data*)(hRot);
271 if(newState !=pData->bFlipPitch ){
272 pData->bFlipPitch = newState;
274 }
275}
276
277void rotator_setFlipRoll(void* const hRot, int newState)
278{
279 rotator_data *pData = (rotator_data*)(hRot);
280 if(newState !=pData->bFlipRoll ){
281 pData->bFlipRoll = newState;
282 rotator_setRoll(hRot, -rotator_getRoll(hRot));
283 }
284}
285
286void rotator_setFlipQuaternion(void* const hRot, int newState)
287{
288 rotator_data *pData = (rotator_data*)(hRot);
289 if(newState !=pData->bFlipQuaternion ){
290 pData->bFlipQuaternion = newState;
294 }
295}
296
297void rotator_setRPYflag(void* const hRot, int newState)
298{
299 rotator_data *pData = (rotator_data*)(hRot);
300 pData->useRollPitchYawFlag = newState;
301}
302
303void rotator_setChOrder(void* const hRot, int newOrder)
304{
305 rotator_data *pData = (rotator_data*)(hRot);
306 if((CH_ORDER)newOrder != CH_FUMA || pData->inputOrder==SH_ORDER_FIRST)/* FUMA only supports 1st order */
307 pData->chOrdering = (CH_ORDER)newOrder;
308}
309
310void rotator_setNormType(void* const hRot, int newType)
311{
312 rotator_data *pData = (rotator_data*)(hRot);
313 if((NORM_TYPES)newType != NORM_FUMA || pData->inputOrder==SH_ORDER_FIRST)/* FUMA only supports 1st order */
314 pData->norm = (NORM_TYPES)newType;
315}
316
317void rotator_setOrder(void* const hRot, int newOrder)
318{
319 rotator_data *pData = (rotator_data*)(hRot);
320 pData->inputOrder = (SH_ORDERS)newOrder;
322 /* FUMA only supports 1st order */
323 if(pData->inputOrder!=SH_ORDER_FIRST && pData->chOrdering == CH_FUMA)
324 pData->chOrdering = CH_ACN;
325 if(pData->inputOrder!=SH_ORDER_FIRST && pData->norm == NORM_FUMA)
326 pData->norm = NORM_SN3D;
327}
328
329
330/*gets*/
331
333{
334 return ROTATOR_FRAME_SIZE;
335}
336
337float rotator_getYaw(void* const hRot)
338{
339 rotator_data *pData = (rotator_data*)(hRot);
340 return pData->bFlipYaw == 1 ? -RAD2DEG(pData->yaw) : RAD2DEG(pData->yaw);
341}
342
343float rotator_getPitch(void* const hRot)
344{
345 rotator_data *pData = (rotator_data*)(hRot);
346 return pData->bFlipPitch == 1 ? -RAD2DEG(pData->pitch) : RAD2DEG(pData->pitch);
347}
348
349float rotator_getRoll(void* const hRot)
350{
351 rotator_data *pData = (rotator_data*)(hRot);
352 return pData->bFlipRoll == 1 ? -RAD2DEG(pData->roll) : RAD2DEG(pData->roll);
353}
354
355float rotator_getQuaternionW(void* const hRot)
356{
357 rotator_data *pData = (rotator_data*)(hRot);
358 return pData->Q.w;
359}
360
361float rotator_getQuaternionX(void* const hRot)
362{
363 rotator_data *pData = (rotator_data*)(hRot);
364 return pData->bFlipQuaternion == 1 ? -(pData->Q.x) : pData->Q.x;
365}
366
367float rotator_getQuaternionY(void* const hRot)
368{
369 rotator_data *pData = (rotator_data*)(hRot);
370 return pData->bFlipQuaternion == 1 ? -(pData->Q.y) : pData->Q.y;
371}
372
373float rotator_getQuaternionZ(void* const hRot)
374{
375 rotator_data *pData = (rotator_data*)(hRot);
376 return pData->bFlipQuaternion == 1 ? -(pData->Q.z) : pData->Q.z;
377}
378
379int rotator_getFlipYaw(void* const hRot)
380{
381 rotator_data *pData = (rotator_data*)(hRot);
382 return pData->bFlipYaw;
383}
384
385int rotator_getFlipPitch(void* const hRot)
386{
387 rotator_data *pData = (rotator_data*)(hRot);
388 return pData->bFlipPitch;
389}
390
391int rotator_getFlipRoll(void* const hRot)
392{
393 rotator_data *pData = (rotator_data*)(hRot);
394 return pData->bFlipRoll;
395}
396
397int rotator_getFlipQuaternion(void* const hRot)
398{
399 rotator_data *pData = (rotator_data*)(hRot);
400 return pData->bFlipQuaternion;
401}
402
403int rotator_getRPYflag(void* const hRot)
404{
405 rotator_data *pData = (rotator_data*)(hRot);
406 return pData->useRollPitchYawFlag;
407}
408
409int rotator_getChOrder(void* const hRot)
410{
411 rotator_data *pData = (rotator_data*)(hRot);
412 return (int)pData->chOrdering;
413}
414
415int rotator_getNormType(void* const hRot)
416{
417 rotator_data *pData = (rotator_data*)(hRot);
418 return (int)pData->norm;
419}
420
421int rotator_getOrder(void* const hRot)
422{
423 rotator_data *pData = (rotator_data*)(hRot);
424 return (int)pData->inputOrder;
425}
426
427int rotator_getNSHrequired(void* const hRot)
428{
429 rotator_data *pData = (rotator_data*)(hRot);
430 return (pData->inputOrder+1)*(pData->inputOrder+1);
431}
432
434{
435 return 0;
436}
NORM_TYPES
Available Ambisonic normalisation conventions.
Definition _common.h:78
@ NORM_SN3D
Schmidt semi-normalisation (SN3D)
Definition _common.h:80
@ NORM_FUMA
(Legacy) Furse-Malham scaling
Definition _common.h:81
CH_ORDER
Available Ambisonic channel ordering conventions.
Definition _common.h:63
@ CH_ACN
Ambisonic Channel Numbering (ACN)
Definition _common.h:64
@ CH_FUMA
(Legacy) Furse-Malham/B-format (WXYZ)
Definition _common.h:65
#define MAX_NUM_SH_SIGNALS
Maximum number of spherical harmonic components/signals supported.
Definition _common.h:243
SH_ORDERS
Available spherical harmonic (SH) input/output order options.
Definition _common.h:42
@ SH_ORDER_FIRST
First-order (4 channels)
Definition _common.h:43
void convertHOAChannelConvention(float *insig, int order, int signalLength, HOA_CH_ORDER inConvention, HOA_CH_ORDER outConvention)
Converts an Ambisonic signal from one channel ordering convention to another.
Definition saf_hoa.c:41
@ HOA_CH_ORDER_FUMA
Furse-Malham (FuMa) convention, often used by older recordings.
Definition saf_hoa.h:187
@ HOA_CH_ORDER_ACN
Ambisonic Channel numbering (ACN) convention, which is employed by all spherical harmonic related fun...
Definition saf_hoa.h:184
#define ORDER2NSH(order)
Converts spherical harmonic order to number of spherical harmonic components i.e: (order+1)^2.
Definition saf_sh.h:51
void getSHrotMtxReal(float Rxyz[3][3], float *RotMtx, int L)
Generates a real-valued spherical harmonic rotation matrix [1] based on a 3x3 rotation matrix (see qu...
Definition saf_sh.c:586
void utility_svvmul(const float *a, const float *b, const int len, float *c)
Single-precision, element-wise vector-vector multiplication i.e.
#define DEG2RAD(x)
Converts degrees to radians.
void quaternion2rotationMatrix(quaternion_data *Q, float R[3][3])
Constructs a 3x3 rotation matrix based on a quaternion.
void euler2Quaternion(float alpha, float beta, float gamma, int degreesFlag, EULER_ROTATION_CONVENTIONS convention, quaternion_data *Q)
Converts Euler angles to a quaternion.
void quaternion2euler(quaternion_data *Q, int degreesFlag, EULER_ROTATION_CONVENTIONS convention, float *alpha, float *beta, float *gamma)
Converts a quaternion to Euler angles.
void utility_svvcopy(const float *a, const int len, float *c)
Single-precision, vector-vector copy, i.e.
#define SAF_MIN(a, b)
Returns the minimum of the two values.
void yawPitchRoll2Rzyx(float yaw, float pitch, float roll, int rollPitchYawFLAG, float R[3][3])
Constructs a 3x3 rotation matrix from the Euler angles, using the yaw-pitch-roll (zyx) convention.
#define RAD2DEG(x)
Converts radians to degrees.
@ EULER_ROTATION_YAW_PITCH_ROLL
yaw-pitch-roll, 'zyx'
@ EULER_ROTATION_ROLL_PITCH_YAW
roll-pitch-yaw, 'xyz'
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
Definition md_malloc.c:59
void rotator_setQuaternionW(void *const hRot, float newValue)
Sets the quaternion 'W' value [-1..1].
Definition rotator.c:231
int rotator_getRPYflag(void *const hRot)
Returns a flag as to whether to use "yaw-pitch-roll" (0) or "roll-pitch-yaw" (1) rotation order.
Definition rotator.c:403
int rotator_getNSHrequired(void *const hRot)
Returns the number of spherical harmonic signals required by the current input/output order: (current...
Definition rotator.c:427
int rotator_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
Definition rotator.c:332
int rotator_getNormType(void *const hRot)
Returns the Ambisonic normalisation convention currently being usedto decode with,...
Definition rotator.c:415
void rotator_setPitch(void *const hRot, float newPitch)
Sets the 'pitch' rotation angle, in DEGREES.
Definition rotator.c:217
float rotator_getQuaternionY(void *const hRot)
Returns the quaternion 'Y' value [-1..1].
Definition rotator.c:367
void rotator_setFlipPitch(void *const hRot, int newState)
Sets a flag as to whether to "flip" the sign of the current 'pitch' angle (0: do not flip sign,...
Definition rotator.c:268
void rotator_create(void **const phRot)
Creates an instance of rotator.
Definition rotator.c:38
void rotator_setFlipRoll(void *const hRot, int newState)
Sets a flag as to whether to "flip" the sign of the current 'roll' angle (0: do not flip sign,...
Definition rotator.c:277
int rotator_getProcessingDelay(void)
Returns the processing delay in samples (may be used for delay compensation features)
Definition rotator.c:433
float rotator_getQuaternionW(void *const hRot)
Returns the quaternion 'W' value [-1..1].
Definition rotator.c:355
int rotator_getFlipRoll(void *const hRot)
Returns a flag as to whether to "flip" the sign of the current 'roll' angle (0: do not flip sign,...
Definition rotator.c:391
void rotator_setRPYflag(void *const hRot, int newState)
Sets a flag as to whether to use "yaw-pitch-roll" (0) or "roll-pitch-yaw" (1) rotation order.
Definition rotator.c:297
float rotator_getQuaternionZ(void *const hRot)
Returns the quaternion 'Z' value [-1..1].
Definition rotator.c:373
float rotator_getPitch(void *const hRot)
Returns the 'pitch' rotation angle, in DEGREES.
Definition rotator.c:343
int rotator_getChOrder(void *const hRot)
Returns the Ambisonic channel ordering convention currently being used to decode with,...
Definition rotator.c:409
void rotator_destroy(void **const phRot)
Destroys an instance of rotator.
Definition rotator.c:67
void rotator_setQuaternionZ(void *const hRot, float newValue)
Sets the quaternion 'Z' value [-1..1].
Definition rotator.c:252
float rotator_getYaw(void *const hRot)
Returns the 'yaw' rotation angle, in DEGREES.
Definition rotator.c:337
void rotator_process(void *const hRot, const float *const *inputs, float *const *const outputs, int nInputs, int nOutputs, int nSamples)
Rotates the input spherical harmonic signals.
Definition rotator.c:101
int rotator_getOrder(void *const hRot)
Returns the input/output order (see SH_ORDERS enum)
Definition rotator.c:421
int rotator_getFlipYaw(void *const hRot)
Returns a flag as to whether to "flip" the sign of the current 'yaw' angle (0: do not flip sign,...
Definition rotator.c:379
void rotator_setRoll(void *const hRot, float newRoll)
Sets the 'roll' rotation angle , in DEGREES.
Definition rotator.c:224
float rotator_getRoll(void *const hRot)
Returns the 'roll' rotation angle, in DEGREES.
Definition rotator.c:349
int rotator_getFlipQuaternion(void *const hRot)
Returns a flag as to whether to invert the quaternion used for rotation (0: do not flip sign,...
Definition rotator.c:397
void rotator_setQuaternionX(void *const hRot, float newValue)
Sets the quaternion 'X' value [-1..1].
Definition rotator.c:238
void rotator_init(void *const hRot, int sampleRate)
Initialises an instance of rotator with default settings.
Definition rotator.c:80
void rotator_setNormType(void *const hRot, int newType)
Sets the Ambisonic normalisation convention to decode with, in order to match with the convention emp...
Definition rotator.c:310
void rotator_setChOrder(void *const hRot, int newOrder)
Sets the Ambisonic channel ordering convention to decode with, in order to match the convention emplo...
Definition rotator.c:303
float rotator_getQuaternionX(void *const hRot)
Returns the quaternion 'X' value [-1..1].
Definition rotator.c:361
void rotator_setFlipYaw(void *const hRot, int newState)
Sets a flag as to whether to "flip" the sign of the current 'yaw' angle (0: do not flip sign,...
Definition rotator.c:259
void rotator_setQuaternionY(void *const hRot, float newValue)
Sets the quaternion 'Y' value [-1..1].
Definition rotator.c:245
int rotator_getFlipPitch(void *const hRot)
Returns a flag as to whether to "flip" the sign of the current 'pitch' angle (0: do not flip sign,...
Definition rotator.c:385
void rotator_setYaw(void *const hRot, float newYaw)
Sets the 'yaw' rotation angle, in DEGREES.
Definition rotator.c:210
void rotator_setFlipQuaternion(void *const hRot, int newState)
Sets a flag as to whether to invert the quaternion used for rotation (0: do not flip sign,...
Definition rotator.c:286
void rotator_setOrder(void *const hRot, int newOrder)
Sets the input/output order (see SH_ORDERS enum)
Definition rotator.c:317
A basic spherical harmonic/ Ambisonic signals rotator, based on the recursive approach detailed in [1...
A basic spherical harmonic/ Ambisonic signals rotator, based on the recursive approach detailed in [1...
@ M_ROT_READY
M_rot is ready.
@ M_ROT_RECOMPUTE_QUATERNION
Use Quaternions to recompute M_rot.
@ M_ROT_RECOMPUTE_EULER
Use Euler angles to recompute M_rot.
#define ROTATOR_FRAME_SIZE
Framesize, in time-domain samples.
_Atomic_FLOAT32 z
Z value of the quaternion [-1..1].
_Atomic_FLOAT32 y
Y value of the quaternion [-1..1].
_Atomic_FLOAT32 x
X value of the quaternion [-1..1].
_Atomic_FLOAT32 w
W value of the quaternion [-1..1].
Main struct for the rotator.
float tempFrame_fadeOut[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Temporary frame with linear interpolation (fade-out) applied.
_Atomic_INT32 bFlipYaw
flag to flip the sign of the yaw rotation angle
_Atomic_INT32 useRollPitchYawFlag
rotation order flag, 1: r-p-y, 0: y-p-r
float M_rot[MAX_NUM_SH_SIGNALS][MAX_NUM_SH_SIGNALS]
Current SH rotation matrix [1].
float outputFrameTD_fadeIn[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Output frame of SH signals with linear interpolation (fade-in) applied.
_Atomic_FLOAT32 roll
roll (Euler) rotation angle, in degrees
float interpolator_fadeOut[ROTATOR_FRAME_SIZE]
Linear Interpolator (fade-out)
_Atomic_FLOAT32 yaw
yaw (Euler) rotation angle, in degrees
float inputFrameTD[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Input frame of signals.
_Atomic_CH_ORDER chOrdering
Ambisonic channel order convention (see CH_ORDER)
int fs
Host sampling rate, in Hz.
_Atomic_SH_ORDERS inputOrder
current input/output SH order
quaternion_data Q
Quaternion used for rotation.
_Atomic_M_ROT_STATUS M_rot_status
see M_ROT_STATUS
_Atomic_INT32 bFlipQuaternion
1: invert quaternion, 0: no inversion
float prev_M_rot[MAX_NUM_SH_SIGNALS][MAX_NUM_SH_SIGNALS]
Previous SH rotation matrix [1].
_Atomic_INT32 bFlipPitch
flag to flip the sign of the pitch rotation angle
float interpolator_fadeIn[ROTATOR_FRAME_SIZE]
Linear Interpolator (fade-in)
_Atomic_INT32 bFlipRoll
flag to flip the sign of the roll rotation angle
float outputFrameTD[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Output frame of SH signals.
_Atomic_FLOAT32 pitch
pitch (Euler) rotation angle, in degrees
_Atomic_NORM_TYPES norm
Ambisonic normalisation convention (see NORM_TYPES)
float tempFrame[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Temporary frame.