summaryrefslogtreecommitdiff
path: root/src/SFML/Audio/SoundStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/SFML/Audio/SoundStream.cpp')
-rw-r--r--src/SFML/Audio/SoundStream.cpp88
1 files changed, 54 insertions, 34 deletions
diff --git a/src/SFML/Audio/SoundStream.cpp b/src/SFML/Audio/SoundStream.cpp
index 9e147a5..0e40548 100644
--- a/src/SFML/Audio/SoundStream.cpp
+++ b/src/SFML/Audio/SoundStream.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2017 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
@@ -51,7 +51,7 @@ m_sampleRate (0),
m_format (0),
m_loop (false),
m_samplesProcessed(0),
-m_endBuffers ()
+m_bufferSeeks ()
{
}
@@ -77,7 +77,9 @@ SoundStream::~SoundStream()
void SoundStream::initialize(unsigned int channelCount, unsigned int sampleRate)
{
m_channelCount = channelCount;
- m_sampleRate = sampleRate;
+ m_sampleRate = sampleRate;
+ m_samplesProcessed = 0;
+ m_isStreaming = false;
// Deduce the format from the number of channels
m_format = priv::AudioDevice::getFormatFromChannelCount(channelCount);
@@ -127,11 +129,7 @@ void SoundStream::play()
stop();
}
- // Move to the beginning
- onSeek(Time::Zero);
-
// Start updating the stream in a separate thread to avoid blocking the application
- m_samplesProcessed = 0;
m_isStreaming = true;
m_threadStartState = Playing;
m_thread.launch();
@@ -169,9 +167,6 @@ void SoundStream::stop()
// Move to the beginning
onSeek(Time::Zero);
-
- // Reset the playing position
- m_samplesProcessed = 0;
}
@@ -263,6 +258,14 @@ bool SoundStream::getLoop() const
////////////////////////////////////////////////////////////
+Int64 SoundStream::onLoop()
+{
+ onSeek(Time::Zero);
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////
void SoundStream::streamData()
{
bool requestStop = false;
@@ -281,7 +284,7 @@ void SoundStream::streamData()
// Create the buffers
alCheck(alGenBuffers(BufferCount, m_buffers));
for (int i = 0; i < BufferCount; ++i)
- m_endBuffers[i] = false;
+ m_bufferSeeks[i] = NoLoop;
// Fill the queue
requestStop = fillQueue();
@@ -341,11 +344,11 @@ void SoundStream::streamData()
}
// Retrieve its size and add it to the samples count
- if (m_endBuffers[bufferNum])
+ if (m_bufferSeeks[bufferNum] != NoLoop)
{
- // This was the last buffer: reset the sample count
- m_samplesProcessed = 0;
- m_endBuffers[bufferNum] = false;
+ // This was the last buffer before EOF or Loop End: reset the sample count
+ m_samplesProcessed = m_bufferSeeks[bufferNum];
+ m_bufferSeeks[bufferNum] = NoLoop;
}
else
{
@@ -390,6 +393,9 @@ void SoundStream::streamData()
// Dequeue any buffer left in the queue
clearQueue();
+ // Reset the playing position
+ m_samplesProcessed = 0;
+
// Delete the buffers
alCheck(alSourcei(m_source, AL_BUFFER, 0));
alCheck(alDeleteBuffers(BufferCount, m_buffers));
@@ -397,34 +403,41 @@ void SoundStream::streamData()
////////////////////////////////////////////////////////////
-bool SoundStream::fillAndPushBuffer(unsigned int bufferNum)
+bool SoundStream::fillAndPushBuffer(unsigned int bufferNum, bool immediateLoop)
{
bool requestStop = false;
- // Acquire audio data
+ // Acquire audio data, also address EOF and error cases if they occur
Chunk data = {NULL, 0};
- if (!onGetData(data))
+ for (Uint32 retryCount = 0; !onGetData(data) && (retryCount < BufferRetries); ++retryCount)
{
- // Mark the buffer as the last one (so that we know when to reset the playing position)
- m_endBuffers[bufferNum] = true;
-
// Check if the stream must loop or stop
- if (m_loop)
+ if (!m_loop)
{
- // Return to the beginning of the stream source
- onSeek(Time::Zero);
-
- // If we previously had no data, try to fill the buffer once again
- if (!data.samples || (data.sampleCount == 0))
- {
- return fillAndPushBuffer(bufferNum);
- }
+ // Not looping: Mark this buffer as ending with 0 and request stop
+ if (data.samples != NULL && data.sampleCount != 0)
+ m_bufferSeeks[bufferNum] = 0;
+ requestStop = true;
+ break;
}
- else
+
+ // Return to the beginning or loop-start of the stream source using onLoop(), and store the result in the buffer seek array
+ // This marks the buffer as the "last" one (so that we know where to reset the playing position)
+ m_bufferSeeks[bufferNum] = onLoop();
+
+ // If we got data, break and process it, else try to fill the buffer once again
+ if (data.samples != NULL && data.sampleCount != 0)
+ break;
+
+ // If immediateLoop is specified, we have to immediately adjust the sample count
+ if (immediateLoop && (m_bufferSeeks[bufferNum] != NoLoop))
{
- // Not looping: request stop
- requestStop = true;
+ // We just tried to begin preloading at EOF or Loop End: reset the sample count
+ m_samplesProcessed = m_bufferSeeks[bufferNum];
+ m_bufferSeeks[bufferNum] = NoLoop;
}
+
+ // We're a looping sound that got no data, so we retry onGetData()
}
// Fill the buffer if some data was returned
@@ -439,6 +452,11 @@ bool SoundStream::fillAndPushBuffer(unsigned int bufferNum)
// Push it into the sound queue
alCheck(alSourceQueueBuffers(m_source, 1, &buffer));
}
+ else
+ {
+ // If we get here, we most likely ran out of retries
+ requestStop = true;
+ }
return requestStop;
}
@@ -451,7 +469,9 @@ bool SoundStream::fillQueue()
bool requestStop = false;
for (int i = 0; (i < BufferCount) && !requestStop; ++i)
{
- if (fillAndPushBuffer(i))
+ // Since no sound has been loaded yet, we can't schedule loop seeks preemptively,
+ // So if we start on EOF or Loop End, we let fillAndPushBuffer() adjust the sample count
+ if (fillAndPushBuffer(i, (i == 0)))
requestStop = true;
}