Browse Source

Allow streaming from memory in FMOD
Fixed seeking for OpenAL streaming audio

BearishSun 9 years ago
parent
commit
ba36a8d11f

+ 26 - 11
Source/BansheeFMOD/Source/BsFMODAudioClip.cpp

@@ -45,9 +45,7 @@ namespace BansheeEngine
 			flags |= FMOD_2D;
 
 		// Load data into a sound buffer
-		// TODO - Vorbis cannot be decompressed from memory by FMOD. Instead we force AudioReadMode::Stream for it.
-		if(mDesc.readMode == AudioReadMode::LoadDecompressed || 
-			(mDesc.readMode == AudioReadMode::LoadCompressed && mDesc.format != AudioFormat::VORBIS))
+		if(mDesc.readMode == AudioReadMode::LoadDecompressed || mDesc.readMode == AudioReadMode::LoadCompressed)
 		{
 			// Read all data into memory
 			SPtr<DataStream> stream;
@@ -137,19 +135,36 @@ namespace BansheeEngine
 		}
 
 		FMOD_MODE flags = FMOD_CREATESTREAM;
+		const char* streamData;
 
 		FMOD_CREATESOUNDEXINFO exInfo;
 		memset(&exInfo, 0, sizeof(exInfo));
 		exInfo.cbsize = sizeof(exInfo);
-		
-		// Streaming from memory not supported.
-		assert(mStreamData->isFile());
 
-		exInfo.length = mStreamSize;
-		exInfo.fileoffset = mStreamOffset;
+		String pathStr;
+		if (mStreamData->isFile())
+		{
+			exInfo.length = mStreamSize;
+			exInfo.fileoffset = mStreamOffset;
+
+			SPtr<FileDataStream> fileStream = std::static_pointer_cast<FileDataStream>(mStreamData);
+			pathStr = fileStream->getPath().toString();
+
+			streamData = pathStr.c_str();
+		}
+		else
+		{
+			SPtr<MemoryDataStream> memStream = std::static_pointer_cast<MemoryDataStream>(mStreamData);
 
-		SPtr<FileDataStream> fileStream = std::static_pointer_cast<FileDataStream>(mStreamData);
-		String pathStr = fileStream->getPath().toString();
+			// Note: I could use FMOD_OPENMEMORY_POINT here to save on memory, but then the caller would need to make
+			// sure the memory is not deallocated. I'm ignoring this for now as streaming from memory should be a rare
+			// occurence (normally only in editor)
+			flags |= FMOD_OPENMEMORY;
+			exInfo.length = mStreamSize;
+
+			memStream->seek(mStreamOffset);
+			streamData = (const char*)memStream->getCurrentPtr();
+		}
 
 		if (is3D())
 			flags |= FMOD_3D;
@@ -185,7 +200,7 @@ namespace BansheeEngine
 
 		FMOD::Sound* sound = nullptr;
 		FMOD::System* fmod = gFMODAudio()._getFMOD();
-		if (fmod->createSound(pathStr.c_str(), flags, &exInfo, &sound) != FMOD_OK)
+		if (fmod->createSound(streamData, flags, &exInfo, &sound) != FMOD_OK)
 		{
 			LOGERR("Failed creating a streaming sound.");
 			return nullptr;

+ 3 - 0
Source/BansheeOpenAudio/Source/BsOAAudioSource.cpp

@@ -239,6 +239,8 @@ namespace BansheeEngine
 			Lock(mMutex);
 
 			mStreamProcessedPosition = 0;
+			mStreamQueuedPosition = 0;
+
 			if (mIsStreaming)
 				stopStreaming();
 		}
@@ -294,6 +296,7 @@ namespace BansheeEngine
 				else
 					mStreamProcessedPosition = 0;
 
+				mStreamQueuedPosition = mStreamProcessedPosition;
 				clipTime = 0.0f;
 			}
 		}