mirror of https://github.com/bjornbytes/lovr.git
Source:isSpatial; Separate spatial from effects;
This commit is contained in:
parent
c824c5c135
commit
d70619ec96
|
@ -229,7 +229,8 @@ static int l_lovrAudioNewSource(lua_State* L) {
|
||||||
Sound* sound = luax_totype(L, 1, Sound);
|
Sound* sound = luax_totype(L, 1, Sound);
|
||||||
|
|
||||||
bool decode = false;
|
bool decode = false;
|
||||||
uint32_t effects = EFFECT_ALL;
|
bool spatial = true;
|
||||||
|
uint32_t effects = ~0u;
|
||||||
if (lua_gettop(L) >= 2) {
|
if (lua_gettop(L) >= 2) {
|
||||||
luaL_checktype(L, 2, LUA_TTABLE);
|
luaL_checktype(L, 2, LUA_TTABLE);
|
||||||
|
|
||||||
|
@ -238,30 +239,27 @@ static int l_lovrAudioNewSource(lua_State* L) {
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_getfield(L, 2, "effects");
|
lua_getfield(L, 2, "effects");
|
||||||
switch (lua_type(L, -1)) {
|
if (!lua_isnil(L, -1)) {
|
||||||
case LUA_TNIL: effects = EFFECT_ALL; break;
|
|
||||||
case LUA_TBOOLEAN: effects = lua_toboolean(L, -1) ? EFFECT_ALL : EFFECT_NONE; break;
|
|
||||||
case LUA_TTABLE:
|
|
||||||
effects = 0;
|
effects = 0;
|
||||||
|
lovrAssert(lua_istable(L, -1), "Source effects must be a table");
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, -2) != 0) {
|
while (lua_next(L, -2) != 0) {
|
||||||
if (lua_type(L, -2) == LUA_TSTRING) {
|
if (lua_type(L, -2) == LUA_TSTRING) {
|
||||||
Effect effect = luax_checkenum(L, -2, Effect, NULL);
|
Effect effect = luax_checkenum(L, -2, Effect, NULL);
|
||||||
if (lua_toboolean(L, -1)) {
|
bool enabled = lua_toboolean(L, -1);
|
||||||
effects |= (1 << effect);
|
effects |= enabled << effect;
|
||||||
} else {
|
|
||||||
effects &= ~(1 << effect);
|
|
||||||
}
|
|
||||||
} else if (lua_type(L, -2) == LUA_TNUMBER) {
|
} else if (lua_type(L, -2) == LUA_TNUMBER) {
|
||||||
Effect effect = luax_checkenum(L, -1, Effect, NULL);
|
Effect effect = luax_checkenum(L, -1, Effect, NULL);
|
||||||
effects |= (1 << effect);
|
effects |= 1 << effect;
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_getfield(L, 2, "spatial");
|
||||||
|
spatial = lua_isnil(L, -1) ? true : lua_toboolean(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sound) {
|
if (!sound) {
|
||||||
|
@ -272,7 +270,7 @@ static int l_lovrAudioNewSource(lua_State* L) {
|
||||||
lovrRetain(sound);
|
lovrRetain(sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
Source* source = lovrSourceCreate(sound, effects);
|
Source* source = lovrSourceCreate(sound, spatial, effects);
|
||||||
luax_pushtype(L, Source, source);
|
luax_pushtype(L, Source, source);
|
||||||
lovrRelease(sound, lovrSoundDestroy);
|
lovrRelease(sound, lovrSoundDestroy);
|
||||||
lovrRelease(source, lovrSourceDestroy);
|
lovrRelease(source, lovrSourceDestroy);
|
||||||
|
|
|
@ -208,6 +208,13 @@ static int l_lovrSourceSetEffectEnabled(lua_State* L) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_lovrSourceIsSpatial(lua_State* L) {
|
||||||
|
Source* source = luax_checktype(L, 1, Source);
|
||||||
|
bool spatial = lovrSourceIsSpatial(source);
|
||||||
|
lua_pushboolean(L, spatial);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg lovrSource[] = {
|
const luaL_Reg lovrSource[] = {
|
||||||
{ "clone", l_lovrSourceClone },
|
{ "clone", l_lovrSourceClone },
|
||||||
{ "getSound", l_lovrSourceGetSound },
|
{ "getSound", l_lovrSourceGetSound },
|
||||||
|
@ -234,5 +241,6 @@ const luaL_Reg lovrSource[] = {
|
||||||
{ "setDirectivity", l_lovrSourceSetDirectivity },
|
{ "setDirectivity", l_lovrSourceSetDirectivity },
|
||||||
{ "isEffectEnabled", l_lovrSourceIsEffectEnabled },
|
{ "isEffectEnabled", l_lovrSourceIsEffectEnabled },
|
||||||
{ "setEffectEnabled", l_lovrSourceSetEffectEnabled },
|
{ "setEffectEnabled", l_lovrSourceSetEffectEnabled },
|
||||||
|
{ "isSpatial", l_lovrSourceIsSpatial },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct Source {
|
||||||
uint8_t effects;
|
uint8_t effects;
|
||||||
bool playing;
|
bool playing;
|
||||||
bool looping;
|
bool looping;
|
||||||
|
bool spatial;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -94,7 +95,7 @@ static void onPlayback(ma_device* device, void* out, const void* in, uint32_t co
|
||||||
// - If EOF is reached, rewind and continue for looping sources, otherwise pad end with zero.
|
// - If EOF is reached, rewind and continue for looping sources, otherwise pad end with zero.
|
||||||
buf = source->converter ? aux : raw;
|
buf = source->converter ? aux : raw;
|
||||||
float* cursor = buf; // Edge of processed frames
|
float* cursor = buf; // Edge of processed frames
|
||||||
uint32_t channelsOut = lovrSourceUsesSpatializer(source) ? 1 : 2; // If spatializer isn't converting to stereo, converter must do it
|
uint32_t channelsOut = source->spatial ? 1 : 2; // If spatializer isn't converting to stereo, converter must do it
|
||||||
uint32_t framesRemaining = BUFFER_SIZE;
|
uint32_t framesRemaining = BUFFER_SIZE;
|
||||||
while (framesRemaining > 0) {
|
while (framesRemaining > 0) {
|
||||||
uint32_t framesRead;
|
uint32_t framesRead;
|
||||||
|
@ -136,7 +137,7 @@ static void onPlayback(ma_device* device, void* out, const void* in, uint32_t co
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spatialize
|
// Spatialize
|
||||||
if (lovrSourceUsesSpatializer(source)) {
|
if (source->spatial) {
|
||||||
state.spatializer->apply(source, buf, mix, BUFFER_SIZE, BUFFER_SIZE);
|
state.spatializer->apply(source, buf, mix, BUFFER_SIZE, BUFFER_SIZE);
|
||||||
buf = mix;
|
buf = mix;
|
||||||
}
|
}
|
||||||
|
@ -378,7 +379,7 @@ void lovrAudioSetAbsorption(float absorption[3]) {
|
||||||
|
|
||||||
// Source
|
// Source
|
||||||
|
|
||||||
Source* lovrSourceCreate(Sound* sound, uint32_t effects) {
|
Source* lovrSourceCreate(Sound* sound, bool spatial, uint32_t effects) {
|
||||||
lovrAssert(lovrSoundGetChannelLayout(sound) != CHANNEL_AMBISONIC, "Ambisonic Sources are not currently supported");
|
lovrAssert(lovrSoundGetChannelLayout(sound) != CHANNEL_AMBISONIC, "Ambisonic Sources are not currently supported");
|
||||||
Source* source = calloc(1, sizeof(Source));
|
Source* source = calloc(1, sizeof(Source));
|
||||||
lovrAssert(source, "Out of memory");
|
lovrAssert(source, "Out of memory");
|
||||||
|
@ -388,14 +389,15 @@ Source* lovrSourceCreate(Sound* sound, uint32_t effects) {
|
||||||
lovrRetain(source->sound);
|
lovrRetain(source->sound);
|
||||||
|
|
||||||
source->volume = 1.f;
|
source->volume = 1.f;
|
||||||
source->effects = effects;
|
source->spatial = spatial;
|
||||||
|
source->effects = spatial ? effects : 0;
|
||||||
quat_identity(source->orientation);
|
quat_identity(source->orientation);
|
||||||
|
|
||||||
ma_data_converter_config config = ma_data_converter_config_init_default();
|
ma_data_converter_config config = ma_data_converter_config_init_default();
|
||||||
config.formatIn = miniaudioFormats[lovrSoundGetFormat(sound)];
|
config.formatIn = miniaudioFormats[lovrSoundGetFormat(sound)];
|
||||||
config.formatOut = miniaudioFormats[OUTPUT_FORMAT];
|
config.formatOut = miniaudioFormats[OUTPUT_FORMAT];
|
||||||
config.channelsIn = lovrSoundGetChannelCount(sound);
|
config.channelsIn = lovrSoundGetChannelCount(sound);
|
||||||
config.channelsOut = lovrSourceUsesSpatializer(source) ? 1 : 2; // See onPlayback
|
config.channelsOut = spatial ? 1 : 2;
|
||||||
config.sampleRateIn = lovrSoundGetSampleRate(sound);
|
config.sampleRateIn = lovrSoundGetSampleRate(sound);
|
||||||
config.sampleRateOut = state.sampleRate;
|
config.sampleRateOut = state.sampleRate;
|
||||||
|
|
||||||
|
@ -424,6 +426,7 @@ Source* lovrSourceClone(Source* source) {
|
||||||
clone->dipolePower = source->dipolePower;
|
clone->dipolePower = source->dipolePower;
|
||||||
clone->effects = source->effects;
|
clone->effects = source->effects;
|
||||||
clone->looping = source->looping;
|
clone->looping = source->looping;
|
||||||
|
clone->spatial = source->spatial;
|
||||||
if (source->converter) {
|
if (source->converter) {
|
||||||
clone->converter = malloc(sizeof(ma_data_converter));
|
clone->converter = malloc(sizeof(ma_data_converter));
|
||||||
lovrAssert(clone->converter, "Out of memory");
|
lovrAssert(clone->converter, "Out of memory");
|
||||||
|
@ -521,8 +524,8 @@ double lovrSourceGetDuration(Source* source, TimeUnit units) {
|
||||||
return units == UNIT_SECONDS ? (double) frames / lovrSoundGetSampleRate(source->sound) : frames;
|
return units == UNIT_SECONDS ? (double) frames / lovrSoundGetSampleRate(source->sound) : frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lovrSourceUsesSpatializer(Source* source) {
|
bool lovrSourceIsSpatial(Source* source) {
|
||||||
return source->effects != EFFECT_NONE; // Currently, all effects require the spatializer
|
return source->spatial;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrSourceGetPose(Source* source, float position[4], float orientation[4]) {
|
void lovrSourceGetPose(Source* source, float position[4], float orientation[4]) {
|
||||||
|
@ -556,11 +559,11 @@ void lovrSourceSetDirectivity(Source* source, float weight, float power) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lovrSourceIsEffectEnabled(Source* source, Effect effect) {
|
bool lovrSourceIsEffectEnabled(Source* source, Effect effect) {
|
||||||
return source->effects == EFFECT_NONE ? false : (source->effects & (1 << effect));
|
return source->effects & (1 << effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrSourceSetEffectEnabled(Source* source, Effect effect, bool enabled) {
|
void lovrSourceSetEffectEnabled(Source* source, Effect effect, bool enabled) {
|
||||||
lovrCheck(source->effects != EFFECT_NONE, "Unable to change effects on a Source with effects disabled");
|
lovrCheck(source->spatial, "Sources must be created with the spatial flag to enable effects");
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
source->effects |= (1 << effect);
|
source->effects |= (1 << effect);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -17,9 +17,7 @@ typedef enum {
|
||||||
EFFECT_OCCLUSION,
|
EFFECT_OCCLUSION,
|
||||||
EFFECT_REVERB,
|
EFFECT_REVERB,
|
||||||
EFFECT_SPATIALIZATION,
|
EFFECT_SPATIALIZATION,
|
||||||
EFFECT_TRANSMISSION,
|
EFFECT_TRANSMISSION
|
||||||
EFFECT_ALL = 0x3f,
|
|
||||||
EFFECT_NONE = 0xff
|
|
||||||
} Effect;
|
} Effect;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -77,7 +75,7 @@ void lovrAudioSetAbsorption(float absorption[3]);
|
||||||
|
|
||||||
// Source
|
// Source
|
||||||
|
|
||||||
Source* lovrSourceCreate(struct Sound* sound, uint32_t effects);
|
Source* lovrSourceCreate(struct Sound* sound, bool spatial, uint32_t effects);
|
||||||
Source* lovrSourceClone(Source* source);
|
Source* lovrSourceClone(Source* source);
|
||||||
void lovrSourceDestroy(void* ref);
|
void lovrSourceDestroy(void* ref);
|
||||||
struct Sound* lovrSourceGetSound(Source* source);
|
struct Sound* lovrSourceGetSound(Source* source);
|
||||||
|
@ -92,7 +90,7 @@ void lovrSourceSetVolume(Source* source, float volume, VolumeUnit units);
|
||||||
void lovrSourceSeek(Source* source, double time, TimeUnit units);
|
void lovrSourceSeek(Source* source, double time, TimeUnit units);
|
||||||
double lovrSourceTell(Source* source, TimeUnit units);
|
double lovrSourceTell(Source* source, TimeUnit units);
|
||||||
double lovrSourceGetDuration(Source* source, TimeUnit units);
|
double lovrSourceGetDuration(Source* source, TimeUnit units);
|
||||||
bool lovrSourceUsesSpatializer(Source* source);
|
bool lovrSourceIsSpatial(Source* source);
|
||||||
void lovrSourceGetPose(Source* source, float position[4], float orientation[4]);
|
void lovrSourceGetPose(Source* source, float position[4], float orientation[4]);
|
||||||
void lovrSourceSetPose(Source* source, float position[4], float orientation[4]);
|
void lovrSourceSetPose(Source* source, float position[4], float orientation[4]);
|
||||||
float lovrSourceGetRadius(Source* source);
|
float lovrSourceGetRadius(Source* source);
|
||||||
|
|
Loading…
Reference in New Issue