From 00c02adcd06f4e7429a12f6331cb8bfaea21da8c Mon Sep 17 00:00:00 2001 From: rcoaxil Date: Thu, 13 Oct 2016 18:18:08 +0300 Subject: [PATCH] issues addressed warnings fixed added type checking to Lua functions stopping queueable source clears buffered data getting queueable source to auto-play if it underruns and then gets re-filled will probably require re-designing pool usage strategy --HG-- branch : minor --- src/modules/audio/openal/Source.cpp | 66 +++++++++++++++++------------ src/modules/audio/openal/Source.h | 6 +-- src/modules/audio/wrap_Audio.cpp | 9 ++-- src/modules/audio/wrap_Source.cpp | 29 ++++++++----- 4 files changed, 65 insertions(+), 45 deletions(-) diff --git a/src/modules/audio/openal/Source.cpp b/src/modules/audio/openal/Source.cpp index 10a8db7e6..67bb563a8 100644 --- a/src/modules/audio/openal/Source.cpp +++ b/src/modules/audio/openal/Source.cpp @@ -362,7 +362,7 @@ bool Source::update() offsetSamples += (curOffsetSamples - newOffsetSamples); offsetSeconds += (curOffsetSecs - newOffsetSecs); - for (unsigned int i = 0; i < processed; i++) + for (unsigned int i = 0; i < (unsigned int)processed; i++) unusedBufferPush(buffers[i]); while (unusedBufferPeek() != AL_NONE) @@ -384,7 +384,7 @@ bool Source::update() alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); alSourceUnqueueBuffers(source, processed, buffers); - for (unsigned int i = 0; i < processed; i++) + for (unsigned int i = 0; i < (unsigned int)processed; i++) { ALint size; alGetBufferi(buffers[i], AL_SIZE, &size); @@ -393,6 +393,8 @@ bool Source::update() } return !isFinished(); } + case TYPE_MAX_ENUM: + break; } return false; @@ -505,6 +507,8 @@ void Source::seekAtomic(float offset, void *unit) offsetSeconds = offsetSamples / sampleRate; } break; + case TYPE_MAX_ENUM: + break; } } @@ -742,13 +746,12 @@ bool Source::queueAtomic(void *data, ALsizei length) } else { - //remaining buffers are stored beyond the tail of unused stack - if (unusedBufferTop >= (int)MAX_BUFFERS - 1) + ALuint buffer = unusedBufferPeekNext(); + if (buffer == AL_NONE) return false; - - ALuint buffer = unusedBuffers[unusedBufferTop + 1]; + + //stack acts as queue while stopped alBufferData(buffer, getFormat(channels, bitDepth), data, length, sampleRate); - //new buffer must go last, so it goes to the base of the stack unusedBufferQueue(buffer); } bufferedBytes += length; @@ -765,7 +768,10 @@ int Source::getFreeBufferCount() const return unusedBufferTop + 1; case TYPE_QUEUE: return valid ? unusedBufferTop + 1 : (int)MAX_BUFFERS - unusedBufferTop - 1; + case TYPE_MAX_ENUM: + return 0; } + return 0; } void Source::prepareAtomic() @@ -807,7 +813,10 @@ void Source::prepareAtomic() if (offsetSamples >= 0) alSourcef(source, AL_SAMPLE_OFFSET, offsetSamples); + break; } + case TYPE_MAX_ENUM: + break; } } @@ -823,40 +832,38 @@ void Source::teardownAtomic() ALint queued; ALuint buffer; + decoder->seek(0); + // drain buffers + //since we only unqueue 1 buffer, it's OK to use singular variable pointer instead of array alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); - for (unsigned int i = 0; i < queued; i++) - { - //since we only unqueue 1 buffer, it's OK to use singular variable pointer instead of array + for (unsigned int i = 0; i < (unsigned int)queued; i++) alSourceUnqueueBuffers(source, 1, &buffer); - unusedBufferPush(buffer); - } + + // generate unused buffers list + for (unsigned int i = 0; i < MAX_BUFFERS; i++) + unusedBuffers[i] = streamBuffers[i]; + + unusedBufferTop = MAX_BUFFERS - 1; break; } case TYPE_QUEUE: { ALint queued; - ALuint buffers[MAX_BUFFERS]; ALuint buffer; - int unused = 0; - - //store all unused buffers, also clear stack - while (unusedBufferPeek() != AL_NONE) - buffers[unused++] = *unusedBufferPop(); alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); - //stack needs to be filled in reverse order - for (unsigned int i = queued; i > 0; i--) - { + for (unsigned int i = (unsigned int)queued; i > 0; i--) alSourceUnqueueBuffers(source, 1, &buffer); - unusedBufferPush(buffer); - } - - // put unused buffers at the end of stack - for (unsigned int i = 0; i < unused; i++) - unusedBuffers[unusedBufferTop + 1 + i] = buffers[i]; + // generate unused buffers list + for (unsigned int i = 0; i < MAX_BUFFERS; i++) + unusedBuffers[i] = streamBuffers[i]; + + unusedBufferTop = -1; break; } + case TYPE_MAX_ENUM: + break; } alSourcei(source, AL_BUFFER, AL_NONE); @@ -1043,6 +1050,11 @@ ALuint Source::unusedBufferPeek() return (unusedBufferTop < 0) ? AL_NONE : unusedBuffers[unusedBufferTop]; } +ALuint Source::unusedBufferPeekNext() +{ + return (unusedBufferTop >= (int)MAX_BUFFERS - 1) ? AL_NONE : unusedBuffers[unusedBufferTop + 1]; +} + ALuint *Source::unusedBufferPop() { return &unusedBuffers[unusedBufferTop--]; diff --git a/src/modules/audio/openal/Source.h b/src/modules/audio/openal/Source.h index 4b06a5414..bbd463a1e 100644 --- a/src/modules/audio/openal/Source.h +++ b/src/modules/audio/openal/Source.h @@ -165,6 +165,7 @@ private: int streamAtomic(ALuint buffer, love::sound::Decoder *d); ALuint unusedBufferPeek(); + ALuint unusedBufferPeekNext(); ALuint *unusedBufferPop(); void unusedBufferPush(ALuint buffer); void unusedBufferQueue(ALuint buffer); @@ -177,9 +178,6 @@ private: ALuint streamBuffers[MAX_BUFFERS]; ALuint unusedBuffers[MAX_BUFFERS]; - int unusedBufferTop; - ALsizei bufferedBytes; - StrongRef staticBuffer; float pitch; @@ -212,6 +210,8 @@ private: StrongRef decoder; unsigned int toLoop; + int unusedBufferTop; + ALsizei bufferedBytes; }; // Source } // openal diff --git a/src/modules/audio/wrap_Audio.cpp b/src/modules/audio/wrap_Audio.cpp index f7e7bedda..cecb9074a 100644 --- a/src/modules/audio/wrap_Audio.cpp +++ b/src/modules/audio/wrap_Audio.cpp @@ -82,10 +82,9 @@ int w_newQueueableSource(lua_State *L) { Source *t = nullptr; - if (lua_isnumber(L, 1) && lua_isnumber(L, 2) && lua_isnumber(L, 3)) - luax_catchexcept(L, [&]() { - t = instance()->newSource((int)lua_tonumber(L, 1), (int)lua_tonumber(L, 2), (int)lua_tonumber(L, 3)); - }); + luax_catchexcept(L, [&]() { + t = instance()->newSource((int)luaL_checknumber(L, 1), (int)luaL_checknumber(L, 2), (int)luaL_checknumber(L, 3)); + }); if (t != nullptr) { @@ -94,7 +93,7 @@ int w_newQueueableSource(lua_State *L) return 1; } else - return luaL_error(L, "Wrong type of arguments to function call."); + return 0; //all argument type errors are checked in above constructor } static std::vector readSourceList(lua_State *L, int n) diff --git a/src/modules/audio/wrap_Source.cpp b/src/modules/audio/wrap_Source.cpp index 605197f9d..0588201f5 100644 --- a/src/modules/audio/wrap_Source.cpp +++ b/src/modules/audio/wrap_Source.cpp @@ -346,10 +346,18 @@ int w_Source_queue(lua_State *L) { love::sound::SoundData *s = luax_totype(L, 2, SOUND_SOUND_DATA_ID); - int length = lua_isnumber(L, 4) ? lua_tonumber(L, 4) : ( lua_isnumber(L, 3) ? lua_tonumber(L, 3) : s->getSize() ); - int offset = lua_isnumber(L, 4) ? lua_tonumber(L, 3) : 0; + int offset = 0; + int length = s->getSize(); - if (length > s->getSize() - offset || offset < 0 || length < 0) + if (lua_gettop(L) == 4) + { + offset = luaL_checknumber(L, 3); + length = luaL_checknumber(L, 4); + } + else if (lua_gettop(L) == 3) + length = luaL_checknumber(L, 3); + + if (length > (int)s->getSize() - offset || offset < 0 || length < 0) return luaL_error(L, "Data region out of bounds."); luax_catchexcept(L, [&]() { @@ -359,16 +367,17 @@ int w_Source_queue(lua_State *L) } else if (lua_islightuserdata(L, 2)) { - if (!(lua_isnumber(L, 3) && lua_isnumber(L, 4))) - return luaL_error(L, "No region specified."); - if (!(lua_isnumber(L, 5) && lua_isnumber(L, 6) && lua_isnumber(L, 7))) - return luaL_error(L, "No format specified."); - if (lua_tonumber(L, 3) < 0 || lua_tonumber(L, 4) < 0) + int offset = luaL_checknumber(L, 3); + int length = luaL_checknumber(L, 4); + int sampleRate = luaL_checknumber(L, 5); + int bitDepth = luaL_checknumber(L, 6); + int channels = luaL_checknumber(L, 7); + + if (length < 0 || offset < 0) return luaL_error(L, "Data region out of bounds."); luax_catchexcept(L, [&]() { - success = t->queue((void*)((uintptr_t)lua_touserdata(L, 2) + (uintptr_t)lua_tonumber(L, 3)), - lua_tonumber(L, 4), (int)lua_tonumber(L, 5), (int)lua_tonumber(L, 6), (int)lua_tonumber(L, 7)); + success = t->queue((void*)((uintptr_t)lua_touserdata(L, 2) + (uintptr_t)offset), length, sampleRate, bitDepth, channels); }); } else