mirror of https://github.com/bjornbytes/lovr.git
Source:setPitch;
Co-authored-by: Nevyn Bengtsson <nevyn@alloverse.com>
This commit is contained in:
parent
1c9adea2e2
commit
d8c23bacec
|
@ -229,6 +229,7 @@ static int l_lovrAudioNewSource(lua_State* L) {
|
|||
Sound* sound = luax_totype(L, 1, Sound);
|
||||
|
||||
bool decode = false;
|
||||
bool pitchable = false;
|
||||
bool spatial = true;
|
||||
uint32_t effects = ~0u;
|
||||
if (lua_gettop(L) >= 2) {
|
||||
|
@ -238,6 +239,10 @@ static int l_lovrAudioNewSource(lua_State* L) {
|
|||
decode = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 2, "pitchable");
|
||||
pitchable = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 2, "effects");
|
||||
if (!lua_isnil(L, -1)) {
|
||||
effects = 0;
|
||||
|
@ -270,7 +275,7 @@ static int l_lovrAudioNewSource(lua_State* L) {
|
|||
lovrRetain(sound);
|
||||
}
|
||||
|
||||
Source* source = lovrSourceCreate(sound, spatial, effects);
|
||||
Source* source = lovrSourceCreate(sound, pitchable, spatial, effects);
|
||||
luax_pushtype(L, Source, source);
|
||||
lovrRelease(sound, lovrSoundDestroy);
|
||||
lovrRelease(source, lovrSourceDestroy);
|
||||
|
|
|
@ -57,6 +57,18 @@ static int l_lovrSourceSetLooping(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrSourceGetPitch(lua_State* L) {
|
||||
Source* source = luax_checktype(L, 1, Source);
|
||||
lua_pushnumber(L, lovrSourceGetPitch(source));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrSourceSetPitch(lua_State* L) {
|
||||
Source* source = luax_checktype(L, 1, Source);
|
||||
lovrSourceSetPitch(source, luax_checkfloat(L, 2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrSourceGetVolume(lua_State* L) {
|
||||
Source* source = luax_checktype(L, 1, Source);
|
||||
VolumeUnit units = luax_checkenum(L, 2, VolumeUnit, "linear");
|
||||
|
@ -224,6 +236,8 @@ const luaL_Reg lovrSource[] = {
|
|||
{ "isPlaying", l_lovrSourceIsPlaying },
|
||||
{ "isLooping", l_lovrSourceIsLooping },
|
||||
{ "setLooping", l_lovrSourceSetLooping },
|
||||
{ "getPitch", l_lovrSourceGetPitch },
|
||||
{ "setPitch", l_lovrSourceSetPitch },
|
||||
{ "getVolume", l_lovrSourceGetVolume },
|
||||
{ "setVolume", l_lovrSourceSetVolume },
|
||||
{ "seek", l_lovrSourceSeek },
|
||||
|
|
|
@ -25,6 +25,7 @@ struct Source {
|
|||
ma_data_converter* converter;
|
||||
intptr_t spatializerMemo;
|
||||
uint32_t offset;
|
||||
float pitch;
|
||||
float volume;
|
||||
float position[4];
|
||||
float orientation[4];
|
||||
|
@ -34,6 +35,7 @@ struct Source {
|
|||
uint8_t effects;
|
||||
bool playing;
|
||||
bool looping;
|
||||
bool pitchable;
|
||||
bool spatial;
|
||||
};
|
||||
|
||||
|
@ -379,7 +381,7 @@ void lovrAudioSetAbsorption(float absorption[3]) {
|
|||
|
||||
// Source
|
||||
|
||||
Source* lovrSourceCreate(Sound* sound, bool spatial, uint32_t effects) {
|
||||
Source* lovrSourceCreate(Sound* sound, bool pitchable, bool spatial, uint32_t effects) {
|
||||
lovrAssert(lovrSoundGetChannelLayout(sound) != CHANNEL_AMBISONIC, "Ambisonic Sources are not currently supported");
|
||||
Source* source = calloc(1, sizeof(Source));
|
||||
lovrAssert(source, "Out of memory");
|
||||
|
@ -388,7 +390,9 @@ Source* lovrSourceCreate(Sound* sound, bool spatial, uint32_t effects) {
|
|||
source->sound = sound;
|
||||
lovrRetain(source->sound);
|
||||
|
||||
source->pitch = 1.f;
|
||||
source->volume = 1.f;
|
||||
source->pitchable = pitchable;
|
||||
source->spatial = spatial;
|
||||
source->effects = spatial ? effects : 0;
|
||||
quat_identity(source->orientation);
|
||||
|
@ -400,8 +404,9 @@ Source* lovrSourceCreate(Sound* sound, bool spatial, uint32_t effects) {
|
|||
config.channelsOut = spatial ? 1 : 2;
|
||||
config.sampleRateIn = lovrSoundGetSampleRate(sound);
|
||||
config.sampleRateOut = state.sampleRate;
|
||||
config.allowDynamicSampleRate = pitchable;
|
||||
|
||||
if (config.formatIn != config.formatOut || config.channelsIn != config.channelsOut || config.sampleRateIn != config.sampleRateOut) {
|
||||
if (pitchable || config.formatIn != config.formatOut || config.channelsIn != config.channelsOut || config.sampleRateIn != config.sampleRateOut) {
|
||||
source->converter = malloc(sizeof(ma_data_converter));
|
||||
lovrAssert(source->converter, "Out of memory");
|
||||
ma_result status = ma_data_converter_init(&config, NULL, source->converter);
|
||||
|
@ -418,6 +423,7 @@ Source* lovrSourceClone(Source* source) {
|
|||
clone->index = ~0u;
|
||||
clone->sound = source->sound;
|
||||
lovrRetain(clone->sound);
|
||||
clone->pitch = source->pitch;
|
||||
clone->volume = source->volume;
|
||||
memcpy(clone->position, source->position, 4 * sizeof(float));
|
||||
memcpy(clone->orientation, source->orientation, 4 * sizeof(float));
|
||||
|
@ -426,6 +432,7 @@ Source* lovrSourceClone(Source* source) {
|
|||
clone->dipolePower = source->dipolePower;
|
||||
clone->effects = source->effects;
|
||||
clone->looping = source->looping;
|
||||
clone->pitchable = source->pitchable;
|
||||
clone->spatial = source->spatial;
|
||||
if (source->converter) {
|
||||
clone->converter = malloc(sizeof(ma_data_converter));
|
||||
|
@ -437,6 +444,7 @@ Source* lovrSourceClone(Source* source) {
|
|||
config.channelsOut = source->converter->channelsOut;
|
||||
config.sampleRateIn = source->converter->sampleRateIn;
|
||||
config.sampleRateOut = source->converter->sampleRateOut;
|
||||
config.allowDynamicSampleRate = clone->pitchable;
|
||||
ma_result status = ma_data_converter_init(&config, NULL, clone->converter);
|
||||
lovrAssert(status == MA_SUCCESS, "Problem creating Source data converter: %s (%d)", ma_result_description(status), status);
|
||||
}
|
||||
|
@ -500,6 +508,23 @@ void lovrSourceSetLooping(Source* source, bool loop) {
|
|||
source->looping = loop;
|
||||
}
|
||||
|
||||
float lovrSourceGetPitch(Source* source) {
|
||||
return source->pitch;
|
||||
}
|
||||
|
||||
void lovrSourceSetPitch(Source* source, float pitch) {
|
||||
lovrCheck(pitch > 0.f, "Source pitch must be positive");
|
||||
lovrCheck(source->pitchable, "Source must be created with the 'pitchable' flag to change its pitch");
|
||||
|
||||
if (source->pitch != pitch) {
|
||||
source->pitch = pitch;
|
||||
ma_mutex_lock(&state.lock);
|
||||
float ratio = (float) lovrSoundGetSampleRate(source->sound) / state.sampleRate;
|
||||
ma_data_converter_set_rate_ratio(source->converter, pitch * ratio);
|
||||
ma_mutex_unlock(&state.lock);
|
||||
}
|
||||
}
|
||||
|
||||
float lovrSourceGetVolume(Source* source, VolumeUnit units) {
|
||||
return units == UNIT_LINEAR ? source->volume : linearToDb(source->volume);
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ void lovrAudioSetAbsorption(float absorption[3]);
|
|||
|
||||
// Source
|
||||
|
||||
Source* lovrSourceCreate(struct Sound* sound, bool spatial, uint32_t effects);
|
||||
Source* lovrSourceCreate(struct Sound* sound, bool pitch, bool spatial, uint32_t effects);
|
||||
Source* lovrSourceClone(Source* source);
|
||||
void lovrSourceDestroy(void* ref);
|
||||
struct Sound* lovrSourceGetSound(Source* source);
|
||||
|
@ -85,11 +85,14 @@ void lovrSourceStop(Source* source);
|
|||
bool lovrSourceIsPlaying(Source* source);
|
||||
bool lovrSourceIsLooping(Source* source);
|
||||
void lovrSourceSetLooping(Source* source, bool loop);
|
||||
float lovrSourceGetPitch(Source* source);
|
||||
void lovrSourceSetPitch(Source* source, float pitch);
|
||||
float lovrSourceGetVolume(Source* source, VolumeUnit units);
|
||||
void lovrSourceSetVolume(Source* source, float volume, VolumeUnit units);
|
||||
void lovrSourceSeek(Source* source, double time, TimeUnit units);
|
||||
double lovrSourceTell(Source* source, TimeUnit units);
|
||||
double lovrSourceGetDuration(Source* source, TimeUnit units);
|
||||
bool lovrSourceIsPitchable(Source* source);
|
||||
bool lovrSourceIsSpatial(Source* source);
|
||||
void lovrSourceGetPose(Source* source, float position[4], float orientation[4]);
|
||||
void lovrSourceSetPose(Source* source, float position[4], float orientation[4]);
|
||||
|
|
Loading…
Reference in New Issue