2 * SOFA info utility for inspecting SOFA file metrics and determining HRTF
3 * utility compatible layouts.
5 * Copyright (C) 2018-2019 Christopher Fitzgerald
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Or visit: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
29 #include "sofa-support.h"
33 #include "win_main_utf8.h"
35 using uint
= unsigned int;
37 static void PrintSofaAttributes(const char *prefix
, struct MYSOFA_ATTRIBUTE
*attribute
)
41 fprintf(stdout
, "%s.%s: %s\n", prefix
, attribute
->name
, attribute
->value
);
42 attribute
= attribute
->next
;
46 static void PrintSofaArray(const char *prefix
, struct MYSOFA_ARRAY
*array
)
48 PrintSofaAttributes(prefix
, array
->attributes
);
49 for(uint i
{0u};i
< array
->elements
;i
++)
50 fprintf(stdout
, "%s[%u]: %.6f\n", prefix
, i
, array
->values
[i
]);
53 /* Attempts to produce a compatible layout. Most data sets tend to be
54 * uniform and have the same major axis as used by OpenAL Soft's HRTF model.
55 * This will remove outliers and produce a maximally dense layout when
56 * possible. Those sets that contain purely random measurements or use
57 * different major axes will fail.
59 static void PrintCompatibleLayout(const uint m
, const float *xyzs
)
63 auto fds
= GetCompatibleLayout(m
, xyzs
);
66 fprintf(stdout
, "No compatible field layouts in SOFA file.\n");
71 for(size_t fi
{0u};fi
< fds
.size();++fi
)
73 for(uint ei
{fds
[fi
].mEvStart
};ei
< fds
[fi
].mEvCount
;++ei
)
74 used_elems
+= fds
[fi
].mAzCounts
[ei
];
77 fprintf(stdout
, "Compatible Layout (%u of %u measurements):\n\ndistance = %.3f", used_elems
, m
,
79 for(size_t fi
{1u};fi
< fds
.size();fi
++)
80 fprintf(stdout
, ", %.3f", fds
[fi
].mDistance
);
82 fprintf(stdout
, "\nazimuths = ");
83 for(size_t fi
{0u};fi
< fds
.size();++fi
)
85 for(uint ei
{0u};ei
< fds
[fi
].mEvStart
;++ei
)
86 fprintf(stdout
, "%d%s", fds
[fi
].mAzCounts
[fds
[fi
].mEvCount
- 1 - ei
], ", ");
87 for(uint ei
{fds
[fi
].mEvStart
};ei
< fds
[fi
].mEvCount
;++ei
)
88 fprintf(stdout
, "%d%s", fds
[fi
].mAzCounts
[ei
],
89 (ei
< (fds
[fi
].mEvCount
- 1)) ? ", " :
90 (fi
< (fds
.size() - 1)) ? ";\n " : "\n");
94 // Load and inspect the given SOFA file.
95 static void SofaInfo(const char *filename
)
98 MySofaHrtfPtr sofa
{mysofa_load(filename
, &err
)};
101 fprintf(stdout
, "Error: Could not load source file '%s' (%s).\n", filename
,
106 /* NOTE: Some valid SOFA files are failing this check. */
107 err
= mysofa_check(sofa
.get());
109 fprintf(stdout
, "Warning: Supposedly malformed source file '%s' (%s).\n", filename
,
112 mysofa_tocartesian(sofa
.get());
114 PrintSofaAttributes("Info", sofa
->attributes
);
116 fprintf(stdout
, "Measurements: %u\n", sofa
->M
);
117 fprintf(stdout
, "Receivers: %u\n", sofa
->R
);
118 fprintf(stdout
, "Emitters: %u\n", sofa
->E
);
119 fprintf(stdout
, "Samples: %u\n", sofa
->N
);
121 PrintSofaArray("SampleRate", &sofa
->DataSamplingRate
);
122 PrintSofaArray("DataDelay", &sofa
->DataDelay
);
124 PrintCompatibleLayout(sofa
->M
, sofa
->SourcePosition
.values
);
127 int main(int argc
, char *argv
[])
131 fprintf(stdout
, "Usage: %s <sofa-file>\n", argv
[0]);