SAF
Loading...
Searching...
No Matches
tvconv.c
Go to the documentation of this file.
1/*
2 * Copyright 2020 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
24#include "tvconv.h"
25#include "tvconv_internal.h"
26
28(
29 void** const phTVCnv
30)
31{
32 tvconv_data* pData = (tvconv_data*)malloc1d(sizeof(tvconv_data));
33 *phTVCnv = (void*)pData;
34
35 /* Default user parameters */
36 pData->nInputChannels = 1;
37
38 /* internal values */
39 pData->hostBlockSize = -1; /* force initialisation */
40 pData->inputFrameTD = NULL;
41 pData->outputFrameTD = NULL;
42 pData->hTVConv = NULL;
43 pData->irs = NULL;
44 pData->reInitFilters = 1;
45 pData->nIrChannels = 0;
46 pData->ir_length = 0;
47 pData->ir_fs = 0;
48 pData->nOutputChannels = 0;
49 pData->sofa_filepath = NULL;
50 pData->sofa_file_error = SAF_TVCONV_NOT_INIT;
51
52 /* set FIFO buffers */
53 pData->host_fs = 48000.0f;
54 pData->FIFO_idx = 0;
55 pData->inFIFO = (float**)calloc2d(MAX_NUM_CHANNELS, MAX_FRAME_SIZE, sizeof(float));
56 pData->outFIFO = (float**)calloc2d(MAX_NUM_CHANNELS, MAX_FRAME_SIZE, sizeof(float));
57 //memset(FLATTEN2D(pData->inFIFO), 0, MAX_NUM_CHANNELS*MAX_FRAME_SIZE*sizeof(float));
58 //memset(FLATTEN2D(pData->outFIFO), 0, MAX_NUM_CHANNELS*MAX_FRAME_SIZE*sizeof(float));
59
60 /* positions */
61 pData->listenerPositions = NULL;
62 pData->nListenerPositions = 0;
63 pData->position_idx = 0;
64 for (int d = 0; d < NUM_DIMENSIONS; d++){
65 pData->sourcePosition[d] = 0.0f;
66 pData->targetPosition[d] = 0.0f;
67 pData->minDimensions[d] = 0.0f;
68 pData->maxDimensions[d] = 0.0f;
69 }
70
71 /* flags/status */
72 pData->progressBar0_1 = 0.0f;
73 pData->progressBarText = malloc1d(PROGRESSBARTEXT_CHAR_LENGTH*sizeof(char));
74 strcpy(pData->progressBarText,"");
75 pData->codecStatus = CODEC_STATUS_NOT_INITIALISED;
76 pData->procStatus = PROC_STATUS_NOT_ONGOING;
77}
78
80(
81 void** const phTVCnv
82)
83{
84 tvconv_data* pData = (tvconv_data*)(*phTVCnv);
85
86 if (pData != NULL){
87 /* not safe to free memory during intialisation/processing loop */
88 while (pData->codecStatus == CODEC_STATUS_INITIALISING ||
89 pData->procStatus == PROC_STATUS_ONGOING){
90 SAF_SLEEP(10);
91 }
92 free(pData->inFIFO);
93 free(pData->outFIFO);
94 free(pData->inputFrameTD);
95 free(pData->outputFrameTD);
96 free(pData->irs);
97 free(pData->listenerPositions);
98 saf_TVConv_destroy(&(pData->hTVConv));
99 free(pData);
100 pData = NULL;
101 *phTVCnv = NULL;
102 }
103}
104
106(
107 void* const hTVCnv,
108 int sampleRate,
109 int hostBlockSize
110)
111{
112 tvconv_data *pData = (tvconv_data*)(hTVCnv);
113
114 pData->host_fs = sampleRate;
115
116 if(pData->hostBlockSize != hostBlockSize){
117 pData->hostBlockSize = hostBlockSize;
119 pData->reInitFilters = 1;
121 }
122 tvconv_checkReInit(hTVCnv);
123}
124
126(
127 void * const hTVCnv,
128 float* const* const inputs,
129 float* const* const outputs,
130 int nInputs,
131 int nOutputs,
132 int nSamples
133)
134{
135 tvconv_data *pData = (tvconv_data*)(hTVCnv);
136 int s, ch, i;
137 int numInputChannels, numOutputChannels;
138
139 tvconv_checkReInit(hTVCnv);
140 pData->procStatus = PROC_STATUS_ONGOING;
141
142 numInputChannels = pData->nInputChannels;
143 numOutputChannels = pData->nOutputChannels;
144
145 for(s=0; s<nSamples; s++){
146 /* Load input signals into inFIFO buffer */
147 for(ch=0; ch<SAF_MIN(SAF_MIN(nInputs,numInputChannels),MAX_NUM_CHANNELS); ch++)
148 pData->inFIFO[ch][pData->FIFO_idx] = inputs[ch][s];
149 for(; ch<numInputChannels; ch++) /* Zero any channels that were not given */
150 pData->inFIFO[ch][pData->FIFO_idx] = 0.0f;
151
152 /* Pull output signals from outFIFO buffer */
153 for(ch=0; ch<SAF_MIN(SAF_MIN(nOutputs, numOutputChannels),MAX_NUM_CHANNELS); ch++)
154 outputs[ch][s] = pData->outFIFO[ch][pData->FIFO_idx];
155 for(; ch<nOutputs; ch++) /* Zero any extra channels */
156 outputs[ch][s] = 0.0f;
157
158 /* Increment buffer index */
159 pData->FIFO_idx++;
160
161 /* Process frame if inFIFO is full and filters are loaded and saf_matrixConv_apply is ready for it */
162 if (pData->FIFO_idx >= pData->hostBlockSize_clamped && pData->reInitFilters == 0 &&
163 pData->codecStatus == CODEC_STATUS_INITIALISED) {
164 pData->FIFO_idx = 0;
165
166 /* Load time-domain data */
167 for(i=0; i < numInputChannels; i++)
168 utility_svvcopy(pData->inFIFO[i], pData->hostBlockSize_clamped, pData->inputFrameTD[i]);
169
170 if(pData->hTVConv != NULL && pData->ir_length>0){
172 FLATTEN2D(pData->inputFrameTD),
173 FLATTEN2D(pData->outputFrameTD),
174 pData->position_idx);
175 }
176 /* if the matrix convolver handle has not been initialised yet (i.e. no filters have been loaded) then zero the output */
177 else
178 memset(FLATTEN2D(pData->outputFrameTD), 0, MAX_NUM_CHANNELS * (pData->hostBlockSize_clamped)*sizeof(float));
179
180 /* copy signals to output buffer */
181 for (i = 0; i < SAF_MIN(numOutputChannels, MAX_NUM_CHANNELS); i++)
182 utility_svvcopy(pData->outputFrameTD[i], pData->hostBlockSize_clamped, pData->outFIFO[i]);
183 }
184 else if(pData->FIFO_idx >= pData->hostBlockSize_clamped){
185 /* clear outFIFO if codec was not ready */
186 pData->FIFO_idx = 0;
187 memset(FLATTEN2D(pData->outFIFO), 0, MAX_NUM_CHANNELS*MAX_FRAME_SIZE*sizeof(float));
188 }
189 }
190 pData->procStatus = PROC_STATUS_NOT_ONGOING;
191}
192
193
194/*sets*/
195
196void tvconv_refreshParams(void* const hTVCnv)
197{
198 tvconv_data *pData = (tvconv_data*)(hTVCnv);
199 pData->reInitFilters = 1;
200 //tvconv_setCodecStatus(hTVCnv, CODEC_STATUS_NOT_INITIALISED);
201}
202
203void tvconv_checkReInit(void* const hTVCnv)
204{
205 tvconv_data *pData = (tvconv_data*)(hTVCnv);
206
207 while (pData->procStatus == CODEC_STATUS_INITIALISING){
208 SAF_SLEEP(10);
209 }
210 /* reinitialise if needed */
211 if ((pData->reInitFilters == 1) && (pData->irs != NULL)) {
212 pData->reInitFilters = 2;
213 saf_TVConv_destroy(&(pData->hTVConv));
214 pData->hTVConv = NULL;
215 /* if length of the loaded sofa file was not divisable by the specified number of inputs, then the handle remains NULL,
216 * and no convolution is applied */
218 if(pData->ir_length>0){
219 saf_TVConv_create(&(pData->hTVConv),
221 pData->irs,
222 pData->ir_length,
223 pData->nListenerPositions,
224 pData->nOutputChannels,
225 pData->position_idx);
226 }
227
228 /* Resize buffers */
229 pData->inputFrameTD = (float**)realloc2d((void**)pData->inputFrameTD, MAX_NUM_CHANNELS, pData->hostBlockSize_clamped, sizeof(float));
230 pData->outputFrameTD = (float**)realloc2d((void**)pData->outputFrameTD, MAX_NUM_CHANNELS, pData->hostBlockSize_clamped, sizeof(float));
231 memset(FLATTEN2D(pData->inputFrameTD), 0, MAX_NUM_CHANNELS*(pData->hostBlockSize_clamped)*sizeof(float));
232
233 /* reset FIFO buffers */
234 pData->FIFO_idx = 0;
235 memset(FLATTEN2D(pData->inFIFO), 0, MAX_NUM_CHANNELS*MAX_FRAME_SIZE*sizeof(float));
236 memset(FLATTEN2D(pData->outFIFO), 0, MAX_NUM_CHANNELS*MAX_FRAME_SIZE*sizeof(float));
237
238 pData->reInitFilters = 0;
239 pData->codecStatus = CODEC_STATUS_INITIALISED;
240 }
241}
242
243void tvconv_setFiltersAndPositions( void* const hTVCnv )
244{
245 tvconv_data* pData = (tvconv_data*) hTVCnv;
246#ifdef SAF_ENABLE_SOFA_READER_MODULE
247 int i;
248 vectorND tmp;
251#endif
252
253 if (pData->codecStatus != CODEC_STATUS_NOT_INITIALISED)
254 return; /* re-init not required, or already happening */
255 while (pData->procStatus == PROC_STATUS_ONGOING){
256 /* re-init required, but we need to wait for the current processing loop to end */
257 pData->codecStatus = CODEC_STATUS_INITIALISING; /* indicate that we want to init */
258 SAF_SLEEP(10);
259 }
260
261 /* for progress bar */
262 pData->codecStatus = CODEC_STATUS_INITIALISING;
263 strcpy(pData->progressBarText,"Initialising");
264 pData->progressBar0_1 = 0.0f;
265
266#ifdef SAF_ENABLE_SOFA_READER_MODULE
267 if(pData->sofa_filepath!=NULL){
268 strcpy(pData->progressBarText,"Opening SOFA file");
269 pData->progressBar0_1 = 0.2f;
270 error = saf_sofa_open(&sofa, pData->sofa_filepath, SAF_SOFA_READER_OPTION_DEFAULT);
271
272 if(error==SAF_SOFA_OK){
273 strcpy(pData->progressBarText,"Loading IRs");
274 pData->progressBar0_1 = 0.5f;
275
276 pData->ir_fs = (int)sofa.DataSamplingRate;
277 pData->ir_length = sofa.DataLengthIR;
278 pData->nIrChannels = sofa.nReceivers;
279 pData->nListenerPositions = sofa.nListeners;
280
281 /* copy only the first source position, because number of source positions might be incorrect in sofa */
282 if(!strcmp(sofa.SourcePositionType, "spherical")){
283 memcpy(tmp, sofa.SourcePosition, sizeof(vectorND));
284 unitSph2cart((float*)tmp, 1, 1, pData->sourcePosition);
285 }
286 else
287 memcpy(pData->sourcePosition, sofa.SourcePosition, sizeof(vectorND));
288
289 pData->irs = (float**)realloc2d((void**)pData->irs, pData->nListenerPositions, pData->nIrChannels*pData->ir_length, sizeof(float));
290 int tmp_length = pData->nIrChannels * pData->ir_length;
291 for(i=0; i<pData->nListenerPositions; i++){
292 memcpy(pData->irs[i], &(sofa.DataIR[i*tmp_length]), tmp_length*sizeof(float));
293 }
294
295 strcpy(pData->progressBarText,"Loading positions");
296 pData->progressBar0_1 = 0.8f;
297
298 pData->listenerPositions = (vectorND*)realloc1d((void*)pData->listenerPositions, pData->nListenerPositions*sizeof(vectorND));
299 memcpy(pData->listenerPositions, sofa.ListenerPosition, pData->nListenerPositions*sizeof(vectorND));
300 }
301
302 /* extra error handling */
303 switch(error){
304 case SAF_SOFA_OK:
305 pData->sofa_file_error = SAF_TVCONV_SOFA_OK;
306 break;
309 break;
311 pData->sofa_file_error = SAF_TVCONV_SOFA_ERROR_DIMENSIONS_UNEXPECTED;
312 break;
314 pData->sofa_file_error = SAF_TVCONV_SOFA_ERROR_FORMAT_UNEXPECTED;
315 break;
317 pData->sofa_file_error = SAF_TVCONV_SOFA_ERROR_NETCDF_IN_USE;
318 break;
319 }
320 }
321 saf_sofa_close(&sofa);
324#else
325 pData->ir_length = 0;
326 saf_print_warning("This example requires SAF_ENABLE_SOFA_READER_MODULE to do anything");
327#endif
328
329 pData->position_idx = 0;
330 pData->codecStatus = CODEC_STATUS_INITIALISED;
331 pData->reInitFilters = 1;
332
333 /* done! */
334 strcpy(pData->progressBarText,"Done!");
335 pData->progressBar0_1 = 1.0f;
336}
337
338void tvconv_setSofaFilePath(void* const hTVCnv, const char* path)
339{
340 tvconv_data *pData = (tvconv_data*)(hTVCnv);
341 pData->sofa_file_error = SAF_TVCONV_SOFA_LOADING;
342 pData->sofa_filepath = malloc1d(strlen(path) + 1);
343 strcpy(pData->sofa_filepath, path);
344 pData->codecStatus = CODEC_STATUS_NOT_INITIALISED;
346
347}
348
349void tvconv_setTargetPosition(void* const hTVCnv, float position, int dim){
350 tvconv_data *pData = (tvconv_data*)(hTVCnv);
351 saf_assert(dim >= 0 && dim < NUM_DIMENSIONS, "Dimension out of scope");
352 pData->targetPosition[dim] = position;
354}
355
356
357/*gets*/
358
359int tvconv_getNumInputChannels(void* const hTVCnv)
360{
361 tvconv_data *pData = (tvconv_data*)(hTVCnv);
362 return pData->nInputChannels;
363}
364
365int tvconv_getNumOutputChannels(void* const hTVCnv)
366{
367 tvconv_data *pData = (tvconv_data*)(hTVCnv);
368 return pData->nOutputChannels;
369}
370
371int tvconv_getHostBlockSize(void* const hTVCnv)
372{
373 tvconv_data *pData = (tvconv_data*)(hTVCnv);
374 return pData->hostBlockSize;
375}
376
377int tvconv_getNumIRs(void* const hTVCnv)
378{
379 tvconv_data *pData = (tvconv_data*)(hTVCnv);
380 return pData->nIrChannels;
381}
382
383int tvconv_getNumListenerPositions(void* const hTVCnv)
384{
385 tvconv_data *pData = (tvconv_data*)(hTVCnv);
386
387 return pData->codecStatus==CODEC_STATUS_INITIALISED ? pData->nListenerPositions : 0;
388}
389
390float tvconv_getListenerPosition(void* const hTVCnv, int index, int dim)
391{
392 tvconv_data *pData = (tvconv_data*)(hTVCnv);
393 return pData->codecStatus==CODEC_STATUS_INITIALISED ? pData->listenerPositions[index][dim] : 0.0f;
394}
395
396int tvconv_getListenerPositionIdx(void* const hTVCnv)
397{
398 tvconv_data *pData = (tvconv_data*)(hTVCnv);
399 return pData->position_idx;
400}
401
402float tvconv_getTargetPosition(void* const hTVCnv, int dim)
403{
404 tvconv_data *pData = (tvconv_data*)(hTVCnv);
405 saf_assert(dim >= 0 && dim < NUM_DIMENSIONS, "Dimension out of scope");
406 return (float) pData->targetPosition[dim];
407}
408
409float tvconv_getSourcePosition(void* const hTVCnv, int dim)
410{
411 tvconv_data *pData = (tvconv_data*)(hTVCnv);
412 saf_assert(dim >= 0 && dim < NUM_DIMENSIONS, "Dimension out of scope");
413 return (float) pData->sourcePosition[dim];
414}
415
416float tvconv_getMinDimension(void* const hTVCnv, int dim)
417{
418 tvconv_data *pData = (tvconv_data*)(hTVCnv);
419 saf_assert(dim >= 0 && dim < NUM_DIMENSIONS, "Dimension out of scope");
420 return (float) pData->minDimensions[dim];
421}
422
423float tvconv_getMaxDimension(void* const hTVCnv, int dim)
424{
425 tvconv_data *pData = (tvconv_data*)(hTVCnv);
426 saf_assert(dim >= 0 && dim < NUM_DIMENSIONS, "Dimension out of scope");
427 return (float) pData->maxDimensions[dim];
428}
429
430int tvconv_getIRLength(void* const hTVCnv)
431{
432 tvconv_data *pData = (tvconv_data*)(hTVCnv);
433 return pData->ir_length;
434}
435
436int tvconv_getIRFs(void* const hTVCnv)
437{
438 tvconv_data *pData = (tvconv_data*)(hTVCnv);
439 return pData->ir_fs;
440}
441
442int tvconv_getHostFs(void* const hTVCnv)
443{
444 tvconv_data *pData = (tvconv_data*)(hTVCnv);
445 return pData->host_fs;
446}
447
448int tvconv_getProcessingDelay(void* const hTVCnv)
449{
450 tvconv_data *pData = (tvconv_data*)(hTVCnv);
451 return pData->hostBlockSize_clamped;
452}
453
454char* tvconv_getSofaFilePath(void* const hTVCnv)
455{
456 tvconv_data *pData = (tvconv_data*)(hTVCnv);
457 if(pData->sofa_filepath!=NULL)
458 return pData->sofa_filepath;
459 else
460 return "no_file";
461}
462
464{
465 tvconv_data* pData = (tvconv_data*)(hTVCnv);
466 return pData->sofa_file_error;
467}
468
470{
471 tvconv_data *pData = (tvconv_data*)(hTVCnv);
472 return pData->codecStatus;
473}
#define MAX_NUM_CHANNELS
Maximum number of input/output channels supported.
Definition _common.h:230
#define PROGRESSBARTEXT_CHAR_LENGTH
Length of progress bar string.
Definition _common.h:227
@ PROC_STATUS_ONGOING
Codec is processing input audio, and should not be reinitialised at this time.
Definition _common.h:220
@ PROC_STATUS_NOT_ONGOING
Codec is not processing input audio, and may be reinitialised if needed.
Definition _common.h:222
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_INITIALISED
Codec is initialised and ready to process input audio.
Definition _common.h:202
@ CODEC_STATUS_INITIALISING
Codec is currently being initialised, input audio should not be processed.
Definition _common.h:207
void saf_sofa_close(saf_sofa_container *c)
Frees all SOFA data in a sofa_container.
SAF_SOFA_ERROR_CODES saf_sofa_open(saf_sofa_container *h, char *sofa_filepath, SAF_SOFA_READER_OPTIONS option)
Fills a 'sofa_container' with data found in a SOFA file (GeneralFIR or SimpleFreeFieldHRIR),...
SAF_SOFA_ERROR_CODES
SOFA loader error codes.
@ SAF_SOFA_READER_OPTION_DEFAULT
The default option is SAF_SOFA_READER_OPTION_LIBMYSOFA.
@ SAF_SOFA_ERROR_INVALID_FILE_OR_FILE_PATH
Not a SOFA file, or no such file was found in the specified location.
@ SAF_SOFA_ERROR_NETCDF_IN_USE
NetCDF is not thread safe!
@ SAF_SOFA_OK
None of the error checks failed.
@ SAF_SOFA_ERROR_FORMAT_UNEXPECTED
The data-type of the SOFA data was not as expected.
@ SAF_SOFA_ERROR_DIMENSIONS_UNEXPECTED
Dimensions of the SOFA data were not as expected.
#define saf_assert(x, message)
Macro to make an assertion, along with a string explaining its purpose.
#define SAF_CLAMP(a, min, max)
Ensures value "a" is clamped between the "min" and "max" values.
void saf_TVConv_apply(void *const hTVC, float *inputSig, float *outputSig, int irIdx)
Performs the matrix convolution.
void saf_TVConv_create(void **const phTVC, int hopSize, float **H, int length_h, int nIRs, int nCHout, int initIdx)
Creates an instance of TVConv.
void utility_svvcopy(const float *a, const int len, float *c)
Single-precision, vector-vector copy, i.e.
void saf_TVConv_destroy(void **const phTVC)
Destroys an instance of matrixConv.
#define SAF_MIN(a, b)
Returns the minimum of the two values.
void unitSph2cart(float *dirs, int nDirs, int anglesInDegreesFLAG, float *dirs_xyz)
Converts spherical coordinates to Cartesian coordinates of unit length.
#define saf_print_warning(message)
Macro to print a warning message along with the filename and line number.
#define MIN_FRAME_SIZE
Minimum framesize, in time-domain samples.
#define MAX_FRAME_SIZE
Maximum framesize, in time-domain samples.
void ** realloc2d(void **ptr, size_t dim1, size_t dim2, size_t data_size)
2-D realloc which does NOT retain previous data order
Definition md_malloc.c:115
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
void ** calloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D calloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:102
#define FLATTEN2D(A)
Use this macro when passing a 2-D dynamic multi-dimensional array to memset, memcpy or any other func...
Definition md_malloc.h:65
SOFA container struct comprising all possible data that can be extracted from SOFA 1....
int DataLengthIR
Length of the IRs, in samples.
float * SourcePosition
Source positions (refer to SourcePositionType & SourcePositionUnits for the convention and units); FL...
int nListeners
Number of listener positions.
char * SourcePositionType
{'cartesian'|'spherical'}
float * ListenerPosition
Listener position (The object incorporating all receivers; refer to ListenerPositionType & ListenerPo...
float DataSamplingRate
Sampling rate used to measure the IRs.
int nReceivers
Number of ears/number of mics etc.
float * DataIR
The impulse response (IR) Data; FLAT:nSources x nReceivers x DataLengthIR.
Main structure for tvconv
int host_fs
current samplerate of the host
int nOutputChannels
number of output channels (same as the number of channels in the loaded wav)
int reInitFilters
FLAG: 0: do not reinit, 1: reinit, 2: reinit in progress.
int hostBlockSize
current host block size
float ** irs
npositionsx x (FLAT: nfilters x filter_length)
int nIrChannels
number of filters per position
vectorND minDimensions
Minimum values across all dimensions.
int hostBlockSize_clamped
Clamped between MIN and MAX_FRAME_SIZE.
void * hTVConv
saf_TVConv handle
int nInputChannels
number of input channels
vectorND maxDimensions
Maximum values across all dimensions.
vectorND * listenerPositions
The listener positions; nListenerPositions x 3.
float tvconv_getListenerPosition(void *const hTVCnv, int index, int dim)
Returns the current coordinate of dimension dim (0 ... NUM_DIMENSIONS-1)
Definition tvconv.c:390
void tvconv_process(void *const hTVCnv, float *const *const inputs, float *const *const outputs, int nInputs, int nOutputs, int nSamples)
Performs the time-varying convolution processing.
Definition tvconv.c:126
int tvconv_getIRFs(void *const hTVCnv)
Returns the samplerate of the loaded filters
Definition tvconv.c:436
void tvconv_refreshParams(void *const hTVCnv)
Sets all intialisation flags to 1.
Definition tvconv.c:196
int tvconv_getProcessingDelay(void *const hTVCnv)
Returns the processing delay in samples (may be used for delay compensation features)
Definition tvconv.c:448
CODEC_STATUS tvconv_getCodecStatus(void *const hTVCnv)
Returns current codec status (see CODEC_STATUS enum)
Definition tvconv.c:469
void tvconv_setFiltersAndPositions(void *const hTVCnv)
Reads IRs and positions from the current sofa file path.
Definition tvconv.c:243
char * tvconv_getSofaFilePath(void *const hTVCnv)
Returns the current Sofa file path.
Definition tvconv.c:454
void tvconv_create(void **const phTVCnv)
Creates an instance of tvconv.
Definition tvconv.c:28
float tvconv_getSourcePosition(void *const hTVCnv, int dim)
Returns the source coordinate of dimension dim (0 ... NUM_DIMENSIONS-1)
Definition tvconv.c:409
void tvconv_setTargetPosition(void *const hTVCnv, float position, int dim)
Sets the target listener position.
Definition tvconv.c:349
int tvconv_getIRLength(void *const hTVCnv)
Returns the current filter length, in samples.
Definition tvconv.c:430
int tvconv_getNumListenerPositions(void *const hTVCnv)
Returns the number of listener positions in the loaded sofa file.
Definition tvconv.c:383
int tvconv_getNumIRs(void *const hTVCnv)
Returns the number of IR channels in the loaded sofa file.
Definition tvconv.c:377
int tvconv_getHostBlockSize(void *const hTVCnv)
Returns the currect host block size.
Definition tvconv.c:371
int tvconv_getHostFs(void *const hTVCnv)
Returns the samperate of the host.
Definition tvconv.c:442
SAF_TVCONV_ERROR_CODES tvconv_getSofaErrorState(void *const hTVCnv)
Returns the current Sofa file error state.
Definition tvconv.c:463
void tvconv_setSofaFilePath(void *const hTVCnv, const char *path)
Sets current sofa file path.
Definition tvconv.c:338
int tvconv_getListenerPositionIdx(void *const hTVCnv)
Returns the index of the current IR position.
Definition tvconv.c:396
float tvconv_getMinDimension(void *const hTVCnv, int dim)
Returns minimum cooridinate of dimension dim (0 ... NUM_DIMENSIONS-1)
Definition tvconv.c:416
float tvconv_getTargetPosition(void *const hTVCnv, int dim)
Returns the current coordinate of dimension dim (0 ... NUM_DIMENSIONS-1)
Definition tvconv.c:402
void tvconv_init(void *const hTVCnv, int sampleRate, int hostBlockSize)
Initialises an instance of tvconv with default settings.
Definition tvconv.c:106
float tvconv_getMaxDimension(void *const hTVCnv, int dim)
Returns minimum cooridinate of dimension dim (0 ... NUM_DIMENSIONS-1)
Definition tvconv.c:423
int tvconv_getNumInputChannels(void *const hTVCnv)
Returns the number input channels.
Definition tvconv.c:359
int tvconv_getNumOutputChannels(void *const hTVCnv)
Returns the number of output channels (the same as the number of channels in the loaded sofa file)
Definition tvconv.c:365
void tvconv_checkReInit(void *const hTVCnv)
Checks whether things have to be reinitialised, and does so if it is needed.
Definition tvconv.c:203
void tvconv_destroy(void **const phTVCnv)
Destroys an instance of tvconv.
Definition tvconv.c:80
A time-varying multi-channel convolver.
SAF_TVCONV_ERROR_CODES
SOFA loader error codes.
Definition tvconv.h:34
@ SAF_TVCONV_SOFA_ERROR_INVALID_FILE_OR_FILE_PATH
Not a SOFA file, or no such file was found in the specified location.
Definition tvconv.h:42
@ SAF_TVCONV_SOFA_ERROR_NETCDF_IN_USE
NetCDF is not thread safe!
Definition tvconv.h:48
@ SAF_TVCONV_SOFA_ERROR_FORMAT_UNEXPECTED
The data-type of the SOFA data was not as expected.
Definition tvconv.h:46
@ SAF_TVCONV_SOFA_ERROR_DIMENSIONS_UNEXPECTED
Dimensions of the SOFA data were not as expected.
Definition tvconv.h:44
@ SAF_TVCONV_SOFA_OK
None of the error checks failed.
Definition tvconv.h:40
@ SAF_TVCONV_NOT_INIT
Not initialized.
Definition tvconv.h:36
@ SAF_TVCONV_SOFA_LOADING
Loading file.
Definition tvconv.h:38
void tvconv_findNearestNeigbour(void *const hTVCnv)
Finds the index holding the nearest neigbour to the selected position.
void tvconv_setCodecStatus(void *const hTVCnv, CODEC_STATUS newStatus)
Sets codec status (see CODEC_STATUS enum)
void tvconv_setMinMaxDimensions(void *const hTVCnv)
Sets the smallest and the highest position of each dimension from the list of positions.
A time-varying multi-channel convolver.
float vectorND[NUM_DIMENSIONS]
Structure for a vector.