mirror of https://github.com/bjornbytes/lovr.git
just a super dummy spatializer
This commit is contained in:
parent
01b8a6baa6
commit
8403c9bd70
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
|
@ -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"
|
||||
};
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue