SAF
Loading...
Searching...
No Matches
test__hades_module.c
Go to the documentation of this file.
1/*
2 * This file is part of the saf_hades module unit tests.
3 * Copyright (c) 2021 - Leo McCormack & Janani Fernandez
4 *
5 * The saf_hades module is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * The saf_hades module is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * See <http://www.gnu.org/licenses/> for a copy of the GNU General Public
16 * License.
17 */
18
27#include "saf_test.h"
28
29#if defined(SAF_ENABLE_HADES_MODULE) && defined(SAF_ENABLE_SOFA_READER_MODULE) /* unit tests rely also on SOFA reader */
30
31void test__hades(void){
32 hades_analysis_handle hAna = NULL; /* Analysis handle */
33 hades_synthesis_handle hSyn = NULL; /* Synthesis handle */
34 hades_param_container_handle hPCon = NULL; /* Parameter container handle */
35 hades_signal_container_handle hSCon = NULL; /* Signal container handle */
36 hades_binaural_config binConfig;
39 int i, ch, nDirs, nMics;
40 int refIndices[2];
41 float* grid_dirs_deg;
42
43 /* Config */
44 const int fs = 48000;
45 const int sigLen = fs*2;
46 const int hopsize = 64;
47 const int blocksize = 256;
48 const int hybridmode = 0;
49
50 /* Analysis */
51 error = saf_sofa_open(&sofa, "/Users/mccorml1/Documents/git/matlab/h_array/h_array_horiz1deg_357.sofa", SAF_SOFA_READER_OPTION_DEFAULT);
52 if(error!=SAF_SOFA_OK)
53 return; /* SOFA File does not exist, so skip this unit test. */
54 nDirs = sofa.nSources;
55 nMics = sofa.nReceivers;
56 grid_dirs_deg = malloc1d(nDirs*2*sizeof(float));
57 cblas_scopy(nDirs, sofa.SourcePosition, 3, grid_dirs_deg, 2); /* azi */
58 cblas_scopy(nDirs, &sofa.SourcePosition[1], 3, &grid_dirs_deg[1], 2); /* elev */
59 hades_analysis_create(&hAna, (float)fs, HADES_USE_AFSTFT_LD, hopsize, blocksize, hybridmode, /* for time-frequency transform */
60 sofa.DataIR, grid_dirs_deg, nDirs, nMics, sofa.DataLengthIR, /* for the array measurements */
61 HADES_USE_COMEDIE, HADES_USE_MUSIC); /* for parameter analysis */
62 saf_sofa_close(&sofa);
63
64 /* Parameter/signal containers */
65 hades_param_container_create(&hPCon, hAna);
67
68 /* Synthesis */
69 binConfig.hrir_fs = __default_hrir_fs;
70 binConfig.lHRIR = __default_hrir_len;
71 binConfig.nHRIR = __default_N_hrir_dirs;
72 binConfig.hrirs = (float*)__default_hrirs;
73 binConfig.hrir_dirs_deg = (float*)__default_hrir_dirs_deg;
74 refIndices[0] = 1;
75 refIndices[1] = 5;
77
78 /* Define input audio */
79 float** inSigMIC;
80 inSigMIC = (float**)malloc2d(nMics, sigLen, sizeof(float));
81 rand_m1_1(FLATTEN2D(inSigMIC), nMics*sigLen);
82
83 /* Main loop */
84 float **inSigMIC_block, **outSigBIN_block, **outSigBIN;
85 inSigMIC_block = (float**)malloc2d(nMics, blocksize, sizeof(float));
86 outSigBIN_block = (float**)malloc2d(NUM_EARS, blocksize, sizeof(float));
87 outSigBIN = (float**)malloc2d(NUM_EARS, sigLen, sizeof(float));
88 for(i=0; i < (int)((float)sigLen/(float)blocksize); i++){
89 /* Copy input to buffer */
90 for(ch=0; ch<nMics; ch++)
91 memcpy(inSigMIC_block[ch], &inSigMIC[ch][i*blocksize], blocksize*sizeof(float));
92
93 /* Analysis/synthesis */
94 hades_analysis_apply(hAna, inSigMIC_block, nMics, blocksize, hPCon, hSCon);
95 hades_synthesis_apply(hSyn, hPCon, hSCon, NUM_EARS, blocksize, outSigBIN_block);
96
97 /* Copy buffer to output */
98 for(ch=0; ch<NUM_EARS; ch++)
99 memcpy(&outSigBIN[ch][i*blocksize], outSigBIN_block[ch], blocksize*sizeof(float));
100 }
101
102 /* Clean-up */
107 free(grid_dirs_deg);
108 free(inSigMIC);
109 free(inSigMIC_block);
110 free(outSigBIN_block);
111 free(outSigBIN);
112}
113
114
115#endif /* SAF_ENABLE_HADES_MODULE */
const int __default_N_hrir_dirs
The number of directions/measurements in the default HRIR dataset.
const float __default_hrirs[836][2][256]
The default HRIR data for SAF.
const float __default_hrir_dirs_deg[836][2]
The measurement directions used for the default HRIR dataset.
const int __default_hrir_len
The length of the filters, in samples, for the default HRIR dataset.
const int __default_hrir_fs
The samplerate used to measure the default HRIR filters
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_OK
None of the error checks failed.
#define NUM_EARS
2 (true for most humans)
#define SAF_TRUE
Boolean true.
void rand_m1_1(float *vector, int length)
Generates random numbers between -1 and 1 and stores them in the input vector.
void ** malloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D malloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:89
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
Definition md_malloc.c:59
#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
void hades_param_container_destroy(hades_param_container_handle *const phPCon)
Destroys an instance of a hades parameter container.
void hades_analysis_destroy(hades_analysis_handle *const phAna)
Destroys an instance of a hades analysis object.
void hades_signal_container_create(hades_signal_container_handle *const phSCon, hades_analysis_handle const hAna)
Creates an instance of a container used for storing the TF-domain audio returned by an analyser for o...
void hades_analysis_create(hades_analysis_handle *const phAna, float fs, HADES_FILTERBANKS fbOption, int hopsize, int blocksize, int hybridmode, float *h_array, float *grid_dirs_deg, int nGrid, int nMics, int h_len, HADES_DIFFUSENESS_ESTIMATORS diffOption, HADES_DOA_ESTIMATORS doaOption)
Creates and returns a handle to an instance of a hades analysis object.
void hades_param_container_create(hades_param_container_handle *const phPCon, hades_analysis_handle const hAna)
Creates an instance of a container used for storing the parameters estimated by an analyser for one '...
void hades_analysis_apply(hades_analysis_handle const hAna, float **input, int nChannels, int blocksize, void *const hPCon, void *const hSCon)
Performs hades encoding: forward time-frequency transform, diffuseness and DoA estimation per band.
void hades_signal_container_destroy(hades_signal_container_handle *const phSCon)
Destroys an instance of a hades signal container.
struct _hades_analysis_data * hades_analysis_handle
Handle for the hades analysis data.
struct _hades_param_container_data * hades_param_container_handle
Handle for the hades parameter container data.
struct _hades_signal_container_data * hades_signal_container_handle
Handle for the hades signal container data.
@ HADES_USE_AFSTFT_LD
Alias-free STFT filterbank (low delay)
@ HADES_USE_MUSIC
Use MUSIC.
@ HADES_USE_COMEDIE
As in [1], after spatially whitening the array SCM.
void hades_synthesis_apply(hades_synthesis_handle const hSyn, hades_param_container_handle const hPCon, hades_signal_container_handle const hSCon, int nChannels, int blocksize, float **output)
Performs hades synthesis.
void hades_synthesis_create(hades_synthesis_handle *const phSyn, hades_analysis_handle const hAna, HADES_BEAMFORMER_TYPE beamOption, int enableCM, int refIndices[2], hades_binaural_config *binConfig, HADES_HRTF_INTERP_OPTIONS interpOption)
Creates and returns a handle to an instance of a hades synthesis object.
void hades_synthesis_destroy(hades_synthesis_handle *const phSyn)
Destroys an instance of hades synthesis.
struct _hades_synthesis_data * hades_synthesis_handle
Handle for the hades synthesis data.
@ HADES_BEAMFORMER_BMVDR
Binaural minimum-variance distortion- less response (MVDR) beamforming.
@ HADES_HRTF_INTERP_NEAREST
Quantise to nearest measurement.
Unit test program for the Spatial_Audio_Framework.
Binaural configuration struct.
int nHRIR
Number of HRIRs.
int hrir_fs
HRIR sample rate.
int lHRIR
Length of HRIRs in samples.
float * hrir_dirs_deg
HRTF directions in [azimuth elevation] format, in degrees; FLAT: nHRIR x 2.
float * hrirs
Matrix of HRIR data; FLAT: nHRIR x NUM_EARS x lHRIR.
SOFA container struct comprising all possible data that can be extracted from SOFA 1....
int DataLengthIR
Length of the IRs, in samples.
int nSources
Number of source/measurement positions.
float * SourcePosition
Source positions (refer to SourcePositionType & SourcePositionUnits for the convention and units); FL...
int nReceivers
Number of ears/number of mics etc.
float * DataIR
The impulse response (IR) Data; FLAT:nSources x nReceivers x DataLengthIR.
void test__hades(void)
Test for hades.