From 36143f98b782fea7b877affcf48e845f9cd10315 Mon Sep 17 00:00:00 2001
From: hyperiris <hyperiris@gmail.com>
Date: Sat, 4 Apr 2009 03:58:16 +0000
Subject: [PATCH] OpenAL: YES! The first version of working OpenAL Backend!
 I've only test in Ikaruga and Metroid Prime, at least they have sound.
 Performance is ugly, :<, still need more work on it. To enable oal in
 Dolphin, uncomment Source/Core/Common/Src/Common.h: //#define HAVE_OPENAL 1

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2865 8ced0084-cf51-0410-be5f-012b33b47a6e
---
 Source/Core/AudioCommon/Src/OpenALStream.cpp | 57 ++++++++++++++++++--
 Source/Core/AudioCommon/Src/OpenALStream.h   |  3 ++
 2 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/Source/Core/AudioCommon/Src/OpenALStream.cpp b/Source/Core/AudioCommon/Src/OpenALStream.cpp
index 39cf4d25ea..b0499f4ae0 100644
--- a/Source/Core/AudioCommon/Src/OpenALStream.cpp
+++ b/Source/Core/AudioCommon/Src/OpenALStream.cpp
@@ -21,6 +21,7 @@
 #if defined HAVE_OPENAL && HAVE_OPENAL
 
 #define AUDIO_NUMBUFFERS			(4)
+//#define	AUDIO_SERVICE_UPDATE_PERIOD	(20)
 
 bool OpenALStream::Start()
 {
@@ -96,16 +97,62 @@ THREAD_RETURN OpenALStream::ThreadFunc(void* args)
 
 void OpenALStream::SoundLoop()
 {
-	while (!threadData) {
-		soundCriticalSection.Enter();
+	ALuint		    uiBuffers[AUDIO_NUMBUFFERS] = {0};
+	ALuint		    uiSource = 0;
+	ALenum err;
+	u32 ulFrequency = m_mixer->GetSampleRate();
+	// Generate some AL Buffers for streaming
+	alGenBuffers(AUDIO_NUMBUFFERS, (ALuint *)uiBuffers);
+	// Generate a Source to playback the Buffers
+	alGenSources(1, &uiSource);
 
-		// Add sound playing here
-		// m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
-		soundCriticalSection.Leave();
+	memset(realtimeBuffer, 0, OAL_BUFFER_SIZE * sizeof(short));
+//*
+	for (int iLoop = 0; iLoop < AUDIO_NUMBUFFERS; iLoop++)
+	{
+		// pay load fake data
+		alBufferData(uiBuffers[iLoop], AL_FORMAT_STEREO16, realtimeBuffer, 1024, ulFrequency);
+		alSourceQueueBuffers(uiSource, 1, &uiBuffers[iLoop]);
+	}
+//*/
+	alSourcePlay(uiSource);
+	err = alGetError();
 
+	while (!threadData) 
+	{
+		ALint iBuffersProcessed = 0;
+		alGetSourcei(uiSource, AL_BUFFERS_PROCESSED, &iBuffersProcessed);
+
+		if (iBuffersProcessed)
+		{
+			// Remove the Buffer from the Queue.  (uiBuffer contains the Buffer ID for the unqueued Buffer)
+			ALuint uiTempBuffer = 0;
+			alSourceUnqueueBuffers(uiSource, 1, &uiTempBuffer);
+
+			soundCriticalSection.Enter();
+			int numBytesToRender = 32768;	//ya, this is a hack, we need real data count
+			 m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
+			soundCriticalSection.Leave();
+
+			unsigned long	ulBytesWritten = 0;
+			//if (ulBytesWritten)
+			{
+				//alBufferData(uiTempBuffer, ulFormat, pDecodeBuffer, ulBytesWritten, ulFrequency);
+				alBufferData(uiTempBuffer, AL_FORMAT_STEREO16, realtimeBuffer, numBytesToRender, ulFrequency);
+				alSourceQueueBuffers(uiSource, 1, &uiTempBuffer);
+			}
+		}
 		if (!threadData)
 			soundSyncEvent.Wait();
 	}
+	alSourceStop(uiSource);
+	alSourcei(uiSource, AL_BUFFER, 0);
+
+	// Clean up buffers and sources
+	alDeleteSources(1, &uiSource);
+	alDeleteBuffers(AUDIO_NUMBUFFERS, (const ALuint *)uiBuffers);
+
 }
 
 #endif //HAVE_OPENAL
+
diff --git a/Source/Core/AudioCommon/Src/OpenALStream.h b/Source/Core/AudioCommon/Src/OpenALStream.h
index f773ec53b9..f5e6659124 100644
--- a/Source/Core/AudioCommon/Src/OpenALStream.h
+++ b/Source/Core/AudioCommon/Src/OpenALStream.h
@@ -33,6 +33,7 @@
 #endif // WIN32
 // public use
 #define SFX_MAX_SOURCE	1
+#define OAL_BUFFER_SIZE 1024*1024
 #endif
 
 
@@ -56,6 +57,8 @@ private:
 	Common::Thread *thread;
 	Common::CriticalSection soundCriticalSection;
 	Common::Event soundSyncEvent;
+	
+	short realtimeBuffer[OAL_BUFFER_SIZE];
 #else
 public:
 	OpenALStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {}