just a super dummy spatializer

This commit is contained in:
Nevyn Bengtsson 2020-11-25 22:28:43 +01:00 committed by Bjorn
parent 01b8a6baa6
commit 8403c9bd70
8 changed files with 115 additions and 32 deletions

View File

@ -308,6 +308,7 @@ target_link_libraries(lovr
if(LOVR_ENABLE_AUDIO)
target_sources(lovr PRIVATE
src/modules/audio/audio.c
src/modules/audio/spatializers/dummy_spatializer.c
src/api/l_audio.c
src/api/l_audio_source.c
src/lib/miniaudio/miniaudio.c

View File

@ -66,6 +66,15 @@ static int l_lovrAudioNewSource(lua_State* L) {
return 1;
}
static int l_lovrAudioSetListenerPose(lua_State *L) {
float position[4], orientation[4];
int index = 1;
index = luax_readvec3(L, index, position, NULL);
index = luax_readquat(L, index, orientation, NULL);
lovrAudioSetListenerPose(position, orientation);
return 0;
}
static const luaL_Reg lovrAudio[] = {
{ "reset", l_lovrAudioReset },
{ "start", l_lovrAudioStart },
@ -73,6 +82,7 @@ static const luaL_Reg lovrAudio[] = {
{ "getVolume", l_lovrAudioGetVolume },
{ "setVolume", l_lovrAudioSetVolume },
{ "newSource", l_lovrAudioNewSource },
{ "setListenerPose", l_lovrAudioSetListenerPose },
{ NULL, NULL }
};

View File

@ -64,6 +64,16 @@ static int l_lovrSourceSetSpatial(lua_State* L) {
return 0;
}
static int l_lovrSourceSetPose(lua_State *L) {
Source* source = luax_checktype(L, 1, Source);
float position[4], orientation[4];
int index = 2;
index = luax_readvec3(L, index, position, NULL);
index = luax_readquat(L, index, orientation, NULL);
lovrSourceSetPose(source, position, orientation);
return 0;
}
static int l_lovrSourceGetDuration(lua_State* L) {
Source* source = luax_checktype(L, 1, Source);
TimeUnit units = luax_checkenum(L, 2, TimeUnit, "seconds");
@ -119,6 +129,7 @@ const luaL_Reg lovrSource[] = {
{ "setVolume", l_lovrSourceSetVolume },
{ "getSpatial", l_lovrSourceGetSpatial },
{ "setSpatial", l_lovrSourceSetSpatial },
{ "setPose", l_lovrSourceSetPose },
{ "getDuration", l_lovrSourceGetDuration },
{ "getTime", l_lovrSourceGetTime },
{ "setTime", l_lovrSourceSetTime },

View File

@ -7,6 +7,7 @@
#include <string.h>
#include <stdlib.h>
#include "lib/miniaudio/miniaudio.h"
#include "audio/spatializer.h"
#define SAMPLE_RATE 44100
@ -30,15 +31,10 @@ struct Source {
bool playing;
bool looping;
bool spatial;
float pose[16];
int output_channel_count;
};
typedef struct {
bool (*init)(void);
void (*destroy)(void);
void (*apply)(Source* source, const float* input /*mono*/, float* output/*stereo*/, uint32_t frames);
} Spatializer;
static struct {
bool initialized;
ma_context context;
@ -74,7 +70,7 @@ static bool mix(Source* source, float* output, uint32_t count) {
if(source->spatial) {
if(state.spatializer) {
state.spatializer->apply(source, aux, mix, framesOut);
state.spatializer->apply(source, source->pose, aux, mix, framesOut);
}
} else {
memcpy(mix, aux, framesOut * 2 * sizeof(float));
@ -125,25 +121,8 @@ static void onCapture(ma_device* device, void* output, const void* input, uint32
static const ma_device_callback_proc callbacks[] = { onPlayback, onCapture };
// Spatializers
static bool phonon_init(void) {
return true;
}
static void phonon_destroy(void) {
//
}
static void phonon_apply(Source* source, const float* input, float* output, uint32_t frames) {
for(int i = 0; i < frames; i++) {
output[i*2] = output[i*2+1] = input[i];
}
//
}
static Spatializer spatializers[] = {
{ phonon_init, phonon_destroy, phonon_apply }
static Spatializer *spatializers[] = {
&dummy_spatializer,
};
// Entry
@ -176,8 +155,8 @@ bool lovrAudioInit(AudioConfig config[2]) {
}
for (size_t i = 0; i < sizeof(spatializers) / sizeof(spatializers[0]); i++) {
if (spatializers[i].init()) {
state.spatializer = &spatializers[i];
if (spatializers[i]->init()) {
state.spatializer = spatializers[i];
break;
}
}
@ -240,6 +219,11 @@ void lovrAudioSetVolume(float volume) {
ma_device_set_master_volume(&state.devices[0], volume);
}
void lovrAudioSetListenerPose(float position[4], float orientation[4])
{
state.spatializer->setListenerPose(position, orientation);
}
// Source
Source* lovrSourceCreate(SoundData* sound) {
@ -330,17 +314,22 @@ void lovrSourceSetVolume(Source* source, float volume) {
ma_mutex_unlock(&state.locks[AUDIO_PLAYBACK]);
}
bool lovrSourceGetSpatial(Source *source)
{
bool lovrSourceGetSpatial(Source *source) {
return source->spatial;
}
void lovrSourceSetSpatial(Source *source, bool spatial)
{
void lovrSourceSetSpatial(Source *source, bool spatial) {
source->spatial = spatial;
source->output_channel_count = source->spatial ? 1 : 2;
_lovrSourceAssignConverter(source);
}
void lovrSourceSetPose(Source *source, float position[4], float orientation[4]) {
mat4_identity(source->pose);
mat4_translate(source->pose, position[0], position[1], position[2]);
mat4_rotate(source->pose, orientation[0], orientation[1], orientation[2], orientation[3]);
}
uint32_t lovrSourceGetTime(Source* source) {
return source->offset;
}

View File

@ -34,6 +34,7 @@ bool lovrAudioStart(AudioType type);
bool lovrAudioStop(AudioType type);
float lovrAudioGetVolume(void);
void lovrAudioSetVolume(float volume);
void lovrAudioSetListenerPose(float position[4], float orientation[4]);
Source* lovrSourceCreate(struct SoundData* soundData);
void lovrSourceDestroy(void* ref);
@ -47,6 +48,7 @@ float lovrSourceGetVolume(Source* source);
void lovrSourceSetVolume(Source* source, float volume);
bool lovrSourceGetSpatial(Source *source);
void lovrSourceSetSpatial(Source *source, bool spatial);
void lovrSourceSetPose(Source *source, float position[4], float orientation[4]);
uint32_t lovrSourceGetTime(Source* source);
void lovrSourceSetTime(Source* source, uint32_t sample);
struct SoundData* lovrSourceGetSoundData(Source* source);

View File

@ -0,0 +1,15 @@
#include "audio.h"
#include "core/maf.h"
typedef struct {
bool (*init)(void);
void (*destroy)(void);
void (*apply)(Source* source, mat4 pose, const float* input /*mono*/, float* output/*stereo*/, uint32_t frames);
void (*setListenerPose)(float position[4], float orientation[4]);
const char *name;
} Spatializer;
bool dummy_spatializer_init(void);
void dummy_spatializer_destroy(void);
void dummy_spatializer_apply(Source* source, mat4 pose, const float* input, float* output, uint32_t frames);
extern Spatializer dummy_spatializer;

View File

@ -0,0 +1,50 @@
#include "../spatializer.h"
struct {
float listener[16];
} state;
bool dummy_spatializer_init(void)
{
mat4_identity(state.listener);
return true;
}
void dummy_spatializer_destroy(void)
{
}
void dummy_spatializer_apply(Source* source, mat4 pose, const float* input, float* output, uint32_t frames) {
float source_pos[4] = {0};
mat4_transform(pose, source_pos);
float listener_pos[4] = {0};
mat4_transform(state.listener, listener_pos);
float distance = vec3_distance(source_pos, listener_pos);
float left_ear[4] = {-0.1,0,0,1};
float right_ear[4] = {0.1,0,0,1};
mat4_transform(state.listener, left_ear);
mat4_transform(state.listener, right_ear);
float ldistance = vec3_distance(source_pos, left_ear);
float rdistance = vec3_distance(source_pos, right_ear);
float distance_attenuation = MAX(1.0 - distance/10.0, 0.0);
float left_attenuation = 0.5 + (rdistance-ldistance)*2.5;
float right_attenuation = 0.5 + (ldistance-rdistance)*2.5;
for(int i = 0; i < frames; i++) {
output[i*2] = input[i] * distance_attenuation * left_attenuation;
output[i*2+1] = input[i] * distance_attenuation * right_attenuation;
}
}
void dummy_spatializer_setListenerPose(float position[4], float orientation[4]) {
mat4_identity(state.listener);
mat4_translate(state.listener, position[0], position[1], position[2]);
mat4_rotate(state.listener, orientation[0], orientation[1], orientation[2], orientation[3]);
}
Spatializer dummy_spatializer = {
dummy_spatializer_init,
dummy_spatializer_destroy,
dummy_spatializer_apply,
dummy_spatializer_setListenerPose,
"dummy"
};

View File

@ -190,6 +190,11 @@ function lovr.run()
if lovr.headset then
lovr.headset.update(dt)
end
if lovr.audio then
if lovr.headset then
lovr.audio.setListenerPose(lovr.headset.getPose())
end
end
if lovr.update then lovr.update(dt) end
if lovr.graphics then
lovr.graphics.origin()