Skip to content

Commit 567be08

Browse files
committed
Implement cone/falloff;
1 parent 27b2445 commit 567be08

File tree

3 files changed

+39
-27
lines changed

3 files changed

+39
-27
lines changed

src/api/l_audio_source.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -242,25 +242,23 @@ static int l_lovrSourceSetCone(lua_State* L) {
242242

243243
static int l_lovrSourceGetFalloff(lua_State* L) {
244244
Source* source = luax_checktype(L, 1, Source);
245-
float innerDistance, outerDistance, outerVolume;
246-
lovrSourceGetFalloff(source, &innerDistance, &outerDistance, &outerVolume);
245+
float innerDistance, minVolume;
246+
lovrSourceGetFalloff(source, &innerDistance, &minVolume);
247247
lua_pushnumber(L, innerDistance);
248-
lua_pushnumber(L, outerDistance);
249-
lua_pushnumber(L, outerVolume);
248+
lua_pushnumber(L, minVolume);
250249
return 3;
251250
}
252251

253252
static int l_lovrSourceSetFalloff(lua_State* L) {
254253
Source* source = luax_checktype(L, 1, Source);
255254
if (!lua_toboolean(L, 2)) {
256-
lovrSourceSetFalloff(source, 0.f, 0.f, 1.f);
255+
lovrSourceSetFalloff(source, 0.f, 1.f);
257256
} else if (lua_isboolean(L, 2)) {
258-
lovrSourceSetFalloff(source, 0.f, FLT_MAX, 0.f);
257+
lovrSourceSetFalloff(source, 0.f, 0.f);
259258
} else {
260259
float innerDistance = luax_checkfloat(L, 2);
261-
float outerDistance = luax_checkfloat(L, 3);
262-
float outerVolume = luax_optfloat(L, 4, 0.);
263-
lovrSourceSetFalloff(source, innerDistance, outerDistance, outerVolume);
260+
float minVolume = luax_optfloat(L, 3, 0.);
261+
lovrSourceSetFalloff(source, innerDistance, minVolume);
264262
}
265263
return 0;
266264
}

src/modules/audio/audio.c

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ struct Source {
4141
float outerAngle;
4242
float outerAngleVolume;
4343
float innerDistance;
44-
float outerDistance;
45-
float outerDistanceVolume;
44+
float minFalloffVolume;
4645
uint32_t occlusionRays;
4746
uint32_t transmissionRays;
4847
float reverb;
@@ -576,8 +575,7 @@ Source* lovrSourceClone(Source* source) {
576575
clone->outerAngle = source->outerAngle;
577576
clone->outerAngleVolume = source->outerAngleVolume;
578577
clone->innerDistance = source->innerDistance;
579-
clone->outerDistance = source->outerDistance;
580-
clone->outerDistanceVolume = source->outerDistanceVolume;
578+
clone->minFalloffVolume = source->minFalloffVolume;
581579
clone->occlusionRays = source->occlusionRays;
582580
clone->transmissionRays = source->transmissionRays;
583581
clone->reverb = source->reverb;
@@ -764,16 +762,14 @@ void lovrSourceSetCone(Source* source, float innerAngle, float outerAngle, float
764762
source->outerAngleVolume = outerVolume;
765763
}
766764

767-
void lovrSourceGetFalloff(Source* source, float* innerDistance, float* outerDistance, float* outerVolume) {
765+
void lovrSourceGetFalloff(Source* source, float* innerDistance, float* minVolume) {
768766
*innerDistance = source->innerDistance;
769-
*outerDistance = source->outerDistance;
770-
*outerVolume = source->outerDistanceVolume;
767+
*minVolume = source->minFalloffVolume;
771768
}
772769

773-
void lovrSourceSetFalloff(Source* source, float innerDistance, float outerDistance, float outerVolume) {
770+
void lovrSourceSetFalloff(Source* source, float innerDistance, float minVolume) {
774771
source->innerDistance = innerDistance;
775-
source->outerDistance = outerDistance;
776-
source->outerDistanceVolume = outerVolume;
772+
source->minFalloffVolume = minVolume;
777773
}
778774

779775
void lovrSourceGetOcclusion(Source* source, uint32_t* occlusionRays, uint32_t* transmissionRays) {
@@ -874,14 +870,32 @@ static void convertPose(float* position, float* orientation, IPLCoordinateSpace3
874870
vec3_init(&basis->origin.x, position);
875871
}
876872

877-
static void applyAttenuation(IPLfloat32 distance, void* userdata) {
873+
static float applyAttenuation(IPLfloat32 distance, void* userdata) {
878874
Source* source = userdata;
879-
return 1.f; // TODO
875+
if (distance <= source->innerDistance) {
876+
return 1.f;
877+
} else {
878+
return MAX(source->innerDistance / distance, source->minFalloffVolume);
879+
}
880880
}
881881

882-
static float applyDirectivity(IPLVector3 direction, void* userdata) {
882+
static float applyDirectivity(IPLVector3 sourceDirection, void* userdata) {
883883
Source* source = userdata;
884-
return 1.f; // TODO
884+
885+
float listenerDirection[3];
886+
vec3_init(listenerDirection, &state.listenerBasis[state.backbuffer].origin.x);
887+
vec3_sub(listenerDirection, source->position);
888+
vec3_normalize(listenerDirection);
889+
float angle = acosf(vec3_dot(&sourceDirection.x, listenerDirection));
890+
891+
if (angle < source->innerAngle) {
892+
return 1.f;
893+
} else if (angle >= source->outerAngle) {
894+
return source->outerAngleVolume;
895+
} else {
896+
float t = (angle - source->innerAngle) / (source->outerAngle - source->innerAngle);
897+
return source->outerAngleVolume + (1.f - source->outerAngleVolume) * t;
898+
}
885899
}
886900

887901
static void onSpatializerLog(IPLLogLevel iplLevel, const char* message) {
@@ -1048,9 +1062,9 @@ static void phonon_update(float dt) {
10481062
vec3_sub(vec3_init(&source->relativeDirection[backbuffer].x, source->position), state.position);
10491063

10501064
source->inputs.directFlags = 0;
1051-
if (source->outerDistanceVolume < 1.f) source->inputs.directFlags |= IPL_DIRECTSIMULATIONFLAGS_AIRABSORPTION;
10521065
if (vec3_dot(source->absorption, source->absorption) > 1e-5) source->inputs.directFlags |= IPL_DIRECTSIMULATIONFLAGS_AIRABSORPTION;
10531066
if (source->innerAngle < (float) M_PI) source->inputs.directFlags |= IPL_DIRECTSIMULATIONFLAGS_DIRECTIVITY;
1067+
if (source->minFalloffVolume < 1.f) source->inputs.directFlags |= IPL_DIRECTSIMULATIONFLAGS_DISTANCEATTENUATION;
10541068
if (source->occlusionRays > 0) source->inputs.directFlags |= IPL_DIRECTSIMULATIONFLAGS_OCCLUSION;
10551069
if (source->occlusionRays > 0 && source->transmissionRays > 0) source->inputs.directFlags |= IPL_DIRECTSIMULATIONFLAGS_TRANSMISSION;
10561070

@@ -1213,7 +1227,7 @@ static bool phonon_mix_source(Source* source, float* _src, float* dst, float* _t
12131227

12141228
// Direct effects, applied in-place
12151229
IPLDirectEffectParams* directParams = &source->outputs[index].direct;
1216-
if (directParams.flags) {
1230+
if (directParams->flags) {
12171231
tail |= !iplDirectEffectApply(source->directEffect, directParams, &src, &src);
12181232
}
12191233

src/modules/audio/audio.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ void lovrSourceGetAbsorption(Source* source, float absorption[3]);
124124
void lovrSourceSetAbsorption(Source* source, float absorption[3]);
125125
void lovrSourceGetCone(Source* source, float* innerAngle, float* outerAngle, float* outerVolume);
126126
void lovrSourceSetCone(Source* source, float innerAngle, float outerAngle, float outerVolume);
127-
void lovrSourceGetFalloff(Source* source, float* innerDistance, float* outerDistance, float* outerVolume);
128-
void lovrSourceSetFalloff(Source* source, float innerDistance, float outerDistance, float outerVolume);
127+
void lovrSourceGetFalloff(Source* source, float* innerDistance, float* minVolume);
128+
void lovrSourceSetFalloff(Source* source, float innerDistance, float minVolume);
129129
void lovrSourceGetOcclusion(Source* source, uint32_t* occlusionRays, uint32_t* transmissionRays);
130130
void lovrSourceSetOcclusion(Source* source, uint32_t occlusionRays, uint32_t transmissionRays);
131131
void lovrSourceGetReverb(Source* source, float* reverb, ReverbMode* mode);

0 commit comments

Comments
 (0)