VAE - Virtual Audio Engine 1
Small Data Driven Audio Engine
vae_hrtf_util.hpp
Go to the documentation of this file.
1#ifndef _VAE_HRTF_UTIL
2#define _VAE_HRTF_UTIL
3
4#include "../vae_types.hpp"
5#include "../vae_util.hpp"
6#include "../pod/vae_hrtf.hpp"
7#include "../voices/vae_voice_hrtf.hpp"
8#include <limits>
9
10namespace vae { namespace core {
11 struct HRTFUtil {
12 /**
13 * @brief Looks for the best matching IR in a HRTF
14 * @details Does bad brute force search, should use kd tree or the mysodalib
15 * @param hrtf
16 * @param direction
17 * @return Size
18 */
19 static inline Size closest(const HRTF& hrtf, const Vec3& direction) {
20 // TODO this is obviously bad
21 VAE_PROFILER_SCOPE_NAMED("Search HRTF")
23 Size closestIndex = ~0;
24 for (Size i = 0; i < hrtf.positions.size(); i++) {
25 const auto& pos = hrtf.positions[i];
26 const Sample dist = glm::distance(pos.pos, direction);
27 if (dist < closest) {
28 closestIndex = i;
29 closest = dist;
30 if (closest < 0.05) {
31 break; // * close enough
32 }
33 }
34 }
35 return closestIndex;
36 };
37
38 /**
39 * @brief Applies simple time domain convolution
40 *
41 * @param hrtf HRTF to use
42 * @param hrtfVoice Convolution data for the voice
43 * @param frames Number of frames
44 * @param target Target buffer to mix into
45 * @param in Signal to convolve
46 * @param distanceAttenuated Volume applied
47 */
48 static inline void apply(
49 HRTF::Position& hrtf, VoiceHRTF& hrtfVoice, SampleIndex frames,
50 ScratchBuffer& target, const Sample* in, Sample distanceAttenuated
51 ) {
52 VAE_PROFILER_SCOPE_NAMED("Apply HRTF")
53 const Sample* irLeft = hrtf.ir[0][0];
54 const Sample* irRight = hrtf.ir[1][0];
55 const Size irLen = hrtf.ir[0].size();
56 Sample* convolutionBuffer = hrtfVoice.convolutionBuffer[0];
57 Size convolutionIndex = hrtfVoice.convolutionIndex;
58 // TODO bad brute force convolution in time domain
59 for (SampleIndex i = 0; i < frames; i++) {
60 Sample leftSum = 0;
61 Sample rightSum = 0;
62 convolutionBuffer[convolutionIndex] = in[i];
63
64 for (SampleIndex n = 0; n < irLen; n++) {
65 const Sample conv = convolutionBuffer[(irLen + convolutionIndex - n) % irLen];
66 leftSum += irLeft[n] * conv;
67 rightSum += irRight[n] * conv;
68 }
69 target[0][i] += leftSum * distanceAttenuated;
70 target[1][i] += rightSum * distanceAttenuated;
71 convolutionIndex = (convolutionIndex + 1) % irLen;
72 }
73 hrtfVoice.convolutionIndex = convolutionIndex;
74 }
75 }; // HRTFUtil
76} } // core::vae
77
78#endif // _VAE_HRTF_UTIL
Size size() const
Returns the allocated length of the buffer.
T max(const T &v1, const T &v2)
Definition: TMath.hpp:21
AudioBuffer::Size SampleIndex
Definition: vae_types.hpp:87
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
float Sample
Default sample types used where ever possible, changing this means the engine needs to be recompiled,...
Definition: vae.hpp:32
AudioBuffer ir[2]
Impulse response needed for the convolution.
Definition: vae_hrtf.hpp:11
HeapBuffer< Position > positions
Definition: vae_hrtf.hpp:13
static Size closest(const HRTF &hrtf, const Vec3 &direction)
Looks for the best matching IR in a HRTF.
static void apply(HRTF::Position &hrtf, VoiceHRTF &hrtfVoice, SampleIndex frames, ScratchBuffer &target, const Sample *in, Sample distanceAttenuated)
Applies simple time domain convolution.
Data needed to process HRTFs.
ScratchBuffer convolutionBuffer
Temporary buffer for the convolution.
Size convolutionIndex
position in convolution buffer
#define VAE_PROFILER_SCOPE_NAMED(name)
Profiles a scope and names it.