Browse Source

Rework source updates, do clean stopping of streaming sources once they end. (bug #295)

Bart van Strien 14 years ago
parent
commit
c28659ae33

+ 1 - 1
src/modules/audio/Source.h

@@ -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;

+ 2 - 1
src/modules/audio/null/Source.cpp

@@ -77,8 +77,9 @@ namespace null
 		return true;
 	}
 
-	void Source::update()
+	bool Source::update()
 	{
+		return false;
 	}
 
 	void Source::setPitch(float pitch)

+ 1 - 1
src/modules/audio/null/Source.h

@@ -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);

+ 4 - 10
src/modules/audio/openal/Pool.cpp

@@ -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)

+ 50 - 32
src/modules/audio/openal/Source.cpp

@@ -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;
+			if (isLooping() || !isFinished())
+			{
+				// Number of processed buffers.
+				ALint processed;
 
-			alGetSourcei(source, AL_BUFFERS_PROCESSED, &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;
 
-			while(processed--)
+					// 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
 			{
-				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);
+				// Actually stop the source,
+				// 'just running out' is bad
+				// practice, and prevents
+				// rewinds.
+				stopAtomic();
+				rewindAtomic();
+				return false;
 			}
 		}
+		return false;
 	}
 
 	void Source::setPitch(float pitch)

+ 1 - 1
src/modules/audio/openal/Source.h

@@ -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);