audio: rm paused and stopped states; rm rewind;

- There is now just one "playing" state.
- Instead of rewind, use :seek(0).

Note that now there is no way to resume or rewind all tracked sources.
This can be improved in the future if there's a need for it, probably
using variadic or table-based variants of the audio module functions.
This commit is contained in:
bjorn 2020-02-26 00:25:49 -08:00
parent fa771b04bd
commit 69dd0d4674
5 changed files with 41 additions and 140 deletions

View File

@ -165,16 +165,6 @@ static int l_lovrAudioPause(lua_State* L) {
return 0;
}
static int l_lovrAudioResume(lua_State* L) {
lovrAudioResume();
return 0;
}
static int l_lovrAudioRewind(lua_State* L) {
lovrAudioRewind();
return 0;
}
static int l_lovrAudioSetDopplerEffect(lua_State* L) {
float factor = luax_optfloat(L, 1, 1.f);
float speedOfSound = luax_optfloat(L, 2, 343.29f);
@ -237,8 +227,6 @@ static const luaL_Reg lovrAudio[] = {
{ "newMicrophone", l_lovrAudioNewMicrophone },
{ "newSource", l_lovrAudioNewSource },
{ "pause", l_lovrAudioPause },
{ "resume", l_lovrAudioResume },
{ "rewind", l_lovrAudioRewind },
{ "setDopplerEffect", l_lovrAudioSetDopplerEffect },
{ "setOrientation", l_lovrAudioSetOrientation },
{ "setPose", l_lovrAudioSetPose },

View File

@ -134,11 +134,6 @@ static int l_lovrSourceIsLooping(lua_State* L) {
return 1;
}
static int l_lovrSourceIsPaused(lua_State* L) {
lua_pushboolean(L, lovrSourceIsPaused(luax_checktype(L, 1, Source)));
return 1;
}
static int l_lovrSourceIsPlaying(lua_State* L) {
lua_pushboolean(L, lovrSourceIsPlaying(luax_checktype(L, 1, Source)));
return 1;
@ -149,11 +144,6 @@ static int l_lovrSourceIsRelative(lua_State* L) {
return 1;
}
static int l_lovrSourceIsStopped(lua_State* L) {
lua_pushboolean(L, lovrSourceIsStopped(luax_checktype(L, 1, Source)));
return 1;
}
static int l_lovrSourcePause(lua_State* L) {
lovrSourcePause(luax_checktype(L, 1, Source));
return 0;
@ -166,16 +156,6 @@ static int l_lovrSourcePlay(lua_State* L) {
return 0;
}
static int l_lovrSourceResume(lua_State* L) {
lovrSourceResume(luax_checktype(L, 1, Source));
return 0;
}
static int l_lovrSourceRewind(lua_State* L) {
lovrSourceRewind(luax_checktype(L, 1, Source));
return 0;
}
static int l_lovrSourceSeek(lua_State* L) {
Source* source = luax_checktype(L, 1, Source);
TimeUnit unit = luax_checkenum(L, 3, TimeUnits, "seconds", "TimeUnit");
@ -306,14 +286,10 @@ const luaL_Reg lovrSource[] = {
{ "getVolume", l_lovrSourceGetVolume },
{ "getVolumeLimits", l_lovrSourceGetVolumeLimits },
{ "isLooping", l_lovrSourceIsLooping },
{ "isPaused", l_lovrSourceIsPaused },
{ "isPlaying", l_lovrSourceIsPlaying },
{ "isRelative", l_lovrSourceIsRelative },
{ "isStopped", l_lovrSourceIsStopped },
{ "pause", l_lovrSourcePause },
{ "play", l_lovrSourcePlay },
{ "resume", l_lovrSourceResume },
{ "rewind", l_lovrSourceRewind },
{ "seek", l_lovrSourceSeek },
{ "setCone", l_lovrSourceSetCone },
{ "setFalloff", l_lovrSourceSetFalloff },

View File

@ -64,13 +64,13 @@ bool lovrAudioInit() {
void lovrAudioDestroy() {
if (!state.initialized) return;
alcMakeContextCurrent(NULL);
alcDestroyContext(state.context);
alcCloseDevice(state.device);
for (size_t i = 0; i < state.sources.length; i++) {
lovrRelease(Source, state.sources.data[i]);
}
arr_free(&state.sources);
alcMakeContextCurrent(NULL);
alcDestroyContext(state.context);
alcCloseDevice(state.device);
memset(&state, 0, sizeof(state));
}
@ -83,7 +83,9 @@ void lovrAudioUpdate() {
}
uint32_t id = lovrSourceGetId(source);
bool isStopped = lovrSourceIsStopped(source);
ALenum sourceState;
alGetSourcei(id, AL_SOURCE_STATE, &sourceState);
bool isStopped = sourceState == AL_STOPPED;
ALint processed;
alGetSourcei(id, AL_BUFFERS_PROCESSED, &processed);
@ -163,18 +165,6 @@ void lovrAudioPause() {
}
}
void lovrAudioResume() {
for (size_t i = 0; i < state.sources.length; i++) {
lovrSourceResume(state.sources.data[i]);
}
}
void lovrAudioRewind() {
for (size_t i = 0; i < state.sources.length; i++) {
lovrSourceRewind(state.sources.data[i]);
}
}
void lovrAudioSetDopplerEffect(float factor, float speedOfSound) {
alDopplerFactor(factor);
alSpeedOfSound(speedOfSound);

View File

@ -22,8 +22,6 @@ float lovrAudioGetVolume(void);
bool lovrAudioHas(struct Source* source);
bool lovrAudioIsSpatialized(void);
void lovrAudioPause(void);
void lovrAudioResume(void);
void lovrAudioRewind(void);
void lovrAudioSetDopplerEffect(float factor, float speedOfSound);
void lovrAudioSetOrientation(float* orientation);
void lovrAudioSetPosition(float* position);

View File

@ -21,7 +21,7 @@ struct Source {
bool isLooping;
};
static ALenum lovrSourceGetState(Source* source) {
static ALenum getState(Source* source) {
ALenum state;
alGetSourcei(source->id, AL_SOURCE_STATE, &state);
return state;
@ -135,12 +135,8 @@ bool lovrSourceIsLooping(Source* source) {
return source->isLooping;
}
bool lovrSourceIsPaused(Source* source) {
return lovrSourceGetState(source) == AL_PAUSED;
}
bool lovrSourceIsPlaying(Source* source) {
return lovrSourceGetState(source) == AL_PLAYING;
return getState(source) == AL_PLAYING;
}
bool lovrSourceIsRelative(Source* source) {
@ -149,71 +145,42 @@ bool lovrSourceIsRelative(Source* source) {
return isRelative == AL_TRUE;
}
bool lovrSourceIsStopped(Source* source) {
return lovrSourceGetState(source) == AL_STOPPED;
}
void lovrSourcePause(Source* source) {
alSourcePause(source->id);
}
void lovrSourcePlay(Source* source) {
if (lovrSourceIsPlaying(source)) {
return;
} else if (lovrSourceIsPaused(source)) {
lovrSourceResume(source);
return;
}
// There is no guarantee that lovrAudioUpdate is called AFTER the state of source becomes STOPPED but
// BEFORE user code calls source:play(). This means that some buffers may still be queued (but processed
// and completely finished playing). These must be unqueued before we can start using the source again.
ALint processed;
ALuint _unused[SOURCE_BUFFERS];
alGetSourcei(lovrSourceGetId(source), AL_BUFFERS_PROCESSED, &processed);
alSourceUnqueueBuffers(source->id, processed, _unused);
lovrSourceStream(source, source->buffers, SOURCE_BUFFERS);
alSourcePlay(source->id);
}
void lovrSourceResume(Source* source) {
if (!lovrSourceIsPaused(source)) {
return;
}
alSourcePlay(source->id);
}
void lovrSourceRewind(Source* source) {
if (lovrSourceIsStopped(source)) {
return;
}
bool wasPaused = lovrSourceIsPaused(source);
alSourceRewind(source->id);
lovrSourceStop(source);
lovrSourcePlay(source);
if (wasPaused) {
lovrSourcePause(source);
if (source->type == SOURCE_STATIC) {
if (getState(source) != AL_PLAYING) {
alSourcePlay(source->id);
}
} else {
switch (getState(source)) {
case AL_INITIAL:
case AL_STOPPED:
alSourcei(source->id, AL_BUFFER, AL_NONE);
lovrSourceStream(source, source->buffers, SOURCE_BUFFERS);
alSourcePlay(source->id);
break;
case AL_PAUSED:
alSourcePlay(source->id);
break;
case AL_PLAYING:
break;
}
}
}
void lovrSourceSeek(Source* source, size_t sample) {
switch (source->type) {
case SOURCE_STATIC:
alSourcef(source->id, AL_SAMPLE_OFFSET, sample);
break;
case SOURCE_STREAM: {
bool wasPaused = lovrSourceIsPaused(source);
lovrSourceStop(source);
lovrAudioStreamSeek(source->stream, sample);
lovrSourcePlay(source);
if (wasPaused) {
lovrSourcePause(source);
}
break;
if (source->type == SOURCE_STATIC) {
alSourcef(source->id, AL_SAMPLE_OFFSET, sample);
} else {
bool wasPaused = getState(source) == AL_PAUSED;
alSourceStop(source->id);
lovrAudioStreamSeek(source->stream, sample);
lovrSourcePlay(source);
if (wasPaused) {
lovrSourcePause(source);
}
}
}
@ -272,30 +239,12 @@ void lovrSourceSetVolumeLimits(Source* source, float min, float max) {
}
void lovrSourceStop(Source* source) {
if (lovrSourceIsStopped(source)) {
return;
}
switch (source->type) {
case SOURCE_STATIC:
alSourceStop(source->id);
break;
case SOURCE_STREAM: {
// Stop the source
alSourceStop(source->id);
alSourcei(source->id, AL_BUFFER, AL_NONE);
// Empty the buffers
int count = 0;
alGetSourcei(source->id, AL_BUFFERS_QUEUED, &count);
alSourceUnqueueBuffers(source->id, count, NULL);
// Rewind the decoder
lovrAudioStreamRewind(source->stream);
break;
}
if (source->type == SOURCE_STATIC) {
alSourceStop(source->id);
} else {
alSourceStop(source->id);
alSourcei(source->id, AL_BUFFER, AL_NONE);
lovrAudioStreamRewind(source->stream);
}
}