Explorar el Código

Fixed XAudio2 audio interface for UWP, moved lock and unlock into the CoreMutex class for convenience

Ivan Safrin hace 10 años
padre
commit
1601b2870c

+ 2 - 1
build/windows/universal/TemplateApp/PolycodeTemplateApp.cpp

@@ -27,7 +27,8 @@ PolycodeTemplateApp::PolycodeTemplateApp(PolycodeView *view) {
     scene->addChild(test);
     scene->addChild(test);
 
 
 	Sound *bgSound = new Sound("bedlayer_main.wav");
 	Sound *bgSound = new Sound("bedlayer_main.wav");
-	bgSound->Play();
+
+	bgSound->Play(true);
 }
 }
 
 
 PolycodeTemplateApp::~PolycodeTemplateApp() {
 PolycodeTemplateApp::~PolycodeTemplateApp() {

+ 4 - 0
build/windows/universal/TemplateApp/PolycodeTemplateApp.h

@@ -14,5 +14,9 @@ public:
     bool Update();
     bool Update();
     
     
 private:
 private:
+
+	Sound *sound1;
+	Sound *sound2;
+
     Core *core;
     Core *core;
 };
 };

+ 1 - 1
build/windows/universal/TemplateApp/TemplateApp.vcxproj

@@ -199,7 +199,7 @@
   </ItemDefinitionGroup>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <Link>
     <Link>
-      <AdditionalDependencies>freetype.lib;Polycore.lib;mincore.lib;d3d11.lib;dxgi.lib;windowscodecs.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>freetype.lib;Polycore.lib;mincore.lib;libGLESv2.lib;libEGL.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64</AdditionalLibraryDirectories>
     </Link>
     </Link>
     <ClCompile>
     <ClCompile>

+ 8 - 4
include/polycode/core/PolyCore.h

