diff --git a/CMakeLists.txt b/CMakeLists.txt index 329c30e..895f9d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,7 +84,9 @@ if(BUILD_TESTS) 137 138 156 - 163) + 163 + 167a + 167b) # issues with osx 96) add_test(fail-issue-${ISSUE} ${PROJECT_SOURCE_DIR}/tests/notcrashed.sh ${PROJECT_SOURCE_DIR}/tests/fail-issue-${ISSUE}) diff --git a/src/hrtf/easy.c b/src/hrtf/easy.c index 011c9c1..2f67ffe 100644 --- a/src/hrtf/easy.c +++ b/src/hrtf/easy.c @@ -21,11 +21,13 @@ static struct MYSOFA_EASY * mysofa_open_default(const char *filename, float samplerate, int *filterlength, int *err, bool applyNorm, float neighbor_angle_step, - float neighbor_radius_step) { + float neighbor_radius_step) +{ struct MYSOFA_EASY *easy = malloc(sizeof(struct MYSOFA_EASY)); - if (!easy) { + if (!easy) + { *err = MYSOFA_NO_MEMORY; return NULL; } @@ -35,24 +37,28 @@ mysofa_open_default(const char *filename, float samplerate, int *filterlength, *easy = (struct MYSOFA_EASY){0}; easy->hrtf = mysofa_load(filename, err); - if (!easy->hrtf) { + if (!easy->hrtf) + { mysofa_close(easy); return NULL; } *err = mysofa_check(easy->hrtf); - if (*err != MYSOFA_OK) { + if (*err != MYSOFA_OK) + { mysofa_close(easy); return NULL; } *err = mysofa_resample(easy->hrtf, samplerate); - if (*err != MYSOFA_OK) { + if (*err != MYSOFA_OK) + { mysofa_close(easy); return NULL; } - if (applyNorm) { + if (applyNorm) + { mysofa_loudness(easy->hrtf); } @@ -62,8 +68,16 @@ mysofa_open_default(const char *filename, float samplerate, int *filterlength, mysofa_tocartesian(easy->hrtf); + if (easy->hrtf->SourcePosition.elements != easy->hrtf->C * easy->hrtf->M) + { + *err = MYSOFA_INVALID_FORMAT; + mysofa_close(easy); + return NULL; + } + easy->lookup = mysofa_lookup_init(easy->hrtf); - if (easy->lookup == NULL) { + if (easy->lookup == NULL) + { *err = MYSOFA_INTERNAL_ERROR; mysofa_close(easy); return NULL; @@ -82,7 +96,8 @@ mysofa_open_default(const char *filename, float samplerate, int *filterlength, MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_open(const char *filename, float samplerate, - int *filterlength, int *err) { + int *filterlength, int *err) +{ return mysofa_open_default(filename, samplerate, filterlength, err, true, MYSOFA_DEFAULT_NEIGH_STEP_ANGLE, MYSOFA_DEFAULT_NEIGH_STEP_RADIUS); @@ -91,7 +106,8 @@ MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_open(const char *filename, MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_open_no_norm(const char *filename, float samplerate, int *filterlength, - int *err) { + int *err) +{ return mysofa_open_default(filename, samplerate, filterlength, err, false, MYSOFA_DEFAULT_NEIGH_STEP_ANGLE, MYSOFA_DEFAULT_NEIGH_STEP_RADIUS); @@ -100,7 +116,8 @@ MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_open_no_norm(const char *filename, MYSOFA_EXPORT struct MYSOFA_EASY * mysofa_open_advanced(const char *filename, float samplerate, int *filterlength, int *err, bool norm, float neighbor_angle_step, - float neighbor_radius_step) { + float neighbor_radius_step) +{ return mysofa_open_default(filename, samplerate, filterlength, err, norm, neighbor_angle_step, neighbor_radius_step); } @@ -108,14 +125,17 @@ mysofa_open_advanced(const char *filename, float samplerate, int *filterlength, MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_open_cached(const char *filename, float samplerate, int *filterlength, - int *err) { + int *err) +{ struct MYSOFA_EASY *res = mysofa_cache_lookup(filename, samplerate); - if (res) { + if (res) + { *filterlength = res->hrtf->N; return res; } res = mysofa_open(filename, samplerate, filterlength, err); - if (res) { + if (res) + { res = mysofa_cache_store(res, filename, samplerate); } return res; @@ -124,7 +144,8 @@ MYSOFA_EXPORT struct MYSOFA_EASY *mysofa_open_cached(const char *filename, MYSOFA_EXPORT void mysofa_getfilter_short(struct MYSOFA_EASY *easy, float x, float y, float z, short *IRleft, short *IRright, int *delayLeft, - int *delayRight) { + int *delayRight) +{ float c[3]; float delays[2]; float *fl; @@ -147,7 +168,8 @@ MYSOFA_EXPORT void mysofa_getfilter_short(struct MYSOFA_EASY *easy, float x, fl = easy->fir; fr = easy->fir + easy->hrtf->N; - for (i = easy->hrtf->N; i > 0; i--) { + for (i = easy->hrtf->N; i > 0; i--) + { *IRleft++ = (short)(*fl++ * 32767.); *IRright++ = (short)(*fr++ * 32767.); } @@ -155,7 +177,8 @@ MYSOFA_EXPORT void mysofa_getfilter_short(struct MYSOFA_EASY *easy, float x, MYSOFA_EXPORT void mysofa_getfilter_float_advanced( struct MYSOFA_EASY *easy, float x, float y, float z, float *IRleft, - float *IRright, float *delayLeft, float *delayRight, bool interpolate) { + float *IRright, float *delayLeft, float *delayRight, bool interpolate) +{ float c[3]; float delays[2]; float *fl; @@ -172,7 +195,8 @@ MYSOFA_EXPORT void mysofa_getfilter_float_advanced( neighbors = mysofa_neighborhood(easy->neighborhood, nearest); // bypass interpolate by forcing current cooordinates to nearest's - if (!interpolate) { + if (!interpolate) + { memcpy(c, easy->hrtf->SourcePosition.values + nearest * easy->hrtf->C, sizeof(float) * easy->hrtf->C); } @@ -185,7 +209,8 @@ MYSOFA_EXPORT void mysofa_getfilter_float_advanced( fl = res; fr = res + easy->hrtf->N; - for (i = easy->hrtf->N; i > 0; i--) { + for (i = easy->hrtf->N; i > 0; i--) + { *IRleft++ = *fl++; *IRright++ = *fr++; } @@ -194,7 +219,8 @@ MYSOFA_EXPORT void mysofa_getfilter_float_advanced( MYSOFA_EXPORT void mysofa_getfilter_float(struct MYSOFA_EASY *easy, float x, float y, float z, float *IRleft, float *IRright, float *delayLeft, - float *delayRight) { + float *delayRight) +{ mysofa_getfilter_float_advanced(easy, x, y, z, IRleft, IRright, delayLeft, delayRight, true); } @@ -202,13 +228,16 @@ MYSOFA_EXPORT void mysofa_getfilter_float(struct MYSOFA_EASY *easy, float x, MYSOFA_EXPORT void mysofa_getfilter_float_nointerp(struct MYSOFA_EASY *easy, float x, float y, float z, float *IRleft, float *IRright, - float *delayLeft, float *delayRight) { + float *delayLeft, float *delayRight) +{ mysofa_getfilter_float_advanced(easy, x, y, z, IRleft, IRright, delayLeft, delayRight, false); } -MYSOFA_EXPORT void mysofa_close(struct MYSOFA_EASY *easy) { - if (easy) { +MYSOFA_EXPORT void mysofa_close(struct MYSOFA_EASY *easy) +{ + if (easy) + { if (easy->fir) free(easy->fir); if (easy->neighborhood) @@ -221,6 +250,7 @@ MYSOFA_EXPORT void mysofa_close(struct MYSOFA_EASY *easy) { } } -MYSOFA_EXPORT void mysofa_close_cached(struct MYSOFA_EASY *easy) { +MYSOFA_EXPORT void mysofa_close_cached(struct MYSOFA_EASY *easy) +{ mysofa_cache_release(easy); } diff --git a/src/hrtf/lookup.c b/src/hrtf/lookup.c index 53579ec..fbaea57 100644 --- a/src/hrtf/lookup.c +++ b/src/hrtf/lookup.c @@ -16,7 +16,8 @@ #include "tools.h" MYSOFA_EXPORT struct MYSOFA_LOOKUP * -mysofa_lookup_init(struct MYSOFA_HRTF *hrtf) { +mysofa_lookup_init(struct MYSOFA_HRTF *hrtf) +{ int i; struct MYSOFA_LOOKUP *lookup; @@ -42,26 +43,33 @@ mysofa_lookup_init(struct MYSOFA_HRTF *hrtf) { lookup->theta_max = FLT_MIN; lookup->radius_min = FLT_MAX; lookup->radius_max = FLT_MIN; - for (i = 0; i < hrtf->M; i++) { + for (i = 0; i < hrtf->M; i++) + { memcpy(origin, hrtf->SourcePosition.values + i * hrtf->C, sizeof(float) * hrtf->C); convertCartesianToSpherical(origin, hrtf->C); - if (origin[0] < lookup->phi_min) { + if (origin[0] < lookup->phi_min) + { lookup->phi_min = origin[0]; } - if (origin[0] > lookup->phi_max) { + if (origin[0] > lookup->phi_max) + { lookup->phi_max = origin[0]; } - if (origin[1] < lookup->theta_min) { + if (origin[1] < lookup->theta_min) + { lookup->theta_min = origin[1]; } - if (origin[1] > lookup->theta_max) { + if (origin[1] > lookup->theta_max) + { lookup->theta_max = origin[1]; } - if (origin[2] < lookup->radius_min) { + if (origin[2] < lookup->radius_min) + { lookup->radius_min = origin[2]; } - if (origin[2] > lookup->radius_max) { + if (origin[2] > lookup->radius_max) + { lookup->radius_max = origin[2]; } } @@ -71,7 +79,8 @@ mysofa_lookup_init(struct MYSOFA_HRTF *hrtf) { * Allocate kd tree */ lookup->kdtree = kd_create(); - if (!lookup->kdtree) { + if (!lookup->kdtree) + { free(lookup); return NULL; } @@ -79,7 +88,8 @@ mysofa_lookup_init(struct MYSOFA_HRTF *hrtf) { /* * add coordinates to the tree */ - for (i = 0; i < hrtf->M; i++) { + for (i = 0; i < hrtf->M; i++) + { float *f = hrtf->SourcePosition.values + i * hrtf->C; kd_insert((struct kdtree *)lookup->kdtree, f, (void *)(intptr_t)i); } @@ -93,18 +103,22 @@ mysofa_lookup_init(struct MYSOFA_HRTF *hrtf) { * A return value of -1 = MYSOFA_INTERNAL_ERROR indicates an error */ MYSOFA_EXPORT int mysofa_lookup(struct MYSOFA_LOOKUP *lookup, - float *coordinate) { + float *coordinate) +{ int index; void *res; int success; float r = radius(coordinate); - if (r > lookup->radius_max) { + if (r > lookup->radius_max) + { r = lookup->radius_max / r; coordinate[0] *= r; coordinate[1] *= r; coordinate[2] *= r; - } else if (r < lookup->radius_min) { + } + else if (r < lookup->radius_min) + { r = lookup->radius_min / r; coordinate[0] *= r; coordinate[1] *= r; @@ -112,15 +126,18 @@ MYSOFA_EXPORT int mysofa_lookup(struct MYSOFA_LOOKUP *lookup, } success = kd_nearest((struct kdtree *)lookup->kdtree, coordinate, &res); - if (success != 0) { + if (success != 0) + { return MYSOFA_INTERNAL_ERROR; } index = (uintptr_t)res; return index; } -MYSOFA_EXPORT void mysofa_lookup_free(struct MYSOFA_LOOKUP *lookup) { - if (lookup) { +MYSOFA_EXPORT void mysofa_lookup_free(struct MYSOFA_LOOKUP *lookup) +{ + if (lookup) + { kd_free((struct kdtree *)lookup->kdtree); free(lookup); } diff --git a/src/hrtf/resample.c b/src/hrtf/resample.c index ee2a03a..9de7a6d 100644 --- a/src/hrtf/resample.c +++ b/src/hrtf/resample.c @@ -15,7 +15,8 @@ #include #include -MYSOFA_EXPORT int mysofa_resample(struct MYSOFA_HRTF *hrtf, float samplerate) { +MYSOFA_EXPORT int mysofa_resample(struct MYSOFA_HRTF *hrtf, float samplerate) +{ int i, err; float factor; unsigned newN; @@ -24,7 +25,7 @@ MYSOFA_EXPORT int mysofa_resample(struct MYSOFA_HRTF *hrtf, float samplerate) { float *out; float zero[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - if (hrtf->DataSamplingRate.elements != 1 || samplerate < 8000.) + if (hrtf->DataSamplingRate.elements != 1 || samplerate < 8000. || hrtf->DataIR.elements != hrtf->R * hrtf->M * hrtf->N) return MYSOFA_INVALID_FORMAT; if (samplerate == hrtf->DataSamplingRate.values[0]) @@ -36,20 +37,21 @@ MYSOFA_EXPORT int mysofa_resample(struct MYSOFA_HRTF *hrtf, float samplerate) { /* * resample FIR filter */ + values = malloc(newN * hrtf->R * hrtf->M * sizeof(float)); if (values == NULL) return MYSOFA_NO_MEMORY; resampler = speex_resampler_init(1, hrtf->DataSamplingRate.values[0], samplerate, 10, &err); - if (resampler == NULL) { + if (resampler == NULL) + { free(values); return err; } - out = malloc(sizeof(float) * - (newN + speex_resampler_get_output_latency(resampler))); - for (i = 0; i < hrtf->R * hrtf->M; i++) { + for (i = 0; i < hrtf->R * hrtf->M; i++) + { unsigned inlen = hrtf->N; unsigned outlen = newN; speex_resampler_reset_mem(resampler); @@ -58,15 +60,16 @@ MYSOFA_EXPORT int mysofa_resample(struct MYSOFA_HRTF *hrtf, float samplerate) { hrtf->DataIR.values + i * hrtf->N, &inlen, values + i * newN, &outlen); assert(inlen == hrtf->N); - while (outlen < newN) { + while (outlen < newN) + { unsigned difflen = newN - outlen; inlen = 10; speex_resampler_process_float(resampler, 0, zero, &inlen, values + i * newN + outlen, &difflen); outlen += difflen; } + assert(outlen == newN); } - free(out); speex_resampler_destroy(resampler); free(hrtf->DataIR.values); diff --git a/tests/fail-issue-167a.sofa b/tests/fail-issue-167a.sofa new file mode 100755 index 0000000..b3b3735 Binary files /dev/null and b/tests/fail-issue-167a.sofa differ diff --git a/tests/fail-issue-167b.sofa b/tests/fail-issue-167b.sofa new file mode 100755 index 0000000..39b77fa Binary files /dev/null and b/tests/fail-issue-167b.sofa differ diff --git a/tests/notcrashed.sh b/tests/notcrashed.sh index 086a260..89b7b15 100755 --- a/tests/notcrashed.sh +++ b/tests/notcrashed.sh @@ -1,6 +1,6 @@ #!/bin/sh test -f "$1".sofa || exit 128 -../build/src/mysofa2json "$1".sofa >/dev/null 2>/dev/null +../build/src/mysofa2json -c "$1".sofa >/dev/null 2>/dev/null ret=$? if [ "$ret" -ge 128 ]; then echo mysofa2json crashed with $ret opening$1.sofa