Przeglądaj źródła

Audio WIP: Added AudioClip interface

BearishSun 9 lat temu
rodzic
commit
eebd06e343

+ 8 - 0
Build/VS2015/BansheeCore.vcxproj

@@ -296,6 +296,11 @@
     </Link>
     </Link>
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudio.h" />
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudioClip.h" />
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudioClipImportOptionsRTTI.h" />
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudioClipRTTI.h" />
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudioClipImportOptions.h" />
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsBoxCollider.h" />
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsBoxCollider.h" />
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsCBoxColliderRTTI.h" />
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsCBoxColliderRTTI.h" />
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsCapsuleCollider.h" />
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsCapsuleCollider.h" />
@@ -517,6 +522,9 @@
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsPhysicsMeshRTTI.h" />
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsPhysicsMeshRTTI.h" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\..\Source\BansheeCore\Source\BsAudio.cpp" />
+    <ClCompile Include="..\..\Source\BansheeCore\Source\BsAudioClip.cpp" />
+    <ClCompile Include="..\..\Source\BansheeCore\Source\BsAudioClipImportOptions.cpp" />
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsBoxCollider.cpp" />
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsBoxCollider.cpp" />
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsCapsuleCollider.cpp" />
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsCapsuleCollider.cpp" />
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsCBoxCollider.cpp" />
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsCBoxCollider.cpp" />

+ 30 - 0
Build/VS2015/BansheeCore.vcxproj.filters

@@ -105,6 +105,12 @@
     <Filter Include="Source Files\Components">
     <Filter Include="Source Files\Components">
       <UniqueIdentifier>{a0113695-a6e4-42af-9c38-f6140bc45cc7}</UniqueIdentifier>
       <UniqueIdentifier>{a0113695-a6e4-42af-9c38-f6140bc45cc7}</UniqueIdentifier>
     </Filter>
     </Filter>
+    <Filter Include="Header Files\Audio">
+      <UniqueIdentifier>{4c7848df-0ad3-4bf7-aace-354af227d1bd}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Audio">
+      <UniqueIdentifier>{497aec69-f961-4703-a5a0-b483fba84508}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsCommonTypes.h">
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsCommonTypes.h">
@@ -764,6 +770,21 @@
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsPhysicsMeshRTTI.h">
     <ClInclude Include="..\..\Source\BansheeCore\Include\BsPhysicsMeshRTTI.h">
       <Filter>Header Files\RTTI</Filter>
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudioClip.h">
+      <Filter>Header Files\Audio</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudioClipRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudio.h">
+      <Filter>Header Files\Audio</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudioClipImportOptions.h">
+      <Filter>Header Files\Importer</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\Source\BansheeCore\Include\BsAudioClipImportOptionsRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsCoreApplication.cpp">
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsCoreApplication.cpp">
@@ -1210,5 +1231,14 @@
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsShaderImportOptions.cpp">
     <ClCompile Include="..\..\Source\BansheeCore\Source\BsShaderImportOptions.cpp">
       <Filter>Source Files\Importer</Filter>
       <Filter>Source Files\Importer</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="..\..\Source\BansheeCore\Source\BsAudioClip.cpp">
+      <Filter>Source Files\Audio</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\BansheeCore\Source\BsAudio.cpp">
+      <Filter>Source Files\Audio</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\Source\BansheeCore\Source\BsAudioClipImportOptions.cpp">
+      <Filter>Source Files\Importer</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </Project>

+ 27 - 0
Source/BansheeCore/Include/BsAudio.h

@@ -0,0 +1,27 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Audio
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT Audio : public Module<Audio>
+	{
+	protected:
+		friend class AudioClip;
+
+		virtual SPtr<AudioClip> createClip(const SPtr<DataStream>& samples, UINT32 numSamples, 
+			const AUDIO_CLIP_DESC& desc) = 0;
+	};
+
+	/** Provides easier access to Audio. */
+	BS_CORE_EXPORT Audio& gAudio();
+
+	/** @} */
+}

+ 82 - 0
Source/BansheeCore/Include/BsAudioClip.h

