52 *phPan = (
void*)pData;
105 if(pData->
hSTFT !=NULL)
129 pData->
fs = sampleRate;
178 const float *
const * inputs,
179 float*
const*
const outputs,
186 int t, ch, ls, i, band, nSources, nLoudspeakers, N_azi, aziIndex, elevIndex, idx3d, idx2D;
187 float aziRes, elevRes, pv_f, gains3D_sum_pvf, gains2D_sum_pvf, Rxyz[3][3], hypotxy;
189 const float_complex calpha = cmplxf(1.0f, 0.0f), cbeta = cmplxf(0.0f, 0.0f);
203 for(i=0; i <
SAF_MIN(nSources,nInputs); i++)
216 for(i=0; i<nSources; i++){
222 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSources, 3, 3, 1.0f,
224 (
float*)Rxyz, 3, 0.0f,
226 for(i=0; i<nSources; i++){
238 N_azi = (int)(360.0f / aziRes + 0.5f) + 1;
239 for (ch = 0; ch < nSources; ch++) {
245 elevIndex = (int)((pData->
src_dirs_rot_deg[ch][1] + 90.0f) / elevRes + 0.5f);
246 idx3d = elevIndex * N_azi + aziIndex;
247 for (ls = 0; ls < nLoudspeakers; ls++)
248 gains3D[ls] = pData->
vbap_gtable[idx3d*nLoudspeakers+ls];
251 pv_f = pData->
pValue[band];
253 gains3D_sum_pvf = 0.0f;
254 for (ls = 0; ls < nLoudspeakers; ls++)
255 gains3D_sum_pvf += powf(
SAF_MAX(gains3D[ls], 0.0f), pv_f);
256 gains3D_sum_pvf = powf(gains3D_sum_pvf, 1.0f/(pv_f+2.23e-9f));
257 for (ls = 0; ls < nLoudspeakers; ls++)
258 pData->
G_src[band][ch][ls] = cmplxf(gains3D[ls] / (gains3D_sum_pvf+2.23e-9f), 0.0f);
261 for (ls = 0; ls < nLoudspeakers; ls++)
262 pData->
G_src[band][ch][ls] = cmplxf(gains3D[ls], 0.0f);
269 cblas_cgemm(CblasRowMajor, CblasTrans, CblasNoTrans, nLoudspeakers,
TIME_SLOTS, nSources, &calpha,
273 for (i = 0; i < nLoudspeakers; i++)
280 for (ch = 0; ch < nSources; ch++) {
285 for (ls = 0; ls < nLoudspeakers; ls++)
286 gains2D[ls] = pData->
vbap_gtable[idx2D*nLoudspeakers+ls];
289 pv_f = pData->
pValue[band];
291 gains2D_sum_pvf = 0.0f;
292 for (ls = 0; ls < nLoudspeakers; ls++)
293 gains2D_sum_pvf += powf(
SAF_MAX(gains2D[ls], 0.0f), pv_f);
294 gains2D_sum_pvf = powf(gains2D_sum_pvf, 1.0f/(pv_f+2.23e-9f));
295 for (ls = 0; ls < nLoudspeakers; ls++)
296 pData->
G_src[band][ch][ls] = cmplxf(gains2D[ls] / (gains2D_sum_pvf+2.23e-9f), 0.0f);
299 for (ls = 0; ls < nLoudspeakers; ls++)
300 pData->
G_src[band][ch][ls] = cmplxf(gains2D[ls], 0.0f);
307 for (ls = 0; ls < nLoudspeakers; ls++)
320 for (ch = 0; ch <
SAF_MIN(nLoudspeakers, nOutputs); ch++)
322 for (; ch < nOutputs; ch++)
327 for (ch=0; ch < nOutputs; ch++)
350 if(newAzi_deg>180.0f)
351 newAzi_deg = -360.0f + newAzi_deg;
352 newAzi_deg =
SAF_MAX(newAzi_deg, -180.0f);
353 newAzi_deg =
SAF_MIN(newAzi_deg, 180.0f);
364 newElev_deg =
SAF_MAX(newElev_deg, -90.0f);
365 newElev_deg =
SAF_MIN(newElev_deg, 90.0f);
379 if(pData->
nSources != new_nSources){
392 if(newAzi_deg>180.0f)
393 newAzi_deg = -360.0f + newAzi_deg;
394 newAzi_deg =
SAF_MAX(newAzi_deg, -180.0f);
395 newAzi_deg =
SAF_MIN(newAzi_deg, 180.0f);
410 newElev_deg =
SAF_MAX(newElev_deg, -90.0f);
411 newElev_deg =
SAF_MIN(newElev_deg, 90.0f);
465 if(pData->
DTT != newValue){
466 pData->
DTT = newValue;
#define MAX_NUM_INPUTS
Maximum number of input channels supported.
#define MAX_NUM_OUTPUTS
Maximum number of output channels supported.
#define PROGRESSBARTEXT_CHAR_LENGTH
Length of progress bar string.
@ PROC_STATUS_ONGOING
Codec is processing input audio, and should not be reinitialised at this time.
@ PROC_STATUS_NOT_ONGOING
Codec is not processing input audio, and may be reinitialised if needed.
CODEC_STATUS
Current status of the codec.
@ CODEC_STATUS_NOT_INITIALISED
Codec has not yet been initialised, or the codec configuration has changed.
@ CODEC_STATUS_INITIALISED
Codec is initialised and ready to process input audio.
@ CODEC_STATUS_INITIALISING
Codec is currently being initialised, input audio should not be processed.
void afSTFT_backward_knownDimensions(void *const hSTFT, float_complex ***dataFD, int framesize, int dataFD_nCH, int dataFD_nHops, float **dataTD)
Performs backward afSTFT transform (dataFD dimensions are known)
void afSTFT_forward_knownDimensions(void *const hSTFT, float **dataTD, int framesize, int dataFD_nCH, int dataFD_nHops, float_complex ***dataFD)
Performs forward afSTFT transform (dataFD dimensions are known)
void afSTFT_getCentreFreqs(void *const hSTFT, float fs, int nBands, float *freqVector)
Returns current frequency vector.
void afSTFT_destroy(void **const phSTFT)
Destroys an instance of afSTFT.
#define TIME_SLOTS
Number of STFT timeslots.
#define HOP_SIZE
STFT hop size.
#define HYBRID_BANDS
Number of frequency bands.
#define SAF_CLAMP(a, min, max)
Ensures value "a" is clamped between the "min" and "max" values.
#define DEG2RAD(x)
Converts degrees to radians.
#define SAF_MAX(a, b)
Returns the maximum of the two values.
float matlab_fmodf(float x, float y)
C fmodf function, except it behaves like 'mod' in Matlab (i.e.
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
void getPvalues(float DTT, float *freq, int nFreq, float *pValues)
Calculates the frequency dependent pValues, which can be applied to ENERGY normalised VBAP gains,...
void ** malloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D malloc (contiguously allocated, so use free() as usual to deallocate)
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
void *** malloc3d(size_t dim1, size_t dim2, size_t dim3, size_t data_size)
3-D malloc (contiguously allocated, so use free() as usual to deallocate)
#define FLATTEN2D(A)
Use this macro when passing a 2-D dynamic multi-dimensional array to memset, memcpy or any other func...
#define FLATTEN3D(A)
Use this macro when passing a 3-D dynamic multi-dimensional array to memset, memcpy or any other func...
void panner_setNumSources(void *const hPan, int new_nSources)
Sets the number of inputs/sources to pan.
void panner_process(void *const hPan, const float *const *inputs, float *const *const outputs, int nInputs, int nOutputs, int nSamples)
Pans the input signals/sources to the loudspeaker channels using VBAP [1], and optional spreading [2]...
void panner_setFlipPitch(void *const hBin, int newState)
Sets a flag as to whether to "flip" the sign of the current 'pitch' angle (0: do not flip sign,...
void panner_setLoudspeakerElev_deg(void *const hPan, int index, float newElev_deg)
Sets the elevation of a specific loudspeaker index, in DEGREES.
void panner_setFlipYaw(void *const hBin, int newState)
Sets a flag as to whether to "flip" the sign of the current 'yaw' angle (0: do not flip sign,...
float panner_getSourceAzi_deg(void *const hPan, int index)
Returns the input/source azimuth for a given index, in DEGREES.
float panner_getYaw(void *const hBin)
Returns the 'yaw' rotation angle, in DEGREES.
int panner_getFlipYaw(void *const hBin)
Returns a flag as to whether to "flip" the sign of the current 'yaw' angle (0: do not flip sign,...
int panner_getNumLoudspeakers(void *const hPan)
Returns the number of loudspeakers in the current layout.
float panner_getLoudspeakerAzi_deg(void *const hPan, int index)
Returns the loudspeaker azimuth for a given index, in DEGREES.
float panner_getProgressBar0_1(void *const hPan)
(Optional) Returns current intialisation/processing progress, between 0..1
int panner_getDAWsamplerate(void *const hPan)
Returns the DAW/Host sample rate.
void panner_create(void **const phPan)
Creates an instance of the panner.
float panner_getDTT(void *const hPan)
Returns the room coefficient value 0..1.
int panner_getMaxNumSources()
Returns the maximum number of inputs/sources permitted by panner.
void panner_setSpread(void *const hPan, float newValue)
Sets the degree of spread, in DEGREES.
void panner_setSourceAzi_deg(void *const hPan, int index, float newAzi_deg)
Sets the azimuth of a specific input/source index, in DEGREES.
void panner_setLoudspeakerAzi_deg(void *const hPan, int index, float newAzi_deg)
Sets the azimuth of a specific loudspeaker index, in DEGREES.
void panner_setRoll(void *const hBin, float newRoll)
Sets the 'roll' rotation angle, in DEGREES.
int panner_getFlipRoll(void *const hBin)
Returns a flag as to whether to "flip" the sign of the current 'roll' angle (0: do not flip sign,...
void panner_setOutputConfigPreset(void *const hPan, int newPresetID)
Sets a preset for the output configuration (see LOUDSPEAKER_ARRAY_PRESETS enum)
float panner_getPitch(void *const hBin)
Returns the 'pitch' rotation angle, in DEGREES.
float panner_getLoudspeakerElev_deg(void *const hPan, int index)
Returns the loudspeaker elevation for a given index, in DEGREES.
void panner_init(void *const hPan, int sampleRate)
Initialises an instance of panner with default settings.
int panner_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
void panner_setDTT(void *const hPan, float newValue)
Sets the room coefficient value 0..1 [1]; 0: normal room, 0.5: dry listening room,...
void panner_destroy(void **const phPan)
Destroys an instance of the panner.
int panner_getMaxNumLoudspeakers()
Returns the maximum number of loudspeakers permitted.
void panner_setYaw(void *const hBin, float newYaw)
Sets the 'yaw' rotation angle, in DEGREES.
void panner_setPitch(void *const hBin, float newPitch)
Sets the 'pitch' rotation angle, in DEGREES.
void panner_setInputConfigPreset(void *const hPan, int newPresetID)
Sets a preset for the input configuration (see SOURCE_CONFIG_PRESETS enum)
float panner_getRoll(void *const hBin)
Returns the 'roll' rotation angle, in DEGREES.
CODEC_STATUS panner_getCodecStatus(void *const hPan)
Returns current codec status (see CODEC_STATUS enum)
void panner_getProgressBarText(void *const hPan, char *text)
(Optional) Returns current intialisation/processing progress text
int panner_getProcessingDelay()
Returns the processing delay in samples (may be used for delay compensation features)
float panner_getSourceElev_deg(void *const hPan, int index)
Returns the input/source elevation for a given index, in DEGREES.
void panner_initCodec(void *const hPan)
Intialises the codec variables, based on current global/user parameters.
void panner_setSourceElev_deg(void *const hPan, int index, float newElev_deg)
Sets the elevation of a specific input/source index, in DEGREES.
void panner_refreshSettings(void *const hPan)
Sets all intialisation flags to 1; re-initialising all settings/variables as panner is currently conf...
float panner_getSpread(void *const hPan)
Returns the spread value, in DEGREES.
int panner_getFlipPitch(void *const hBin)
Returns a flag as to whether to "flip" the sign of the current 'pitch' angle (0: do not flip sign,...
void panner_setNumLoudspeakers(void *const hPan, int new_nLoudspeakers)
Sets the number of loudspeakers to pan to.
void panner_setFlipRoll(void *const hBin, int newState)
Sets a flag as to whether to "flip" the sign of the current 'roll' angle (0: do not flip sign,...
int panner_getNumSources(void *const hPan)
Returns the number of inputs/sources in the current layout.
#define PANNER_SPREAD_MAX_VALUE
Maximum supported spread angle, degrees.
#define PANNER_SPREAD_MIN_VALUE
Minimum supported spread angle, degrees.
void panner_initGainTables(void *const hPan)
Intialises the VBAP gain table used for panning.
void panner_setCodecStatus(void *const hPan, CODEC_STATUS newStatus)
Sets codec status (see CODEC_STATUS enum)
void panner_loadLoudspeakerPreset(LOUDSPEAKER_ARRAY_PRESETS preset, float dirs_deg[MAX_NUM_INPUTS][2], int *newNCH, int *nDims)
Loads source/loudspeaker directions from preset.
void panner_initTFT(void *const hPan)
Initialise the filterbank used by panner.
void panner_loadSourcePreset(SOURCE_CONFIG_PRESETS preset, float dirs_deg[MAX_NUM_INPUTS][2], int *newNCH, int *nDims)
Loads source directions from preset.
A frequency-dependent 3D panner based on the Vector-base Amplitude Panning (VBAP) method [1],...
#define PANNER_FRAME_SIZE
Framesize, in time-domain samples.
Main structure for panner.
float roll
roll (Euler) rotation angle, in degrees
float freqVector[HYBRID_BANDS]
Frequency vector (centre frequencies)
int recalc_gainsFLAG[MAX_NUM_INPUTS]
1: VBAP gains need to be recalculated for this source, 0: do not
float DTT
Room coefficient [3].
float ** inputFrameTD
Input signals, in the time-domain; MAX_NUM_INPUTS x PANNER_FRAME_SIZE.
int vbapTableRes[2]
[0] azimuth, and [1] elevation grid resolution, in degrees
CODEC_STATUS codecStatus
see CODEC_STATUS
int nSources
Current number of inputs/sources.
float_complex *** inputframeTF
Input signals, in the time-frequency domain; HYBRID_BANDS x MAX_NUM_INPUTS x TIME_SLOTS.
float_complex *** outputframeTF
Output signals, in the time-frequency domain; HYBRID_BANDS x MAX_NUM_OUTPUTS x TIME_SLOTS.
int recalc_M_rotFLAG
1: recalculate the rotation matrix, 0: do not
float src_dirs_deg[MAX_NUM_INPUTS][2]
Current source directions.
int output_nDims
Dimensionality of the loudspeaker array, 2: 2-D, 3: 3-D.
int new_nSources
New number of inputs/sources.
int nLoudpkrs
Current number of loudspeakers in the array.
float spread_deg
Source spread/MDAP [2].
float yaw
yaw (Euler) rotation angle, in degrees
float loudpkrs_dirs_deg[MAX_NUM_OUTPUTS][2]
Current loudspeaker directions.
char * progressBarText
Current (re)initialisation step, string.
float src_dirs_xyz[MAX_NUM_INPUTS][3]
Intermediate source directions, as unit-length Cartesian coordinates.
float * vbap_gtable
Current VBAP gains; FLAT: N_hrtf_vbap_gtable x nLoudpkrs.
PROC_STATUS procStatus
see PROC_STATUS
float_complex G_src[HYBRID_BANDS][MAX_NUM_INPUTS][MAX_NUM_OUTPUTS]
Current VBAP gains per source.
float ** outputFrameTD
Output signals, in the time-domain; MAX_NUM_OUTPUTS x PANNER_FRAME_SIZE.
float pitch
pitch (Euler) rotation angle, in degrees
float src_dirs_rot_deg[MAX_NUM_INPUTS][2]
Intermediate rotated source directions, in degrees.
int bFlipRoll
flag to flip the sign of the roll rotation angle
float src_dirs_rot_xyz[MAX_NUM_INPUTS][3]
Intermediate rotated source directions, as unit-length Cartesian coordinates.
int new_nLoudpkrs
New number of loudspeakers in the array.
void * hSTFT
afSTFT handle
float pValue[HYBRID_BANDS]
Used for the frequency-dependent panning normalisation.
int fs
Host sampling rate.
float progressBar0_1
Current (re)initialisation progress, between [0..1].
int reInitGainTables
1: reinitialise the VBAP gain table, 0: do not
int bFlipPitch
flag to flip the sign of the pitch rotation angle
int bFlipYaw
flag to flip the sign of the yaw rotation angle