@@ -39,6 +39,10 @@ namespace Polycode {
           
           
 	class _PolyExport CoreMutex : public PolyBase {
 	class _PolyExport CoreMutex : public PolyBase {
 	public:
 	public:
+
+		virtual void lock() = 0;
+		virtual void unlock() = 0;
+
 		int mutexID;
 		int mutexID;
 	};
 	};
 	
 	
@@ -149,16 +153,16 @@ namespace Polycode {
 		virtual void createThread(Threaded *target);
 		virtual void createThread(Threaded *target);
 
 
 		/**
 		/**
-		* Locks a mutex.
+		* Locks a mutex. Legacy method. Use the "lock" method of CoreMutex!
 		* @param mutex Mutex to lock.
 		* @param mutex Mutex to lock.
 		*/
 		*/
-		virtual void lockMutex(CoreMutex *mutex) = 0;
+		void lockMutex(CoreMutex *mutex);
 		
 		
 		/**
 		/**
-		* Unlocks a mutex.
+		* Unlocks a mutex.  Legacy method. Use the "unlock" method of CoreMutex!
 		* @param mutex Mutex to lock.
 		* @param mutex Mutex to lock.
 		*/		
 		*/		
-		virtual void unlockMutex(CoreMutex *mutex) = 0;
+		void unlockMutex(CoreMutex *mutex);
 		
 		
 		/**
 		/**
 		* Creates a mutex
 		* Creates a mutex

+ 1 - 1
include/polycode/core/PolySoundManager.h

@@ -25,7 +25,7 @@
 #include "polycode/core/PolyVector3.h"
 #include "polycode/core/PolyVector3.h"
 #include "polycode/core/PolySound.h"
 #include "polycode/core/PolySound.h"
 
 
-#define POLY_FRAMES_PER_BUFFER 512
+#define POLY_FRAMES_PER_BUFFER 2048
 #define POLY_AUDIO_FREQ 44100
 #define POLY_AUDIO_FREQ 44100
 #define POLY_CIRCULAR_BUFFER_SIZE 32
 #define POLY_CIRCULAR_BUFFER_SIZE 32
 #define POLY_NUM_CHANNELS 2
 #define POLY_NUM_CHANNELS 2

+ 2 - 2
include/polycode/core/PolyUWPCore.h

@@ -59,6 +59,8 @@ namespace Polycode {
 
 
 	class UWPCoreMutex : public CoreMutex {
 	class UWPCoreMutex : public CoreMutex {
 	public:
 	public:
+		void lock();
+		void unlock();
 		std::mutex mutex;
 		std::mutex mutex;
 	};
 	};
 
 
@@ -74,8 +76,6 @@ namespace Polycode {
 		bool systemUpdate();
 		bool systemUpdate();
 		void setCursor(int cursorType);
 		void setCursor(int cursorType);
 		void createThread(Threaded *target);
 		void createThread(Threaded *target);
-		void lockMutex(CoreMutex *mutex);
-		void unlockMutex(CoreMutex *mutex);
 		CoreMutex *createMutex();
 		CoreMutex *createMutex();
 		void copyStringToClipboard(const String& str);
 		void copyStringToClipboard(const String& str);
 		String getClipboardString();
 		String getClipboardString();

+ 24 - 3
include/polycode/core/PolyXAudio2AudioInterface.h

@@ -29,14 +29,32 @@ THE SOFTWARE.
 #include "polycode/core/PolyThreaded.h"
 #include "polycode/core/PolyThreaded.h"
 #include "polycode/core/PolySoundManager.h"
 #include "polycode/core/PolySoundManager.h"
 
 
-#define MAX_XAUDIO_BUFFER_COUNT 3
+#include <queue>
+
+#define MAX_XAUDIO_BUFFER_COUNT 4
 
 
 #ifndef SAFE_RELEASE
 #ifndef SAFE_RELEASE
 #define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=nullptr; } }
 #define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=nullptr; } }
 #endif
 #endif
 
 
+
 namespace Polycode {
 namespace Polycode {
 
 
+	class XAudioInterfaceBuffer {
+		public:
+			int16_t bufferData[POLY_FRAMES_PER_BUFFER * POLY_NUM_CHANNELS];
+	};
+
+	class XAudio2FillThread : public Threaded {
+		public:
+
+			void runThread();
+
+			AudioMixer *mixer;
+			std::queue<XAudioInterfaceBuffer*> bufferQueue;
+			CoreMutex *bufferMutex;
+	};
+
 	class XAudio2Stream : public Threaded, IXAudio2VoiceCallback {
 	class XAudio2Stream : public Threaded, IXAudio2VoiceCallback {
 		public:
 		public:
 
 
@@ -71,13 +89,16 @@ namespace Polycode {
 
 
 				
 				
 		private:
 		private:
-
-				int16_t buffer[POLY_FRAMES_PER_BUFFER];
+				
+				XAudioInterfaceBuffer *lastBuffer;
+				XAudioInterfaceBuffer *lastBuffer2;
 
 
 				AudioMixer *mixer;
 				AudioMixer *mixer;
 
 
 				HANDLE hBufferEndEvent;
 				HANDLE hBufferEndEvent;
 
 
+				XAudio2FillThread *fillThread;
+
 				IXAudio2* pXAudio2;
 				IXAudio2* pXAudio2;
 				IXAudio2MasteringVoice* pMasterVoice;
 				IXAudio2MasteringVoice* pMasterVoice;
 				IXAudio2SourceVoice* pSourceVoice;
 				IXAudio2SourceVoice* pSourceVoice;

BIN
lib/windows/x64/Polycore.lib


BIN
lib/windows/x64/Polycored.lib


+ 9 - 1
src/core/PolyCore.cpp

@@ -384,6 +384,14 @@ namespace Polycode {
         systemParseFolder(pathString, showHidden, retVec);        
         systemParseFolder(pathString, showHidden, retVec);        
         return retVec;
         return retVec;
     }
     }
-    
+
+	void Core::lockMutex(CoreMutex *mutex) {
+		mutex->lock();
+	}
+
+
+	void Core::unlockMutex(CoreMutex *mutex) {
+		mutex->unlock();
+	}
 	
 	
 }
 }

+ 10 - 6
src/core/PolySoundManager.cpp

@@ -114,6 +114,7 @@ void SoundManager::unregisterSound(Sound *sound) {
     for(int i=0; i < mixer->sounds.size(); i++) {
     for(int i=0; i < mixer->sounds.size(); i++) {
         if(mixer->sounds[i] == sound) {
         if(mixer->sounds[i] == sound) {
             mixer->sounds.erase(mixer->sounds.begin()+i);
             mixer->sounds.erase(mixer->sounds.begin()+i);
+			Services()->getCore()->unlockMutex(mixer->mixerMutex);
             return;
             return;
         }
         }
     }
     }
@@ -122,6 +123,9 @@ void SoundManager::unregisterSound(Sound *sound) {
 
 
 void SoundManager::setAudioInterface(AudioInterface *audioInterface) {
 void SoundManager::setAudioInterface(AudioInterface *audioInterface) {
     this->audioInterface = audioInterface;
     this->audioInterface = audioInterface;
+	if (!mixer->mixerMutex) {
+		mixer->mixerMutex = Services()->getCore()->createMutex();
+	}
     audioInterface->setMixer(mixer);
     audioInterface->setMixer(mixer);
 }
 }
 
 
@@ -157,12 +161,12 @@ AudioMixer::~AudioMixer() {
 }
 }
 
 
 void AudioMixer::mixIntoBuffer(int16_t *buffer, unsigned int numSamples) {
 void AudioMixer::mixIntoBuffer(int16_t *buffer, unsigned int numSamples) {
-    
-	if (!mixerMutex) {
-		mixerMutex = Services()->getCore()->createMutex();
-	}
+	mixerMutex->lock();
 
 
-	Services()->getCore()->lockMutex(mixerMutex);
+	if (sounds.size() == 0) {
+		mixerMutex->unlock();
+		return;
+	}
 
 
     for(int i=0; i < sounds.size(); i++) {
     for(int i=0; i < sounds.size(); i++) {
         sounds[i]->updateStream(numSamples);
         sounds[i]->updateStream(numSamples);
@@ -198,7 +202,7 @@ void AudioMixer::mixIntoBuffer(int16_t *buffer, unsigned int numSamples) {
             bufferPtr++;
             bufferPtr++;
         }
         }
     }
     }
-	Services()->getCore()->unlockMutex(mixerMutex);
+	 mixerMutex->unlock();
 }
 }
 
 
 void SoundManager::Update() {
 void SoundManager::Update() {

+ 10 - 9
src/core/PolyUWPCore.cpp

@@ -34,6 +34,15 @@ using namespace ABI::Windows::Storage;
 using namespace Microsoft::WRL;
 using namespace Microsoft::WRL;
 using namespace Microsoft::WRL::Wrappers;
 using namespace Microsoft::WRL::Wrappers;
 
 
+void UWPCoreMutex::lock() {
+	mutex.lock();
+}
+
+void UWPCoreMutex::unlock() {
+	mutex.unlock();
+}
+
+
 UWPCore::UWPCore(PolycodeView *view, int xRes, int yRes, bool fullScreen, bool vSync, int aaLevel, int anisotropyLevel, int frameRate, int monitorIndex, bool retinaSupport) 
 UWPCore::UWPCore(PolycodeView *view, int xRes, int yRes, bool fullScreen, bool vSync, int aaLevel, int anisotropyLevel, int frameRate, int monitorIndex, bool retinaSupport) 
 	: Core(xRes, yRes, fullScreen, vSync, aaLevel, anisotropyLevel, frameRate, monitorIndex) {
 	: Core(xRes, yRes, fullScreen, vSync, aaLevel, anisotropyLevel, frameRate, monitorIndex) {
 
 
@@ -94,15 +103,7 @@ void launchThread(Threaded *target) {
 void UWPCore::createThread(Threaded * target) {
 void UWPCore::createThread(Threaded * target) {
 	Core::createThread(target);
 	Core::createThread(target);
 	std::thread *thread = new std::thread(launchThread, target);
 	std::thread *thread = new std::thread(launchThread, target);
-
-}
-
-void UWPCore::lockMutex(CoreMutex *mutex) {
-	((UWPCoreMutex*)mutex)->mutex.lock();
-}
-
-void UWPCore::unlockMutex(CoreMutex *mutex) {
-	((UWPCoreMutex*)mutex)->mutex.unlock();
+	 
 }
 }
 
 
 CoreMutex *UWPCore::createMutex() {
 CoreMutex *UWPCore::createMutex() {

+ 44 - 15
src/core/PolyXAudio2AudioInterface.cpp

@@ -73,6 +73,18 @@ HRESULT XAudio2Stream::initXAudio2() {
 	
 	
 }
 }
 
 
+void XAudio2FillThread::runThread() {
+	while (threadRunning) {
+		bufferMutex->lock();
+		if (bufferQueue.size() < MAX_XAUDIO_BUFFER_COUNT) {
+			XAudioInterfaceBuffer *buffer = new XAudioInterfaceBuffer();
+			mixer->mixIntoBuffer(&buffer->bufferData[0], POLY_FRAMES_PER_BUFFER);
+			bufferQueue.push(buffer);
+		}
+		bufferMutex->unlock();
+	}
+}
+
 void XAudio2Stream::runThread() {
 void XAudio2Stream::runThread() {
 
 
 	CoInitializeEx(nullptr, COINIT_MULTITHREADED);
 	CoInitializeEx(nullptr, COINIT_MULTITHREADED);
@@ -83,34 +95,51 @@ void XAudio2Stream::runThread() {
 		Logger::log("ERROR INITIALIZING XAUDIO2!\n");
 		Logger::log("ERROR INITIALIZING XAUDIO2!\n");
 	}
 	}
 
 
+	fillThread = new XAudio2FillThread();
+	fillThread->mixer = mixer;
+	fillThread->bufferMutex = Services()->getCore()->createMutex();
+
+	Services()->getCore()->createThread(fillThread);
+
+	lastBuffer = NULL; 
+
 	while (threadRunning) {
 	while (threadRunning) {
 
 
 		XAUDIO2_VOICE_STATE state;
 		XAUDIO2_VOICE_STATE state;
 		for (;; )
 		for (;; )
 		{
 		{
+
 			pSourceVoice->GetState(&state);
 			pSourceVoice->GetState(&state);
-			if (state.BuffersQueued == 0) {
+			if (state.BuffersQueued < MAX_XAUDIO_BUFFER_COUNT-1) {
 				break;
 				break;
 			}
 			}
+
 			WaitForSingleObject(hBufferEndEvent, INFINITE);
 			WaitForSingleObject(hBufferEndEvent, INFINITE);
 		}
 		}
 
 
-		XAUDIO2_BUFFER buf = { 0 };
-
-		buf.AudioBytes = POLY_FRAMES_PER_BUFFER*POLY_NUM_CHANNELS*2;
-
-		//memset(buffer,0, POLY_FRAMES_PER_BUFFER * sizeof(int16_t));
-		if (mixer) {
-			Services()->getCore()->lockMutex(mixer->mixerMutex);
-			mixer->mixIntoBuffer(buffer, POLY_FRAMES_PER_BUFFER);
-			Services()->getCore()->unlockMutex(mixer->mixerMutex);
+		if (lastBuffer) {
+		//	delete lastBuffer;
+			lastBuffer = NULL;
 		}
 		}
-
-		buf.pAudioData = (BYTE*) buffer;
-		pSourceVoice->SubmitSourceBuffer(&buf);
-
+		
+		fillThread->bufferMutex->lock();
+		if(fillThread->bufferQueue.size() > 1) {
+			XAUDIO2_BUFFER buf = { 0 };
+			buf.AudioBytes = POLY_FRAMES_PER_BUFFER*POLY_NUM_CHANNELS * 2;
+			lastBuffer = fillThread->bufferQueue.front();
+			buf.Flags = XAUDIO2_END_OF_STREAM;
+			buf.pAudioData = (BYTE*)&lastBuffer->bufferData[0];
+			buf.LoopCount = 0;
+			buf.LoopBegin = 0;
+			pSourceVoice->SubmitSourceBuffer(&buf);		
+			delete lastBuffer;
+			fillThread->bufferQueue.pop();
+		}
+		fillThread->bufferMutex->unlock();
 	}
 	}
 
 
+	fillThread->killThread();
+
 	pMasterVoice->DestroyVoice();
 	pMasterVoice->DestroyVoice();
 	SAFE_RELEASE(pXAudio2);
 	SAFE_RELEASE(pXAudio2);
 
 
@@ -126,11 +155,11 @@ void XAudio2Stream::setMixer(AudioMixer *mixer) {
 void XAudio2AudioInterface::setMixer(AudioMixer *mixer) {
 void XAudio2AudioInterface::setMixer(AudioMixer *mixer) {
 	xAudioStream->setMixer(mixer);
 	xAudioStream->setMixer(mixer);
 	AudioInterface::setMixer(mixer);
 	AudioInterface::setMixer(mixer);
+	Services()->getCore()->createThread(xAudioStream);
 }
 }
 
 
 XAudio2AudioInterface::XAudio2AudioInterface() {
 XAudio2AudioInterface::XAudio2AudioInterface() {
 	xAudioStream = new XAudio2Stream();
 	xAudioStream = new XAudio2Stream();
-	Services()->getCore()->createThread(xAudioStream);
 }
 }
 
 
 XAudio2AudioInterface::~XAudio2AudioInterface() {
 XAudio2AudioInterface::~XAudio2AudioInterface() {