@@ -0,0 +1,82 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsResource.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Audio
+	 *  @{
+	 */
+
+	enum class AudioFormat
+	{
+		PCM,
+		VORBIS
+	};
+
+	enum class AudioReadMode
+	{
+		LoadDecompressed,
+		LoadCompressed,
+		Stream
+	};
+
+	struct AUDIO_CLIP_DESC
+	{
+		AudioReadMode readMode = AudioReadMode::LoadDecompressed;
+		AudioFormat format = AudioFormat::PCM;
+		UINT32 frequency = 44100;
+		UINT32 bitDepth = 16;
+		UINT32 numChannels = 2;
+	};
+
+	class BS_CORE_EXPORT AudioClip : public Resource
+	{
+	public:
+		static HAudioClip create(UINT32 numSamples, const AUDIO_CLIP_DESC& desc);
+		static HAudioClip create(const SPtr<DataStream>& samples, UINT32 numSamples, const AUDIO_CLIP_DESC& desc);
+
+		UINT32 getBitDepth() const { return mDesc.bitDepth; }
+		UINT32 getFrequency() const { return mDesc.frequency; }
+		UINT32 getNumChannels() const { return mDesc.numChannels; }
+		AudioFormat getFormat() const { return mDesc.format; }
+		AudioReadMode getReadMode() const { return mDesc.readMode; }
+		UINT32 getLength() const { return mNumSamples / mDesc.frequency; }
+		UINT32 getNumSamples() const { return mNumSamples; }
+
+		virtual UINT32 getDataSize() const = 0;
+		virtual UINT8* getData() const = 0;
+
+		// Note: This will convert internal audio read mode to LoadCompressed (if ogg) or LoadDecompressed (if PCM)
+		virtual void setData(UINT8* samples, UINT32 numSamples) = 0;
+
+	public: // ***** INTERNAL ******
+		/** @name Internal
+		 *  @{
+		 */
+
+		static SPtr<AudioClip> _createPtr(const SPtr<DataStream>& samples, UINT32 numSamples, const AUDIO_CLIP_DESC& desc);
+
+		/** @} */
+	private:
+		AudioClip(const SPtr<DataStream>& samples, UINT32 numSamples, const AUDIO_CLIP_DESC& desc);
+
+	protected:
+		AUDIO_CLIP_DESC mDesc;
+		UINT32 mNumSamples;
+		SPtr<DataStream> mStreamData;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class AudioClipRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
+}

+ 41 - 0
Source/BansheeCore/Include/BsAudioClipImportOptions.h

@@ -0,0 +1,41 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsImportOptions.h"
+#include "BsAudioClip.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Importer
+	 *  @{
+	 */
+
+	/** Contains import options you may use to control how an audio clip is imported. */
+	class BS_CORE_EXPORT AudioClipImportOptions : public ImportOptions
+	{
+	public:
+		AudioFormat getFormat() const { return mFormat; }
+		void setFormat(AudioFormat format) { mFormat = format; }
+
+		AudioReadMode getReadMode() const { return mReadMode; }
+		void setReadMode(AudioReadMode readMode) { mReadMode = readMode; }
+
+		// Note: Add options to resample to a different frequency, reduce/increase bit depth, and stereo -> mono conversion
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class AudioClipImportOptionsRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	private:
+		AudioFormat mFormat = AudioFormat::PCM;
+		AudioReadMode mReadMode = AudioReadMode::LoadDecompressed;
+	};
+
+	/** @} */
+}

+ 51 - 0
Source/BansheeCore/Include/BsAudioClipImportOptionsRTTI.h

@@ -0,0 +1,51 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsAudioClipImportOptions.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT AudioClipImportOptionsRTTI : public RTTIType<AudioClipImportOptions, ImportOptions, AudioClipImportOptionsRTTI>
+	{
+	private:
+		BS_PLAIN_MEMBER(mFormat);
+		BS_PLAIN_MEMBER(mReadMode);
+
+	public:
+		AudioClipImportOptionsRTTI()
+		{
+			BS_ADD_PLAIN_FIELD(mFormat, 0);
+			BS_ADD_PLAIN_FIELD(mReadMode, 1);
+		}
+
+		/** @copydoc RTTIType::getRTTIName */
+		const String& getRTTIName() override
+		{
+			static String name = "AudioClipImportOptions";
+			return name;
+		}
+
+		/** @copydoc RTTIType::getRTTIId */
+		UINT32 getRTTIId() override
+		{
+			return TID_AudioClipImportOptions;
+		}
+
+		/** @copydoc RTTIType::newRTTIObject */
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr_new<AudioClipImportOptions>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 78 - 0
Source/BansheeCore/Include/BsAudioClipRTTI.h

@@ -0,0 +1,78 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsAudioClip.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT AudioClipRTTI : public RTTIType <AudioClip, Resource, AudioClipRTTI>
+	{
+	private:
+		BS_PLAIN_MEMBER_NAMED(readMode, mDesc.readMode);
+		BS_PLAIN_MEMBER_NAMED(format, mDesc.format);
+		BS_PLAIN_MEMBER_NAMED(frequency, mDesc.frequency);
+		BS_PLAIN_MEMBER_NAMED(bitDepth, mDesc.bitDepth);
+		BS_PLAIN_MEMBER_NAMED(numChannels, mDesc.numChannels);
+		BS_PLAIN_MEMBER(mNumSamples);
+
+		ManagedDataBlock getData(AudioClip* obj)
+		{
+			ManagedDataBlock dataBlock((UINT8*)obj->getData(), obj->getDataSize());
+			return dataBlock;
+		}
+
+		void setData(AudioClip* obj, ManagedDataBlock val)
+		{
+			// TODO: This method isn't needed as this data will be loaded from the data stream
+			obj->setData(val.getData(), obj->mNumSamples);
+		}
+
+		static UINT8* allocateData(AudioClip* obj, UINT32 numBytes)
+		{
+			// TODO: This method isn't needed as this data will be loaded from the data stream
+			return (UINT8*)bs_alloc(numBytes);
+		}
+
+	public:
+		AudioClipRTTI()
+		{
+			BS_ADD_PLAIN_FIELD(readMode, 0);
+			BS_ADD_PLAIN_FIELD(format, 1);
+			BS_ADD_PLAIN_FIELD(frequency, 2);
+			BS_ADD_PLAIN_FIELD(bitDepth, 3);
+			BS_ADD_PLAIN_FIELD(numChannels, 4);
+			BS_ADD_PLAIN_FIELD(mNumSamples, 5);
+
+			addDataBlockField("mData", 6, &AudioClipRTTI::getData, &AudioClipRTTI::setData, 
+				0, &AudioClipRTTI::allocateData);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "AudioClip";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_AudioClip;
+		}
+
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			AUDIO_CLIP_DESC desc;
+			return AudioClip::_createPtr(nullptr, 0, desc); // Initial values don't matter, they will get overwritten
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 9 - 1
Source/BansheeCore/Include/BsCorePrerequisites.h

@@ -13,6 +13,10 @@
  *  @{
  *  @{
  */
  */
 
 
+/** @defgroup Audio Audio
+ *	Audio clips, 3D sound and music reproduction.
+ */
+
 /** @defgroup CoreThread Core thread
 /** @defgroup CoreThread Core thread
  *	Core objects and interaction with the core (rendering) thread.
  *	Core objects and interaction with the core (rendering) thread.
  */
  */
@@ -358,6 +362,7 @@ namespace BansheeEngine
 	class StringTable;
 	class StringTable;
 	class PhysicsMaterial;
 	class PhysicsMaterial;
 	class PhysicsMesh;
 	class PhysicsMesh;
+	class AudioClip;
 	struct CollisionData;
 	struct CollisionData;
 	// Scene
 	// Scene
 	class SceneObject;
 	class SceneObject;
@@ -382,6 +387,7 @@ namespace BansheeEngine
 	struct SLIDER_JOINT_DESC;
 	struct SLIDER_JOINT_DESC;
 	struct SPHERICAL_JOINT_DESC;
 	struct SPHERICAL_JOINT_DESC;
 	struct D6_JOINT_DESC;
 	struct D6_JOINT_DESC;
+	struct AUDIO_CLIP_DESC;
 
 
 	template<class T>
 	template<class T>
 	class CoreThreadAccessor;
 	class CoreThreadAccessor;
@@ -485,6 +491,8 @@ namespace BansheeEngine
 		TID_CCharacterController = 1108,
 		TID_CCharacterController = 1108,
 		TID_FPhysicsMesh = 1109,
 		TID_FPhysicsMesh = 1109,
 		TID_ShaderImportOptions = 1110,
 		TID_ShaderImportOptions = 1110,
+		TID_AudioClip = 1111,
+		TID_AudioClipImportOptions = 1112
 	};
 	};
 }
 }
 
 
@@ -511,11 +519,11 @@ namespace BansheeEngine
 	typedef ResourceHandle<StringTable> HStringTable;
 	typedef ResourceHandle<StringTable> HStringTable;
 	typedef ResourceHandle<PhysicsMaterial> HPhysicsMaterial;
 	typedef ResourceHandle<PhysicsMaterial> HPhysicsMaterial;
 	typedef ResourceHandle<PhysicsMesh> HPhysicsMesh;
 	typedef ResourceHandle<PhysicsMesh> HPhysicsMesh;
+	typedef ResourceHandle<AudioClip> HAudioClip;
 
 
 	/** @} */
 	/** @} */
 }
 }
 
 
