1 /* 2 3 Copyright 2016 Christian Hoene, Symonics GmbH 4 5 */ 6 7 #ifndef MYSOFA_H_INCLUDED 8 #define MYSOFA_H_INCLUDED 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 #include <stdbool.h> 14 #include <stdint.h> 15 16 #define MYSOFA_DEFAULT_NEIGH_STEP_ANGLE 0.5f 17 #define MYSOFA_DEFAULT_NEIGH_STEP_RADIUS 0.01f 18 19 /** debugging output */ 20 #ifdef VDEBUG 21 #include <stdio.h> 22 #define mylog(...) \ 23 { \ 24 fprintf(stderr, "%s:%d: ", __FILE__, __LINE__); \ 25 fprintf(stderr, __VA_ARGS__); \ 26 } 27 #else 28 #define mylog(...) 29 #endif 30 31 /** attributes */ 32 struct MYSOFA_ATTRIBUTE { 33 struct MYSOFA_ATTRIBUTE *next; 34 char *name; 35 char *value; 36 }; 37 38 struct MYSOFA_ARRAY { 39 float *values; 40 unsigned int elements; 41 struct MYSOFA_ATTRIBUTE *attributes; 42 }; 43 44 /** additional variable */ 45 struct MYSOFA_VARIABLE { 46 struct MYSOFA_VARIABLE *next; 47 char *name; 48 struct MYSOFA_ARRAY *value; 49 }; 50 51 /* 52 * The HRTF structure data types 53 */ 54 struct MYSOFA_HRTF { 55 56 /* Dimensions defined in AES69 57 M Number of measurements; must be integer greater than zero. 58 R Number of receivers; must be integer greater than zero. 59 E Number of emitters; must be integer greater than zero. 60 N Number of data samples describing one measurement; must be integer greater 61 than zero. S Number of characters in a string; must be integer greater than 62 zero. I 1 Singleton dimension, defines a scalar value. C 3 Coordinate 63 triplet, always three; the coordinate type defines the meaning of this 64 dimension. 65 */ 66 unsigned I, C, R, E, N, M; 67 68 struct MYSOFA_ARRAY ListenerPosition; 69 70 struct MYSOFA_ARRAY ReceiverPosition; 71 72 struct MYSOFA_ARRAY SourcePosition; 73 74 struct MYSOFA_ARRAY EmitterPosition; 75 76 struct MYSOFA_ARRAY ListenerUp; 77 78 struct MYSOFA_ARRAY ListenerView; 79 80 /** array of filter coefficients. Sizes are filters*filter_length. */ 81 struct MYSOFA_ARRAY DataIR; 82 83 /** the sampling rate used in this structure */ 84 struct MYSOFA_ARRAY DataSamplingRate; 85 86 /** array of min-phase delays. Sizes are filters */ 87 struct MYSOFA_ARRAY DataDelay; 88 89 /** general file attributes */ 90 struct MYSOFA_ATTRIBUTE *attributes; 91 92 /** additional variables that might be present in a SOFA file */ 93 struct MYSOFA_VARIABLE *variables; 94 }; 95 96 /* structure for lookup HRTF filters */ 97 struct MYSOFA_LOOKUP { 98 void *kdtree; 99 float radius_min, radius_max; 100 float theta_min, theta_max; 101 float phi_min, phi_max; 102 }; 103 104 struct MYSOFA_NEIGHBORHOOD { 105 int elements; 106 int *index; 107 }; 108 109 enum { 110 MYSOFA_OK = 0, 111 MYSOFA_INTERNAL_ERROR = -1, 112 MYSOFA_INVALID_FORMAT = 10000, 113 MYSOFA_UNSUPPORTED_FORMAT, 114 MYSOFA_NO_MEMORY, 115 MYSOFA_READ_ERROR, 116 MYSOFA_INVALID_ATTRIBUTES, 117 MYSOFA_INVALID_DIMENSIONS, 118 MYSOFA_INVALID_DIMENSION_LIST, 119 MYSOFA_INVALID_COORDINATE_TYPE, 120 MYSOFA_ONLY_EMITTER_WITH_ECI_SUPPORTED, 121 MYSOFA_ONLY_DELAYS_WITH_IR_OR_MR_SUPPORTED, 122 MYSOFA_ONLY_THE_SAME_SAMPLING_RATE_SUPPORTED, 123 MYSOFA_RECEIVERS_WITH_RCI_SUPPORTED, 124 MYSOFA_RECEIVERS_WITH_CARTESIAN_SUPPORTED, 125 MYSOFA_INVALID_RECEIVER_POSITIONS, 126 MYSOFA_ONLY_SOURCES_WITH_MC_SUPPORTED 127 }; 128 129 struct MYSOFA_HRTF *mysofa_load(const char *filename, int *err); 130 131 int mysofa_check(struct MYSOFA_HRTF *hrtf); 132 char *mysofa_getAttribute(struct MYSOFA_ATTRIBUTE *attr, char *name); 133 void mysofa_tospherical(struct MYSOFA_HRTF *hrtf); 134 void mysofa_tocartesian(struct MYSOFA_HRTF *hrtf); 135 void mysofa_free(struct MYSOFA_HRTF *hrtf); 136 137 struct MYSOFA_LOOKUP *mysofa_lookup_init(struct MYSOFA_HRTF *hrtf); 138 int mysofa_lookup(struct MYSOFA_LOOKUP *lookup, float *coordinate); 139 void mysofa_lookup_free(struct MYSOFA_LOOKUP *lookup); 140 141 struct MYSOFA_NEIGHBORHOOD * 142 mysofa_neighborhood_init(struct MYSOFA_HRTF *hrtf, 143 struct MYSOFA_LOOKUP *lookup); 144 struct MYSOFA_NEIGHBORHOOD *mysofa_neighborhood_init_withstepdefine( 145 struct MYSOFA_HRTF *hrtf, struct MYSOFA_LOOKUP *lookup, 146 float neighbor_angle_step, float neighbor_radius_step); 147 int *mysofa_neighborhood(struct MYSOFA_NEIGHBORHOOD *neighborhood, int pos); 148 void mysofa_neighborhood_free(struct MYSOFA_NEIGHBORHOOD *neighborhood); 149 150 float *mysofa_interpolate(struct MYSOFA_HRTF *hrtf, float *cordinate, 151 int nearest, int *neighborhood, float *fir, 152 float *delays); 153 154 int mysofa_resample(struct MYSOFA_HRTF *hrtf, float samplerate); 155 float mysofa_loudness(struct MYSOFA_HRTF *hrtf); 156 int mysofa_minphase(struct MYSOFA_HRTF *hrtf, float threshold); 157 158 struct MYSOFA_EASY *mysofa_cache_lookup(const char *filename, float samplerate); 159 struct MYSOFA_EASY *mysofa_cache_store(struct MYSOFA_EASY *, 160 const char *filename, float samplerate); 161 void mysofa_cache_release(struct MYSOFA_EASY *); 162 void mysofa_cache_release_all(void); 163 164 void mysofa_c2s(float *values); 165 void mysofa_s2c(float *values); 166 167 struct MYSOFA_EASY { 168 struct MYSOFA_HRTF *hrtf; 169 struct MYSOFA_LOOKUP *lookup; 170 struct MYSOFA_NEIGHBORHOOD *neighborhood; 171 float *fir; 172 }; 173 174 struct MYSOFA_EASY *mysofa_open(const char *filename, float samplerate, 175 int *filterlength, int *err); 176 struct MYSOFA_EASY *mysofa_open_no_norm(const char *filename, float samplerate, 177 int *filterlength, int *err); 178 struct MYSOFA_EASY *mysofa_open_advanced(const char *filename, float samplerate, 179 int *filterlength, int *err, bool norm, 180 float neighbor_angle_step, 181 float neighbor_radius_step); 182 struct MYSOFA_EASY *mysofa_open_cached(const char *filename, float samplerate, 183 int *filterlength, int *err); 184 void mysofa_getfilter_short(struct MYSOFA_EASY *easy, float x, float y, float z, 185 short *IRleft, short *IRright, int *delayLeft, 186 int *delayRight); 187 void mysofa_getfilter_float(struct MYSOFA_EASY *easy, float x, float y, float z, 188 float *IRleft, float *IRright, float *delayLeft, 189 float *delayRight); 190 void mysofa_getfilter_float_nointerp(struct MYSOFA_EASY *easy, float x, float y, 191 float z, float *IRleft, float *IRright, 192 float *delayLeft, float *delayRight); 193 void mysofa_close(struct MYSOFA_EASY *easy); 194 void mysofa_close_cached(struct MYSOFA_EASY *easy); 195 196 void mysofa_getversion(int *major, int *minor, int *patch); 197 198 #ifdef __cplusplus 199 } 200 #endif 201 #endif 202