ソースを参照

OpenAudio streaming tested and working

BearishSun 9 年 前
コミット
4a520c9e77

+ 1 - 1
Source/BansheeOpenAudio/Source/BsOAAudio.cpp

@@ -386,7 +386,7 @@ namespace BansheeEngine
 			}
 			else
 			{
-				ALenum format = _getOpenALBufferFormat(info.numChannels, 16);
+				ALenum format = _getOpenALBufferFormat(info.numChannels, info.bitDepth);
 				alBufferData(bufferId, format, samples, info.numSamples * (info.bitDepth / 8), info.sampleRate);
 			}
 		}

+ 29 - 11
Source/BansheeOpenAudio/Source/BsOAAudioSource.cpp

@@ -49,6 +49,9 @@ namespace BansheeEngine
 				alSourcei(mSourceIDs[i], AL_BUFFER, oaBuffer);
 			}
 		}
+
+		// Looping is influenced by streaming mode, so re-apply it in case it changed
+		setIsLooping(mLoop);
 	}
 
 	void OAAudioSource::setPosition(const Vector3& position)
@@ -121,6 +124,10 @@ namespace BansheeEngine
 	{
 		AudioSource::setIsLooping(loop);
 
+		// When streaming we handle looping manually
+		if (requiresStreaming())
+			loop = false;
+
 		auto& contexts = gOAAudio()._getContexts();
 		UINT32 numContexts = (UINT32)contexts.size();
 		for (UINT32 i = 0; i < numContexts; i++)
@@ -181,7 +188,10 @@ namespace BansheeEngine
 			Lock(mMutex);
 			
 			if (!mIsStreaming)
+			{
 				startStreaming();
+				stream(); // Stream first block on this thread to ensure something can play right away
+			}
 		}
 		
 		auto& contexts = gOAAudio()._getContexts();
@@ -214,14 +224,6 @@ namespace BansheeEngine
 	{
 		AudioSource::stop();
 
-		{
-			Lock(mMutex);
-
-			mStreamProcessedPosition = 0;
-			if (mIsStreaming)
-				stopStreaming();
-		}
-
 		auto& contexts = gOAAudio()._getContexts();
 		UINT32 numContexts = (UINT32)contexts.size();
 		for (UINT32 i = 0; i < numContexts; i++)
@@ -232,6 +234,14 @@ namespace BansheeEngine
 			alSourceStop(mSourceIDs[i]);
 			alSourcef(mSourceIDs[i], AL_SEC_OFFSET, 0.0f);
 		}
+
+		{
+			Lock(mMutex);
+
+			mStreamProcessedPosition = 0;
+			if (mIsStreaming)
+				stopStreaming();
+		}
 	}
 
 	void OAAudioSource::setGlobalPause(bool pause)
@@ -368,10 +378,14 @@ namespace BansheeEngine
 				alcMakeContextCurrent(contexts[i]);
 
 			alSourcef(mSourceIDs[i], AL_PITCH, mPitch);
-			alSourcef(mSourceIDs[i], AL_LOOPING, mLoop);
 			alSourcef(mSourceIDs[i], AL_REFERENCE_DISTANCE, mMinDistance);
 			alSourcef(mSourceIDs[i], AL_ROLLOFF_FACTOR, mAttenuation);
 
+			if(requiresStreaming())
+				alSourcef(mSourceIDs[i], AL_LOOPING, false);
+			else
+				alSourcef(mSourceIDs[i], AL_LOOPING, mLoop);
+
 			if (is3D())
 			{
 				alSourcei(mSourceIDs[i], AL_SOURCE_RELATIVE, false);
@@ -475,7 +489,7 @@ namespace BansheeEngine
 			UINT32 buffer;
 			alSourceUnqueueBuffers(mSourceIDs[0], 1, &buffer);
 
-			UINT32 bufferIdx = 0;
+			INT32 bufferIdx = -1;
 			for (UINT32 j = 0; j < StreamBufferCount; j++)
 			{
 				if (buffer == mStreamBuffers[j])
@@ -484,6 +498,10 @@ namespace BansheeEngine
 					break;
 				}
 			}
+			
+			// Possibly some buffer from previous playback remained unqueued, in which case ignore it
+			if (bufferIdx == -1)
+				continue;
 
 			mBusyBuffers[bufferIdx] = false;
 
@@ -501,7 +519,7 @@ namespace BansheeEngine
 			else
 			{
 				UINT32 bytesPerSample = bufferBits / 8;
-				mStreamProcessedPosition = bufferSize / bytesPerSample;
+				mStreamProcessedPosition += bufferSize / bytesPerSample;
 			}
 
 			if (mStreamProcessedPosition == totalNumSamples) // Reached the end