-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPlugin_HoaLibrary_Spatializer.cpp
executable file
·195 lines (154 loc) · 7.26 KB
/
Plugin_HoaLibrary_Spatializer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
//==============================================================================
// HoaLibrary for Unity - version 1.0.0
// https://github.com/CICM/HoaLibrary-Unity
// Copyright (c) 2019, Eliott Paris, CICM, ArTeC.
// For information on usage and redistribution, and for a DISCLAIMER OF ALL
// WARRANTIES, see the file, "LICENSE.txt," in this distribution.
// Thirdparty :
// - HoaLibrary-Light: https://github.com/CICM/HoaLibrary-Light
// - Unity nativeaudioplugins SDK: https://bitbucket.org/Unity-Technologies/nativeaudioplugins.
//==============================================================================
// Please note that this plugin will only work on Unity 5.2 or higher.
#include "HoaLibraryUnity.h"
#include "AudioPluginInterface.h"
#include "AudioPluginUtil.h"
namespace HoaLibrary_Spatializer
{
using namespace HoaLibraryUnity;
using source_id_t = HoaLibraryApi::source_id_t;
using effect_definition_t = UnityAudioEffectDefinition;
using param_definition_t = UnityAudioParameterDefinition;
using effect_state_t = UnityAudioEffectState;
//==============================================================================
// Processor
//==============================================================================
//! @brief Sends audio and spatialization data to the HoaLibrary System
class HoaAudioProcessor
{
public:
// parameters
enum Param
{
DistanceAttenuation,
Gain,
CustomFalloff,
Optim,
Size
};
HoaAudioProcessor() = default;
~HoaAudioProcessor() = default;
static int registerEffect(effect_definition_t& definition)
{
const int numparams = Param::Size;
definition.paramdefs = new param_definition_t[numparams];
RegisterParameter(definition, "Attenuation", "",
0.0f, 1.0f, 1.0f, 1.0f, 1.0f, Param::DistanceAttenuation,
"AudioSource distance attenuation");
RegisterParameter(definition, "Gain", "dB",
0.f, 20.f, 0.0f, 1.0f, 1.0f, Param::Gain,
"Additional gain");
RegisterParameter(definition, "Custom Falloff", "",
0.0f, 1.0f, 0.0f, 1.0f, 1.0f, Param::CustomFalloff,
"Custom volume falloff amount (logarithmic)");
RegisterParameter(definition, "Optim", "",
0.0f, 2.0f, 0.0f, 1.0f, 1.0f, Param::Optim,
"Ambisonic optimization (Basic | MaxRe | inPhase)");
// required flag to be recognized as a spatialiser plugin by unity
definition.flags |= UnityAudioEffectDefinitionFlags_IsSpatializer;
return numparams;
}
//! @brief Called when the plugin is created
void create(effect_state_t* state)
{
state->effectdata = this;
if (isHostCompatible(state))
state->spatializerdata->distanceattenuationcallback = DistanceAttenuationCallback;
InitParametersFromDefinitions(registerEffect, p.data());
m_source_id = HoaLibraryUnity::CreateSource();
}
//! @brief Release ressources.
void release()
{
HoaLibraryUnity::DestroySource(m_source_id);
}
bool setFloatParameter(effect_state_t* state, int index, float_t value)
{
if (index >= Param::Size)
return false;
p[index] = value;
return true;
}
bool getFloatParameter(effect_state_t* state, int index, float_t* value, char *valuestr)
{
if (index >= Param::Size)
return false;
if (value)
*value = p[index];
if (valuestr)
valuestr[0] = 0;
return true;
}
//! @brief Check host compatibility.
//! @details because hostapiversion is only supported from SDK version 1.03
//! (i.e. Unity 5.2) and onwards.
//! Since we are only checking for version 0x010300 here, we can't use
//! newer fields in the UnityAudioSpatializerData struct,
//! such as minDistance and maxDistance.
bool isHostCompatible(effect_state_t* state) const
{
return (state->structsize >= sizeof(effect_state_t)
&& state->hostapiversion >= 0x010300);
}
float getAttenuation(effect_state_t* state, float_t distanceIn, float_t attenuationIn)
{
return (p[Param::DistanceAttenuation] * attenuationIn +
p[Param::CustomFalloff] * (1.0f / FastMax(1.0f, distanceIn)));
}
void process(effect_state_t* state,
float_t* inputs, float_t* outputs, unsigned int length,
int numins, int numouts)
{
// Check that I/O formats are right and that the host API supports this feature
if ((numins != 2 || numouts != 2)
|| (!isHostCompatible(state) || !state->spatializerdata)
|| m_source_id == HoaLibraryApi::invalid_source_id)
{
std::fill(outputs, outputs + length * numouts, 0.f);
return;
}
const auto& spatinfos = *state->spatializerdata;
const auto pan = spatinfos.stereopan; // [-1 to 1]
const int optimization = static_cast<int>(p[Param::Optim]);
auto const* sm = spatinfos.sourcematrix;
auto const* lm = spatinfos.listenermatrix;
// Currently we ignore source orientation and only use the position
const float_t pos_x = sm[12];
const float_t pos_y = sm[13];
const float_t pos_z = sm[14];
const float_t dir_x = lm[0] * pos_x + lm[4] * pos_y + lm[ 8] * pos_z + lm[12];
const float_t dir_y = lm[1] * pos_x + lm[5] * pos_y + lm[ 9] * pos_z + lm[13];
const float_t dir_z = lm[2] * pos_x + lm[6] * pos_y + lm[10] * pos_z + lm[14];
const auto gain = std::powf(10.f, p[Param::Gain] * 0.05f);
HoaLibraryUnity::SetSourceGain(m_source_id, gain);
HoaLibraryUnity::SetSourcePan(m_source_id, pan);
HoaLibraryUnity::SetSourcePosition(m_source_id, dir_x, dir_y, dir_z);
HoaLibraryUnity::SetSourceOptim(m_source_id, optimization);
HoaLibraryUnity::ProcessSource(m_source_id, length, inputs);
// Copy inputs to outputs to allow post processing/analysis features in Unity.
std::memcpy(outputs, inputs, length * sizeof(float_t) * numouts);
}
private:
static UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK
DistanceAttenuationCallback(effect_state_t* state,
float_t distanceIn, float_t attenuationIn, float_t* attenuationOut)
{
auto* processor = state->GetEffectData<HoaAudioProcessor>();
*attenuationOut = processor->getAttenuation(state, distanceIn, attenuationIn);
return UNITY_AUDIODSP_OK;
}
private:
std::array<float_t, Param::Size> p;
source_id_t m_source_id = HoaLibraryApi::invalid_source_id;
};
#include "UnityCallbacks.hpp"
}