VAE - Virtual Audio Engine 1
Small Data Driven Audio Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
vae_hrtf_loader.hpp
Go to the documentation of this file.
1#ifndef _VAE_HRTF_LOADER
2#define _VAE_HRTF_LOADER
3
4#include "../vae_types.hpp"
5#include "../vae_util.hpp"
6#include "../vae_config.hpp"
7#include "../pod/vae_hrtf.hpp"
8
9#include "../../wrapped/vae_fs.hpp"
10
11#ifndef _JSON_H
12 #include "../../../external/headeronly/json.h"
13 #include "../../../external/headeronly/json.c"
14#endif
15
16#include "../../../external/glm/glm/gtc/matrix_transform.hpp"
17// #include "../../../external/tklb/src/types/audio/resampler/TResampler.hpp"
18// #include "../../../external/tklb/src/types/audio/fft/TOouraFFT.hpp"
19
20namespace vae { namespace core {
21 class HRTFLoader {
22 static void* allocate(size_t size, int zero, void* context) {
24 void* ptr = reinterpret_cast<void*>(allocator.allocate(size));
25 if (zero) {
26 memset(ptr, 0, size);
27 }
28 return ptr;
29 }
30
31 static void deallocate(void* ptr, void* context) {
33 allocator.deallocate(reinterpret_cast<char*>(ptr), 0);
34 }
35 public:
36 Result load(const char* path, Size length, const char* rootPath, const Size sampleRate, HRTF& hrtf) {
38
39 /**
40 * Open file and decode json
41 */
42 const char* encoded = path; // The plain json text
43
44 String jsonText;
45 if (length == 0) { // length 0 indicates the file is on disk
46 #ifndef VAE_NO_STDIO
47 VAE_DEBUG("Started loading HRTF %s", path)
49 PathString folder;
50 folder = rootPath;
51 folder.append(path);
52
53 fs::File file(folder.c_str());
54 jsonText.resize(file.size());
55 if (!file.readAll(jsonText.data())) {
57 }
58 length = jsonText.size();
59 encoded = jsonText.c_str();
60 #else
62 #endif
63 }
64
65
66
67
68 json_settings settings = { };
69 settings.mem_alloc = allocate;
70 settings.mem_free = deallocate;
71
72 json_value* json;
73 {
74 VAE_PROFILER_SCOPE_NAMED("HRTF Parse")
75 json = json_parse_ex(&settings, encoded, length, 0);
76 }
77 if (json == nullptr) {
78 VAE_ERROR("Failed to parse HRTF")
80 }
81 json_value& data = (*json);
82
83 hrtf.rate = sampleRate;
84 hrtf.originalRate = (json_int_t) data["samplerate"];
85
86 Vec3 up = {
87 float((double) data["up"][0]),
88 float((double) data["up"][1]),
89 float((double) data["up"][2]),
90 };
91
92 Vec3 front = {
93 float((double) data["front"][0]),
94 float((double) data["front"][1]),
95 float((double) data["front"][2]),
96 };
97
99 Vec3 frontNeed = Vec3(ref.front.x, ref.front.y, ref.front.z);
100 Vec3 upNeed = Vec3(ref.up.x, ref.up.y, ref.up.z);
101
102 glm::mat4x4 matchCoord = glm::lookAt(
103 Vec3(0.f, 0.f, 0.f),
104 front,
105 up
106 );
107
108 Vec3 up1 = (matchCoord * glm::vec4(up, 1.f));
109 Vec3 front1 = (matchCoord * glm::vec4(front, 1.f));
110 // These should match upNeed
111
112 auto& positions = data["positions"].u.array;
113 const Size positionCount = positions.length;
114 hrtf.positions.resize(positionCount);
115
116 const bool needsResample = hrtf.originalRate != sampleRate;
117 if (needsResample) {
118 // TODO
119 VAE_ERROR("Can't open HRTF, resampling needed!")
121 }
122
123 Size maxIrLength = 0;
124 {
125 VAE_PROFILER_SCOPE_NAMED("HRTF Convert")
126 for (Size i = 0; i < positionCount; i++) {
127 HRTF::Position& p = hrtf.positions[i];
128 auto& pi = *positions.values[i];
129 glm::vec4 pos((double) pi["x"], (double)pi["y"], (double)pi["z"], 1.0);
130 p.pos = matchCoord * pos;
131 json_value irSamples[2] = { pi["left"], pi["right"]};
132 const Size irLength = irSamples[0].u.array.length;
133 maxIrLength = std::max(maxIrLength, irLength);
134 for (int c = 0; c < 2; c++) {
135 p.ir[c].resize(irLength, 1);
136 for (Size j = 0; j < irLength; j++) {
137 p.ir[c][0][j] = (double) *(irSamples[c].u.array.values[j]);
138 }
139 }
140 }
141 }
142
143 hrtf.irLength = maxIrLength;
144 {
145 VAE_PROFILER_SCOPE_NAMED("HRTF Dealloc")
146 json_value_free_ex(&settings, json);
147 }
148
149 VAE_DEBUG("Finished loading HRTF %s", path)
150
151 return Result::Success;
152 }
153 };
154} } // namespace vae::vore
155
156#endif // _VAE_HRTF_LOADER
bool resize(const Size length, uchar channels)
! Will not keep the contents! Resizes the buffer to the desired length and channel count.
const char * c_str() const
Definition: TString.hpp:83
Size size() const
Definition: TString.hpp:86
void resize(Size size)
Definition: TString.hpp:131
void append(const String &str)
Definition: TString.hpp:102
char * data()
Definition: TString.hpp:89
Result load(const char *path, Size length, const char *rootPath, const Size sampleRate, HRTF &hrtf)
static void * allocate(size_t size, int zero, void *context)
static void deallocate(void *ptr, void *context)
bool readAll(char *dest)
Definition: vae_fs.hpp:72
T max(const T &v1, const T &v2)
Definition: TMath.hpp:21
glm::vec3 Vec3
Definition: vae_types.hpp:47
Contains Typedefinitions and basic structures use by the public API and internally.
Definition: vae.hpp:31
unsigned int Size
How the elements are addressed in the heapbuffer.
Definition: vae.hpp:33
Result
Return Types for most engine functions.
Definition: vae.hpp:73
@ FileOpenError
File system could not load file.
@ BankFormatError
Generic bank loading error.
@ GenericFailure
:(
Listener uses additional up vector.
Definition: vae.hpp:133
Vector3 up
Y up.
Definition: vae.hpp:136
Vector3 front
-z front
Definition: vae.hpp:135
float y
Definition: vae.hpp:115
float z
Definition: vae.hpp:115
float x
Definition: vae.hpp:115
AudioBuffer ir[2]
Impulse response needed for the convolution.
Definition: vae_hrtf.hpp:11
HeapBuffer< Position > positions
Definition: vae_hrtf.hpp:13
Allocator used for all heapbuffers in VAE.
T * allocate(size_t n) noexcept
void deallocate(T *ptr, std::size_t n) noexcept
#define VAE_ERROR(msg,...)
Definition: vae_logger.hpp:80
#define VAE_DEBUG(msg,...)
Definition: vae_logger.hpp:83
#define VAE_PROFILER_SCOPE_NAMED(name)
Profiles a scope and names it.
#define VAE_PROFILER_SCOPE()
Profiles a scope.