-
 #include "BsGameObjectHandle.h"
 #include "BsGameObjectHandle.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine

+ 11 - 0
Source/BansheeCore/Source/BsAudio.cpp

@@ -0,0 +1,11 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsAudio.h"
+
+namespace BansheeEngine
+{
+	Audio& gAudio()
+	{
+		return Audio::instance();
+	}
+}

+ 45 - 0
Source/BansheeCore/Source/BsAudioClip.cpp

@@ -0,0 +1,45 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsAudioClip.h"
+#include "BsResources.h"
+#include "BsAudio.h"
+#include "BsAudioClipRTTI.h"
+
+namespace BansheeEngine
+{
+	AudioClip::AudioClip(const SPtr<DataStream>& samples, UINT32 numSamples, const AUDIO_CLIP_DESC& desc)
+		:Resource(false), mDesc(desc), mNumSamples(numSamples), mStreamData(samples)
+	{
+		if (mDesc.readMode != AudioReadMode::Stream)
+			mStreamData = nullptr;
+	}
+
+	HAudioClip AudioClip::create(UINT32 numSamples, const AUDIO_CLIP_DESC& desc)
+	{
+		return static_resource_cast<AudioClip>(gResources()._createResourceHandle(_createPtr(nullptr, numSamples, desc)));
+	}
+
+	HAudioClip AudioClip::create(const SPtr<DataStream>& samples, UINT32 numSamples, const AUDIO_CLIP_DESC& desc)
+	{
+		return static_resource_cast<AudioClip>(gResources()._createResourceHandle(_createPtr(samples, numSamples, desc)));
+	}
+
+	SPtr<AudioClip> AudioClip::_createPtr(const SPtr<DataStream>& samples, UINT32 numSamples, const AUDIO_CLIP_DESC& desc)
+	{
+		SPtr<AudioClip> newClip = gAudio().createClip(samples, numSamples, desc);
+		newClip->_setThisPtr(newClip);
+		newClip->initialize();
+
+		return newClip;
+	}
+
+	RTTITypeBase* AudioClip::getRTTIStatic()
+	{
+		return AudioClipRTTI::instance();
+	}
+
+	RTTITypeBase* AudioClip::getRTTI() const
+	{
+		return getRTTIStatic();
+	}
+}

+ 20 - 0
Source/BansheeCore/Source/BsAudioClipImportOptions.cpp

@@ -0,0 +1,20 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsAudioClipImportOptions.h"
+#include "BsAudioClipImportOptionsRTTI.h"
+
+namespace BansheeEngine
+{
+	/************************************************************************/
+	/* 								SERIALIZATION                      		*/
+	/************************************************************************/
+	RTTITypeBase* AudioClipImportOptions::getRTTIStatic()
+	{
+		return AudioClipImportOptionsRTTI::instance();
+	}
+
+	RTTITypeBase* AudioClipImportOptions::getRTTI() const
+	{
+		return getRTTIStatic();
+	}
+}