mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Rework source updates, do clean stopping of streaming sources once they end. (bug #295)
This commit is contained in:
@@ -64,7 +64,7 @@ namespace audio
|
||||
virtual bool isStopped() const = 0;
|
||||
virtual bool isPaused() const = 0;
|
||||
virtual bool isFinished() const = 0;
|
||||
virtual void update() = 0;
|
||||
virtual bool update() = 0;
|
||||
|
||||
virtual void setPitch(float pitch) = 0;
|
||||
virtual float getPitch() const = 0;
|
||||
|
||||
@@ -77,8 +77,9 @@ namespace null
|
||||
return true;
|
||||
}
|
||||
|
||||
void Source::update()
|
||||
bool Source::update()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Source::setPitch(float pitch)
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace null
|
||||
virtual bool isStopped() const;
|
||||
virtual bool isPaused() const;
|
||||
virtual bool isFinished() const;
|
||||
virtual void update();
|
||||
virtual bool update();
|
||||
virtual void setPitch(float pitch);
|
||||
virtual float getPitch() const;
|
||||
virtual void setVolume(float volume);
|
||||
|
||||
@@ -86,18 +86,14 @@ namespace openal
|
||||
|
||||
while(i != playing.end())
|
||||
{
|
||||
if(i->first->isStopped())
|
||||
if(!i->first->update())
|
||||
{
|
||||
i->first->stopAtomic();
|
||||
i->first->release();
|
||||
available.push(i->second);
|
||||
playing.erase(i++);
|
||||
}
|
||||
else
|
||||
{
|
||||
i->first->update();
|
||||
i++;
|
||||
playing.erase(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,9 +215,7 @@ namespace openal
|
||||
void Pool::rewind(Source * source)
|
||||
{
|
||||
thread::Lock lock(mutex);
|
||||
ALuint out;
|
||||
if(findSource(source, out))
|
||||
source->rewindAtomic();
|
||||
source->rewindAtomic();
|
||||
}
|
||||
|
||||
void Pool::release(Source * source)
|
||||
|
||||
@@ -143,49 +143,67 @@ namespace openal
|
||||
return type == TYPE_STATIC ? isStopped() : isStopped() && !isLooping() && decoder->isFinished();
|
||||
}
|
||||
|
||||
void Source::update()
|
||||
bool Source::update()
|
||||
{
|
||||
if(valid && type == TYPE_STATIC)
|
||||
if (!valid)
|
||||
return false;
|
||||
if (type == TYPE_STATIC)
|
||||
{
|
||||
// Looping mode could have changed.
|
||||
alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE);
|
||||
return !isStopped();
|
||||
}
|
||||
else if(valid && type == TYPE_STREAM && !(!isLooping() && isFinished()))
|
||||
else if (type == TYPE_STREAM)
|
||||
{
|
||||
// Number of processed buffers.
|
||||
ALint processed;
|
||||
|
||||
alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
|
||||
|
||||
while(processed--)
|
||||
if (isLooping() || !isFinished())
|
||||
{
|
||||
ALuint buffer;
|
||||
|
||||
float curOffsetSamples, curOffsetSecs;
|
||||
|
||||
alGetSourcef(source, AL_SAMPLE_OFFSET, &curOffsetSamples);
|
||||
|
||||
ALint b;
|
||||
alGetSourcei(source, AL_BUFFER, &b);
|
||||
int freq;
|
||||
alGetBufferi(b, AL_FREQUENCY, &freq);
|
||||
curOffsetSecs = curOffsetSamples / freq;
|
||||
|
||||
// Get a free buffer.
|
||||
alSourceUnqueueBuffers(source, 1, &buffer);
|
||||
|
||||
float newOffsetSamples, newOffsetSecs;
|
||||
|
||||
alGetSourcef(source, AL_SAMPLE_OFFSET, &newOffsetSamples);
|
||||
newOffsetSecs = newOffsetSamples / freq;
|
||||
|
||||
offsetSamples += (curOffsetSamples - newOffsetSamples);
|
||||
offsetSeconds += (curOffsetSecs - newOffsetSecs);
|
||||
|
||||
streamAtomic(buffer, decoder);
|
||||
alSourceQueueBuffers(source, 1, &buffer);
|
||||
// Number of processed buffers.
|
||||
ALint processed;
|
||||
|
||||
alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
|
||||
|
||||
while(processed--)
|
||||
{
|
||||
ALuint buffer;
|
||||
|
||||
float curOffsetSamples, curOffsetSecs;
|
||||
|
||||
alGetSourcef(source, AL_SAMPLE_OFFSET, &curOffsetSamples);
|
||||
|
||||
ALint b;
|
||||
alGetSourcei(source, AL_BUFFER, &b);
|
||||
int freq;
|
||||
alGetBufferi(b, AL_FREQUENCY, &freq);
|
||||
curOffsetSecs = curOffsetSamples / freq;
|
||||
|
||||
// Get a free buffer.
|
||||
alSourceUnqueueBuffers(source, 1, &buffer);
|
||||
|
||||
float newOffsetSamples, newOffsetSecs;
|
||||
|
||||
alGetSourcef(source, AL_SAMPLE_OFFSET, &newOffsetSamples);
|
||||
newOffsetSecs = newOffsetSamples / freq;
|
||||
|
||||
offsetSamples += (curOffsetSamples - newOffsetSamples);
|
||||
offsetSeconds += (curOffsetSecs - newOffsetSecs);
|
||||
|
||||
streamAtomic(buffer, decoder);
|
||||
alSourceQueueBuffers(source, 1, &buffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Actually stop the source,
|
||||
// 'just running out' is bad
|
||||
// practice, and prevents
|
||||
// rewinds.
|
||||
stopAtomic();
|
||||
rewindAtomic();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Source::setPitch(float pitch)
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace openal
|
||||
virtual bool isStopped() const;
|
||||
virtual bool isPaused() const;
|
||||
virtual bool isFinished() const;
|
||||
virtual void update();
|
||||
virtual bool update();
|
||||
virtual void setPitch(float pitch);
|
||||
virtual float getPitch() const;
|
||||
virtual void setVolume(float volume);
|
||||
|
||||
Reference in New Issue
Block a user