mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
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
This commit is contained in:
@@ -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--];
|
||||
|
||||
@@ -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<StaticDataBuffer> staticBuffer;
|
||||
|
||||
float pitch;
|
||||
@@ -212,6 +210,8 @@ private:
|
||||
StrongRef<love::sound::Decoder> decoder;
|
||||
|
||||
unsigned int toLoop;
|
||||
int unusedBufferTop;
|
||||
ALsizei bufferedBytes;
|
||||
}; // Source
|
||||
|
||||
} // openal
|
||||
|
||||
@@ -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<Source*> readSourceList(lua_State *L, int n)
|
||||
|
||||
@@ -346,10 +346,18 @@ int w_Source_queue(lua_State *L)
|
||||
{
|
||||
love::sound::SoundData *s = luax_totype<love::sound::SoundData>(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
|
||||
|
||||
Reference in New Issue
Block a user