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];
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 &(pData->yaw), &(pData->pitch), &(pData->roll));
149 }
150 getSHrotMtxReal(Rxyz, (float*)M_rot_tmp, order);
151 for(i=0; i<nSH; i++)
152 for(j=0; j<nSH; j++)
153 pData->M_rot[i][j] = M_rot_tmp[i*nSH+j];
154 mixWithPreviousFLAG = 1;
155 pData->M_rot_status = M_ROT_READY;
156 }
157
158 /* apply rotation */
159 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, ROTATOR_FRAME_SIZE, nSH, 1.0f,
160 (float*)(pData->M_rot), MAX_NUM_SH_SIGNALS,
161 (float*)pData->inputFrameTD, ROTATOR_FRAME_SIZE, 0.0f,
162 (float*)pData->outputFrameTD, ROTATOR_FRAME_SIZE);
163
164 /* Fade between (linearly inerpolate) the new rotation matrix and the previous rotation matrix (only if the new rotation matrix is different) */
165 if(mixWithPreviousFLAG){
166 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, ROTATOR_FRAME_SIZE, nSH, 1.0f,
167 (float*)pData->prev_M_rot, MAX_NUM_SH_SIGNALS,
168 (float*)pData->inputFrameTD, ROTATOR_FRAME_SIZE, 0.0f,
169 (float*)pData->tempFrame, ROTATOR_FRAME_SIZE);
170
171 /* Apply the linear interpolation */
172 for (i=0; i < nSH; i++){
173 utility_svvmul((float*)pData->interpolator_fadeIn, (float*)pData->outputFrameTD[i], ROTATOR_FRAME_SIZE, (float*)pData->outputFrameTD_fadeIn[i]);
174 utility_svvmul((float*)pData->interpolator_fadeOut, (float*)pData->tempFrame[i], ROTATOR_FRAME_SIZE, (float*)pData->tempFrame_fadeOut[i]);
175 }
176 cblas_scopy(nSH*ROTATOR_FRAME_SIZE, (float*)pData->outputFrameTD_fadeIn, 1, (float*)pData->outputFrameTD, 1);
177 cblas_saxpy(nSH*ROTATOR_FRAME_SIZE, 1.0f, (float*)pData->tempFrame_fadeOut, 1, (float*)pData->outputFrameTD, 1);
178
179 /* for next frame */
180 utility_svvcopy((const float*)pData->M_rot, MAX_NUM_SH_SIGNALS*MAX_NUM_SH_SIGNALS, (float*)pData->prev_M_rot);
181 }
182 }
183 else /* Pass-through the omni (cannot be rotated...) */
184 utility_svvcopy((const float*)pData->inputFrameTD[0], ROTATOR_FRAME_SIZE, (float*)pData->outputFrameTD[0]);
185
186 /* account for channel order */
187 switch(chOrdering){
188 case CH_ACN: /* do nothing */ break;
190 }
191
192 /* Copy to output */
193 for (i = 0; i < SAF_MIN(nSH, nOutputs); i++)
194 utility_svvcopy(pData->outputFrameTD[i], ROTATOR_FRAME_SIZE, outputs[i]);
195 for (; i < nOutputs; i++)
196 memset(outputs[i], 0, ROTATOR_FRAME_SIZE*sizeof(float));
197 }
198 else{
199 for (i = 0; i < nOutputs; i++)
200 memset(outputs[i], 0, ROTATOR_FRAME_SIZE*sizeof(float));
201 }
202}
203
204
205/*sets*/
206
207void rotator_setYaw(void* const hRot, float newYaw)
208{
209 rotator_data *pData = (rotator_data*)(hRot);
210 pData->yaw = pData->bFlipYaw == 1 ? -DEG2RAD(newYaw) : DEG2RAD(newYaw);
212}
213
214void rotator_setPitch(void* const hRot, float newPitch)
215{
216 rotator_data *pData = (rotator_data*)(hRot);
217 pData->pitch = pData->bFlipPitch == 1 ? -DEG2RAD(newPitch) : DEG2RAD(newPitch);
219}
220
221void rotator_setRoll(void* const hRot, float newRoll)
222{
223 rotator_data *pData = (rotator_data*)(hRot);
224 pData->roll = pData->bFlipRoll == 1 ? -DEG2RAD(newRoll) : DEG2RAD(newRoll);
226}
227
228void rotator_setQuaternionW(void* const hRot, float newValue)
229{
230 rotator_data *pData = (rotator_data*)(hRot);
231 pData->Q.w = newValue;
233}
234
235void rotator_setQuaternionX(void* const hRot, float newValue)
236{
237 rotator_data *pData = (rotator_data*)(hRot);
238 pData->Q.x = pData->bFlipQuaternion == 1 ? -newValue : newValue;
240}
241
242void rotator_setQuaternionY(void* const hRot, float newValue)
243{
244 rotator_data *pData = (rotator_data*)(hRot);
245 pData->Q.y = pData->bFlipQuaternion == 1 ? -newValue : newValue;
247}
248
249void rotator_setQuaternionZ(void* const hRot, float newValue)
250{
251 rotator_data *pData = (rotator_data*)(hRot);
252 pData->Q.z = pData->bFlipQuaternion == 1 ? -newValue : newValue;
254}
255
256void rotator_setFlipYaw(void* const hRot, int newState)
257{
258 rotator_data *pData = (rotator_data*)(hRot);
259 if(newState !=pData->bFlipYaw ){
260 pData->bFlipYaw = newState;
261 rotator_setYaw(hRot, -rotator_getYaw(hRot));
262 }
263}
264
265void rotator_setFlipPitch(void* const hRot, int newState)
266{
267 rotator_data *pData = (rotator_data*)(hRot);
268 if(newState !=pData->bFlipPitch ){
269 pData->bFlipPitch = newState;
271 }
272}
273
274void rotator_setFlipRoll(void* const hRot, int newState)
275{
276 rotator_data *pData = (rotator_data*)(hRot);
277 if(newState !=pData->bFlipRoll ){
278 pData->bFlipRoll = newState;
279 rotator_setRoll(hRot, -rotator_getRoll(hRot));
280 }
281}
282
283void rotator_setFlipQuaternion(void* const hRot, int newState)
284{
285 rotator_data *pData = (rotator_data*)(hRot);
286 if(newState !=pData->bFlipQuaternion ){
287 pData->bFlipQuaternion = newState;
291 }
292}
293
294void rotator_setRPYflag(void* const hRot, int newState)
295{
296 rotator_data *pData = (rotator_data*)(hRot);
297 pData->useRollPitchYawFlag = newState;
298}
299
300void rotator_setChOrder(void* const hRot, int newOrder)
301{
302 rotator_data *pData = (rotator_data*)(hRot);
303 if((CH_ORDER)newOrder != CH_FUMA || pData->inputOrder==SH_ORDER_FIRST)/* FUMA only supports 1st order */
304 pData->chOrdering = (CH_ORDER)newOrder;
305}
306
307void rotator_setNormType(void* const hRot, int newType)
308{
309 rotator_data *pData = (rotator_data*)(hRot);
310 if((NORM_TYPES)newType != NORM_FUMA || pData->inputOrder==SH_ORDER_FIRST)/* FUMA only supports 1st order */
311 pData->norm = (NORM_TYPES)newType;
312}
313
314void rotator_setOrder(void* const hRot, int newOrder)
315{
316 rotator_data *pData = (rotator_data*)(hRot);
317 pData->inputOrder = (SH_ORDERS)newOrder;
319 /* FUMA only supports 1st order */
320 if(pData->inputOrder!=SH_ORDER_FIRST && pData->chOrdering == CH_FUMA)
321 pData->chOrdering = CH_ACN;
322 if(pData->inputOrder!=SH_ORDER_FIRST && pData->norm == NORM_FUMA)
323 pData->norm = NORM_SN3D;
324}
325
326
327/*gets*/
328
330{
331 return ROTATOR_FRAME_SIZE;
332}
333
334float rotator_getYaw(void* const hRot)
335{
336 rotator_data *pData = (rotator_data*)(hRot);
337 return pData->bFlipYaw == 1 ? -RAD2DEG(pData->yaw) : RAD2DEG(pData->yaw);
338}
339
340float rotator_getPitch(void* const hRot)
341{
342 rotator_data *pData = (rotator_data*)(hRot);
343 return pData->bFlipPitch == 1 ? -RAD2DEG(pData->pitch) : RAD2DEG(pData->pitch);
344}
345
346float rotator_getRoll(void* const hRot)
347{
348 rotator_data *pData = (rotator_data*)(hRot);
349 return pData->bFlipRoll == 1 ? -RAD2DEG(pData->roll) : RAD2DEG(pData->roll);
350}
351
352float rotator_getQuaternionW(void* const hRot)
353{
354 rotator_data *pData = (rotator_data*)(hRot);
355 return pData->Q.w;
356}
357
358float rotator_getQuaternionX(void* const hRot)
359{
360 rotator_data *pData = (rotator_data*)(hRot);
361 return pData->bFlipQuaternion == 1 ? -(pData->Q.x) : pData->Q.x;
362}
363
364float rotator_getQuaternionY(void* const hRot)
365{
366 rotator_data *pData = (rotator_data*)(hRot);
367 return pData->bFlipQuaternion == 1 ? -(pData->Q.y) : pData->Q.y;
368}
369
370float rotator_getQuaternionZ(void* const hRot)
371{
372 rotator_data *pData = (rotator_data*)(hRot);
373 return pData->bFlipQuaternion == 1 ? -(pData->Q.z) : pData->Q.z;
374}
375
376int rotator_getFlipYaw(void* const hRot)
377{
378 rotator_data *pData = (rotator_data*)(hRot);
379 return pData->bFlipYaw;
380}
381
382int rotator_getFlipPitch(void* const hRot)
383{
384 rotator_data *pData = (rotator_data*)(hRot);
385 return pData->bFlipPitch;
386}
387
388int rotator_getFlipRoll(void* const hRot)
389{
390 rotator_data *pData = (rotator_data*)(hRot);
391 return pData->bFlipRoll;
392}
393
394int rotator_getFlipQuaternion(void* const hRot)
395{
396 rotator_data *pData = (rotator_data*)(hRot);
397 return pData->bFlipQuaternion;
398}
399
400int rotator_getRPYflag(void* const hRot)
401{
402 rotator_data *pData = (rotator_data*)(hRot);
403 return pData->useRollPitchYawFlag;
404}
405
406int rotator_getChOrder(void* const hRot)
407{
408 rotator_data *pData = (rotator_data*)(hRot);
409 return (int)pData->chOrdering;
410}
411
412int rotator_getNormType(void* const hRot)
413{
414 rotator_data *pData = (rotator_data*)(hRot);
415 return (int)pData->norm;
416}
417
418int rotator_getOrder(void* const hRot)
419{
420 rotator_data *pData = (rotator_data*)(hRot);
421 return (int)pData->inputOrder;
422}
423
424int rotator_getNSHrequired(void* const hRot)
425{
426 rotator_data *pData = (rotator_data*)(hRot);
427 return (pData->inputOrder+1)*(pData->inputOrder+1);
428}
429
431{
432 return ROTATOR_FRAME_SIZE;
433}
NORM_TYPES
Available Ambisonic normalisation conventions.
Definition _common.h:74
@ NORM_SN3D
Schmidt semi-normalisation (SN3D)
Definition _common.h:76
@ NORM_FUMA
(Legacy) Furse-Malham scaling
Definition _common.h:77
CH_ORDER
Available Ambisonic channel ordering conventions.
Definition _common.h:59
@ CH_ACN
Ambisonic Channel Numbering (ACN)
Definition _common.h:60
@ CH_FUMA
(Legacy) Furse-Malham/B-format (WXYZ)
Definition _common.h:61
#define MAX_NUM_SH_SIGNALS
Maximum number of spherical harmonic components/signals supported.
Definition _common.h:239
SH_ORDERS
Available spherical harmonic (SH) input/output order options.
Definition _common.h:38
@ SH_ORDER_FIRST
First-order (4 channels)
Definition _common.h:39
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:228
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:400
int rotator_getNSHrequired(void *const hRot)
Returns the number of spherical harmonic signals required by the current input/output order: (current...
Definition rotator.c:424
int rotator_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
Definition rotator.c:329
int rotator_getNormType(void *const hRot)
Returns the Ambisonic normalisation convention currently being usedto decode with,...
Definition rotator.c:412
void rotator_setPitch(void *const hRot, float newPitch)
Sets the 'pitch' rotation angle, in DEGREES.
Definition rotator.c:214
float rotator_getQuaternionY(void *const hRot)
Returns the quaternion 'Y' value [-1..1].
Definition rotator.c:364
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:265
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:274
int rotator_getProcessingDelay(void)
Returns the processing delay in samples (may be used for delay compensation features)
Definition rotator.c:430
float rotator_getQuaternionW(void *const hRot)
Returns the quaternion 'W' value [-1..1].
Definition rotator.c:352
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:388
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:294
float rotator_getQuaternionZ(void *const hRot)
Returns the quaternion 'Z' value [-1..1].
Definition rotator.c:370
float rotator_getPitch(void *const hRot)
Returns the 'pitch' rotation angle, in DEGREES.
Definition rotator.c:340
int rotator_getChOrder(void *const hRot)
Returns the Ambisonic channel ordering convention currently being used to decode with,...
Definition rotator.c:406
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:249
float rotator_getYaw(void *const hRot)
Returns the 'yaw' rotation angle, in DEGREES.
Definition rotator.c:334
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:418
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:376
void rotator_setRoll(void *const hRot, float newRoll)
Sets the 'roll' rotation angle , in DEGREES.
Definition rotator.c:221
float rotator_getRoll(void *const hRot)
Returns the 'roll' rotation angle, in DEGREES.
Definition rotator.c:346
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:394
void rotator_setQuaternionX(void *const hRot, float newValue)
Sets the quaternion 'X' value [-1..1].
Definition rotator.c:235
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:307
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:300
float rotator_getQuaternionX(void *const hRot)
Returns the quaternion 'X' value [-1..1].
Definition rotator.c:358
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:256
void rotator_setQuaternionY(void *const hRot, float newValue)
Sets the quaternion 'Y' value [-1..1].
Definition rotator.c:242
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:382
void rotator_setYaw(void *const hRot, float newYaw)
Sets the 'yaw' rotation angle, in DEGREES.
Definition rotator.c:207
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:283
void rotator_setOrder(void *const hRot, int newOrder)
Sets the input/output order (see SH_ORDERS enum)
Definition rotator.c:314
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.
float x
X value of the quaternion [-1..1].
float z
Z value of the quaternion [-1..1].
float y
Y value of the quaternion [-1..1].
float 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.
float pitch
pitch (Euler) rotation angle, in degrees
int bFlipRoll
flag to flip the sign of the roll rotation angle
float M_rot[MAX_NUM_SH_SIGNALS][MAX_NUM_SH_SIGNALS]
Current SH rotation matrix [1].
int useRollPitchYawFlag
rotation order flag, 1: r-p-y, 0: y-p-r
M_ROT_STATUS M_rot_status
see M_ROT_STATUS
NORM_TYPES norm
Ambisonic normalisation convention (see NORM_TYPES)
float outputFrameTD_fadeIn[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Output frame of SH signals with linear interpolation (fade-in) applied.
float interpolator_fadeOut[ROTATOR_FRAME_SIZE]
Linear Interpolator (fade-out)
float inputFrameTD[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Input frame of signals.
float roll
roll (Euler) rotation angle, in degrees
SH_ORDERS inputOrder
current input/output SH order
int bFlipQuaternion
1: invert quaternion, 0: no inversion
float yaw
yaw (Euler) rotation angle, in degrees
int bFlipYaw
flag to flip the sign of the yaw rotation angle
int fs
Host sampling rate, in Hz.
quaternion_data Q
Quaternion used for rotation.
CH_ORDER chOrdering
Ambisonic channel order convention (see CH_ORDER)
float prev_M_rot[MAX_NUM_SH_SIGNALS][MAX_NUM_SH_SIGNALS]
Previous SH rotation matrix [1].
float interpolator_fadeIn[ROTATOR_FRAME_SIZE]
Linear Interpolator (fade-in)
float outputFrameTD[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Output frame of SH signals.
float tempFrame[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Temporary frame.
int bFlipPitch
flag to flip the sign of the pitch rotation angle