1 #include "../hrtf/mysofa.h"
2 #include "../hrtf/tools.h"
3 #include "json.h"
4 #include "tests.h"
5 #include <float.h>
6 #include <math.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 
11 #ifndef M_PI
12 #define M_PI (3.14159265358979323846)
13 #endif
14 
15 /* #define VDEBUG */
16 
test_easy_open()17 void test_easy_open() {
18   struct MYSOFA_EASY *easy;
19   int err = 0;
20   int filterlength;
21 
22   easy = mysofa_open("tests/MIT_KEMAR_normal_pinna.old.sofa", 8000.,
23                      &filterlength, &err);
24   if (!easy) {
25     CU_FAIL_FATAL("Error reading file.");
26     return;
27   }
28 
29   mysofa_close(easy);
30 }
31 
test_easy()32 void test_easy() {
33   struct MYSOFA_EASY *easy;
34   int err = 0;
35   int filterlength;
36   int filters = 0;
37   float theta, r;
38   float *coordinates;
39   float *ir;
40   float *delays;
41   int count = 0;
42   FILE *file;
43   float c[3];
44   float l1, l2;
45   float sdiff1, sdiff2, diff1, diff2;
46 
47   easy = mysofa_open("tests/tester.sofa", 48000, &filterlength, &err);
48   if (!easy) {
49     CU_FAIL_FATAL("Error reading file.");
50     return;
51   }
52   mysofa_minphase(easy->hrtf, 0.01);
53 
54   for (filters = 0; filters < easy->hrtf->M; filters++) {
55     c[0] = easy->hrtf->SourcePosition.values[filters * 3];
56     c[1] = easy->hrtf->SourcePosition.values[filters * 3 + 1];
57     c[2] = easy->hrtf->SourcePosition.values[filters * 3 + 2];
58     mysofa_c2s(c);
59 
60 #ifdef VDEBUG
61     printf("in %d %f %f %f # %f %f %f\n", filters, c[0], c[1], c[2],
62            easy->hrtf->SourcePosition.values[filters * 3],
63            easy->hrtf->SourcePosition.values[filters * 3 + 1],
64            easy->hrtf->SourcePosition.values[filters * 3 + 2]);
65 #endif
66     c[0] = fmod(round(c[0] + 360), 360);
67     c[1] = fmod(round(c[1] + 361), 360);
68     l1 = round(easy->hrtf->DataDelay.values[filters * 2] * 48000 * 2);
69     l2 = round(easy->hrtf->DataDelay.values[filters * 2 + 1] * 48000 * 2);
70 
71 #ifdef VDEBUG
72     /*   		printf("compare %d %f %f %f %f
73      * %f\n",filters,c[0],c[1],c[2],l1,l2);
74      */
75 #endif
76     CU_ASSERT(
77         !((fabs(c[0] - l1) > 2 || fabs(c[1] - l2) > 2) && !fequals(l2, 90)));
78   }
79 
80   filters = 0;
81   for (theta = -90.; theta <= 90.; theta += 5.) {
82     r = round(cos(theta * M_PI / 180.) * 120.);
83     if (r == 0.)
84       r = 1;
85     filters += r;
86   }
87 #ifdef VDEBUG
88   printf("Filters %d\n", filters);
89 #endif
90 
91   coordinates = malloc(filters * sizeof(float) * 3);
92   ir = malloc(filters * easy->hrtf->N * sizeof(float) * 2);
93   delays = malloc(filters * 2 * sizeof(float));
94 
95   sdiff1 = sdiff2 = 0;
96   err = 0;
97   for (theta = -90.; theta <= 90.; theta += 5.) {
98     int r = round(cos(theta * M_PI / 180.) * 120.);
99     int phi;
100     if (r == 0)
101       r = 1;
102     for (phi = 0; phi < r; phi++) {
103       coordinates[count * 3 + 0] = phi * (360. / r);
104       coordinates[count * 3 + 1] = theta;
105       coordinates[count * 3 + 2] = 1;
106       mysofa_s2c(coordinates + count * 3);
107 #ifdef VDEBUG
108       printf("req %f %f %d %f %f %f\n", phi * (360. / r), theta, count,
109              coordinates[count * 3 + 0], coordinates[count * 3 + 1],
110              coordinates[count * 3 + 2]);
111 #endif
112       mysofa_getfilter_float(
113           easy, coordinates[count * 3 + 0], coordinates[count * 3 + 1],
114           coordinates[count * 3 + 2], ir + 2 * count * easy->hrtf->N,
115           ir + (2 * count + 1) * easy->hrtf->N, &delays[2 * count],
116           &delays[2 * count + 1]);
117       diff1 = fabs(phi * (360. / r) - delays[2 * count] * 48000 * 2);
118       diff2 = fabs(fmod(theta + 360, 360) - delays[2 * count + 1] * 48000 * 2);
119       if (diff1 > 5 || diff2 > 5)
120         err++;
121       else {
122         sdiff1 += diff1;
123         sdiff2 += diff2;
124       }
125 
126 #ifdef VDEBUG
127       printf("diff %f %f\t", diff1, diff2);
128       printf("delays %f %f %f %f\n", phi * (360. / r), fmod(theta + 360, 360),
129              delays[2 * count] * 48000 * 2, delays[2 * count + 1] * 48000 * 2);
130 #endif
131       count++;
132     }
133   }
134   err = err * 100. / count;
135   sdiff1 = sdiff1 / (count - err);
136   sdiff2 = sdiff2 / (count - err);
137 
138 #ifdef VDEBUG
139   printf("errors %f%% diffs %f %f\n", err * 100. / count,
140          sdiff1 / (count - err), sdiff2 / (count - err));
141 #endif
142   CU_ASSERT(err < 31.7);
143   CU_ASSERT(sdiff1 < 1.67);
144   CU_ASSERT(sdiff2 < 1.43);
145 
146   free(easy->hrtf->DataDelay.values);
147   free(easy->hrtf->DataIR.values);
148   free(easy->hrtf->SourcePosition.values);
149   easy->hrtf->DataDelay.elements = filters * 2;
150   easy->hrtf->DataDelay.values = delays;
151   easy->hrtf->DataIR.elements = filters * 2 * easy->hrtf->N;
152   easy->hrtf->DataIR.values = ir;
153   easy->hrtf->SourcePosition.elements = filters * 3;
154   easy->hrtf->SourcePosition.values = coordinates;
155   easy->hrtf->M = filters;
156 
157   file = fopen("/tmp/easy.tmp.json", "w");
158   CU_ASSERT(file != NULL);
159   printJson(file, easy->hrtf, 0);
160   fclose(file);
161 
162   mysofa_close(easy);
163 }
164 
test_easy_nonorm()165 void test_easy_nonorm() {
166   struct MYSOFA_EASY *easy;
167   int err = 0;
168   int filterlength;
169   int filters = 0;
170   float diff1, diff2;
171 
172   /* Test raw opening (no norm) and MxR delay .sofa */
173   easy = mysofa_open_no_norm("tests/tester2.sofa", 48000., &filterlength, &err);
174   if (!easy) {
175     CU_FAIL_FATAL("Error reading file.");
176     return;
177   }
178 
179   err = 0;
180 
181   for (filters = 0; filters < easy->hrtf->M; filters++) {
182     // see tester2.sofa file creation in tester2.m file
183     diff1 = filters - easy->hrtf->DataDelay.values[easy->hrtf->R * filters];
184     diff2 = filters + easy->hrtf->DataDelay.values[easy->hrtf->R * filters + 1];
185     if (diff1 > 0.1 || diff2 > 0.1)
186       err++;
187 #ifdef VDEBUG
188     printf("delays: %f %f \t",
189            easy->hrtf->DataDelay.values[easy->hrtf->R * filters],
190            easy->hrtf->DataDelay.values[easy->hrtf->R * filters + 1]);
191     printf("diff: %f %f %i\n", diff1, diff2, err);
192 #endif
193   }
194   CU_ASSERT(err < 1);
195 
196   mysofa_close(easy);
197 }
198