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
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 memset(pData->prev_inputFrameTD, 0, MAX_NUM_SH_SIGNALS*ROTATOR_FRAME_SIZE*sizeof(float));
98 pData->M_rot_status = M_ROT_RECOMPUTE_EULER;//M_ROT_RECOMPUTE_QUATERNION;
99}
100
102(
103 void * const hRot,
104 const float *const * inputs,
105 float* const* const outputs,
106 int nInputs,
107 int nOutputs,
108 int nSamples
109)
110{
111 rotator_data *pData = (rotator_data*)(hRot);
112 int i, j, order, nSH, mixWithPreviousFLAG;
113 float Rxyz[3][3];
114 float M_rot_tmp[MAX_NUM_SH_SIGNALS*MAX_NUM_SH_SIGNALS];
115 CH_ORDER chOrdering;
116
117 /* locals */
118 chOrdering = pData->chOrdering;
119 order = (int)pData->inputOrder;
120 nSH = ORDER2NSH(order);
121
122 if (nSamples == ROTATOR_FRAME_SIZE) {
123
124 /* Load time-domain data */
125 for(i=0; i < SAF_MIN(nSH, nInputs); i++)
126 utility_svvcopy(inputs[i], ROTATOR_FRAME_SIZE, pData->inputFrameTD[i]);
127 for(; i<MAX_NUM_SH_SIGNALS; i++)
128 memset(pData->inputFrameTD[i], 0, ROTATOR_FRAME_SIZE * sizeof(float)); /* fill remaining channels with zeros */
129
130 /* account for channel order */
131 switch(chOrdering){
132 case CH_ACN: /* already ACN */ break; /* Otherwise, convert to ACN... */
134 }
135
136 if (order>0){
137 /* calculate rotation matrix */
138 mixWithPreviousFLAG = 0;
139 if(pData->M_rot_status != M_ROT_READY){
140 memset(pData->M_rot, 0, MAX_NUM_SH_SIGNALS*MAX_NUM_SH_SIGNALS*sizeof(float));
142 yawPitchRoll2Rzyx (pData->yaw, pData->pitch, pData->roll, pData->useRollPitchYawFlag, Rxyz);
143 euler2Quaternion(pData->yaw, pData->pitch, pData->roll, 0,
145 }
146 else {/* M_ROT_RECOMPUTE_QUATERNION */
147 quaternion2rotationMatrix(&(pData->Q), Rxyz);
149 &(pData->yaw), &(pData->pitch), &(pData->roll));
150 }
151 getSHrotMtxReal(Rxyz, (float*)M_rot_tmp, order);
152 for(i=0; i<nSH; i++)
153 for(j=0; j<nSH; j++)
154 pData->M_rot[i][j] = M_rot_tmp[i*nSH+j];
155 mixWithPreviousFLAG = 1;
156 pData->M_rot_status = M_ROT_READY;
157 }
158
159 /* apply rotation */
160 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, ROTATOR_FRAME_SIZE, nSH, 1.0f,
161 (float*)(pData->M_rot), MAX_NUM_SH_SIGNALS,
162 (float*)pData->prev_inputFrameTD, ROTATOR_FRAME_SIZE, 0.0f,
163 (float*)pData->outputFrameTD, ROTATOR_FRAME_SIZE);
164
165 /* Fade between (linearly inerpolate) the new rotation matrix and the previous rotation matrix (only if the new rotation matrix is different) */
166 if(mixWithPreviousFLAG){
167 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSH, ROTATOR_FRAME_SIZE, nSH, 1.0f,
168 (float*)pData->prev_M_rot, MAX_NUM_SH_SIGNALS,
169 (float*)pData->prev_inputFrameTD, ROTATOR_FRAME_SIZE, 0.0f,
170 (float*)pData->tempFrame, ROTATOR_FRAME_SIZE);
171
172 /* Apply the linear interpolation */
173 for (i=0; i < nSH; i++){
174 utility_svvmul((float*)pData->interpolator_fadeIn, (float*)pData->outputFrameTD[i], ROTATOR_FRAME_SIZE, (float*)pData->outputFrameTD_fadeIn[i]);
175 utility_svvmul((float*)pData->interpolator_fadeOut, (float*)pData->tempFrame[i], ROTATOR_FRAME_SIZE, (float*)pData->tempFrame_fadeOut[i]);
176 }
177 cblas_scopy(nSH*ROTATOR_FRAME_SIZE, (float*)pData->outputFrameTD_fadeIn, 1, (float*)pData->outputFrameTD, 1);
178 cblas_saxpy(nSH*ROTATOR_FRAME_SIZE, 1.0f, (float*)pData->tempFrame_fadeOut, 1, (float*)pData->outputFrameTD, 1);
179
180 /* for next frame */
181 utility_svvcopy((const float*)pData->M_rot, MAX_NUM_SH_SIGNALS*MAX_NUM_SH_SIGNALS, (float*)pData->prev_M_rot);
182 }
183
184 /* for next frame */
186 }
187 else /* Pass-through the omni (cannot be rotated...) */
188 utility_svvcopy((const float*)pData->inputFrameTD[0], ROTATOR_FRAME_SIZE, (float*)pData->outputFrameTD[0]);
189
190 /* account for channel order */
191 switch(chOrdering){
192 case CH_ACN: /* do nothing */ break;
194 }
195
196 /* Copy to output */
197 for (i = 0; i < SAF_MIN(nSH, nOutputs); i++)
198 utility_svvcopy(pData->outputFrameTD[i], ROTATOR_FRAME_SIZE, outputs[i]);
199 for (; i < nOutputs; i++)
200 memset(outputs[i], 0, ROTATOR_FRAME_SIZE*sizeof(float));
201 }
202 else{
203 for (i = 0; i < nOutputs; i++)
204 memset(outputs[i], 0, ROTATOR_FRAME_SIZE*sizeof(float));
205 }
206}
207
208
209/*sets*/
210
211void rotator_setYaw(void* const hRot, float newYaw)
212{
213 rotator_data *pData = (rotator_data*)(hRot);
214 pData->yaw = pData->bFlipYaw == 1 ? -DEG2RAD(newYaw) : DEG2RAD(newYaw);
216}
217
218void rotator_setPitch(void* const hRot, float newPitch)
219{
220 rotator_data *pData = (rotator_data*)(hRot);
221 pData->pitch = pData->bFlipPitch == 1 ? -DEG2RAD(newPitch) : DEG2RAD(newPitch);
223}
224
225void rotator_setRoll(void* const hRot, float newRoll)
226{
227 rotator_data *pData = (rotator_data*)(hRot);
228 pData->roll = pData->bFlipRoll == 1 ? -DEG2RAD(newRoll) : DEG2RAD(newRoll);
230}
231
232void rotator_setQuaternionW(void* const hRot, float newValue)
233{
234 rotator_data *pData = (rotator_data*)(hRot);
235 pData->Q.w = newValue;
237}
238
239void rotator_setQuaternionX(void* const hRot, float newValue)
240{
241 rotator_data *pData = (rotator_data*)(hRot);
242 pData->Q.x = pData->bFlipQuaternion == 1 ? -newValue : newValue;
244}
245
246void rotator_setQuaternionY(void* const hRot, float newValue)
247{
248 rotator_data *pData = (rotator_data*)(hRot);
249 pData->Q.y = pData->bFlipQuaternion == 1 ? -newValue : newValue;
251}
252
253void rotator_setQuaternionZ(void* const hRot, float newValue)
254{
255 rotator_data *pData = (rotator_data*)(hRot);
256 pData->Q.z = pData->bFlipQuaternion == 1 ? -newValue : newValue;
258}
259
260void rotator_setFlipYaw(void* const hRot, int newState)
261{
262 rotator_data *pData = (rotator_data*)(hRot);
263 if(newState !=pData->bFlipYaw ){
264 pData->bFlipYaw = newState;
265 rotator_setYaw(hRot, -rotator_getYaw(hRot));
266 }
267}
268
269void rotator_setFlipPitch(void* const hRot, int newState)
270{
271 rotator_data *pData = (rotator_data*)(hRot);
272 if(newState !=pData->bFlipPitch ){
273 pData->bFlipPitch = newState;
275 }
276}
277
278void rotator_setFlipRoll(void* const hRot, int newState)
279{
280 rotator_data *pData = (rotator_data*)(hRot);
281 if(newState !=pData->bFlipRoll ){
282 pData->bFlipRoll = newState;
283 rotator_setRoll(hRot, -rotator_getRoll(hRot));
284 }
285}
286
287void rotator_setFlipQuaternion(void* const hRot, int newState)
288{
289 rotator_data *pData = (rotator_data*)(hRot);
290 if(newState !=pData->bFlipQuaternion ){
291 pData->bFlipQuaternion = newState;
295 }
296}
297
298void rotator_setRPYflag(void* const hRot, int newState)
299{
300 rotator_data *pData = (rotator_data*)(hRot);
301 pData->useRollPitchYawFlag = newState;
302}
303
304void rotator_setChOrder(void* const hRot, int newOrder)
305{
306 rotator_data *pData = (rotator_data*)(hRot);
307 if((CH_ORDER)newOrder != CH_FUMA || pData->inputOrder==SH_ORDER_FIRST)/* FUMA only supports 1st order */
308 pData->chOrdering = (CH_ORDER)newOrder;
309}
310
311void rotator_setNormType(void* const hRot, int newType)
312{
313 rotator_data *pData = (rotator_data*)(hRot);
314 if((NORM_TYPES)newType != NORM_FUMA || pData->inputOrder==SH_ORDER_FIRST)/* FUMA only supports 1st order */
315 pData->norm = (NORM_TYPES)newType;
316}
317
318void rotator_setOrder(void* const hRot, int newOrder)
319{
320 rotator_data *pData = (rotator_data*)(hRot);
321 pData->inputOrder = (SH_ORDERS)newOrder;
323 /* FUMA only supports 1st order */
324 if(pData->inputOrder!=SH_ORDER_FIRST && pData->chOrdering == CH_FUMA)
325 pData->chOrdering = CH_ACN;
326 if(pData->inputOrder!=SH_ORDER_FIRST && pData->norm == NORM_FUMA)
327 pData->norm = NORM_SN3D;
328}
329
330
331/*gets*/
332
334{
335 return ROTATOR_FRAME_SIZE;
336}
337
338float rotator_getYaw(void* const hRot)
339{
340 rotator_data *pData = (rotator_data*)(hRot);
341 return pData->bFlipYaw == 1 ? -RAD2DEG(pData->yaw) : RAD2DEG(pData->yaw);
342}
343
344float rotator_getPitch(void* const hRot)
345{
346 rotator_data *pData = (rotator_data*)(hRot);
347 return pData->bFlipPitch == 1 ? -RAD2DEG(pData->pitch) : RAD2DEG(pData->pitch);
348}
349
350float rotator_getRoll(void* const hRot)
351{
352 rotator_data *pData = (rotator_data*)(hRot);
353 return pData->bFlipRoll == 1 ? -RAD2DEG(pData->roll) : RAD2DEG(pData->roll);
354}
355
356float rotator_getQuaternionW(void* const hRot)
357{
358 rotator_data *pData = (rotator_data*)(hRot);
359 return pData->Q.w;
360}
361
362float rotator_getQuaternionX(void* const hRot)
363{
364 rotator_data *pData = (rotator_data*)(hRot);
365 return pData->bFlipQuaternion == 1 ? -(pData->Q.x) : pData->Q.x;
366}
367
368float rotator_getQuaternionY(void* const hRot)
369{
370 rotator_data *pData = (rotator_data*)(hRot);
371 return pData->bFlipQuaternion == 1 ? -(pData->Q.y) : pData->Q.y;
372}
373
374float rotator_getQuaternionZ(void* const hRot)
375{
376 rotator_data *pData = (rotator_data*)(hRot);
377 return pData->bFlipQuaternion == 1 ? -(pData->Q.z) : pData->Q.z;
378}
379
380int rotator_getFlipYaw(void* const hRot)
381{
382 rotator_data *pData = (rotator_data*)(hRot);
383 return pData->bFlipYaw;
384}
385
386int rotator_getFlipPitch(void* const hRot)
387{
388 rotator_data *pData = (rotator_data*)(hRot);
389 return pData->bFlipPitch;
390}
391
392int rotator_getFlipRoll(void* const hRot)
393{
394 rotator_data *pData = (rotator_data*)(hRot);
395 return pData->bFlipRoll;
396}
397
398int rotator_getFlipQuaternion(void* const hRot)
399{
400 rotator_data *pData = (rotator_data*)(hRot);
401 return pData->bFlipQuaternion;
402}
403
404int rotator_getRPYflag(void* const hRot)
405{
406 rotator_data *pData = (rotator_data*)(hRot);
407 return pData->useRollPitchYawFlag;
408}
409
410int rotator_getChOrder(void* const hRot)
411{
412 rotator_data *pData = (rotator_data*)(hRot);
413 return (int)pData->chOrdering;
414}
415
416int rotator_getNormType(void* const hRot)
417{
418 rotator_data *pData = (rotator_data*)(hRot);
419 return (int)pData->norm;
420}
421
422int rotator_getOrder(void* const hRot)
423{
424 rotator_data *pData = (rotator_data*)(hRot);
425 return (int)pData->inputOrder;
426}
427
428int rotator_getNSHrequired(void* const hRot)
429{
430 rotator_data *pData = (rotator_data*)(hRot);
431 return (pData->inputOrder+1)*(pData->inputOrder+1);
432}
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:232
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:404
int rotator_getNSHrequired(void *const hRot)
Returns the number of spherical harmonic signals required by the current input/output order: (current...
Definition rotator.c:428
int rotator_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
Definition rotator.c:333
int rotator_getNormType(void *const hRot)
Returns the Ambisonic normalisation convention currently being usedto decode with,...
Definition rotator.c:416
void rotator_setPitch(void *const hRot, float newPitch)
Sets the 'pitch' rotation angle, in DEGREES.
Definition rotator.c:218
float rotator_getQuaternionY(void *const hRot)
Returns the quaternion 'Y' value [-1..1].
Definition rotator.c:368
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:269
void rotator_create(void **const phRot)
Creates an instance of rotator.
Definition rotator.c:38
int rotator_getProcessingDelay()
Returns the processing delay in samples (may be used for delay compensation features)
Definition rotator.c:434
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:278
float rotator_getQuaternionW(void *const hRot)
Returns the quaternion 'W' value [-1..1].
Definition rotator.c:356
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:392
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:298
float rotator_getQuaternionZ(void *const hRot)
Returns the quaternion 'Z' value [-1..1].
Definition rotator.c:374
float rotator_getPitch(void *const hRot)
Returns the 'pitch' rotation angle, in DEGREES.
Definition rotator.c:344
int rotator_getChOrder(void *const hRot)
Returns the Ambisonic channel ordering convention currently being used to decode with,...
Definition rotator.c:410
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:253
float rotator_getYaw(void *const hRot)
Returns the 'yaw' rotation angle, in DEGREES.
Definition rotator.c:338
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:102
int rotator_getOrder(void *const hRot)
Returns the input/output order (see SH_ORDERS enum)
Definition rotator.c:422
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:380
void rotator_setRoll(void *const hRot, float newRoll)
Sets the 'roll' rotation angle , in DEGREES.
Definition rotator.c:225
float rotator_getRoll(void *const hRot)
Returns the 'roll' rotation angle, in DEGREES.
Definition rotator.c:350
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:398
void rotator_setQuaternionX(void *const hRot, float newValue)
Sets the quaternion 'X' value [-1..1].
Definition rotator.c:239
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:311
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:304
float rotator_getQuaternionX(void *const hRot)
Returns the quaternion 'X' value [-1..1].
Definition rotator.c:362
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:260
void rotator_setQuaternionY(void *const hRot, float newValue)
Sets the quaternion 'Y' value [-1..1].
Definition rotator.c:246
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:386
void rotator_setYaw(void *const hRot, float newYaw)
Sets the 'yaw' rotation angle, in DEGREES.
Definition rotator.c:211
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:287
void rotator_setOrder(void *const hRot, int newOrder)
Sets the input/output order (see SH_ORDERS enum)
Definition rotator.c:318
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 prev_inputFrameTD[MAX_NUM_SH_SIGNALS][ROTATOR_FRAME_SIZE]
Previous frame of signals.
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