diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index 4f015915..72d1fe30 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -9361,7 +9361,7 @@ cAudioManager::ResetTimers(uint32 time)
 		SampleManager.SetEffectsFadeVolume(0);
 		SampleManager.SetMusicFadeVolume(0);
 		MusicManager.ResetMusicAfterReload();
-#ifdef OPENAL
+#ifdef AUDIO_OAL
 		SampleManager.Service();
 #endif
 	}
@@ -9419,7 +9419,7 @@ cAudioManager::ServiceSoundEffects()
 	ProcessMissionAudio();
 	AdjustSamplesVolume();
 	ProcessActiveQueues();
-#ifdef OPENAL
+#ifdef AUDIO_OAL
 	SampleManager.Service();
 #endif
 	for(int32 i = 0; i < m_sAudioScriptObjectManager.m_nScriptObjectEntityTotal; ++i) {
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 9479d1cd..8fc13ed8 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -600,6 +600,8 @@ public:
 	uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
 };
 
-//dstatic_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
+#ifdef AUDIO_MSS
+static_assert(sizeof(cAudioManager) == 19220, "cAudioManager: error");
+#endif
 
 extern cAudioManager AudioManager;
diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp
index 11c85dbd..8681f345 100644
--- a/src/audio/DMAudio.cpp
+++ b/src/audio/DMAudio.cpp
@@ -5,6 +5,7 @@
 #include "AudioManager.h"
 #include "AudioScriptObject.h"
 #include "sampman.h"
+#include "Text.h"
 
 cDMAudio DMAudio;
 
@@ -104,6 +105,28 @@ cDMAudio::Get3DProviderName(uint8 id)
 	return AudioManager.Get3DProviderName(id);
 }
 
+int8 cDMAudio::AutoDetect3DProviders(void)
+{
+	for ( int32 i = 0; i < GetNum3DProvidersAvailable(); i++ )
+	{
+		wchar buff[64];
+		
+		char *name = Get3DProviderName(i);
+		AsciiToUnicode(name, buff);
+		char *providername = UnicodeToAscii(buff);
+		strupr(providername);
+#if defined(AUDIO_MSS)
+		if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") )
+			return i;
+#elif defined(AUDIO_OAL)
+		if ( !strcmp(providername, "OPEANAL SOFT") )
+			return i;
+#endif
+	}
+
+	return -1;
+}
+
 int8
 cDMAudio::GetCurrent3DProviderIndex(void)
 {
diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h
index 42688fa6..6a94d57f 100644
--- a/src/audio/DMAudio.h
+++ b/src/audio/DMAudio.h
@@ -205,6 +205,8 @@ public:
 	uint8 GetNum3DProvidersAvailable(void);
 	char *Get3DProviderName(uint8 id);
 	
+	int8 AutoDetect3DProviders(void);
+	
 	int8 GetCurrent3DProviderIndex(void);
 	int8 SetCurrent3DProvider(uint8 which);
 	
diff --git a/src/audio/miles/sampman_mss.h b/src/audio/miles/sampman_mss.h
deleted file mode 100644
index ebedfb63..00000000
--- a/src/audio/miles/sampman_mss.h
+++ /dev/null
@@ -1,339 +0,0 @@
-#pragma once
-#include "common.h"
-#include "AudioSamples.h"
-
-#define MAX_VOLUME 127
-
-struct tSample {
-	int32 nOffset;
-	uint32 nSize;
-	int32 nFrequency;
-	int32 nLoopStart;
-	int32 nLoopEnd;
-};
-
-enum
-{
-	SAMPLEBANK_MAIN,
-	SAMPLEBANK_PED,
-	MAX_SAMPLEBANKS,
-	SAMPLEBANK_INVALID
-};
-
-#define MAX_PEDSFX                 7
-#define PED_BLOCKSIZE              79000
-
-#define MAXPROVIDERS               64
-
-#define MAXCHANNELS                28
-#define MAXCHANNELS_SURROUND       24
-#define MAX2DCHANNELS              1
-#define CHANNEL2D                  MAXCHANNELS
-
-#define MAX_MP3STREAMS             2
-
-#define DIGITALRATE                32000
-#define DIGITALBITS                16
-#define DIGITALCHANNELS            2
-
-#define MAX_DIGITAL_MIXER_CHANNELS 32
-
-class cSampleManager
-{
-	uint8   m_nEffectsVolume;
-	uint8   m_nMusicVolume;
-	uint8   m_nEffectsFadeVolume;
-	uint8   m_nMusicFadeVolume;
-	uint8   m_nMonoMode;
-	char	unk;
-	char    m_szCDRomRootPath[80];
-	bool    m_bInitialised;
-	uint8   m_nNumberOfProviders;
-	char   *m_aAudioProviders[MAXPROVIDERS];
-	tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
-
-public:
-	
-	
-
-	cSampleManager(void) :
-		m_nNumberOfProviders(0)
-	{ }
-
-	~cSampleManager(void)
-	{ }
-	
-	void SetSpeakerConfig(int32 nConfig);
-	uint32 GetMaximumSupportedChannels(void);
-	
-	uint32 GetNum3DProvidersAvailable()          { return m_nNumberOfProviders; }
-	void SetNum3DProvidersAvailable(uint32 num)  { m_nNumberOfProviders = num; }
-	
-	char *Get3DProviderName(uint8 id)            { return m_aAudioProviders[id]; }
-	void Set3DProviderName(uint8 id, char *name) { m_aAudioProviders[id] = name; }
-	
-	int8 GetCurrent3DProviderIndex(void);
-	int8 SetCurrent3DProvider(uint8 which);
-	
-	bool IsMP3RadioChannelAvailable(void);
-	
-	void ReleaseDigitalHandle  (void);
-	void ReacquireDigitalHandle(void);
-	
-	bool Initialise(void);
-	void Terminate (void);
-	
-	bool CheckForAnAudioFileOnCD(void);
-	char GetCDAudioDriveLetter  (void);
-	
-	void UpdateEffectsVolume(void);
-
-	void SetEffectsMasterVolume(uint8 nVolume);
-	void SetMusicMasterVolume  (uint8 nVolume);
-	void SetEffectsFadeVolume  (uint8 nVolume);
-	void SetMusicFadeVolume    (uint8 nVolume);
-	
-	bool LoadSampleBank    (uint8 nBank);
-	void UnloadSampleBank  (uint8 nBank);
-	bool IsSampleBankLoaded(uint8 nBank);
-	
-	bool IsPedCommentLoaded(uint32 nComment);
-	bool LoadPedComment    (uint32 nComment);
-
-	int32 _GetPedCommentSlot(uint32 nComment);
-	
-	int32  GetSampleBaseFrequency  (uint32 nSample);
-	int32  GetSampleLoopStartOffset(uint32 nSample);
-	int32  GetSampleLoopEndOffset  (uint32 nSample);
-	uint32 GetSampleLength         (uint32 nSample);
-	
-	bool  UpdateReverb(void);
-	
-	void  SetChannelReverbFlag    (uint32 nChannel, uint8 nReverbFlag);
-	bool  InitialiseChannel       (uint32 nChannel, uint32 nSfx, uint8 nBank);
-	void  SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
-	void  SetChannel3DPosition    (uint32 nChannel, float fX, float fY, float fZ);
-	void  SetChannel3DDistances   (uint32 nChannel, float fMax, float fMin);
-	void  SetChannelVolume        (uint32 nChannel, uint32 nVolume);
-	void  SetChannelPan           (uint32 nChannel, uint32 nPan);
-	void  SetChannelFrequency     (uint32 nChannel, uint32 nFreq);
-	void  SetChannelLoopPoints    (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
-	void  SetChannelLoopCount     (uint32 nChannel, uint32 nLoopCount);
-	bool  GetChannelUsedFlag      (uint32 nChannel);
-	void  StartChannel            (uint32 nChannel);
-	void  StopChannel             (uint32 nChannel);
-	
-	void  PreloadStreamedFile                                     (uint8 nFile, uint8 nStream);
-	void  PauseStream                                        (uint8 nPauseFlag, uint8 nStream);
-	void  StartPreloadedStreamedFile                                           (uint8 nStream);
-	bool  StartStreamedFile                          (uint8 nFile, uint32 nPos, uint8 nStream);
-	void  StopStreamedFile                                                     (uint8 nStream);
-	int32 GetStreamedFilePosition                                              (uint8 nStream);
-	void  SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
-	int32 GetStreamedFileLength                                                (uint8 nStream);
-	bool  IsStreamPlaying                                                      (uint8 nStream);
-	bool  InitialiseSampleBanks(void);
-};
-
-extern cSampleManager SampleManager;
-extern int32 BankStartOffset[MAX_SAMPLEBANKS];
-
-static char StreamedNameTable[][25]=
-{
-	"AUDIO\\HEAD.WAV",
-	"AUDIO\\CLASS.WAV",
-	"AUDIO\\KJAH.WAV",
-	"AUDIO\\RISE.WAV",
-	"AUDIO\\LIPS.WAV",
-	"AUDIO\\GAME.WAV",
-	"AUDIO\\MSX.WAV",
-	"AUDIO\\FLASH.WAV",
-	"AUDIO\\CHAT.WAV",
-	"AUDIO\\HEAD.WAV",
-	"AUDIO\\POLICE.WAV",
-	"AUDIO\\CITY.WAV",
-	"AUDIO\\WATER.WAV",
-	"AUDIO\\COMOPEN.WAV",
-	"AUDIO\\SUBOPEN.WAV",
-	"AUDIO\\JB.MP3",
-	"AUDIO\\BET.MP3",
-	"AUDIO\\L1_LG.MP3",
-	"AUDIO\\L2_DSB.MP3",
-	"AUDIO\\L3_DM.MP3",
-	"AUDIO\\L4_PAP.MP3",
-	"AUDIO\\L5_TFB.MP3",
-	"AUDIO\\J0_DM2.MP3",
-	"AUDIO\\J1_LFL.MP3",
-	"AUDIO\\J2_KCL.MP3",
-	"AUDIO\\J3_VH.MP3",
-	"AUDIO\\J4_ETH.MP3",
-	"AUDIO\\J5_DST.MP3",
-	"AUDIO\\J6_TBJ.MP3",
-	"AUDIO\\T1_TOL.MP3",
-	"AUDIO\\T2_TPU.MP3",
-	"AUDIO\\T3_MAS.MP3",
-	"AUDIO\\T4_TAT.MP3",
-	"AUDIO\\T5_BF.MP3",
-	"AUDIO\\S0_MAS.MP3",
-	"AUDIO\\S1_PF.MP3",
-	"AUDIO\\S2_CTG.MP3",
-	"AUDIO\\S3_RTC.MP3",
-	"AUDIO\\S5_LRQ.MP3",
-	"AUDIO\\S4_BDBA.MP3",
-	"AUDIO\\S4_BDBB.MP3",
-	"AUDIO\\S2_CTG2.MP3",
-	"AUDIO\\S4_BDBD.MP3",
-	"AUDIO\\S5_LRQB.MP3",
-	"AUDIO\\S5_LRQC.MP3",
-	"AUDIO\\A1_SSO.WAV",
-	"AUDIO\\A2_PP.WAV",
-	"AUDIO\\A3_SS.WAV",
-	"AUDIO\\A4_PDR.WAV",
-	"AUDIO\\A5_K2FT.WAV",
-	"AUDIO\\K1_KBO.MP3",
-	"AUDIO\\K2_GIS.MP3",
-	"AUDIO\\K3_DS.MP3",
-	"AUDIO\\K4_SHI.MP3",
-	"AUDIO\\K5_SD.MP3",
-	"AUDIO\\R0_PDR2.MP3",
-	"AUDIO\\R1_SW.MP3",
-	"AUDIO\\R2_AP.MP3",
-	"AUDIO\\R3_ED.MP3",
-	"AUDIO\\R4_GF.MP3",
-	"AUDIO\\R5_PB.MP3",
-	"AUDIO\\R6_MM.MP3",
-	"AUDIO\\D1_STOG.MP3",
-	"AUDIO\\D2_KK.MP3",
-	"AUDIO\\D3_ADO.MP3",
-	"AUDIO\\D5_ES.MP3",
-	"AUDIO\\D7_MLD.MP3",
-	"AUDIO\\D4_GTA.MP3",
-	"AUDIO\\D4_GTA2.MP3",
-	"AUDIO\\D6_STS.MP3",
-	"AUDIO\\A6_BAIT.WAV",
-	"AUDIO\\A7_ETG.WAV",
-	"AUDIO\\A8_PS.WAV",
-	"AUDIO\\A9_ASD.WAV",
-	"AUDIO\\K4_SHI2.MP3",
-	"AUDIO\\C1_TEX.MP3",
-	"AUDIO\\EL_PH1.MP3",
-	"AUDIO\\EL_PH2.MP3",
-	"AUDIO\\EL_PH3.MP3",
-	"AUDIO\\EL_PH4.MP3",
-	"AUDIO\\YD_PH1.MP3",
-	"AUDIO\\YD_PH2.MP3",
-	"AUDIO\\YD_PH3.MP3",
-	"AUDIO\\YD_PH4.MP3",
-	"AUDIO\\HD_PH1.MP3",
-	"AUDIO\\HD_PH2.MP3",
-	"AUDIO\\HD_PH3.MP3",
-	"AUDIO\\HD_PH4.MP3",
-	"AUDIO\\HD_PH5.MP3",
-	"AUDIO\\MT_PH1.MP3",
-	"AUDIO\\MT_PH2.MP3",
-	"AUDIO\\MT_PH3.MP3",
-	"AUDIO\\MT_PH4.MP3",
-	"AUDIO\\MISCOM.WAV",
-	"AUDIO\\END.MP3",
-	"AUDIO\\lib_a1.WAV",
-	"AUDIO\\lib_a2.WAV",
-	"AUDIO\\lib_a.WAV",
-	"AUDIO\\lib_b.WAV",
-	"AUDIO\\lib_c.WAV",
-	"AUDIO\\lib_d.WAV",
-	"AUDIO\\l2_a.WAV",
-	"AUDIO\\j4t_1.WAV",
-	"AUDIO\\j4t_2.WAV",
-	"AUDIO\\j4t_3.WAV",
-	"AUDIO\\j4t_4.WAV",
-	"AUDIO\\j4_a.WAV",
-	"AUDIO\\j4_b.WAV",
-	"AUDIO\\j4_c.WAV",
-	"AUDIO\\j4_d.WAV",
-	"AUDIO\\j4_e.WAV",
-	"AUDIO\\j4_f.WAV",
-	"AUDIO\\j6_1.WAV",
-	"AUDIO\\j6_a.WAV",
-	"AUDIO\\j6_b.WAV",
-	"AUDIO\\j6_c.WAV",
-	"AUDIO\\j6_d.WAV",
-	"AUDIO\\t4_a.WAV",
-	"AUDIO\\s1_a.WAV",
-	"AUDIO\\s1_a1.WAV",
-	"AUDIO\\s1_b.WAV",
-	"AUDIO\\s1_c.WAV",
-	"AUDIO\\s1_c1.WAV",
-	"AUDIO\\s1_d.WAV",
-	"AUDIO\\s1_e.WAV",
-	"AUDIO\\s1_f.WAV",
-	"AUDIO\\s1_g.WAV",
-	"AUDIO\\s1_h.WAV",
-	"AUDIO\\s1_i.WAV",
-	"AUDIO\\s1_j.WAV",
-	"AUDIO\\s1_k.WAV",
-	"AUDIO\\s1_l.WAV",
-	"AUDIO\\s3_a.WAV",
-	"AUDIO\\s3_b.WAV",
-	"AUDIO\\el3_a.WAV",
-	"AUDIO\\mf1_a.WAV",
-	"AUDIO\\mf2_a.WAV",
-	"AUDIO\\mf3_a.WAV",
-	"AUDIO\\mf3_b.WAV",
-	"AUDIO\\mf3_b1.WAV",
-	"AUDIO\\mf3_c.WAV",
-	"AUDIO\\mf4_a.WAV",
-	"AUDIO\\mf4_b.WAV",
-	"AUDIO\\mf4_c.WAV",
-	"AUDIO\\a1_a.WAV",
-	"AUDIO\\a3_a.WAV",
-	"AUDIO\\a5_a.WAV",
-	"AUDIO\\a4_a.WAV",
-	"AUDIO\\a4_b.WAV",
-	"AUDIO\\a4_c.WAV",
-	"AUDIO\\a4_d.WAV",
-	"AUDIO\\k1_a.WAV",
-	"AUDIO\\k3_a.WAV",
-	"AUDIO\\r1_a.WAV",
-	"AUDIO\\r2_a.WAV",
-	"AUDIO\\r2_b.WAV",
-	"AUDIO\\r2_c.WAV",
-	"AUDIO\\r2_d.WAV",
-	"AUDIO\\r2_e.WAV",
-	"AUDIO\\r2_f.WAV",
-	"AUDIO\\r2_g.WAV",
-	"AUDIO\\r2_h.WAV",
-	"AUDIO\\r5_a.WAV",
-	"AUDIO\\r6_a.WAV",
-	"AUDIO\\r6_a1.WAV",
-	"AUDIO\\r6_b.WAV",
-	"AUDIO\\lo2_a.WAV",
-	"AUDIO\\lo6_a.WAV",
-	"AUDIO\\yd2_a.WAV",
-	"AUDIO\\yd2_b.WAV",
-	"AUDIO\\yd2_c.WAV",
-	"AUDIO\\yd2_c1.WAV",
-	"AUDIO\\yd2_d.WAV",
-	"AUDIO\\yd2_e.WAV",
-	"AUDIO\\yd2_f.WAV",
-	"AUDIO\\yd2_g.WAV",
-	"AUDIO\\yd2_h.WAV",
-	"AUDIO\\yd2_ass.WAV",
-	"AUDIO\\yd2_ok.WAV",
-	"AUDIO\\h5_a.WAV",
-	"AUDIO\\h5_b.WAV",
-	"AUDIO\\h5_c.WAV",
-	"AUDIO\\ammu_a.WAV",
-	"AUDIO\\ammu_b.WAV",
-	"AUDIO\\ammu_c.WAV",
-	"AUDIO\\door_1.WAV",
-	"AUDIO\\door_2.WAV",
-	"AUDIO\\door_3.WAV",
-	"AUDIO\\door_4.WAV",
-	"AUDIO\\door_5.WAV",
-	"AUDIO\\door_6.WAV",
-	"AUDIO\\t3_a.WAV",
-	"AUDIO\\t3_b.WAV",
-	"AUDIO\\t3_c.WAV",
-	"AUDIO\\k1_b.WAV",
-	"AUDIO\\cat1.WAV"
-};
diff --git a/src/audio/oal/aldlist.cpp b/src/audio/oal/aldlist.cpp
new file mode 100644
index 00000000..2c2f13a8
--- /dev/null
+++ b/src/audio/oal/aldlist.cpp
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2006, Creative Labs Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without modification, are permitted provided
+ * that the following conditions are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright notice, this list of conditions and
+ * 	     the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
+ * 	     and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or
+ * 	     promote products derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "aldlist.h"
+#ifdef AUDIO_OAL
+/* 
+ * Init call
+ */
+ALDeviceList::ALDeviceList()
+{
+	ALDEVICEINFO	ALDeviceInfo;
+	char *devices;
+	int index;
+	const char *defaultDeviceName;
+	const char *actualDeviceName;
+
+	// DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support
+	vDeviceInfo.empty();
+	vDeviceInfo.reserve(10);
+
+	defaultDeviceIndex = 0;
+
+	if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")) {
+		devices = (char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
+		defaultDeviceName = (char *)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
+		
+		index = 0;
+		// go through device list (each device terminated with a single NULL, list terminated with double NULL)
+		while (*devices != NULL) {
+			if (strcmp(defaultDeviceName, devices) == 0) {
+				defaultDeviceIndex = index;
+			}
+			ALCdevice *device = alcOpenDevice(devices);
+			if (device) {
+				ALCcontext *context = alcCreateContext(device, NULL);
+				if (context) {
+					alcMakeContextCurrent(context);
+					// if new actual device name isn't already in the list, then add it...
+					actualDeviceName = alcGetString(device, ALC_DEVICE_SPECIFIER);
+					bool bNewName = true;
+					for (int i = 0; i < GetNumDevices(); i++) {
+						if (strcmp(GetDeviceName(i), actualDeviceName) == 0) {
+							bNewName = false;
+						}
+					}
+					if ((bNewName) && (actualDeviceName != NULL) && (strlen(actualDeviceName) > 0)) {
+						memset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO));
+						ALDeviceInfo.bSelected = true;
+						ALDeviceInfo.strDeviceName = std::string(actualDeviceName, strlen(actualDeviceName));
+						alcGetIntegerv(device, ALC_MAJOR_VERSION, sizeof(int), &ALDeviceInfo.iMajorVersion);
+						alcGetIntegerv(device, ALC_MINOR_VERSION, sizeof(int), &ALDeviceInfo.iMinorVersion);
+
+						ALDeviceInfo.pvstrExtensions = new std::vector<std::string>;
+
+						// Check for ALC Extensions
+						if (alcIsExtensionPresent(device, "ALC_EXT_CAPTURE") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_CAPTURE");
+						if (alcIsExtensionPresent(device, "ALC_EXT_EFX") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("ALC_EXT_EFX");
+
+						// Check for AL Extensions
+						if (alIsExtensionPresent("AL_EXT_OFFSET") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_OFFSET");
+
+						if (alIsExtensionPresent("AL_EXT_LINEAR_DISTANCE") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_LINEAR_DISTANCE");
+						if (alIsExtensionPresent("AL_EXT_EXPONENT_DISTANCE") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("AL_EXT_EXPONENT_DISTANCE");
+						
+						if (alIsExtensionPresent("EAX2.0") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("EAX2.0");
+						if (alIsExtensionPresent("EAX3.0") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("EAX3.0");
+						if (alIsExtensionPresent("EAX4.0") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("EAX4.0");
+						if (alIsExtensionPresent("EAX5.0") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("EAX5.0");
+
+						if (alIsExtensionPresent("EAX-RAM") == AL_TRUE)
+							ALDeviceInfo.pvstrExtensions->push_back("EAX-RAM");
+
+						// Get Source Count
+						ALDeviceInfo.uiSourceCount = GetMaxNumSources();
+
+						vDeviceInfo.push_back(ALDeviceInfo);
+					}
+					alcMakeContextCurrent(NULL);
+					alcDestroyContext(context);
+				}
+				alcCloseDevice(device);
+			}
+			devices += strlen(devices) + 1;
+			index += 1;
+		}
+	}
+
+	ResetFilters();
+}
+
+/* 
+ * Exit call
+ */
+ALDeviceList::~ALDeviceList()
+{
+	for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
+		if (vDeviceInfo[i].pvstrExtensions) {
+			vDeviceInfo[i].pvstrExtensions->empty();
+			delete vDeviceInfo[i].pvstrExtensions;
+		}
+	}
+
+	vDeviceInfo.empty();
+}
+
+/*
+ * Returns the number of devices in the complete device list
+ */
+int ALDeviceList::GetNumDevices()
+{
+	return (int)vDeviceInfo.size();	
+}
+
+/* 
+ * Returns the device name at an index in the complete device list
+ */
+char * ALDeviceList::GetDeviceName(int index)
+{
+	if (index < GetNumDevices())
+		return (char *)vDeviceInfo[index].strDeviceName.c_str();
+	else
+		return NULL;
+}
+
+/*
+ * Returns the major and minor version numbers for a device at a specified index in the complete list
+ */
+void ALDeviceList::GetDeviceVersion(int index, int *major, int *minor)
+{
+	if (index < GetNumDevices()) {
+		if (major)
+			*major = vDeviceInfo[index].iMajorVersion;
+		if (minor)
+			*minor = vDeviceInfo[index].iMinorVersion;
+	}
+	return;
+}
+
+/*
+ * Returns the maximum number of Sources that can be generate on the given device
+ */
+unsigned int ALDeviceList::GetMaxNumSources(int index)
+{
+	if (index < GetNumDevices())
+		return vDeviceInfo[index].uiSourceCount;
+	else
+		return 0;
+}
+
+/*
+ * Checks if the extension is supported on the given device
+ */
+bool ALDeviceList::IsExtensionSupported(int index, char *szExtName)
+{
+	bool bReturn = false;
+
+	if (index < GetNumDevices()) {
+		for (unsigned int i = 0; i < vDeviceInfo[index].pvstrExtensions->size(); i++) {
+			if (!_stricmp(vDeviceInfo[index].pvstrExtensions->at(i).c_str(), szExtName)) {
+				bReturn = true;
+				break;
+			}				
+		}
+	}
+
+	return bReturn;
+}
+
+/*
+ * returns the index of the default device in the complete device list
+ */
+int ALDeviceList::GetDefaultDevice()
+{
+	return defaultDeviceIndex;
+}
+
+/* 
+ * Deselects devices which don't have the specified minimum version
+ */
+void ALDeviceList::FilterDevicesMinVer(int major, int minor)
+{
+	int dMajor, dMinor;
+	for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
+		GetDeviceVersion(i, &dMajor, &dMinor);
+		if ((dMajor < major) || ((dMajor == major) && (dMinor < minor))) {
+			vDeviceInfo[i].bSelected = false;
+		}
+	}
+}
+
+/* 
+ * Deselects devices which don't have the specified maximum version
+ */
+void ALDeviceList::FilterDevicesMaxVer(int major, int minor)
+{
+	int dMajor, dMinor;
+	for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
+		GetDeviceVersion(i, &dMajor, &dMinor);
+		if ((dMajor > major) || ((dMajor == major) && (dMinor > minor))) {
+			vDeviceInfo[i].bSelected = false;
+		}
+	}
+}
+
+/*
+ * Deselects device which don't support the given extension name
+ */
+void ALDeviceList::FilterDevicesExtension(char *szExtName)
+{
+	bool bFound;
+
+	for (unsigned int i = 0; i < vDeviceInfo.size(); i++) {
+		bFound = false;
+		for (unsigned int j = 0; j < vDeviceInfo[i].pvstrExtensions->size(); j++) {
+			if (!_stricmp(vDeviceInfo[i].pvstrExtensions->at(j).c_str(), szExtName)) {
+				bFound = true;
+				break;
+			}
+		}
+		if (!bFound)
+			vDeviceInfo[i].bSelected = false;
+	}
+}
+
+/*
+ * Resets all filtering, such that all devices are in the list
+ */
+void ALDeviceList::ResetFilters()
+{
+	for (int i = 0; i < GetNumDevices(); i++) {
+		vDeviceInfo[i].bSelected = true;
+	}
+	filterIndex = 0;
+}
+
+/*
+ * Gets index of first filtered device
+ */
+int ALDeviceList::GetFirstFilteredDevice()
+{
+	int i;
+
+	for (i = 0; i < GetNumDevices(); i++) {
+		if (vDeviceInfo[i].bSelected == true) {
+			break;
+		}
+	}
+	filterIndex = i + 1;
+	return i;
+}
+
+/*
+ * Gets index of next filtered device
+ */
+int ALDeviceList::GetNextFilteredDevice()
+{
+	int i;
+
+	for (i = filterIndex; i < GetNumDevices(); i++) {
+		if (vDeviceInfo[i].bSelected == true) {
+			break;
+		}
+	}
+	filterIndex = i + 1;
+	return i;
+}
+
+/*
+ * Internal function to detemine max number of Sources that can be generated
+ */
+unsigned int ALDeviceList::GetMaxNumSources()
+{
+	ALuint uiSources[256];
+	unsigned int iSourceCount = 0;
+
+	// Clear AL Error Code
+	alGetError();
+
+	// Generate up to 256 Sources, checking for any errors
+	for (iSourceCount = 0; iSourceCount < 256; iSourceCount++)
+	{
+		alGenSources(1, &uiSources[iSourceCount]);
+		if (alGetError() != AL_NO_ERROR)
+			break;
+	}
+
+	// Release the Sources
+	alDeleteSources(iSourceCount, uiSources);
+	if (alGetError() != AL_NO_ERROR)
+	{
+		for (unsigned int i = 0; i < 256; i++)
+		{
+			alDeleteSources(1, &uiSources[i]);
+		}
+	}
+
+	return iSourceCount;
+}
+#endif
\ No newline at end of file
diff --git a/src/audio/oal/aldlist.h b/src/audio/oal/aldlist.h
new file mode 100644
index 00000000..b8f1b31a
--- /dev/null
+++ b/src/audio/oal/aldlist.h
@@ -0,0 +1,49 @@
+#ifndef ALDEVICELIST_H
+#define ALDEVICELIST_H
+
+#include "oal_utils.h"
+
+#ifdef AUDIO_OAL
+#pragma warning(disable: 4786)  //disable warning "identifier was truncated to '255' characters in the browser information"
+#include <vector>
+#include <string>
+
+typedef struct
+{
+	std::string			strDeviceName;
+	int				iMajorVersion;
+	int				iMinorVersion;
+	unsigned int	uiSourceCount;
+	std::vector<std::string>	*pvstrExtensions;
+	bool			bSelected;
+} ALDEVICEINFO, *LPALDEVICEINFO;
+
+class ALDeviceList
+{
+private:
+	std::vector<ALDEVICEINFO> vDeviceInfo;
+	int defaultDeviceIndex;
+	int filterIndex;
+
+public:
+	ALDeviceList ();
+	~ALDeviceList ();
+	int GetNumDevices();
+	char *GetDeviceName(int index);
+	void GetDeviceVersion(int index, int *major, int *minor);
+	unsigned int GetMaxNumSources(int index);
+	bool IsExtensionSupported(int index, char *szExtName);
+	int GetDefaultDevice();
+	void FilterDevicesMinVer(int major, int minor);
+	void FilterDevicesMaxVer(int major, int minor);
+	void FilterDevicesExtension(char *szExtName);
+	void ResetFilters();
+	int GetFirstFilteredDevice();
+	int GetNextFilteredDevice();
+
+private:
+	unsigned int GetMaxNumSources();
+};
+#endif
+
+#endif // ALDEVICELIST_H
\ No newline at end of file
diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp
new file mode 100644
index 00000000..d8b50161
--- /dev/null
+++ b/src/audio/oal/channel.cpp
@@ -0,0 +1,209 @@
+#include "channel.h"
+
+#ifdef AUDIO_OAL
+#include "sampman.h"
+
+extern bool IsFXSupported();
+
+CChannel::CChannel()
+{
+	alChannel = AL_NONE;
+	alFilter  = AL_FILTER_NULL;
+	SetDefault();
+}
+
+void CChannel::SetDefault()
+{
+	Buffer = AL_NONE;
+
+	Pitch = 1.0f;
+	Gain = 1.0f;
+	Mix = 0.0f;
+		
+	Position[0] = 0.0f; Position[1] = 0.0f; Position[2] = 0.0f;
+	Distances[0] = 0.0f; Distances[1] = FLT_MAX;
+	LoopCount  = 1;
+	LoopPoints[0] = 0; LoopPoints[1] = -1;
+	
+	Frequency = MAX_FREQ;
+}
+
+void CChannel::Reset()
+{
+	ClearBuffer();
+	SetDefault();
+}
+
+void CChannel::Init(bool Is2D)
+{
+	ASSERT(!HasSource());
+	alGenSources(1, &alChannel);
+	if ( HasSource() )
+	{
+		alSourcei(alChannel, AL_SOURCE_RELATIVE, AL_TRUE);
+		if ( IsFXSupported() )
+			alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
+		
+		if ( Is2D )
+		{
+			alSource3f(alChannel, AL_POSITION, 0.0f, 0.0f, 0.0f);
+			alSourcef (alChannel, AL_GAIN, 1.0f);
+		}
+		else
+		{
+			if ( IsFXSupported() )
+				alGenFilters(1,&alFilter);
+		}
+	}
+}
+
+void CChannel::Term()
+{
+	Stop();
+	if ( HasSource() )
+	{
+		if ( IsFXSupported() )
+		{
+			alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
+			
+			if(alFilter != AL_FILTER_NULL)
+				alDeleteFilters(1,&alFilter);
+		}
+
+		alDeleteSources(1, &alChannel);
+	}
+	alChannel = AL_NONE;
+	alFilter = AL_FILTER_NULL;
+}
+
+void CChannel::Start()
+{
+	if ( !HasSource() ) return;
+	
+	if ( LoopPoints[0] != 0 && LoopPoints[0] != -1 )
+		alBufferiv(Buffer, AL_LOOP_POINTS_SOFT, LoopPoints);
+	alSourcei   (alChannel, AL_BUFFER, Buffer);
+	alSourcePlay(alChannel);
+}
+
+void CChannel::Stop()
+{
+	if ( HasSource() )
+		alSourceStop(alChannel);
+	
+	Reset();
+}
+
+bool CChannel::HasSource()
+{
+	return alChannel != AL_NONE;
+}
+	
+bool CChannel::IsUsed()
+{
+	if ( HasSource() )
+	{
+		ALint sourceState;
+		alGetSourcei(alChannel, AL_SOURCE_STATE, &sourceState);
+		return sourceState == AL_PLAYING;
+	}
+	return false;
+}
+
+void CChannel::SetPitch(float pitch)
+{
+	if ( !HasSource() ) return;
+	alSourcef(alChannel, AL_PITCH, pitch);
+}
+
+void CChannel::SetGain(float gain)
+{
+	if ( !HasSource() ) return;
+	alSourcef(alChannel, AL_GAIN, gain);
+}
+	
+void CChannel::SetVolume(int32 vol)
+{
+	SetGain(ALfloat(vol) / MAX_VOLUME);
+}
+	
+void CChannel::SetSampleID(uint32 nSfx)
+{
+	Sample = nSfx;
+}
+	
+void CChannel::SetFreq(int32 freq)
+{
+	Frequency = freq;
+}
+	
+void CChannel::SetCurrentFreq(uint32 freq)
+{
+	SetPitch(ALfloat(freq) / Frequency);
+}
+
+void CChannel::SetLoopCount(int32 loopCount) // fake. TODO:
+{
+	if ( !HasSource() ) return;
+	alSourcei(alChannel, AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE);
+}
+
+void CChannel::SetLoopPoints(ALint start, ALint end)
+{
+	LoopPoints[0] = start;
+	LoopPoints[1] = end;
+}
+	
+void CChannel::SetPosition(float x, float y, float z)
+{
+	if ( !HasSource() ) return;
+	alSource3f(alChannel, AL_POSITION, x, y, z);
+}
+	
+void CChannel::SetDistances(float max, float min)
+{
+	if ( !HasSource() ) return;
+	alSourcef   (alChannel, AL_MAX_DISTANCE,       max);
+	alSourcef   (alChannel, AL_REFERENCE_DISTANCE, min);
+	alSourcef   (alChannel, AL_MAX_GAIN, 1.0f);
+	alSourcef   (alChannel, AL_ROLLOFF_FACTOR, 1.0f);
+}
+	
+void CChannel::SetPan(uint32 pan)
+{
+	SetPosition((pan-63)/64.0f, 0.0f, sqrtf(1.0f-SQR((pan-63)/64.0f)));
+}
+
+void CChannel::SetBuffer(ALuint buffer)
+{
+	Buffer = buffer;
+}
+
+void CChannel::ClearBuffer()
+{
+	if ( !HasSource() ) return;
+	SetBuffer(AL_NONE);
+	alSourcei(alChannel, AL_BUFFER, AL_NONE);
+}
+
+void CChannel::SetReverbMix(ALuint slot, float mix)
+{
+	if ( !IsFXSupported() ) return;
+	if ( !HasSource() ) return;
+	if ( alFilter == AL_FILTER_NULL ) return;
+	
+	Mix = mix;
+	EAX3_SetReverbMix(alFilter, mix);
+	alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
+}
+
+void CChannel::UpdateReverb(ALuint slot)
+{
+	if ( !IsFXSupported() ) return;
+	if ( !HasSource() ) return;
+	if ( alFilter == AL_FILTER_NULL ) return;
+	EAX3_SetReverbMix(alFilter, Mix);
+	alSource3i(alChannel, AL_AUXILIARY_SEND_FILTER, slot, 0, alFilter);
+}
+
+#endif
\ No newline at end of file
diff --git a/src/audio/oal/channel.h b/src/audio/oal/channel.h
new file mode 100644
index 00000000..d9ffea22
--- /dev/null
+++ b/src/audio/oal/channel.h
@@ -0,0 +1,51 @@
+#pragma once
+#include "common.h"
+
+#ifdef AUDIO_OAL
+#include "oal/oal_utils.h"
+#include <AL/al.h>
+#include <AL/alext.h>
+#include <AL/efx.h>
+
+
+class CChannel
+{
+	ALuint alChannel;
+	ALuint alFilter;
+	ALuint Buffer;
+	float  Pitch, Gain;
+	float  Mix;
+	int32  Frequency;
+	float  Position[3];
+	float  Distances[2];
+	int32  LoopCount;
+	ALint  LoopPoints[2];
+	uint32 Sample;
+public:
+	CChannel();
+	void SetDefault();
+	void Reset();
+	void Init(bool Is2D = false);
+	void Term();
+	void Start();
+	void Stop();
+	bool HasSource();
+	bool IsUsed();
+	void SetPitch(float pitch);
+	void SetGain(float gain);
+	void SetVolume(int32 vol);
+	void SetSampleID(uint32 nSfx);
+	void SetFreq(int32 freq);
+	void SetCurrentFreq(uint32 freq);
+	void SetLoopCount(int32 loopCount); // fake
+	void SetLoopPoints(ALint start, ALint end);
+	void SetPosition(float x, float y, float z);
+	void SetDistances(float max, float min);
+	void SetPan(uint32 pan);
+	void SetBuffer(ALuint buffer);
+	void ClearBuffer();
+	void SetReverbMix(ALuint slot, float mix);
+	void UpdateReverb(ALuint slot);
+};
+
+#endif
\ No newline at end of file
diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp
new file mode 100644
index 00000000..a2df61c1
--- /dev/null
+++ b/src/audio/oal/oal_utils.cpp
@@ -0,0 +1,176 @@
+#include "oal_utils.h"
+
+#ifdef AUDIO_OAL
+
+LPALGENEFFECTS alGenEffects;
+LPALDELETEEFFECTS alDeleteEffects;
+LPALISEFFECT alIsEffect;
+LPALEFFECTI alEffecti;
+LPALEFFECTIV alEffectiv;
+LPALEFFECTF alEffectf;
+LPALEFFECTFV alEffectfv;
+LPALGETEFFECTI alGetEffecti;
+LPALGETEFFECTIV alGetEffectiv;
+LPALGETEFFECTF alGetEffectf;
+LPALGETEFFECTFV alGetEffectfv;
+LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
+LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
+LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
+LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
+LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
+LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
+LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
+LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
+LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
+LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
+LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
+LPALGENFILTERS alGenFilters;
+LPALDELETEFILTERS alDeleteFilters;
+LPALISFILTER alIsFilter;
+LPALFILTERI alFilteri;
+LPALFILTERIV alFilteriv;
+LPALFILTERF alFilterf;
+LPALFILTERFV alFilterfv;
+LPALGETFILTERI alGetFilteri;
+LPALGETFILTERIV alGetFilteriv;
+LPALGETFILTERF alGetFilterf;
+LPALGETFILTERFV alGetFilterfv;
+
+
+void EFXInit()
+{
+	if (alIsExtensionPresent((ALchar*)"EAX3.0"))
+		DEV("\nBIG EAX IN TOWN\n");
+	else
+		DEV("\nNO EAX\n");
+	
+	
+	 /* Define a macro to help load the function pointers. */
+#define LOAD_PROC(T, x)  ((x) = (T)alGetProcAddress(#x))
+    LOAD_PROC(LPALGENEFFECTS, alGenEffects);
+    LOAD_PROC(LPALDELETEEFFECTS, alDeleteEffects);
+    LOAD_PROC(LPALISEFFECT, alIsEffect);
+    LOAD_PROC(LPALEFFECTI, alEffecti);
+    LOAD_PROC(LPALEFFECTIV, alEffectiv);
+    LOAD_PROC(LPALEFFECTF, alEffectf);
+    LOAD_PROC(LPALEFFECTFV, alEffectfv);
+    LOAD_PROC(LPALGETEFFECTI, alGetEffecti);
+    LOAD_PROC(LPALGETEFFECTIV, alGetEffectiv);
+    LOAD_PROC(LPALGETEFFECTF, alGetEffectf);
+    LOAD_PROC(LPALGETEFFECTFV, alGetEffectfv);
+
+	LOAD_PROC(LPALGENFILTERS, alGenFilters);
+	LOAD_PROC(LPALDELETEFILTERS, alDeleteFilters);
+	LOAD_PROC(LPALISFILTER, alIsFilter);
+	LOAD_PROC(LPALFILTERI, alFilteri);
+	LOAD_PROC(LPALFILTERIV, alFilteriv);
+	LOAD_PROC(LPALFILTERF, alFilterf);
+	LOAD_PROC(LPALFILTERFV, alFilterfv);
+	LOAD_PROC(LPALGETFILTERI, alGetFilteri);
+	LOAD_PROC(LPALGETFILTERIV, alGetFilteriv);
+	LOAD_PROC(LPALGETFILTERF, alGetFilterf);
+	LOAD_PROC(LPALGETFILTERFV, alGetFilterfv);
+
+    LOAD_PROC(LPALGENAUXILIARYEFFECTSLOTS, alGenAuxiliaryEffectSlots);
+    LOAD_PROC(LPALDELETEAUXILIARYEFFECTSLOTS, alDeleteAuxiliaryEffectSlots);
+    LOAD_PROC(LPALISAUXILIARYEFFECTSLOT, alIsAuxiliaryEffectSlot);
+    LOAD_PROC(LPALAUXILIARYEFFECTSLOTI, alAuxiliaryEffectSloti);
+    LOAD_PROC(LPALAUXILIARYEFFECTSLOTIV, alAuxiliaryEffectSlotiv);
+    LOAD_PROC(LPALAUXILIARYEFFECTSLOTF, alAuxiliaryEffectSlotf);
+    LOAD_PROC(LPALAUXILIARYEFFECTSLOTFV, alAuxiliaryEffectSlotfv);
+    LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTI, alGetAuxiliaryEffectSloti);
+    LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTIV, alGetAuxiliaryEffectSlotiv);
+    LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTF, alGetAuxiliaryEffectSlotf);
+    LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv);
+#undef LOAD_PROC
+}
+
+
+void SetEffectsLevel(ALuint uiFilter, float level)
+{
+	alFilteri(uiFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
+	alFilterf(uiFilter, AL_LOWPASS_GAIN, 1.0f);
+	alFilterf(uiFilter, AL_LOWPASS_GAINHF, level);
+}
+
+static inline float gain_to_mB(float gain)
+{
+    return (gain > 1e-5f) ? (float)(log10f(gain) * 2000.0f) : -10000l;
+}
+
+static inline float mB_to_gain(float millibels)
+{
+    return (millibels > -10000.0f) ? powf(10.0f, millibels/2000.0f) : 0.0f;
+}
+
+static inline FLOAT clampF(FLOAT val, FLOAT minval, FLOAT maxval)
+{
+    if(val >= maxval) return maxval;
+    if(val <= minval) return minval;
+    return val;
+}
+
+void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props)
+{
+	alEffecti (effect, AL_EFFECT_TYPE,                     AL_EFFECT_EAXREVERB);
+    alEffectf (effect, AL_EAXREVERB_DENSITY,               clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f));
+    alEffectf (effect, AL_EAXREVERB_DIFFUSION,             props->flEnvironmentDiffusion);
+    alEffectf (effect, AL_EAXREVERB_GAIN,                  mB_to_gain((float)props->lRoom));
+    alEffectf (effect, AL_EAXREVERB_GAINHF,                mB_to_gain((float)props->lRoomHF));
+    alEffectf (effect, AL_EAXREVERB_GAINLF,                mB_to_gain((float)props->lRoomLF));
+    alEffectf (effect, AL_EAXREVERB_DECAY_TIME,            props->flDecayTime);
+    alEffectf (effect, AL_EAXREVERB_DECAY_HFRATIO,         props->flDecayHFRatio);
+    alEffectf (effect, AL_EAXREVERB_DECAY_LFRATIO,         props->flDecayLFRatio);
+    alEffectf (effect, AL_EAXREVERB_REFLECTIONS_GAIN,      clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN));
+    alEffectf (effect, AL_EAXREVERB_REFLECTIONS_DELAY,     props->flReflectionsDelay);
+    alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN,       &props->vReflectionsPan.x);
+    alEffectf (effect, AL_EAXREVERB_LATE_REVERB_GAIN,      clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN));
+    alEffectf (effect, AL_EAXREVERB_LATE_REVERB_DELAY,     props->flReverbDelay);
+    alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN,       &props->vReverbPan.x);
+    alEffectf (effect, AL_EAXREVERB_ECHO_TIME,             props->flEchoTime);
+    alEffectf (effect, AL_EAXREVERB_ECHO_DEPTH,            props->flEchoDepth);
+    alEffectf (effect, AL_EAXREVERB_MODULATION_TIME,       props->flModulationTime);
+    alEffectf (effect, AL_EAXREVERB_MODULATION_DEPTH,      props->flModulationDepth);
+    alEffectf (effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF));
+    alEffectf (effect, AL_EAXREVERB_HFREFERENCE,           props->flHFReference);
+    alEffectf (effect, AL_EAXREVERB_LFREFERENCE,           props->flLFReference);
+    alEffectf (effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR,   props->flRoomRolloffFactor);
+    alEffecti (effect, AL_EAXREVERB_DECAY_HFLIMIT,         (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE);
+}
+
+void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props)
+{
+	alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
+
+	alEffectf(effect, AL_REVERB_DENSITY,               clampF(powf(props->flEnvironmentSize, 3.0f) / 16.0f, 0.0f, 1.0f));
+	alEffectf(effect, AL_REVERB_DIFFUSION,             props->flEnvironmentDiffusion);
+	alEffectf(effect, AL_REVERB_GAIN,                  mB_to_gain((float)props->lRoom));
+	alEffectf(effect, AL_REVERB_GAINHF,                mB_to_gain((float)props->lRoomHF));
+	alEffectf(effect, AL_REVERB_DECAY_TIME,            props->flDecayTime);
+	alEffectf(effect, AL_REVERB_DECAY_HFRATIO,         props->flDecayHFRatio);
+	alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN,      clampF(mB_to_gain((float)props->lReflections), AL_EAXREVERB_MIN_REFLECTIONS_GAIN, AL_EAXREVERB_MAX_REFLECTIONS_GAIN));
+	alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY,     props->flReflectionsDelay);
+	alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN,      clampF(mB_to_gain((float)props->lReverb), AL_EAXREVERB_MIN_LATE_REVERB_GAIN, AL_EAXREVERB_MAX_LATE_REVERB_GAIN));
+	alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY,     props->flReverbDelay);
+	alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, clampF(mB_to_gain(props->flAirAbsorptionHF), AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF, AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF));
+	alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR,   props->flRoomRolloffFactor);
+	alEffecti(effect, AL_REVERB_DECAY_HFLIMIT,         (props->ulFlags&EAXLISTENERFLAGS_DECAYHFLIMIT) ? AL_TRUE : AL_FALSE);
+}
+
+void EAX3_SetReverbMix(ALuint filter, float mix)
+{
+	//long vol=(long)linear_to_dB(mix);
+	//DSPROPERTY_EAXBUFFER_ROOMHF,
+	//DSPROPERTY_EAXBUFFER_ROOM,
+	//DSPROPERTY_EAXBUFFER_REVERBMIX,
+	
+	long mbvol = gain_to_mB(mix);
+	float mb   = mbvol;
+	float mbhf = mbvol;
+	
+	alFilteri(filter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
+	alFilterf(filter, AL_LOWPASS_GAIN,   mB_to_gain(Min(mb, 0.0f)));
+	alFilterf(filter, AL_LOWPASS_GAINHF, mB_to_gain(mbhf));
+}
+
+#endif
\ No newline at end of file
diff --git a/src/audio/oal/oal_utils.h b/src/audio/oal/oal_utils.h
new file mode 100644
index 00000000..af45a944
--- /dev/null
+++ b/src/audio/oal/oal_utils.h
@@ -0,0 +1,48 @@
+#pragma once
+#include "common.h"
+
+#ifdef AUDIO_OAL
+#include "eax.h"
+#include "AL/efx.h"
+
+
+void EFXInit();
+void EAX3_Set(ALuint effect, const EAXLISTENERPROPERTIES *props);
+void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props);
+void EAX3_SetReverbMix(ALuint filter, float mix);
+void SetEffectsLevel(ALuint uiFilter, float level);
+
+extern LPALGENEFFECTS alGenEffects;
+extern LPALDELETEEFFECTS alDeleteEffects;
+extern LPALISEFFECT alIsEffect;
+extern LPALEFFECTI alEffecti;
+extern LPALEFFECTIV alEffectiv;
+extern LPALEFFECTF alEffectf;
+extern LPALEFFECTFV alEffectfv;
+extern LPALGETEFFECTI alGetEffecti;
+extern LPALGETEFFECTIV alGetEffectiv;
+extern LPALGETEFFECTF alGetEffectf;
+extern LPALGETEFFECTFV alGetEffectfv;
+extern LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
+extern LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
+extern LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
+extern LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
+extern LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
+extern LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
+extern LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
+extern LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
+extern LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
+extern LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
+extern LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
+extern LPALGENFILTERS alGenFilters;
+extern LPALDELETEFILTERS alDeleteFilters;
+extern LPALISFILTER alIsFilter;
+extern LPALFILTERI alFilteri;
+extern LPALFILTERIV alFilteriv;
+extern LPALFILTERF alFilterf;
+extern LPALFILTERFV alFilterfv;
+extern LPALGETFILTERI alGetFilteri;
+extern LPALGETFILTERIV alGetFilteriv;
+extern LPALGETFILTERF alGetFilterf;
+extern LPALGETFILTERFV alGetFilterfv;
+#endif
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
new file mode 100644
index 00000000..a65c9794
--- /dev/null
+++ b/src/audio/oal/stream.cpp
@@ -0,0 +1,118 @@
+#include "stream.h"
+#include "common.h"
+
+#ifdef AUDIO_OAL
+
+void CStream::Initialise()
+{
+	//mpg123_init();
+}
+
+void CStream::Terminate()
+{
+	//mpg123_exit();
+}
+
+CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) :
+	m_alSource(source),
+	m_alBuffers(buffers),
+	m_nBitRate(0), 
+	m_nFormat(0),
+	m_nFreq(0),
+	m_nLength(0), 
+	m_nLengthMS(0), 
+	m_nBufferSize(0),
+	m_pBuffer(NULL),
+	m_bIsOpened(false),
+	m_bPaused(true)
+	
+{
+	strcpy(m_aFilename, filename);
+		
+	//DEV("Stream %s\n", m_aFilename);
+
+	/*
+	if ( true )
+	{				
+		m_nBitRate     = (wBitsPerSample * nChannels * wfex.nSamplesPerSec)/1000;
+		m_nLength      = ulDataSize;
+		m_nLengthMS    = m_nLength*8 / m_nBitRate;
+		m_nBufferSize  = nAvgBytesPerSec >> 2;
+		m_nBufferSize -= (m_nLength % wfex.nBlockAlign);
+		m_pBuffer      = malloc(m_nBufferSize);
+		m_bIsOpened = true;
+		return;
+	}*/
+}
+
+CStream::~CStream()
+{
+	Delete();
+}
+
+void CStream::Delete()
+{	
+	if ( m_pBuffer )
+	{
+		free(m_pBuffer);
+		m_pBuffer = NULL;
+	}
+}
+
+bool CStream::IsOpened()
+{
+	return m_bIsOpened;
+}
+
+bool CStream::IsPlaying()
+{
+	return false;
+}
+
+void CStream::SetPause(bool bPause)
+{
+}
+
+void CStream::SetVolume(uint32 nVol)
+{
+	
+}
+
+void CStream::SetPan(uint8 nPan)
+{
+}
+
+void CStream::SetPos(uint32 nPos)
+{
+}
+
+uint32 CStream::GetPos()
+{
+	return 0;
+}
+
+uint32 CStream::GetLength()
+{
+	return m_nLengthMS;
+}
+
+bool CStream::Setup()
+{
+	if ( !IsOpened() )
+		return false;
+		
+	return IsOpened();
+}
+
+void CStream::Start()
+{
+
+}
+
+void CStream::Update()
+{
+	if ( !IsOpened() )
+		return;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/audio/oal/stream.h b/src/audio/oal/stream.h
new file mode 100644
index 00000000..666d42e0
--- /dev/null
+++ b/src/audio/oal/stream.h
@@ -0,0 +1,57 @@
+#pragma once
+#include "common.h"
+
+#ifdef AUDIO_OAL
+#include <AL/al.h>
+
+#define NUM_STREAMBUFFERS 5
+#define STREAMBUFFER_SIZE 0x4000
+
+class CStream
+{
+	char     m_aFilename[128];
+	ALuint  &m_alSource;
+	ALuint (&m_alBuffers)[NUM_STREAMBUFFERS];
+	
+	bool     m_bIsOpened;
+	bool     m_bPaused;
+		
+	uint32   m_nLength;
+	uint32   m_nLengthMS;
+	uint32   m_nBitRate;
+	
+	unsigned long   m_nFormat;
+	unsigned long   m_nFreq;
+	
+	uint32   m_nBufferSize;
+	void    *m_pBuffer;
+	
+	ALint iTotalBuffersProcessed;
+	
+	bool   FillBuffer(ALuint alBuffer);
+	int32  FillBuffers();
+public:
+	static void Initialise();
+	static void Terminate();
+	
+	CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]);
+	~CStream();
+	
+	void   Delete();
+	
+	bool   IsOpened();
+	bool   IsPlaying();
+	void   SetPause (bool bPause);
+	void   SetVolume(uint32 nVol);
+	void   SetPan   (uint8 nPan);
+	void   SetPos   (uint32 nPos); 
+
+	uint32 GetPos();
+	uint32 GetLength();
+	
+	bool Setup();
+	void Start();
+	void Update(void);
+};
+
+#endif
\ No newline at end of file
diff --git a/src/audio/openal/samp_oal.cpp b/src/audio/openal/samp_oal.cpp
deleted file mode 100644
index e8213cd9..00000000
--- a/src/audio/openal/samp_oal.cpp
+++ /dev/null
@@ -1,1404 +0,0 @@
-#include <al.h>
-#include <alc.h>
-#include <mpg123_pre.h>
-//#include <mpg123.h>
-#include <time.h>
-#include <io.h>
-#include "samp_oal.h"
-#include "AudioManager.h"
-#include "MusicManager.h"
-#include "Frontend.h"
-#include "Timer.h"
-
-#pragma comment( lib, "libmpg123.lib" )
-#pragma comment( lib, "OpenAL32.lib" )
-
-cSampleManager SampleManager;
-int32 BankStartOffset[MAX_SAMPLEBANKS];
-
-
-///////////////////////////////////////////////////////////////
-class MP3Stream
-{
-public:
-	mpg123_handle *m_pMPG;
-	FILE *m_fpFile;
-	unsigned char *m_pBuf;
-	char m_aFilename[128];
-	size_t m_nBufSize;
-	size_t m_nLengthInBytes;
-	long m_nRate;
-	int  m_nBitRate;
-	int m_nChannels;
-	int m_nEncoding;
-	int m_nLength;
-	int m_nBlockSize;
-	int m_nNumBlocks;
-	ALuint m_alSource;
-	ALuint m_alBuffers[5];
-	unsigned char *m_pBlocks;
-	bool m_bIsFree;
-	bool m_bIsOpened;
-	bool m_bIsPaused;
-	int  m_nVolume;
-	
-	void Initialize(void);
-	bool FillBuffer(ALuint alBuffer);
-	void Update(void);
-	void SetPos(uint32 nPos);
-	int32 FillBuffers();
-	MP3Stream(char *filename, ALuint source, ALuint *buffers);
-	~MP3Stream() { Delete(); }
-	void Delete();
-
-};
-///////////////////////////////////////////////////////////////
-
-char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
-char SampleBankDataFilename[] = "AUDIO\\SFX.RAW";
-
-FILE *fpSampleDescHandle;
-FILE *fpSampleDataHandle;
-bool  bSampleBankLoaded            [MAX_SAMPLEBANKS];
-int32 nSampleBankDiscStartOffset   [MAX_SAMPLEBANKS];
-int32 nSampleBankSize              [MAX_SAMPLEBANKS];
-int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
-int32 _nSampleDataEndOffset;
-
-int32 nPedSlotSfx    [MAX_PEDSFX];
-int32 nPedSlotSfxAddr[MAX_PEDSFX];
-uint8 nCurrentPedSlot;
-
-
-
-uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
-
-///////////////////////////////////////////////////////////////
-ALuint alChannel[MAXCHANNELS+MAX2DCHANNELS];
-ALuint ALStreamSources[MAX_STREAMS];
-ALuint ALStreamBuffers[MAX_STREAMS][5];
-struct
-{
-	ALuint buffer;
-	ALuint timer;
-}ALBuffers[SAMPLEBANK_MAX];
-
-ALuint pedBuffers[MAX_PEDSFX];
-//bank0Buffers
-
-uint32 nNumMP3s;
-
-MP3Stream *mp3Stream[MAX_STREAMS];
-int8 nStreamPan   [MAX_STREAMS];
-int8 nStreamVolume[MAX_STREAMS];
-
-float ChannelPitch[MAXCHANNELS+MAX2DCHANNELS];
-uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
-uint32 ChannelSample[MAXCHANNELS+MAX2DCHANNELS];
-int32 currentChannelMaxFrontDistance[MAXCHANNELS+MAX2DCHANNELS];
-int32 currentChannelFrequency[MAXCHANNELS+MAX2DCHANNELS];
-int32 currentChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
-
-
-cSampleManager::cSampleManager(void)
-{
-	;
-}
-
-cSampleManager::~cSampleManager(void)
-{
-	ASSERT((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED] == NULL);
-	free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
-	
-	if ( fpSampleDescHandle != NULL )
-	{
-		fclose(fpSampleDescHandle);
-		fpSampleDescHandle = NULL;
-	}
-	
-	if ( fpSampleDataHandle != NULL )
-	{
-		fclose(fpSampleDataHandle);
-		fpSampleDataHandle = NULL;
-	}
-}
-
-void cSampleManager::SetSpeakerConfig(int32 nConfig)
-{
-
-}
-
-uint32 cSampleManager::GetMaximumSupportedChannels(void)
-{
-	return 20;
-}
-
-uint32 cSampleManager::GetNum3DProvidersAvailable()
-{
-	return 1;
-}
-
-void cSampleManager::SetNum3DProvidersAvailable(uint32 num)
-{
-	;
-}
-
-char *cSampleManager::Get3DProviderName(uint8 id)
-{
-	static char PROVIDER[256] = "OpenAL";
-	return PROVIDER;
-}
-
-void cSampleManager::Set3DProviderName(uint8 id, char *name)
-{
-	;
-}
-
-int8 cSampleManager::GetCurrent3DProviderIndex(void)
-{
-	return 0;
-}
-
-int8 cSampleManager::SetCurrent3DProvider(uint8 which)
-{
-	return 0;
-}
-
-bool
-cSampleManager::IsMP3RadioChannelAvailable(void)
-{
-	return nNumMP3s != 0;
-}
-
-
-void cSampleManager::ReleaseDigitalHandle(void)
-{
-
-}
-
-void cSampleManager::ReacquireDigitalHandle(void)
-{
-
-}
-
-bool
-cSampleManager::Initialise(void)
-{
-	ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0};
-	
-	m_pDevice  = alcOpenDevice(NULL);
-	ASSERT(m_pDevice != NULL);
-	
-	m_pContext = alcCreateContext(m_pDevice, attr);
-	ASSERT(m_pContext != NULL);
-	
-	alcMakeContextCurrent(m_pContext);
-	
-	mpg123_init();
-	
-
-
-	for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
-	{
-		m_aSamples[i].nOffset    = 0;
-		m_aSamples[i].nSize      = 0;
-		m_aSamples[i].nFrequency = MAX_FREQ;
-		m_aSamples[i].nLoopStart = 0;
-		m_aSamples[i].nLoopEnd   = -1;
-	}
-	
-	for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
-		nStreamLength[i] = 3600000;
-	
-	for ( int32 i = 0; i < MAX_STREAMS; i++ )
-	{
-		mp3Stream[i]     = NULL;
-		nStreamVolume[i] = 100;
-		nStreamPan[i]    = 63;
-	}
-	
-	alGenSources(MAX_STREAMS,   (ALuint *)ALStreamSources);
-	alGenBuffers(MAX_STREAMS*5, (ALuint *)ALStreamBuffers);
-	
-	m_nMonoMode = 0;
-	
-	m_nEffectsVolume     = MAX_VOLUME;
-	m_nMusicVolume       = MAX_VOLUME;
-	m_nEffectsFadeVolume = MAX_VOLUME;
-	m_nMusicFadeVolume   = MAX_VOLUME;
-
-	
-	memset(alChannel,      0, sizeof(alChannel));
-	memset(nChannelVolume, 0, sizeof(nChannelVolume));
-	memset(ChannelSample,  0, sizeof(ChannelSample));
-	
-	for ( int32 i = 0; i < ARRAY_SIZE(ChannelPitch); i++ )
-		ChannelPitch[i] = 1.0f;
-	
-	
-	fpSampleDescHandle = NULL;
-	fpSampleDataHandle = NULL;
-	
-	for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
-	{
-		bSampleBankLoaded[i]             = false;
-		nSampleBankDiscStartOffset[i]    = 0;
-		nSampleBankSize[i]               = 0;
-		nSampleBankMemoryStartAddress[i] = 0;
-	}
-	
-	alGenBuffers(MAX_PEDSFX, pedBuffers);
-	
-	for ( int32 i = 0; i < MAX_PEDSFX; i++ )
-	{
-		nPedSlotSfx[i]     = NO_SAMPLE;
-		nPedSlotSfxAddr[i] = 0;
-	}
-	
-	nCurrentPedSlot = 0;
-	
-	for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
-	{
-		ALBuffers[i].buffer = 0;
-		ALBuffers[i].timer  = 0;
-	}
-	
-	alListenerf (AL_GAIN,     1.0f);
-	alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
-	alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f);
-	ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
-	alListenerfv(AL_ORIENTATION, orientation);
-	
-	if ( !InitialiseSampleBanks() )
-	{
-		Terminate();
-		return false;
-	}
-	
-	nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]);
-	ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL);
-	
-	if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL )
-	{
-		Terminate();
-		return false;
-	}
-	
-	nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
-	ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL);
-	
-	alGenSources(MAXCHANNELS, alChannel);
-	for ( int32 i = 0; i < MAXCHANNELS; i++ )
-	{
-		if ( alChannel[i] )
-			alSourcei(alChannel[i], AL_SOURCE_RELATIVE, AL_TRUE);
-	}
-	
-	alGenSources(MAX2DCHANNELS, &alChannel[CHANNEL2D]);
-	if ( alChannel[CHANNEL2D] )
-	{
-		alSourcei (alChannel[CHANNEL2D], AL_SOURCE_RELATIVE, AL_TRUE);
-		alSource3f(alChannel[CHANNEL2D], AL_POSITION, 0.0f, 0.0f, 0.0f);
-		alSourcef (alChannel[CHANNEL2D], AL_GAIN, 1.0f);
-	}
-	
-	LoadSampleBank(SAMPLEBANK_MAIN);
-	
-	return true;
-}
-
-void
-cSampleManager::Terminate(void)
-{
-	mpg123_exit();
-	alcMakeContextCurrent(NULL);
-	alcDestroyContext(m_pContext);
-	alcCloseDevice(m_pDevice);
-}
-
-void
-cSampleManager::UpdateSoundBuffers(void)
-{	
-	for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
-	{
-		if ( ALBuffers[i].timer > 0 )
-		{
-			ALBuffers[i].timer -= ALuint(CTimer::GetTimeStep() * 20.0f);
-			
-			if ( ALBuffers[i].timer <= 0 )
-			{
-				if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) )
-				{
-					alDeleteBuffers(1, &ALBuffers[i].buffer);
-					
-					if ( alGetError() == AL_NO_ERROR )
-						ALBuffers[i].buffer = 0;
-					else
-						ALBuffers[i].buffer = 120000;
-				}
-			}
-		}
-	}
-}
-
-bool cSampleManager::CheckForAnAudioFileOnCD(void)
-{
-	return true;
-}
-
-char cSampleManager::GetCDAudioDriveLetter(void)
-{
-	return '\0';
-}
-
-void
-cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
-{
-	m_nEffectsVolume = nVolume;
-}
-
-void
-cSampleManager::SetMusicMasterVolume(uint8 nVolume)
-{
-	m_nMusicVolume = nVolume;
-}
-
-void
-cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
-{
-	m_nEffectsFadeVolume = nVolume;
-}
-
-void
-cSampleManager::SetMusicFadeVolume(uint8 nVolume)
-{
-	m_nMusicFadeVolume = nVolume;
-}
-
-void
-cSampleManager::SetMonoMode(uint8 nMode)
-{
-	m_nMonoMode = nMode;
-}
-
-bool
-cSampleManager::LoadSampleBank(uint8 nBank)
-{
-	ASSERT( nBank < MAX_SAMPLEBANKS );
-	
-	if ( CTimer::GetIsCodePaused() )
-		return false;
-	
-	if ( MusicManager.IsInitialised()
-		&& MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
-		&& nBank != SAMPLEBANK_MAIN )
-	{
-		return false;
-	}
-	
-	if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
-		return false;
-	
-	if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank], fpSampleDataHandle) != nSampleBankSize[nBank] )
-		return false;
-	
-	bSampleBankLoaded[nBank] = true;
-	
-	return true;
-}
-
-void
-cSampleManager::UnloadSampleBank(uint8 nBank)
-{
-	ASSERT( nBank < MAX_SAMPLEBANKS );
-	
-	; // NOIMP
-}
-
-bool
-cSampleManager::IsSampleBankLoaded(uint8 nBank)
-{
-	ASSERT( nBank < MAX_SAMPLEBANKS );
-	return true;
-}
-
-bool
-cSampleManager::IsPedCommentLoaded(uint32 nComment)
-{
-	ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
-	
-	uint8 slot;
-
-	for ( int32 i = 0; i < _TODOCONST(3); i++ )
-	{
-		slot = nCurrentPedSlot - i - 1;
-		if ( nComment == nPedSlotSfx[slot] )
-			return true;
-	}
-	
-	return false;
-}
-
-
-int32
-cSampleManager::_GetPedCommentSlot(uint32 nComment)
-{
-	uint8 slot;
-
-	for (int32 i = 0; i < _TODOCONST(3); i++)
-	{
-		slot = nCurrentPedSlot - i - 1;
-		if (nComment == nPedSlotSfx[slot])
-			return slot;
-	}
-
-	return -1;
-}
-
-bool
-cSampleManager::LoadPedComment(uint32 nComment)
-{
-	ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
-	
-	if ( CTimer::GetIsCodePaused() )
-		return false;
-	
-	// no talking peds during cutsenes or the game end
-	if ( MusicManager.IsInitialised() )
-	{
-		switch ( MusicManager.GetMusicMode() )
-		{
-			case MUSICMODE_CUTSCENE:
-			{
-				return false;
-
-				break;
-			}
-			
-			case MUSICMODE_FRONTEND:
-			{
-				if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
-					return false;
-
-				break;
-			}
-		}
-	}
-	
-	if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 )
-		return false;
-	
-	if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
-		return false;
-	
-	nPedSlotSfx[nCurrentPedSlot] = nComment;
-	
-	alBufferData(pedBuffers[nCurrentPedSlot],
-		AL_FORMAT_MONO16,
-		(void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot),
-		m_aSamples[nComment].nSize,
-		MAX_FREQ);
-	
-	if ( ++nCurrentPedSlot >= MAX_PEDSFX )
-		nCurrentPedSlot = 0;
-	
-	return true;
-}
-
-int32
-cSampleManager::GetBankContainingSound(uint32 offset)
-{
-	if ( offset >= BankStartOffset[SAMPLEBANK_PED] )
-		return SAMPLEBANK_PED;
-	
-	if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] )
-		return SAMPLEBANK_MAIN;
-	
-	return SAMPLEBANK_INVALID;
-}
-
-int32
-cSampleManager::GetSampleBaseFrequency(uint32 nSample)
-{
-	ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
-	return m_aSamples[nSample].nFrequency;
-}
-
-int32
-cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
-{
-	ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
-	return m_aSamples[nSample].nLoopStart;
-}
-
-int32
-cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
-{
-	ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
-	return m_aSamples[nSample].nLoopEnd;
-}
-
-uint32
-cSampleManager::GetSampleLength(uint32 nSample)
-{
-	ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
-	return m_aSamples[nSample].nSize >> 1;
-}
-
-bool cSampleManager::UpdateReverb(void)
-{
-	return false;
-}
-
-void
-cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
-{
-	; // NOIMP
-}
-
-bool
-cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	ALuint buffer;
-	
-	if ( nSfx < SAMPLEBANK_MAX )
-	{
-		int32 offset = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nOffset  - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nOffset;
-		int32 size   = (m_aSamples[nSfx].nLoopStart > 0) ? (m_aSamples[nSfx].nLoopEnd - m_aSamples[nSfx].nLoopStart) : m_aSamples[nSfx].nSize;
-		
-		void *data = malloc(size);
-		ASSERT(data != NULL);
-		
-		if ( fseek(fpSampleDataHandle, offset + nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
-		{
-			free(data);
-			return false;
-		}
-		
-		if ( fread(data, 1, size, fpSampleDataHandle) != size )
-		{	
-			free(data);
-			return false;
-		}
-		
-		ALuint buf;
-		alGenBuffers(1, &buf);
-		alBufferData(buf, AL_FORMAT_MONO16, data, size, MAX_FREQ);
-		free(data);
-		
-		if ( !IsSampleBankLoaded(nBank) )
-			return false;
-		
-		ALBuffers[nSfx].buffer = buf;
-		ALBuffers[nSfx].timer  = 120000;
-		
-		buffer = ALBuffers[nSfx].buffer;
-		
-		ChannelSample[nChannel] = nSfx;
-	}
-	else
-	{
-		if ( !IsPedCommentLoaded(nSfx) )
-			return false;
-		
-		int32 slot = _GetPedCommentSlot(nSfx);
-		
-		buffer = pedBuffers[slot];
-	}
-	
-	if ( buffer == 0 )
-	{
-		TRACE("No buffer to play id %d", nSfx);
-		return false;
-	}
-	
-	if ( GetChannelUsedFlag(nChannel) )
-	{
-		TRACE("Stopping channel %d - really!!!", nChannel);
-		StopChannel(nChannel);
-	}
-	
-	alSourcei(alChannel[nChannel], AL_BUFFER, 0);
-	currentChannelVolume          [nChannel] = -1;
-	currentChannelFrequency       [nChannel] = -1;
-	currentChannelMaxFrontDistance[nChannel] = -1;
-	
-	if ( alChannel[nChannel] )
-	{
-		alSourcei(alChannel[nChannel], AL_BUFFER, buffer);
-		alSourcef(alChannel[nChannel], AL_PITCH,  1.0f);
-		ChannelPitch[nChannel] = 1.0f;
-		return true;
-	}
-	
-	return false;
-}
-
-void
-cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	uint32 vol = nVolume;
-	if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
-	
-	nChannelVolume[nChannel] = vol;
-	
-	// reduce the volume for JB.MP3 and S4_BDBD.MP3
-	if (   MusicManager.GetMusicMode()    == MUSICMODE_CUTSCENE
-		&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
-		&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
-	{
-		nChannelVolume[nChannel] >>= 2;
-	}
-
-	uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14;
-	if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_REV_10 >= ChannelSample[nChannel] ) // nice hack
-		channelVol >>= 1;
-	
-	if ( alChannel[nChannel] )
-	{
-		if ( currentChannelVolume[nChannel] != channelVol )
-		{
-			ALfloat gain = ALfloat(channelVol) / MAX_VOLUME;
-			alSourcef(alChannel[nChannel], AL_GAIN, gain);
-			currentChannelVolume[nChannel] = channelVol;
-		}
-	}
-}
-
-void
-cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	if ( alChannel[nChannel] )
-	{
-		alSource3f(alChannel[nChannel], AL_POSITION, -fX, fY, fZ);
-	}
-}
-
-void
-cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	if ( alChannel[nChannel] )
-	{
-		if ( float(currentChannelMaxFrontDistance[nChannel]) != fMax )
-		{
-			alSourcef(alChannel[nChannel], AL_MAX_DISTANCE,       fMax);
-			alSourcef(alChannel[nChannel], AL_REFERENCE_DISTANCE, 5.0f);
-			alSourcef(alChannel[nChannel], AL_MAX_GAIN,           1.0f);
-			currentChannelMaxFrontDistance[nChannel] = int32(fMax);
-		}
-	}
-}
-
-void
-cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	if ( nChannel == CHANNEL2D )
-	{
-		uint32 vol = nVolume;
-		if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
-		
-		nChannelVolume[nChannel] = vol;
-		
-		// increase the volume for JB.MP3 and S4_BDBD.MP3
-		if (   MusicManager.GetMusicMode()    == MUSICMODE_CUTSCENE
-			&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
-			&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
-		{
-			nChannelVolume[nChannel] >>= 2;
-		}
-		
-		uint32 channelVol = m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14;
-		if ( ChannelSample[nChannel] >= SFX_CAR_REV_1 && SFX_CAR_IDLE_10 >= ChannelSample[nChannel] ) // nice hack
-			channelVol >>= 1;
-	
-		if ( alChannel[nChannel] )
-		{
-			if ( currentChannelVolume[nChannel] != channelVol )
-			{
-				ALfloat gain = ALfloat(channelVol) / MAX_VOLUME;
-				alSourcef(alChannel[nChannel], AL_GAIN, gain);
-				currentChannelVolume[nChannel] = channelVol;
-			}
-		}
-	}
-}
-
-void
-cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	; // NOIMP
-}
-
-void
-cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	if ( alChannel[nChannel] )
-	{
-		if ( currentChannelFrequency[nChannel] != nFreq )
-		{
-			ALfloat pitch = ALfloat(nFreq) / MAX_FREQ;
-			alSourcef(alChannel[nChannel], AL_PITCH, pitch);
-			currentChannelFrequency[nChannel] = nFreq;
-			
-			if ( Abs(1.0f - pitch) < 0.01f )
-				ChannelPitch[nChannel] = 1.0f;
-			else
-				ChannelPitch[nChannel] = pitch;
-		}
-	}
-}
-
-void
-cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	; // NOIMP
-}
-
-void
-cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	if ( nLoopCount != 0 )
-		alSourcei(alChannel[nChannel], AL_LOOPING, AL_FALSE);
-	else
-		alSourcei(alChannel[nChannel], AL_LOOPING, AL_TRUE);
-}
-
-bool
-cSampleManager::GetChannelUsedFlag(uint32 nChannel)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	if ( alChannel[nChannel] )
-	{
-		ALint sourceState;
-		alGetSourcei(alChannel[nChannel], AL_SOURCE_STATE, &sourceState);
-		return sourceState == AL_PLAYING;
-	}
-	
-	return false;
-}
-
-void
-cSampleManager::StartChannel(uint32 nChannel)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	if ( alChannel[nChannel] )
-	{
-		if ( ChannelSample[nChannel] > SAMPLEBANK_END ) // PED's Bank
-		{
-			if ( ChannelPitch[nChannel] != 1.0f )
-				ChannelPitch[nChannel] = 1.0f;
-		}
-
-		alSourcef   (alChannel[nChannel], AL_PITCH, ChannelPitch[nChannel]);
-		alSourcePlay(alChannel[nChannel]);
-	}
-}
-
-void
-cSampleManager::StopChannel(uint32 nChannel)
-{
-	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
-	
-	if ( alChannel[nChannel] )
-	{
-		alSourceStop(alChannel[nChannel]);
-		
-		currentChannelVolume          [nChannel] = -1;
-		currentChannelFrequency       [nChannel] = -1;
-		currentChannelMaxFrontDistance[nChannel] = -1;
-		ChannelPitch                  [nChannel] = 1.0f;
-	}
-}
-
-void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
-{
-	char filename[256];
-	
-	ASSERT( nStream < MAX_STREAMS );
-
-	if ( nFile < TOTAL_STREAMED_SOUNDS )
-	{
-		if ( mp3Stream[nStream] )
-		{
-			delete mp3Stream[nStream];
-			mp3Stream[nStream] = NULL;
-		}
-		
-		strcpy(filename, StreamedNameTable[nFile]);
-		
-		MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
-		ASSERT(stream != NULL);
-		
-		mp3Stream[nStream] = stream;
-		
-		if ( stream->m_bIsOpened )
-		{
-			;
-		}
-		else
-		{
-			delete stream;
-			mp3Stream[nStream] = NULL;
-		}
-	}
-}
-
-void
-cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
-{
-	ASSERT( nStream < MAX_STREAMS );
-	
-	MP3Stream *stream = mp3Stream[nStream];
-	
-	if ( stream )
-	{
-		if ( nPauseFlag != 0 )
-		{
-			if ( !stream->m_bIsPaused )
-			{
-				alSourcePause(stream->m_alSource);
-				stream->m_bIsPaused = true;
-			}
-		}
-		else
-		{
-			if ( stream->m_bIsPaused )
-			{
-				alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
-				alSourcePlay(stream->m_alSource);
-				stream->m_bIsPaused = false;
-			}
-		}
-	}
-}
-
-void
-cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
-{
-	ASSERT( nStream < MAX_STREAMS );
-	
-	MP3Stream *stream = mp3Stream[nStream];
-	
-	if ( stream )
-	{
-		stream->Initialize();
-		if ( stream->m_bIsOpened )
-		{
-			//NOTE: set pos here on mobile
-			
-			if ( stream->FillBuffers() != 0 )
-			{
-				alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
-				alSourcePlay(stream->m_alSource);
-				stream->m_bIsFree = false;
-			}
-		}
-	}
-}
-
-bool
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
-{
-	char filename[256];
-	
-	ASSERT( nStream < MAX_STREAMS );
-	
-	if ( nFile < TOTAL_STREAMED_SOUNDS )
-	{
-		if ( mp3Stream[nStream] )
-		{
-			delete mp3Stream[nStream];
-			mp3Stream[nStream] = NULL;
-		}
-		
-		strcpy(filename, StreamedNameTable[nFile]);
-		
-		MP3Stream *stream = new MP3Stream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
-		ASSERT(stream != NULL);
-		
-		mp3Stream[nStream] = stream;
-		
-		if ( stream->m_bIsOpened )
-		{
-			stream->Initialize();
-			nStreamLength[nFile] = stream->m_nLength;
-			//MusicManager.SetTrackInfoLength(nFile, stream->m_nLength);
-			
-			if ( stream->m_bIsOpened )
-			{
-				if ( nPos != 0 )
-				{
-					stream->SetPos(nPos);
-				}
-				
-				if ( stream->FillBuffers() != 0 )
-				{
-					alSourcef(stream->m_alSource, AL_PITCH, 1.0f);
-					alSourcePlay(stream->m_alSource);
-					stream->m_bIsFree = false;
-				}
-			}
-			
-			return true;
-		}
-		else
-		{
-			delete stream;
-			mp3Stream[nStream] = NULL;
-		}
-	}
-	
-	return false;
-}
-
-void
-cSampleManager::StopStreamedFile(uint8 nStream)
-{
-	ASSERT( nStream < MAX_STREAMS );
-
-	MP3Stream *stream = mp3Stream[nStream];
-	
-	if ( stream )
-	{
-		delete stream;
-		mp3Stream[nStream] = NULL;
-	}
-}
-
-int32
-cSampleManager::GetStreamedFilePosition(uint8 nStream)
-{
-	ASSERT( nStream < MAX_STREAMS );
-	
-	MP3Stream *stream = mp3Stream[nStream];
-	
-	if ( stream )
-	{
-		return (ftell(stream->m_fpFile) * 8) / stream->m_nBitRate;
-	}
-	
-	return 0;
-}
-
-void
-cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
-{
-	ASSERT( nStream < MAX_STREAMS );
-	
-	if ( nVolume > MAX_VOLUME )
-		nVolume = MAX_VOLUME;
-	
-	if ( nPan > MAX_VOLUME )
-		nPan = MAX_VOLUME;
-		
-	nStreamVolume[nStream] = m_nMusicFadeVolume * nVolume;
-	nStreamPan   [nStream] = nPan;
-	
-	MP3Stream *stream = mp3Stream[nStream];
-	
-	if ( stream )
-	{
-		uint32 vol;
-		if ( nEffectFlag )
-			vol = m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14;
-		else
-			vol = m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14;
-		
-		if ( stream->m_nVolume != vol )
-		{
-			if ( stream->m_bIsOpened )
-			{
-				ALuint source = stream->m_alSource;
-				if ( source )
-				{
-					ALfloat gain = ALfloat(vol) / MAX_VOLUME;
-					alSourcef(source, AL_GAIN, gain);
-					stream = mp3Stream[nStream];
-				}
-			}
-			
-			stream->m_nVolume = vol;
-		}
-	}
-}
-
-int32
-cSampleManager::GetStreamedFileLength(uint8 nStream)
-{
-	ASSERT( nStream < TOTAL_STREAMED_SOUNDS );
-
-	return nStreamLength[nStream];
-}
-
-bool
-cSampleManager::IsStreamPlaying(uint8 nStream)
-{
-	ASSERT( nStream < MAX_STREAMS );
-	
-	MP3Stream *stream = mp3Stream[nStream];
-	
-	if ( stream && stream->m_bIsOpened && !stream->m_bIsPaused )
-	{
-		ALint sourceState;
-		alGetSourcei(stream->m_alSource, AL_SOURCE_STATE, &sourceState);
-		if ( !stream->m_bIsFree || sourceState == AL_PLAYING )
-			return true;
-	}
-	
-	return false;
-}
-
-void
-cSampleManager::Service(void)
-{	
-	for ( int32 i = 0; i < MAX_STREAMS; i++ )
-	{
-		if ( mp3Stream[i] )
-			mp3Stream[i]->Update();
-	}
-	
-	UpdateSoundBuffers();
-}
-
-bool
-cSampleManager::InitialiseSampleBanks(void)
-{
-	int32 nBank = SAMPLEBANK_MAIN;
-	
-	fpSampleDescHandle = fopen(SampleBankDescFilename, "rb");
-	if ( fpSampleDescHandle == NULL )
-		return false;
-	
-	fpSampleDataHandle = fopen(SampleBankDataFilename, "rb");
-	if ( fpSampleDataHandle == NULL )
-	{
-		fclose(fpSampleDescHandle);
-		fpSampleDescHandle = NULL;
-		
-		return false;
-	}
-	
-	fseek(fpSampleDataHandle, 0, SEEK_END);
-	int32 _nSampleDataEndOffset = ftell(fpSampleDataHandle);
-	rewind(fpSampleDataHandle);
-	
-	fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle);
-	
-	fclose(fpSampleDescHandle);
-	fpSampleDescHandle = NULL;
-	
-	for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
-	{
-		if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i )
-		{
-			nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
-			nBank++;
-		}
-	}
-
-	nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
-	nSampleBankSize[SAMPLEBANK_PED]  = _nSampleDataEndOffset                      - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
-	
-	return true;
-}
-
-/*
-sub_1D8D40
-PreloadSoundBank(tSample *,uchar)
-CheckOpenALChannels(void)
-*/
-
-void MP3Stream::Initialize(void)
-{
-	if ( !m_bIsOpened )
-		return;
-	
-	mpg123_format_none(m_pMPG);
-	
-	mpg123_format(m_pMPG, 11000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
-	mpg123_format(m_pMPG, 24000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
-	mpg123_format(m_pMPG, 32000, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
-	mpg123_format(m_pMPG, 44100, MPG123_MONO|MPG123_STEREO, MPG123_ENC_SIGNED_16);
-	
-	if ( mpg123_open_feed(m_pMPG) != MPG123_OK )
-		return;
-	
-	const uint32 CHUNK_SIZE = 1024*5;
-	
-	if ( fread(m_pBuf, 1, CHUNK_SIZE, m_fpFile) != CHUNK_SIZE )
-	{
-		Delete();
-		return;
-	}
-	
-	m_nBufSize -= CHUNK_SIZE;
-	
-	mpg123_feed(m_pMPG, m_pBuf, CHUNK_SIZE);
-	
-	if ( mpg123_getformat(m_pMPG, &m_nRate, &m_nChannels, &m_nEncoding) != MPG123_OK )
-	{
-		Delete();
-		return;
-	}
-	
-	mpg123_frameinfo info;
-	if ( mpg123_info(m_pMPG, &info) != MPG123_OK )
-	{
-		Delete();
-		return;
-	}
-	
-	m_nBitRate = info.bitrate;
-	m_nLength = 8 * m_nLengthInBytes / info.bitrate;
-	m_nBlockSize = mpg123_outblock(m_pMPG);
-	m_nNumBlocks = 5;
-	m_pBlocks = (unsigned char *)malloc(m_nNumBlocks * m_nBlockSize);
-}
-
-bool MP3Stream::FillBuffer(ALuint alBuffer)
-{
-	size_t done;
-	
-	uint8 *pBlockBuff = (uint8 *)m_pBlocks;
-	
-	bool fail = !(m_nBufSize > 1); 
-	
-	int err = mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done);
-	if ( alBuffer == 0 )
-	{
-		if ( err == MPG123_OK )
-		{
-			while ( mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done) == MPG123_OK )
-				;
-		}
-		
-		return true;
-	}
-	
-	int32 blocks = 0;
-	for ( blocks = 0; blocks < m_nNumBlocks; blocks++ )
-	{
-		if ( err == MPG123_NEED_MORE )
-		{
-			if ( fail )
-				break;
-			
-			size_t readSize = m_nBufSize;
-			if ( readSize > 0x4000 )
-			{
-				if ( fread(m_pBuf, 1, 0x4000, m_fpFile) != 0x4000 )
-				{
-					fail = true;
-					TRACE("MP3 ************* : MP3 read unsuccessful mid file, stopping queuing");
-					break;
-				}
-				
-				m_nBufSize -= 0x4000;
-				mpg123_feed(m_pMPG, m_pBuf, 0x4000);
-			}
-			else
-			{
-				if ( fread(m_pBuf, 1, readSize, m_fpFile) != readSize )
-				{
-					fail = true;
-					break;
-				}
-				
-				m_nBufSize -= readSize;
-				mpg123_feed(m_pMPG, m_pBuf, readSize);
-			}
-		}
-		else if ( err == MPG123_OK )
-		{
-			pBlockBuff += m_nBlockSize;
-		}
-		else
-		{
-			fail = true;
-			break;
-		}
-		
-		err = mpg123_read(m_pMPG, pBlockBuff, m_nBlockSize, &done);
-	}
-	
-	if ( blocks != 0 )
-	{
-		if ( m_nChannels == 1 )
-			alBufferData(alBuffer, AL_FORMAT_MONO16,   m_pBlocks, m_nBlockSize*blocks, m_nRate);
-		else
-			alBufferData(alBuffer, AL_FORMAT_STEREO16, m_pBlocks, m_nBlockSize*blocks, m_nRate);
-	}
-	
-	if ( fail && blocks < m_nNumBlocks )
-		m_bIsFree = true;
-	
-	return blocks != 0;
-}
-
-void MP3Stream::Update(void)
-{
-	if ( !m_bIsOpened )
-		return;
-	
-	if ( m_bIsFree )
-		return;
-	
-	if ( !m_bIsPaused )
-	{
-		ALint sourceState;
-		ALint buffersProcessed = 0;
-		
-		alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
-		alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
-		
-		ALint looping = AL_FALSE;
-		alGetSourcei(m_alSource, AL_LOOPING, &looping);
-		
-		if ( looping == AL_TRUE )
-		{
-			TRACE("stream set looping");
-			alSourcei(m_alSource, AL_LOOPING, AL_TRUE);
-		}
-		
-		while( buffersProcessed-- )
-		{
-			ALuint buffer;
-			
-			alSourceUnqueueBuffers(m_alSource, 1, &buffer);
-			
-			if ( !m_bIsFree && FillBuffer(buffer) )
-				alSourceQueueBuffers(m_alSource, 1, &buffer);
-		}
-		
-		if ( sourceState != AL_PLAYING )
-		{
-			alSourcef(m_alSource, AL_PITCH, 1.0f);
-			alSourcePlay(m_alSource);
-		}
-	}
-}
-
-void MP3Stream::SetPos(uint32 nPos)
-{
-	uint32 pos = nPos;
-	if ( nPos > m_nLength )
-		pos %= m_nLength;
-	
-	uint32 blockPos = m_nBitRate * pos / 8;
-	if ( blockPos > m_nLengthInBytes )
-		blockPos %= m_nLengthInBytes;
-	
-	fseek(m_fpFile, blockPos, SEEK_SET);
-
-	size_t done;
-	while ( mpg123_read(m_pMPG, m_pBlocks, m_nBlockSize, &done) == MPG123_OK )
-		;
-}
-
-int32 MP3Stream::FillBuffers()
-{
-	int32 i = 0;
-	for ( i = 0; i < ARRAY_SIZE(m_alBuffers); i++ )
-	{
-		if ( !FillBuffer(m_alBuffers[i]) )
-			break;
-		alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]);
-	}
-	
-	return i;
-}
-
-MP3Stream::MP3Stream(char *filename, ALuint source, ALuint *buffers)
-{
-	strcpy(m_aFilename, filename);
-	memset(m_alBuffers, 0, sizeof(m_alBuffers));
-	m_alSource = source;
-	memcpy(m_alBuffers, buffers, sizeof(m_alBuffers));
-	m_nVolume    = -1;
-	m_pBlocks    = NULL;
-	m_pBuf       = NULL;
-	m_pMPG       = NULL;
-	m_bIsPaused  = false;
-	m_bIsOpened  = true;
-	m_bIsFree    = true;
-	m_fpFile     = fopen(m_aFilename, "rb");
-	
-	if ( m_fpFile )
-	{
-		m_nBufSize = filelength(fileno(m_fpFile));
-		m_nLengthInBytes = m_nBufSize;
-		m_pMPG = mpg123_new(NULL, NULL);
-		m_pBuf = (unsigned char *)malloc(0x4000);
-	}
-	else
-	{
-		m_bIsOpened = false;
-		Delete();
-	}
-}
-
-void MP3Stream::Delete()
-{
-	if ( m_pMPG )
-	{
-		mpg123_delete(m_pMPG);
-		m_pMPG = NULL;
-	}
-	
-	if ( m_fpFile )
-	{
-		fclose(m_fpFile);
-		m_fpFile = NULL;
-	}
-	
-	if ( m_alSource )
-	{
-		ALint sourceState = AL_STOPPED;
-		alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
-		if (sourceState != AL_STOPPED )
-			alSourceStop(m_alSource);
-		
-		ALint buffersQueued;
-		alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued);
-
-		ALuint value;
-		while (buffersQueued--)
-			alSourceUnqueueBuffers(m_alSource, 1, &value);
-		
-		m_alSource = 0;
-	}
-	
-	if ( m_pBlocks )
-	{
-		free(m_pBlocks);
-		m_pBlocks = NULL;
-	}
-	
-	if ( m_pBuf )
-	{
-		free(m_pBuf);
-		m_pBuf = NULL;
-	}
-	
-	m_bIsOpened = false;
-}
\ No newline at end of file
diff --git a/src/audio/openal/samp_oal.h b/src/audio/openal/samp_oal.h
deleted file mode 100644
index 8bbdbcc9..00000000
--- a/src/audio/openal/samp_oal.h
+++ /dev/null
@@ -1,340 +0,0 @@
-#pragma once
-#include "common.h"
-#include "AudioSamples.h"
-
-#define MAX_VOLUME 127
-//#define MAX_FREQ                22050
-#define MAX_FREQ                32000
-
-struct tSample {
-	int32 nOffset;
-	uint32 nSize;
-	int32 nFrequency;
-	int32 nLoopStart;
-	int32 nLoopEnd;
-};
-
-enum
-{
-	SAMPLEBANK_MAIN,
-	SAMPLEBANK_PED,
-	MAX_SAMPLEBANKS,
-	SAMPLEBANK_INVALID
-};
-
-#define MAX_PEDSFX                 7
-#define PED_BLOCKSIZE              79000
-
-
-//#define MAXCHANNELS                21 android
-#define MAXCHANNELS                28
-#define MAX2DCHANNELS              1
-#define CHANNEL2D                  MAXCHANNELS
-
-#define MAX_STREAMS             2
-
-struct ALCdevice_struct;
-struct ALCcontext_struct;
-typedef struct ALCdevice_struct ALCdevice;
-typedef struct ALCcontext_struct ALCcontext;
-
-class cSampleManager
-{
-	int field_0;
-	ALCdevice  *m_pDevice;
-	ALCcontext *m_pContext;
-  
-	uint8   m_nEffectsVolume;
-	uint8   m_nMusicVolume;
-	uint8   m_nEffectsFadeVolume;
-	uint8   m_nMusicFadeVolume;
-	uint8   m_nMonoMode;
-	char _pad0[3];
-	tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
-
-public:
-	
-	
-
-	cSampleManager(void);
-	~cSampleManager(void);
-	
-	void SetSpeakerConfig(int32 nConfig);
-	uint32 GetMaximumSupportedChannels(void);
-	
-	uint32 GetNum3DProvidersAvailable();
-	void SetNum3DProvidersAvailable(uint32 num);
-	
-	char *Get3DProviderName(uint8 id);
-	void Set3DProviderName(uint8 id, char *name);
-	
-	int8 GetCurrent3DProviderIndex(void);
-	int8 SetCurrent3DProvider(uint8 which);
-	
-	bool IsMP3RadioChannelAvailable(void);
-	
-	void ReleaseDigitalHandle  (void);
-	void ReacquireDigitalHandle(void);
-	
-	bool Initialise(void);
-	void Terminate (void);
-	
-	void UpdateSoundBuffers(void);
-	
-	bool CheckForAnAudioFileOnCD(void);
-	char GetCDAudioDriveLetter  (void);
-	
-	void UpdateEffectsVolume(void);
-
-	void SetEffectsMasterVolume(uint8 nVolume);
-	void SetMusicMasterVolume  (uint8 nVolume);
-	void SetEffectsFadeVolume  (uint8 nVolume);
-	void SetMusicFadeVolume    (uint8 nVolume);
-	void SetMonoMode           (uint8 nMode);
-	
-	bool LoadSampleBank    (uint8 nBank);
-	void UnloadSampleBank  (uint8 nBank);
-	bool IsSampleBankLoaded(uint8 nBank);
-	
-	bool IsPedCommentLoaded(uint32 nComment);
-	bool LoadPedComment    (uint32 nComment);
-	int32 GetBankContainingSound(uint32 offset);
-
-	int32 _GetPedCommentSlot(uint32 nComment);
-	
-	int32  GetSampleBaseFrequency  (uint32 nSample);
-	int32  GetSampleLoopStartOffset(uint32 nSample);
-	int32  GetSampleLoopEndOffset  (uint32 nSample);
-	uint32 GetSampleLength         (uint32 nSample);
-	
-	bool  UpdateReverb(void);
-	
-	void  SetChannelReverbFlag    (uint32 nChannel, uint8 nReverbFlag);
-	bool  InitialiseChannel       (uint32 nChannel, uint32 nSfx, uint8 nBank);
-	void  SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
-	void  SetChannel3DPosition    (uint32 nChannel, float fX, float fY, float fZ);
-	void  SetChannel3DDistances   (uint32 nChannel, float fMax, float fMin);
-	void  SetChannelVolume        (uint32 nChannel, uint32 nVolume);
-	void  SetChannelPan           (uint32 nChannel, uint32 nPan);
-	void  SetChannelFrequency     (uint32 nChannel, uint32 nFreq);
-	void  SetChannelLoopPoints    (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
-	void  SetChannelLoopCount     (uint32 nChannel, uint32 nLoopCount);
-	bool  GetChannelUsedFlag      (uint32 nChannel);
-	void  StartChannel            (uint32 nChannel);
-	void  StopChannel             (uint32 nChannel);
-	
-	void  PreloadStreamedFile                                     (uint8 nFile, uint8 nStream);
-	void  PauseStream                                        (uint8 nPauseFlag, uint8 nStream);
-	void  StartPreloadedStreamedFile                                           (uint8 nStream);
-	bool  StartStreamedFile                          (uint8 nFile, uint32 nPos, uint8 nStream);
-	void  StopStreamedFile                                                     (uint8 nStream);
-	int32 GetStreamedFilePosition                                              (uint8 nStream);
-	void  SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
-	int32 GetStreamedFileLength                                                (uint8 nStream);
-	bool  IsStreamPlaying                                                      (uint8 nStream);
-	void  Service(void);
-	bool  InitialiseSampleBanks(void);
-};
-
-extern cSampleManager SampleManager;
-extern int32 BankStartOffset[MAX_SAMPLEBANKS];
-
-static char StreamedNameTable[][25]=
-{
-	"AUDIO\\HEAD.MP3",
-	"AUDIO\\CLASS.MP3",
-	"AUDIO\\KJAH.MP3",
-	"AUDIO\\RISE.MP3",
-	"AUDIO\\LIPS.MP3",
-	"AUDIO\\GAME.MP3",
-	"AUDIO\\MSX.MP3",
-	"AUDIO\\FLASH.MP3",
-	"AUDIO\\CHAT.MP3",
-	"AUDIO\\HEAD.MP3",
-	"AUDIO\\POLICE.MP3",
-	"AUDIO\\CITY.MP3",
-	"AUDIO\\WATER.MP3",
-	"AUDIO\\COMOPEN.MP3",
-	"AUDIO\\SUBOPEN.MP3",
-	"AUDIO\\JB.MP3",
-	"AUDIO\\BET.MP3",
-	"AUDIO\\L1_LG.MP3",
-	"AUDIO\\L2_DSB.MP3",
-	"AUDIO\\L3_DM.MP3",
-	"AUDIO\\L4_PAP.MP3",
-	"AUDIO\\L5_TFB.MP3",
-	"AUDIO\\J0_DM2.MP3",
-	"AUDIO\\J1_LFL.MP3",
-	"AUDIO\\J2_KCL.MP3",
-	"AUDIO\\J3_VH.MP3",
-	"AUDIO\\J4_ETH.MP3",
-	"AUDIO\\J5_DST.MP3",
-	"AUDIO\\J6_TBJ.MP3",
-	"AUDIO\\T1_TOL.MP3",
-	"AUDIO\\T2_TPU.MP3",
-	"AUDIO\\T3_MAS.MP3",
-	"AUDIO\\T4_TAT.MP3",
-	"AUDIO\\T5_BF.MP3",
-	"AUDIO\\S0_MAS.MP3",
-	"AUDIO\\S1_PF.MP3",
-	"AUDIO\\S2_CTG.MP3",
-	"AUDIO\\S3_RTC.MP3",
-	"AUDIO\\S5_LRQ.MP3",
-	"AUDIO\\S4_BDBA.MP3",
-	"AUDIO\\S4_BDBB.MP3",
-	"AUDIO\\S2_CTG2.MP3",
-	"AUDIO\\S4_BDBD.MP3",
-	"AUDIO\\S5_LRQB.MP3",
-	"AUDIO\\S5_LRQC.MP3",
-	"AUDIO\\A1_SSO.MP3",
-	"AUDIO\\A2_PP.MP3",
-	"AUDIO\\A3_SS.MP3",
-	"AUDIO\\A4_PDR.MP3",
-	"AUDIO\\A5_K2FT.MP3",
-	"AUDIO\\K1_KBO.MP3",
-	"AUDIO\\K2_GIS.MP3",
-	"AUDIO\\K3_DS.MP3",
-	"AUDIO\\K4_SHI.MP3",
-	"AUDIO\\K5_SD.MP3",
-	"AUDIO\\R0_PDR2.MP3",
-	"AUDIO\\R1_SW.MP3",
-	"AUDIO\\R2_AP.MP3",
-	"AUDIO\\R3_ED.MP3",
-	"AUDIO\\R4_GF.MP3",
-	"AUDIO\\R5_PB.MP3",
-	"AUDIO\\R6_MM.MP3",
-	"AUDIO\\D1_STOG.MP3",
-	"AUDIO\\D2_KK.MP3",
-	"AUDIO\\D3_ADO.MP3",
-	"AUDIO\\D5_ES.MP3",
-	"AUDIO\\D7_MLD.MP3",
-	"AUDIO\\D4_GTA.MP3",
-	"AUDIO\\D4_GTA2.MP3",
-	"AUDIO\\D6_STS.MP3",
-	"AUDIO\\A6_BAIT.MP3",
-	"AUDIO\\A7_ETG.MP3",
-	"AUDIO\\A8_PS.MP3",
-	"AUDIO\\A9_ASD.MP3",
-	"AUDIO\\K4_SHI2.MP3",
-	"AUDIO\\C1_TEX.MP3",
-	"AUDIO\\EL_PH1.MP3",
-	"AUDIO\\EL_PH2.MP3",
-	"AUDIO\\EL_PH3.MP3",
-	"AUDIO\\EL_PH4.MP3",
-	"AUDIO\\YD_PH1.MP3",
-	"AUDIO\\YD_PH2.MP3",
-	"AUDIO\\YD_PH3.MP3",
-	"AUDIO\\YD_PH4.MP3",
-	"AUDIO\\HD_PH1.MP3",
-	"AUDIO\\HD_PH2.MP3",
-	"AUDIO\\HD_PH3.MP3",
-	"AUDIO\\HD_PH4.MP3",
-	"AUDIO\\HD_PH5.MP3",
-	"AUDIO\\MT_PH1.MP3",
-	"AUDIO\\MT_PH2.MP3",
-	"AUDIO\\MT_PH3.MP3",
-	"AUDIO\\MT_PH4.MP3",
-	"AUDIO\\MISCOM.MP3",
-	"AUDIO\\END.MP3",
-	"AUDIO\\lib_a1.MP3",
-	"AUDIO\\lib_a2.MP3",
-	"AUDIO\\lib_a.MP3",
-	"AUDIO\\lib_b.MP3",
-	"AUDIO\\lib_c.MP3",
-	"AUDIO\\lib_d.MP3",
-	"AUDIO\\l2_a.MP3",
-	"AUDIO\\j4t_1.MP3",
-	"AUDIO\\j4t_2.MP3",
-	"AUDIO\\j4t_3.MP3",
-	"AUDIO\\j4t_4.MP3",
-	"AUDIO\\j4_a.MP3",
-	"AUDIO\\j4_b.MP3",
-	"AUDIO\\j4_c.MP3",
-	"AUDIO\\j4_d.MP3",
-	"AUDIO\\j4_e.MP3",
-	"AUDIO\\j4_f.MP3",
-	"AUDIO\\j6_1.MP3",
-	"AUDIO\\j6_a.MP3",
-	"AUDIO\\j6_b.MP3",
-	"AUDIO\\j6_c.MP3",
-	"AUDIO\\j6_d.MP3",
-	"AUDIO\\t4_a.MP3",
-	"AUDIO\\s1_a.MP3",
-	"AUDIO\\s1_a1.MP3",
-	"AUDIO\\s1_b.MP3",
-	"AUDIO\\s1_c.MP3",
-	"AUDIO\\s1_c1.MP3",
-	"AUDIO\\s1_d.MP3",
-	"AUDIO\\s1_e.MP3",
-	"AUDIO\\s1_f.MP3",
-	"AUDIO\\s1_g.MP3",
-	"AUDIO\\s1_h.MP3",
-	"AUDIO\\s1_i.MP3",
-	"AUDIO\\s1_j.MP3",
-	"AUDIO\\s1_k.MP3",
-	"AUDIO\\s1_l.MP3",
-	"AUDIO\\s3_a.MP3",
-	"AUDIO\\s3_b.MP3",
-	"AUDIO\\el3_a.MP3",
-	"AUDIO\\mf1_a.MP3",
-	"AUDIO\\mf2_a.MP3",
-	"AUDIO\\mf3_a.MP3",
-	"AUDIO\\mf3_b.MP3",
-	"AUDIO\\mf3_b1.MP3",
-	"AUDIO\\mf3_c.MP3",
-	"AUDIO\\mf4_a.MP3",
-	"AUDIO\\mf4_b.MP3",
-	"AUDIO\\mf4_c.MP3",
-	"AUDIO\\a1_a.MP3",
-	"AUDIO\\a3_a.MP3",
-	"AUDIO\\a5_a.MP3",
-	"AUDIO\\a4_a.MP3",
-	"AUDIO\\a4_b.MP3",
-	"AUDIO\\a4_c.MP3",
-	"AUDIO\\a4_d.MP3",
-	"AUDIO\\k1_a.MP3",
-	"AUDIO\\k3_a.MP3",
-	"AUDIO\\r1_a.MP3",
-	"AUDIO\\r2_a.MP3",
-	"AUDIO\\r2_b.MP3",
-	"AUDIO\\r2_c.MP3",
-	"AUDIO\\r2_d.MP3",
-	"AUDIO\\r2_e.MP3",
-	"AUDIO\\r2_f.MP3",
-	"AUDIO\\r2_g.MP3",
-	"AUDIO\\r2_h.MP3",
-	"AUDIO\\r5_a.MP3",
-	"AUDIO\\r6_a.MP3",
-	"AUDIO\\r6_a1.MP3",
-	"AUDIO\\r6_b.MP3",
-	"AUDIO\\lo2_a.MP3",
-	"AUDIO\\lo6_a.MP3",
-	"AUDIO\\yd2_a.MP3",
-	"AUDIO\\yd2_b.MP3",
-	"AUDIO\\yd2_c.MP3",
-	"AUDIO\\yd2_c1.MP3",
-	"AUDIO\\yd2_d.MP3",
-	"AUDIO\\yd2_e.MP3",
-	"AUDIO\\yd2_f.MP3",
-	"AUDIO\\yd2_g.MP3",
-	"AUDIO\\yd2_h.MP3",
-	"AUDIO\\yd2_ass.MP3",
-	"AUDIO\\yd2_ok.MP3",
-	"AUDIO\\h5_a.MP3",
-	"AUDIO\\h5_b.MP3",
-	"AUDIO\\h5_c.MP3",
-	"AUDIO\\ammu_a.MP3",
-	"AUDIO\\ammu_b.MP3",
-	"AUDIO\\ammu_c.MP3",
-	"AUDIO\\door_1.MP3",
-	"AUDIO\\door_2.MP3",
-	"AUDIO\\door_3.MP3",
-	"AUDIO\\door_4.MP3",
-	"AUDIO\\door_5.MP3",
-	"AUDIO\\door_6.MP3",
-	"AUDIO\\t3_a.MP3",
-	"AUDIO\\t3_b.MP3",
-	"AUDIO\\t3_c.MP3",
-	"AUDIO\\k1_b.MP3",
-	"AUDIO\\cat1.MP3"
-};
diff --git a/src/audio/sampman.cpp b/src/audio/sampman.cpp
deleted file mode 100644
index aa6b67dc..00000000
--- a/src/audio/sampman.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-#include "common.h"
-#ifndef OPENAL
-#include "miles\sampman_mss.cpp"
-#else
-#include "openal\samp_oal.cpp"
-#endif
\ No newline at end of file
diff --git a/src/audio/sampman.h b/src/audio/sampman.h
index f454d236..d3c82943 100644
--- a/src/audio/sampman.h
+++ b/src/audio/sampman.h
@@ -1,7 +1,345 @@
 #pragma once
 #include "common.h"
-#ifndef OPENAL
-#include "miles\sampman_mss.h"
-#else
-#include "openal\samp_oal.h"
-#endif
\ No newline at end of file
+#include "AudioSamples.h"
+
+#define MAX_VOLUME 127
+#define MAX_FREQ   22050
+
+struct tSample {
+	int32 nOffset;
+	uint32 nSize;
+	int32 nFrequency;
+	int32 nLoopStart;
+	int32 nLoopEnd;
+};
+
+enum
+{
+	SAMPLEBANK_MAIN,
+	SAMPLEBANK_PED,
+	MAX_SAMPLEBANKS,
+	SAMPLEBANK_INVALID
+};
+
+#define MAX_PEDSFX                 7
+#define PED_BLOCKSIZE              79000
+
+#define MAXPROVIDERS               64
+
+#define MAXCHANNELS                28
+#define MAXCHANNELS_SURROUND       24
+#define MAX2DCHANNELS              1
+#define CHANNEL2D                  MAXCHANNELS
+
+#define MAX_STREAMS                2
+
+#define DIGITALRATE                32000
+#define DIGITALBITS                16
+#define DIGITALCHANNELS            2
+
+#define MAX_DIGITAL_MIXER_CHANNELS 32
+
+class cSampleManager
+{
+	uint8   m_nEffectsVolume;
+	uint8   m_nMusicVolume;
+	uint8   m_nEffectsFadeVolume;
+	uint8   m_nMusicFadeVolume;
+	uint8   m_nMonoMode;
+	char	unk;
+	char    m_szCDRomRootPath[80];
+	bool    m_bInitialised;
+	uint8   m_nNumberOfProviders;
+	char   *m_aAudioProviders[MAXPROVIDERS];
+	tSample m_aSamples[TOTAL_AUDIO_SAMPLES];
+
+public:
+	
+	
+
+	cSampleManager(void);
+	~cSampleManager(void);
+	
+	void SetSpeakerConfig(int32 nConfig);
+	uint32 GetMaximumSupportedChannels(void);
+	
+	uint32 GetNum3DProvidersAvailable(void);
+	void SetNum3DProvidersAvailable(uint32 num);
+	
+	char *Get3DProviderName(uint8 id);
+	void Set3DProviderName(uint8 id, char *name);
+	
+	int8 GetCurrent3DProviderIndex(void);
+	int8 SetCurrent3DProvider(uint8 which);
+	
+	bool IsMP3RadioChannelAvailable(void);
+	
+	void ReleaseDigitalHandle  (void);
+	void ReacquireDigitalHandle(void);
+	
+	bool Initialise(void);
+	void Terminate (void);
+	
+#ifdef AUDIO_OAL
+	void UpdateSoundBuffers(void);
+#endif
+	
+	bool CheckForAnAudioFileOnCD(void);
+	char GetCDAudioDriveLetter  (void);
+	
+	void UpdateEffectsVolume(void);
+
+	void SetEffectsMasterVolume(uint8 nVolume);
+	void SetMusicMasterVolume  (uint8 nVolume);
+	void SetEffectsFadeVolume  (uint8 nVolume);
+	void SetMusicFadeVolume    (uint8 nVolume);
+	void SetMonoMode           (uint8 nMode);
+	
+	bool LoadSampleBank    (uint8 nBank);
+	void UnloadSampleBank  (uint8 nBank);
+	bool IsSampleBankLoaded(uint8 nBank);
+	
+	bool IsPedCommentLoaded(uint32 nComment);
+	bool LoadPedComment    (uint32 nComment);
+	int32 GetBankContainingSound(uint32 offset);
+
+	int32 _GetPedCommentSlot(uint32 nComment);
+	
+	int32  GetSampleBaseFrequency  (uint32 nSample);
+	int32  GetSampleLoopStartOffset(uint32 nSample);
+	int32  GetSampleLoopEndOffset  (uint32 nSample);
+	uint32 GetSampleLength         (uint32 nSample);
+	
+	bool  UpdateReverb(void);
+	
+	void  SetChannelReverbFlag    (uint32 nChannel, uint8 nReverbFlag);
+	bool  InitialiseChannel       (uint32 nChannel, uint32 nSfx, uint8 nBank);
+	void  SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume);
+	void  SetChannel3DPosition    (uint32 nChannel, float fX, float fY, float fZ);
+	void  SetChannel3DDistances   (uint32 nChannel, float fMax, float fMin);
+	void  SetChannelVolume        (uint32 nChannel, uint32 nVolume);
+	void  SetChannelPan           (uint32 nChannel, uint32 nPan);
+	void  SetChannelFrequency     (uint32 nChannel, uint32 nFreq);
+	void  SetChannelLoopPoints    (uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd);
+	void  SetChannelLoopCount     (uint32 nChannel, uint32 nLoopCount);
+	bool  GetChannelUsedFlag      (uint32 nChannel);
+	void  StartChannel            (uint32 nChannel);
+	void  StopChannel             (uint32 nChannel);
+	
+	void  PreloadStreamedFile                                     (uint8 nFile, uint8 nStream);
+	void  PauseStream                                        (uint8 nPauseFlag, uint8 nStream);
+	void  StartPreloadedStreamedFile                                           (uint8 nStream);
+	bool  StartStreamedFile                          (uint8 nFile, uint32 nPos, uint8 nStream);
+	void  StopStreamedFile                                                     (uint8 nStream);
+	int32 GetStreamedFilePosition                                              (uint8 nStream);
+	void  SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
+	int32 GetStreamedFileLength                                                (uint8 nStream);
+	bool  IsStreamPlaying                                                      (uint8 nStream);
+#ifdef AUDIO_OAL
+	void  Service(void);
+#endif
+	bool  InitialiseSampleBanks(void);
+};
+
+extern cSampleManager SampleManager;
+extern uint32 BankStartOffset[MAX_SAMPLEBANKS];
+
+static char StreamedNameTable[][25]=
+{
+	"AUDIO\\HEAD.WAV",
+	"AUDIO\\CLASS.WAV",
+	"AUDIO\\KJAH.WAV",
+	"AUDIO\\RISE.WAV",
+	"AUDIO\\LIPS.WAV",
+	"AUDIO\\GAME.WAV",
+	"AUDIO\\MSX.WAV",
+	"AUDIO\\FLASH.WAV",
+	"AUDIO\\CHAT.WAV",
+	"AUDIO\\HEAD.WAV",
+	"AUDIO\\POLICE.WAV",
+	"AUDIO\\CITY.WAV",
+	"AUDIO\\WATER.WAV",
+	"AUDIO\\COMOPEN.WAV",
+	"AUDIO\\SUBOPEN.WAV",
+	"AUDIO\\JB.MP3",
+	"AUDIO\\BET.MP3",
+	"AUDIO\\L1_LG.MP3",
+	"AUDIO\\L2_DSB.MP3",
+	"AUDIO\\L3_DM.MP3",
+	"AUDIO\\L4_PAP.MP3",
+	"AUDIO\\L5_TFB.MP3",
+	"AUDIO\\J0_DM2.MP3",
+	"AUDIO\\J1_LFL.MP3",
+	"AUDIO\\J2_KCL.MP3",
+	"AUDIO\\J3_VH.MP3",
+	"AUDIO\\J4_ETH.MP3",
+	"AUDIO\\J5_DST.MP3",
+	"AUDIO\\J6_TBJ.MP3",
+	"AUDIO\\T1_TOL.MP3",
+	"AUDIO\\T2_TPU.MP3",
+	"AUDIO\\T3_MAS.MP3",
+	"AUDIO\\T4_TAT.MP3",
+	"AUDIO\\T5_BF.MP3",
+	"AUDIO\\S0_MAS.MP3",
+	"AUDIO\\S1_PF.MP3",
+	"AUDIO\\S2_CTG.MP3",
+	"AUDIO\\S3_RTC.MP3",
+	"AUDIO\\S5_LRQ.MP3",
+	"AUDIO\\S4_BDBA.MP3",
+	"AUDIO\\S4_BDBB.MP3",
+	"AUDIO\\S2_CTG2.MP3",
+	"AUDIO\\S4_BDBD.MP3",
+	"AUDIO\\S5_LRQB.MP3",
+	"AUDIO\\S5_LRQC.MP3",
+	"AUDIO\\A1_SSO.WAV",
+	"AUDIO\\A2_PP.WAV",
+	"AUDIO\\A3_SS.WAV",
+	"AUDIO\\A4_PDR.WAV",
+	"AUDIO\\A5_K2FT.WAV",
+	"AUDIO\\K1_KBO.MP3",
+	"AUDIO\\K2_GIS.MP3",
+	"AUDIO\\K3_DS.MP3",
+	"AUDIO\\K4_SHI.MP3",
+	"AUDIO\\K5_SD.MP3",
+	"AUDIO\\R0_PDR2.MP3",
+	"AUDIO\\R1_SW.MP3",
+	"AUDIO\\R2_AP.MP3",
+	"AUDIO\\R3_ED.MP3",
+	"AUDIO\\R4_GF.MP3",
+	"AUDIO\\R5_PB.MP3",
+	"AUDIO\\R6_MM.MP3",
+	"AUDIO\\D1_STOG.MP3",
+	"AUDIO\\D2_KK.MP3",
+	"AUDIO\\D3_ADO.MP3",
+	"AUDIO\\D5_ES.MP3",
+	"AUDIO\\D7_MLD.MP3",
+	"AUDIO\\D4_GTA.MP3",
+	"AUDIO\\D4_GTA2.MP3",
+	"AUDIO\\D6_STS.MP3",
+	"AUDIO\\A6_BAIT.WAV",
+	"AUDIO\\A7_ETG.WAV",
+	"AUDIO\\A8_PS.WAV",
+	"AUDIO\\A9_ASD.WAV",
+	"AUDIO\\K4_SHI2.MP3",
+	"AUDIO\\C1_TEX.MP3",
+	"AUDIO\\EL_PH1.MP3",
+	"AUDIO\\EL_PH2.MP3",
+	"AUDIO\\EL_PH3.MP3",
+	"AUDIO\\EL_PH4.MP3",
+	"AUDIO\\YD_PH1.MP3",
+	"AUDIO\\YD_PH2.MP3",
+	"AUDIO\\YD_PH3.MP3",
+	"AUDIO\\YD_PH4.MP3",
+	"AUDIO\\HD_PH1.MP3",
+	"AUDIO\\HD_PH2.MP3",
+	"AUDIO\\HD_PH3.MP3",
+	"AUDIO\\HD_PH4.MP3",
+	"AUDIO\\HD_PH5.MP3",
+	"AUDIO\\MT_PH1.MP3",
+	"AUDIO\\MT_PH2.MP3",
+	"AUDIO\\MT_PH3.MP3",
+	"AUDIO\\MT_PH4.MP3",
+	"AUDIO\\MISCOM.WAV",
+	"AUDIO\\END.MP3",
+	"AUDIO\\lib_a1.WAV",
+	"AUDIO\\lib_a2.WAV",
+	"AUDIO\\lib_a.WAV",
+	"AUDIO\\lib_b.WAV",
+	"AUDIO\\lib_c.WAV",
+	"AUDIO\\lib_d.WAV",
+	"AUDIO\\l2_a.WAV",
+	"AUDIO\\j4t_1.WAV",
+	"AUDIO\\j4t_2.WAV",
+	"AUDIO\\j4t_3.WAV",
+	"AUDIO\\j4t_4.WAV",
+	"AUDIO\\j4_a.WAV",
+	"AUDIO\\j4_b.WAV",
+	"AUDIO\\j4_c.WAV",
+	"AUDIO\\j4_d.WAV",
+	"AUDIO\\j4_e.WAV",
+	"AUDIO\\j4_f.WAV",
+	"AUDIO\\j6_1.WAV",
+	"AUDIO\\j6_a.WAV",
+	"AUDIO\\j6_b.WAV",
+	"AUDIO\\j6_c.WAV",
+	"AUDIO\\j6_d.WAV",
+	"AUDIO\\t4_a.WAV",
+	"AUDIO\\s1_a.WAV",
+	"AUDIO\\s1_a1.WAV",
+	"AUDIO\\s1_b.WAV",
+	"AUDIO\\s1_c.WAV",
+	"AUDIO\\s1_c1.WAV",
+	"AUDIO\\s1_d.WAV",
+	"AUDIO\\s1_e.WAV",
+	"AUDIO\\s1_f.WAV",
+	"AUDIO\\s1_g.WAV",
+	"AUDIO\\s1_h.WAV",
+	"AUDIO\\s1_i.WAV",
+	"AUDIO\\s1_j.WAV",
+	"AUDIO\\s1_k.WAV",
+	"AUDIO\\s1_l.WAV",
+	"AUDIO\\s3_a.WAV",
+	"AUDIO\\s3_b.WAV",
+	"AUDIO\\el3_a.WAV",
+	"AUDIO\\mf1_a.WAV",
+	"AUDIO\\mf2_a.WAV",
+	"AUDIO\\mf3_a.WAV",
+	"AUDIO\\mf3_b.WAV",
+	"AUDIO\\mf3_b1.WAV",
+	"AUDIO\\mf3_c.WAV",
+	"AUDIO\\mf4_a.WAV",
+	"AUDIO\\mf4_b.WAV",
+	"AUDIO\\mf4_c.WAV",
+	"AUDIO\\a1_a.WAV",
+	"AUDIO\\a3_a.WAV",
+	"AUDIO\\a5_a.WAV",
+	"AUDIO\\a4_a.WAV",
+	"AUDIO\\a4_b.WAV",
+	"AUDIO\\a4_c.WAV",
+	"AUDIO\\a4_d.WAV",
+	"AUDIO\\k1_a.WAV",
+	"AUDIO\\k3_a.WAV",
+	"AUDIO\\r1_a.WAV",
+	"AUDIO\\r2_a.WAV",
+	"AUDIO\\r2_b.WAV",
+	"AUDIO\\r2_c.WAV",
+	"AUDIO\\r2_d.WAV",
+	"AUDIO\\r2_e.WAV",
+	"AUDIO\\r2_f.WAV",
+	"AUDIO\\r2_g.WAV",
+	"AUDIO\\r2_h.WAV",
+	"AUDIO\\r5_a.WAV",
+	"AUDIO\\r6_a.WAV",
+	"AUDIO\\r6_a1.WAV",
+	"AUDIO\\r6_b.WAV",
+	"AUDIO\\lo2_a.WAV",
+	"AUDIO\\lo6_a.WAV",
+	"AUDIO\\yd2_a.WAV",
+	"AUDIO\\yd2_b.WAV",
+	"AUDIO\\yd2_c.WAV",
+	"AUDIO\\yd2_c1.WAV",
+	"AUDIO\\yd2_d.WAV",
+	"AUDIO\\yd2_e.WAV",
+	"AUDIO\\yd2_f.WAV",
+	"AUDIO\\yd2_g.WAV",
+	"AUDIO\\yd2_h.WAV",
+	"AUDIO\\yd2_ass.WAV",
+	"AUDIO\\yd2_ok.WAV",
+	"AUDIO\\h5_a.WAV",
+	"AUDIO\\h5_b.WAV",
+	"AUDIO\\h5_c.WAV",
+	"AUDIO\\ammu_a.WAV",
+	"AUDIO\\ammu_b.WAV",
+	"AUDIO\\ammu_c.WAV",
+	"AUDIO\\door_1.WAV",
+	"AUDIO\\door_2.WAV",
+	"AUDIO\\door_3.WAV",
+	"AUDIO\\door_4.WAV",
+	"AUDIO\\door_5.WAV",
+	"AUDIO\\door_6.WAV",
+	"AUDIO\\t3_a.WAV",
+	"AUDIO\\t3_b.WAV",
+	"AUDIO\\t3_c.WAV",
+	"AUDIO\\k1_b.WAV",
+	"AUDIO\\cat1.WAV"
+};
diff --git a/src/audio/miles/sampman_mss.cpp b/src/audio/sampman_miles.cpp
similarity index 97%
rename from src/audio/miles/sampman_mss.cpp
rename to src/audio/sampman_miles.cpp
index f3a6ba80..caf2917f 100644
--- a/src/audio/miles/sampman_mss.cpp
+++ b/src/audio/sampman_miles.cpp
@@ -1,3 +1,6 @@
+#include "common.h"
+
+#ifdef AUDIO_MSS
 #include <windows.h>
 #include <shobjidl.h>
 #include <shlguid.h>
@@ -8,7 +11,7 @@
 #include "eax-util.h"
 #include "mss.h"
 
-#include "sampman_mss.h"
+#include "sampman.h"
 #include "AudioManager.h"
 #include "MusicManager.h"
 #include "Frontend.h"
@@ -18,7 +21,7 @@
 #pragma comment( lib, "mss32.lib" )
 
 cSampleManager SampleManager;
-int32 BankStartOffset[MAX_SAMPLEBANKS];
+uint32 BankStartOffset[MAX_SAMPLEBANKS];
 ///////////////////////////////////////////////////////////////
 
 char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
@@ -55,9 +58,9 @@ struct tMP3Entry
 uint32 nNumMP3s;
 tMP3Entry *_pMP3List;
 char _mp3DirectoryPath[MAX_PATH];
-HSTREAM mp3Stream [MAX_MP3STREAMS];
-int8 nStreamPan   [MAX_MP3STREAMS];
-int8 nStreamVolume[MAX_MP3STREAMS];
+HSTREAM mp3Stream [MAX_STREAMS];
+int8 nStreamPan   [MAX_STREAMS];
+int8 nStreamVolume[MAX_STREAMS];
 uint32 _CurMP3Index;
 int32 _CurMP3Pos;
 bool _bIsMp3Active;
@@ -261,6 +264,17 @@ set_new_provider(S32 index)
 	return false;
 }
 
+cSampleManager::cSampleManager(void) : 
+	m_nNumberOfProviders(0)
+{
+	;
+}
+
+cSampleManager::~cSampleManager(void)
+{
+	
+}
+
 void
 cSampleManager::SetSpeakerConfig(int32 which)
 {
@@ -296,6 +310,26 @@ cSampleManager::GetMaximumSupportedChannels(void)
 	return _maxSamples;
 }
 
+uint32 cSampleManager::GetNum3DProvidersAvailable()
+{
+	return m_nNumberOfProviders;
+}
+
+void cSampleManager::SetNum3DProvidersAvailable(uint32 num)
+{
+	m_nNumberOfProviders = num;
+}
+	
+char *cSampleManager::Get3DProviderName(uint8 id)
+{
+	return m_aAudioProviders[id];
+}
+
+void cSampleManager::Set3DProviderName(uint8 id, char *name)
+{
+	m_aAudioProviders[id] = name;
+}
+
 int8
 cSampleManager::GetCurrent3DProviderIndex(void)
 {
@@ -1084,7 +1118,7 @@ cSampleManager::Initialise(void)
 	
 	TRACE("stream");
 	{
-		for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
+		for ( int32 i = 0; i < MAX_STREAMS; i++ )
 		{
 			mp3Stream    [i] = NULL;
 			nStreamPan   [i] = 63;
@@ -1199,7 +1233,7 @@ cSampleManager::Initialise(void)
 void
 cSampleManager::Terminate(void)
 {
-	for ( int32 i = 0; i < MAX_MP3STREAMS; i++ )
+	for ( int32 i = 0; i < MAX_STREAMS; i++ )
 	{
 		if ( mp3Stream[i] )
 		{
@@ -1366,6 +1400,12 @@ cSampleManager::SetMusicFadeVolume(uint8 nVolume)
 	m_nMusicFadeVolume = nVolume;
 }
 
+void
+cSampleManager::SetMonoMode(uint8 nMode)
+{
+	m_nMonoMode = nMode;
+}
+
 bool
 cSampleManager::LoadSampleBank(uint8 nBank)
 {
@@ -1475,6 +1515,18 @@ cSampleManager::LoadPedComment(uint32 nComment)
 	return true;
 }
 
+int32
+cSampleManager::GetBankContainingSound(uint32 offset)
+{
+	if ( offset >= BankStartOffset[SAMPLEBANK_PED] )
+		return SAMPLEBANK_PED;
+	
+	if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] )
+		return SAMPLEBANK_MAIN;
+	
+	return SAMPLEBANK_INVALID;
+}
+
 int32
 cSampleManager::GetSampleBaseFrequency(uint32 nSample)
 {
@@ -1664,7 +1716,7 @@ cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
 			OutputDebugString(AIL_last_error());
 			return false;
 		}
-			
+		
 		return true;
 	}
 }
@@ -2255,3 +2307,5 @@ cSampleManager::InitialiseSampleBanks(void)
 	
 	return true;
 }
+
+#endif
\ No newline at end of file
diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp
new file mode 100644
index 00000000..3eb296ae
--- /dev/null
+++ b/src/audio/sampman_oal.cpp
@@ -0,0 +1,1372 @@
+#include "common.h"
+//#define JUICY_OAL
+
+#ifdef AUDIO_OAL
+#include "sampman.h"
+
+#include <time.h>
+#include <io.h>
+
+#include "eax.h"
+#include "eax-util.h"
+
+#include <AL/al.h>
+#include <AL/alc.h>
+#include <AL/alext.h>
+#include <AL/efx.h>
+#include <AL/efx-presets.h>
+
+#include "oal/oal_utils.h"
+#include "oal/aldlist.h"
+#include "oal/channel.h"
+#include "oal/stream.h"
+
+#include "AudioManager.h"
+#include "MusicManager.h"
+#include "Frontend.h"
+#include "Timer.h"
+
+//todo max channals
+//todo queue
+//todo loop count
+//todo mp3/wav stream
+//todo mp3 player
+
+#pragma comment( lib, "OpenAL32.lib" )
+
+cSampleManager SampleManager;
+bool _bSampmanInitialised = false;
+
+uint32 BankStartOffset[MAX_SAMPLEBANKS];
+
+int           prevprovider=-1;
+int           curprovider=-1;
+int           usingEAX=0;
+int           usingEAX3=0;
+//int         speaker_type=0;
+ALCdevice    *ALDevice = NULL;
+ALCcontext   *ALContext = NULL;
+unsigned int _maxSamples;
+float        _fPrevEaxRatioDestination;
+bool         _usingEFX;
+float        _fEffectsLevel;
+ALuint       ALEffect = AL_EFFECT_NULL;
+ALuint       ALEffectSlot = AL_EFFECTSLOT_NULL;
+struct
+{
+	std::string id;
+	char name[256];
+	int sources;
+}providers[MAXPROVIDERS];
+
+int defaultProvider;
+
+
+char SampleBankDescFilename[] = "AUDIO\\SFX.SDT";
+char SampleBankDataFilename[] = "AUDIO\\SFX.RAW";
+
+FILE *fpSampleDescHandle;
+FILE *fpSampleDataHandle;
+bool  bSampleBankLoaded            [MAX_SAMPLEBANKS];
+int32 nSampleBankDiscStartOffset   [MAX_SAMPLEBANKS];
+int32 nSampleBankSize              [MAX_SAMPLEBANKS];
+int32 nSampleBankMemoryStartAddress[MAX_SAMPLEBANKS];
+int32 _nSampleDataEndOffset;
+
+int32 nPedSlotSfx    [MAX_PEDSFX];
+int32 nPedSlotSfxAddr[MAX_PEDSFX];
+uint8 nCurrentPedSlot;
+
+ALuint pedBuffers[MAX_PEDSFX];
+
+CChannel aChannel[MAXCHANNELS+MAX2DCHANNELS];
+uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
+
+uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
+ALuint ALStreamSources[MAX_STREAMS];
+ALuint ALStreamBuffers[MAX_STREAMS][NUM_STREAMBUFFERS];
+struct
+{
+	ALuint buffer;
+	ALuint timer;
+}ALBuffers[SAMPLEBANK_MAX];
+
+uint32     nNumMP3s;
+CStream    *aStream[MAX_STREAMS];
+uint8      nStreamPan   [MAX_STREAMS];
+uint8      nStreamVolume[MAX_STREAMS];
+
+///////////////////////////////////////////////////////////////
+//	Env		Size	Diffus	Room	RoomHF	RoomLF	DecTm	DcHF	DcLF	Refl	RefDel	Ref Pan				Revb	RevDel		Rev Pan				EchTm	EchDp	ModTm	ModDp	AirAbs	HFRef		LFRef	RRlOff	FLAGS
+EAXLISTENERPROPERTIES StartEAX3 =
+	{26,	1.7f,	0.8f,	-1000,	-1000,	-100,	4.42f,	0.14f,	1.00f,	429,	0.014f,	0.00f,0.00f,0.00f,	1023,	0.021f,		0.00f,0.00f,0.00f,	0.250f,	0.000f,	0.250f,	0.000f,	-5.0f,	2727.1f,	250.0f,	0.00f,	0x3f };
+
+EAXLISTENERPROPERTIES FinishEAX3 =
+	{26,	100.0f,	1.0f,	0,		-1000,	-2200,	20.0f,	1.39f,	1.00f,	1000,	0.069f,	0.00f,0.00f,0.00f,	400,	0.100f,		0.00f,0.00f,0.00f,	0.250f,	1.000f,	3.982f,	0.000f,	-18.0f,	3530.8f,	417.9f,	6.70f,	0x3f };
+
+EAXLISTENERPROPERTIES EAX3Params;
+
+
+bool IsFXSupported()
+{
+	return usingEAX || usingEAX3 || _usingEFX;
+}
+
+void EAX_SetAll(const EAXLISTENERPROPERTIES *allparameters)
+{
+	if ( usingEAX || usingEAX3 )
+		EAX3_Set(ALEffect, allparameters);
+	else
+		EFX_Set(ALEffect, allparameters);
+}
+
+static void
+add_providers()
+{
+	SampleManager.SetNum3DProvidersAvailable(0);
+	
+	ALDeviceList *pDeviceList = NULL;
+	pDeviceList = new ALDeviceList();
+
+	if ((pDeviceList) && (pDeviceList->GetNumDevices()))
+	{
+		const int devNumber = Min(pDeviceList->GetNumDevices(), MAXPROVIDERS);
+		int n = 0;
+		
+		for (int i = 0; i < devNumber; i++) 
+		{
+			if ( n < MAXPROVIDERS )
+			{
+				providers[n].id=std::string(pDeviceList->GetDeviceName(i), strlen(pDeviceList->GetDeviceName(i)));
+				strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name));
+				providers[n].sources = pDeviceList->GetMaxNumSources(i);
+				SampleManager.Set3DProviderName(n, providers[n].name);
+				n++;
+			}
+			
+			if ( alGetEnumValue("AL_EFFECT_EAXREVERB") != 0
+				|| pDeviceList->IsExtensionSupported(i, "EAX2.0")
+				|| pDeviceList->IsExtensionSupported(i, "EAX3.0") 
+				|| pDeviceList->IsExtensionSupported(i, "EAX4.0")
+				|| pDeviceList->IsExtensionSupported(i, "EAX5.0") )
+			{
+				if ( n < MAXPROVIDERS )
+				{
+					providers[n].id=std::string(pDeviceList->GetDeviceName(i), strlen(pDeviceList->GetDeviceName(i)));
+					strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name));
+					strcat(providers[n].name, " EAX");
+					providers[n].sources = pDeviceList->GetMaxNumSources(i);
+					SampleManager.Set3DProviderName(n, providers[n].name);
+					n++;
+				}
+				
+				if ( n < MAXPROVIDERS )
+				{
+					providers[n].id=std::string(pDeviceList->GetDeviceName(i), strlen(pDeviceList->GetDeviceName(i)));
+					strncpy(providers[n].name, pDeviceList->GetDeviceName(i), sizeof(providers[n].name));
+					strcat(providers[n].name, " EAX3");
+					providers[n].sources = pDeviceList->GetMaxNumSources(i);
+					SampleManager.Set3DProviderName(n, providers[n].name);
+					n++;
+				}
+			}
+		}
+		SampleManager.SetNum3DProvidersAvailable(n);
+	
+		for(int j=n;j<MAXPROVIDERS;j++)
+			SampleManager.Set3DProviderName(j, NULL);
+		
+		defaultProvider = pDeviceList->GetDefaultDevice();
+		if ( defaultProvider > MAXPROVIDERS )
+			defaultProvider = 0;
+	
+		delete pDeviceList;
+	}
+}
+
+static void
+release_existing()
+{
+	for ( int32 i = 0; i < MAXCHANNELS; i++ )
+		aChannel[i].Term();
+	aChannel[CHANNEL2D].Term();
+	
+	if ( IsFXSupported() )
+	{
+		if ( alIsEffect(ALEffect) )
+		{
+			alEffecti(ALEffect, AL_EFFECT_TYPE, AL_EFFECT_NULL);
+			alDeleteEffects(1, &ALEffect);
+			ALEffect = AL_EFFECT_NULL;
+		}
+		
+		if (alIsAuxiliaryEffectSlot(ALEffectSlot))
+		{
+			alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECT_NULL);
+			
+			alDeleteAuxiliaryEffectSlots(1, &ALEffectSlot);
+			ALEffectSlot = AL_EFFECTSLOT_NULL;
+		}
+	}
+	
+	for ( int32 i = 0; i < MAX_STREAMS; i++ )
+	{
+		alDeleteSources(1, &ALStreamSources[i]);
+		alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
+	}
+	
+	alDeleteBuffers(MAX_PEDSFX, pedBuffers);
+	
+	for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+	{
+		if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) )
+			alDeleteBuffers(1, &ALBuffers[i].buffer);
+		
+		ALBuffers[i].timer = 0;
+	}
+	
+	if ( ALContext )
+	{
+		alcMakeContextCurrent(NULL);
+		alcSuspendContext(ALContext);
+		alcDestroyContext(ALContext);
+	}
+	if ( ALDevice )
+		alcCloseDevice(ALDevice);
+	
+	ALDevice = NULL;
+	ALContext = NULL;
+	
+	_fPrevEaxRatioDestination = 0.0f;
+	_usingEFX                 = false;
+	_fEffectsLevel            = 0.0f;
+	
+	DEV("release_existing()\n");
+}
+
+static bool
+set_new_provider(int index)
+{
+	if ( curprovider == index )
+		return true;
+	
+	curprovider = index;
+	
+	release_existing();
+	
+	if ( curprovider != -1 )
+	{
+		DEV("set_new_provider()\n");
+		
+		//TODO:
+		_maxSamples = MAXCHANNELS;
+		
+		ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0};
+		
+		ALDevice  = alcOpenDevice(providers[index].id.c_str());
+		ASSERT(ALDevice != NULL);
+		
+		ALContext = alcCreateContext(ALDevice, attr);
+		ASSERT(ALContext != NULL);
+		
+		alcMakeContextCurrent(ALContext);
+	
+		const char* ext=(const char*)alGetString(AL_EXTENSIONS);
+		ASSERT(strstr(ext,"AL_SOFT_loop_points")!=NULL);
+		if ( strstr(ext,"AL_SOFT_loop_points")==NULL )
+		{
+			curprovider=-1;
+			release_existing();
+			return false;
+		}
+		
+		alListenerf (AL_GAIN,     1.0f);
+		alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
+		alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f);
+		ALfloat orientation[6] = { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f };
+		alListenerfv(AL_ORIENTATION, orientation);
+		
+		alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+		
+		if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
+		{
+			alGenAuxiliaryEffectSlots(1, &ALEffectSlot);
+			alGenEffects(1, &ALEffect);
+		}
+		
+		for ( int32 i = 0; i < MAX_STREAMS; i++ )
+		{
+			alGenSources(1, &ALStreamSources[i]);
+			alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
+		}
+		
+		for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+		{
+			ALBuffers[i].buffer = 0;
+			ALBuffers[i].timer  = 0;
+		}
+		
+		alGenBuffers(MAX_PEDSFX,    pedBuffers);
+		
+		usingEAX = 0;
+		usingEAX3 = 0;
+		_usingEFX = false;
+		
+		if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX3")], " EAX3") 
+				&& alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
+		{
+			EAX_SetAll(&FinishEAX3);
+			
+			usingEAX = 1;
+			usingEAX3 = 1;
+
+			DEV("EAX3\n");
+		}
+		else if ( alcIsExtensionPresent(ALDevice, (ALCchar*)ALC_EXT_EFX_NAME) )
+		{
+			EAX_SetAll(&EAX30_ORIGINAL_PRESETS[EAX_ENVIRONMENT_CAVE]);
+			
+			if ( !strcmp(&providers[index].name[strlen(providers[index].name) - strlen(" EAX")], " EAX"))
+			{
+				usingEAX = 1;
+				DEV("EAX1\n");
+			}
+			else
+			{
+				_usingEFX = true;
+				DEV("EFX\n");
+			}
+		}
+		
+		//SampleManager.SetSpeakerConfig(speaker_type);
+				
+		for ( int32 i = 0; i < MAXCHANNELS; i++ )
+			aChannel[i].Init();
+		aChannel[CHANNEL2D].Init(true);
+		
+		if ( IsFXSupported() )
+		{
+			/**/
+			alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
+			/**/
+			
+			for ( int32 i = 0; i < MAXCHANNELS; i++ )
+				aChannel[i].SetReverbMix(ALEffectSlot, 0.0f);
+		}
+		
+		return true;
+	}
+	
+	return false;
+}
+
+cSampleManager::cSampleManager(void)
+{
+	;
+}
+
+cSampleManager::~cSampleManager(void)
+{
+	
+}
+
+void cSampleManager::SetSpeakerConfig(int32 nConfig)
+{
+
+}
+
+uint32 cSampleManager::GetMaximumSupportedChannels(void)
+{
+	if ( _maxSamples > MAXCHANNELS )
+		return MAXCHANNELS;
+	
+	return _maxSamples;
+}
+
+uint32 cSampleManager::GetNum3DProvidersAvailable()
+{
+	return m_nNumberOfProviders;
+}
+
+void cSampleManager::SetNum3DProvidersAvailable(uint32 num)
+{
+	m_nNumberOfProviders = num;
+}
+
+char *cSampleManager::Get3DProviderName(uint8 id)
+{
+	return m_aAudioProviders[id];
+}
+
+void cSampleManager::Set3DProviderName(uint8 id, char *name)
+{
+	m_aAudioProviders[id] = name;
+}
+
+int8 cSampleManager::GetCurrent3DProviderIndex(void)
+{
+	return curprovider;
+}
+
+int8 cSampleManager::SetCurrent3DProvider(uint8 nProvider)
+{
+	ASSERT( nProvider < m_nNumberOfProviders );
+	int savedprovider = curprovider;
+	
+	if ( nProvider < m_nNumberOfProviders )
+	{
+		if ( set_new_provider(nProvider) )
+			return curprovider;
+		else if ( savedprovider != -1 && savedprovider < m_nNumberOfProviders && set_new_provider(savedprovider) )
+			return curprovider;
+		else
+			return -1;
+	}
+	else
+		return curprovider;
+}
+
+bool
+cSampleManager::IsMP3RadioChannelAvailable(void)
+{
+	return nNumMP3s != 0;
+}
+
+
+void cSampleManager::ReleaseDigitalHandle(void)
+{
+	if ( ALDevice )
+	{
+		prevprovider = curprovider;
+		release_existing();
+		curprovider = -1;
+	}
+}
+
+void cSampleManager::ReacquireDigitalHandle(void)
+{
+	if ( ALDevice )
+	{
+		if ( prevprovider != -1 )
+			set_new_provider(prevprovider);
+	}
+}
+
+bool
+cSampleManager::Initialise(void)
+{
+	if ( _bSampmanInitialised )
+		return true;
+
+	EFXInit();
+	CStream::Initialise();
+
+	{
+		for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+		{
+			m_aSamples[i].nOffset    = 0;
+			m_aSamples[i].nSize      = 0;
+			m_aSamples[i].nFrequency = MAX_FREQ;
+			m_aSamples[i].nLoopStart = 0;
+			m_aSamples[i].nLoopEnd   = -1;
+		}
+		
+		m_nEffectsVolume     = MAX_VOLUME;
+		m_nMusicVolume       = MAX_VOLUME;
+		m_nEffectsFadeVolume = MAX_VOLUME;
+		m_nMusicFadeVolume   = MAX_VOLUME;
+	
+		m_nMonoMode = 0;
+	}
+	
+	{
+		curprovider = -1;
+		prevprovider = -1;
+			
+		_usingEFX = false;
+		usingEAX =0;
+		usingEAX3=0;
+			
+		_fEffectsLevel = 0.0f;
+			
+		_maxSamples = 0;
+		
+		ALDevice = NULL;
+		ALContext = NULL;
+	}
+	
+	{
+		fpSampleDescHandle = NULL;
+		fpSampleDataHandle = NULL;
+		
+		for ( int32 i = 0; i < MAX_SAMPLEBANKS; i++ )
+		{
+			bSampleBankLoaded[i]             = false;
+			nSampleBankDiscStartOffset[i]    = 0;
+			nSampleBankSize[i]               = 0;
+			nSampleBankMemoryStartAddress[i] = 0;
+		}
+	}
+	
+	{
+		for ( int32 i = 0; i < MAX_PEDSFX; i++ )
+		{
+			nPedSlotSfx[i]     = NO_SAMPLE;
+			nPedSlotSfxAddr[i] = 0;
+		}
+		
+		nCurrentPedSlot = 0;
+	}
+	
+	{
+		for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
+			nChannelVolume[i] = 0;
+	}
+	
+	{
+		add_providers();
+		
+		if ( !InitialiseSampleBanks() )
+		{
+			Terminate();
+			return false;
+		}
+		
+		nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = (int32)malloc(nSampleBankSize[SAMPLEBANK_MAIN]);
+		ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != NULL);
+		
+		if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] == NULL )
+		{
+			Terminate();
+			return false;
+		}
+		
+		nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = (int32)malloc(PED_BLOCKSIZE*MAX_PEDSFX);
+		ASSERT(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != NULL);
+	}
+	
+	{
+		for ( int32 i = 0; i < MAX_STREAMS; i++ )
+		{
+			aStream[i]     = NULL;
+			nStreamVolume[i] = 100;
+			nStreamPan[i]    = 63;
+		}
+		
+		for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+			nStreamLength[i] = 3600000;
+	}
+	
+	{
+		_bSampmanInitialised = true;
+		
+		if ( 0 >= defaultProvider && defaultProvider < m_nNumberOfProviders )
+		{
+			set_new_provider(defaultProvider);
+		}
+		else
+		{
+			Terminate();
+			return false;
+		}
+	}
+	
+	LoadSampleBank(SAMPLEBANK_MAIN);
+	
+	return true;
+}
+
+void
+cSampleManager::Terminate(void)
+{
+	release_existing();
+
+	for (int32 i = 0; i < MAX_STREAMS; i++)
+	{
+		CStream *stream = aStream[i];
+		if (stream)
+		{
+			delete stream;
+			aStream[i] = NULL;
+		}
+	}
+
+	CStream::Terminate();
+	
+	if ( nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] != 0 )
+	{
+		free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN]);
+		nSampleBankMemoryStartAddress[SAMPLEBANK_MAIN] = 0;
+	}
+
+	if ( nSampleBankMemoryStartAddress[SAMPLEBANK_PED] != 0 )
+	{
+		free((void *)nSampleBankMemoryStartAddress[SAMPLEBANK_PED]);
+		nSampleBankMemoryStartAddress[SAMPLEBANK_PED] = 0;
+	}
+	
+	_bSampmanInitialised = false;
+}
+
+void
+cSampleManager::UpdateSoundBuffers(void)
+{	
+	for ( int32 i = 0; i < SAMPLEBANK_MAX; i++ )
+	{
+		if ( ALBuffers[i].timer > 0 )
+		{
+			ALBuffers[i].timer -= ALuint(CTimer::GetTimeStepInMilliseconds());
+			
+			if ( ALBuffers[i].timer <= 0 )
+			{
+				if ( ALBuffers[i].buffer != 0 && alIsBuffer(ALBuffers[i].buffer) )
+				{
+					alDeleteBuffers(1, &ALBuffers[i].buffer);
+					
+					if ( alGetError() == AL_NO_ERROR )
+						ALBuffers[i].timer = 0;
+					else
+						ALBuffers[i].timer = 10000;
+				}
+			}
+		}
+	}
+}
+
+bool cSampleManager::CheckForAnAudioFileOnCD(void)
+{
+	return true;
+}
+
+char cSampleManager::GetCDAudioDriveLetter(void)
+{
+	return '\0';
+}
+
+void
+cSampleManager::UpdateEffectsVolume(void)
+{
+	if ( _bSampmanInitialised )
+	{
+		for ( int32 i = 0; i < MAXCHANNELS+MAX2DCHANNELS; i++ )
+		{
+			if ( GetChannelUsedFlag(i) )
+			{
+				if ( nChannelVolume[i] != 0 )
+					aChannel[i].SetVolume(m_nEffectsFadeVolume * nChannelVolume[i] * m_nEffectsVolume >> 14);
+			}
+		}
+	}
+}
+
+void
+cSampleManager::SetEffectsMasterVolume(uint8 nVolume)
+{
+	m_nEffectsVolume = nVolume;
+	UpdateEffectsVolume();
+}
+
+void
+cSampleManager::SetMusicMasterVolume(uint8 nVolume)
+{
+	m_nMusicVolume = nVolume;
+}
+
+void
+cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
+{
+	m_nEffectsFadeVolume = nVolume;
+	UpdateEffectsVolume();
+}
+
+void
+cSampleManager::SetMusicFadeVolume(uint8 nVolume)
+{
+	m_nMusicFadeVolume = nVolume;
+}
+
+void
+cSampleManager::SetMonoMode(uint8 nMode)
+{
+	m_nMonoMode = nMode;
+}
+
+bool
+cSampleManager::LoadSampleBank(uint8 nBank)
+{
+	ASSERT( nBank < MAX_SAMPLEBANKS );
+	
+	if ( CTimer::GetIsCodePaused() )
+		return false;
+	
+	if ( MusicManager.IsInitialised()
+		&& MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
+		&& nBank != SAMPLEBANK_MAIN )
+	{
+		return false;
+	}
+	
+	if ( fseek(fpSampleDataHandle, nSampleBankDiscStartOffset[nBank], SEEK_SET) != 0 )
+		return false;
+	
+	if ( fread((void *)nSampleBankMemoryStartAddress[nBank], 1, nSampleBankSize[nBank], fpSampleDataHandle) != nSampleBankSize[nBank] )
+		return false;
+	
+	bSampleBankLoaded[nBank] = true;
+	
+	return true;
+}
+
+void
+cSampleManager::UnloadSampleBank(uint8 nBank)
+{
+	ASSERT( nBank < MAX_SAMPLEBANKS );
+	
+	bSampleBankLoaded[nBank] = false;
+}
+
+bool
+cSampleManager::IsSampleBankLoaded(uint8 nBank)
+{
+	ASSERT( nBank < MAX_SAMPLEBANKS );
+	
+	return bSampleBankLoaded[nBank];
+}
+
+bool
+cSampleManager::IsPedCommentLoaded(uint32 nComment)
+{
+	ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
+	
+	uint8 slot;
+
+	for ( int32 i = 0; i < _TODOCONST(3); i++ )
+	{
+		slot = nCurrentPedSlot - i - 1;
+		if ( nComment == nPedSlotSfx[slot] )
+			return true;
+	}
+	
+	return false;
+}
+
+
+int32
+cSampleManager::_GetPedCommentSlot(uint32 nComment)
+{
+	uint8 slot;
+
+	for (int32 i = 0; i < _TODOCONST(3); i++)
+	{
+		slot = nCurrentPedSlot - i - 1;
+		if (nComment == nPedSlotSfx[slot])
+			return slot;
+	}
+
+	return -1;
+}
+
+bool
+cSampleManager::LoadPedComment(uint32 nComment)
+{
+	ASSERT( nComment < TOTAL_AUDIO_SAMPLES );
+	
+	if ( CTimer::GetIsCodePaused() )
+		return false;
+	
+	// no talking peds during cutsenes or the game end
+	if ( MusicManager.IsInitialised() )
+	{
+		switch ( MusicManager.GetMusicMode() )
+		{
+			case MUSICMODE_CUTSCENE:
+			{
+				return false;
+
+				break;
+			}
+			
+			case MUSICMODE_FRONTEND:
+			{
+				if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
+					return false;
+
+				break;
+			}
+		}
+	}
+	
+	if ( fseek(fpSampleDataHandle, m_aSamples[nComment].nOffset, SEEK_SET) != 0 )
+		return false;
+	
+	if ( fread((void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot), 1, m_aSamples[nComment].nSize, fpSampleDataHandle) != m_aSamples[nComment].nSize )
+		return false;
+	
+	nPedSlotSfx[nCurrentPedSlot] = nComment;
+	
+	alBufferData(pedBuffers[nCurrentPedSlot],
+		AL_FORMAT_MONO16,
+		(void *)(nSampleBankMemoryStartAddress[SAMPLEBANK_PED] + PED_BLOCKSIZE*nCurrentPedSlot),
+		m_aSamples[nComment].nSize,
+		m_aSamples[nComment].nFrequency);
+	
+	if ( ++nCurrentPedSlot >= MAX_PEDSFX )
+		nCurrentPedSlot = 0;
+	
+	return true;
+}
+
+int32
+cSampleManager::GetBankContainingSound(uint32 offset)
+{
+	if ( offset >= BankStartOffset[SAMPLEBANK_PED] )
+		return SAMPLEBANK_PED;
+	
+	if ( offset >= BankStartOffset[SAMPLEBANK_MAIN] )
+		return SAMPLEBANK_MAIN;
+	
+	return SAMPLEBANK_INVALID;
+}
+
+int32
+cSampleManager::GetSampleBaseFrequency(uint32 nSample)
+{
+	ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+	return m_aSamples[nSample].nFrequency;
+}
+
+int32
+cSampleManager::GetSampleLoopStartOffset(uint32 nSample)
+{
+	ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+	return m_aSamples[nSample].nLoopStart;
+}
+
+int32
+cSampleManager::GetSampleLoopEndOffset(uint32 nSample)
+{
+	ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+	return m_aSamples[nSample].nLoopEnd;
+}
+
+uint32
+cSampleManager::GetSampleLength(uint32 nSample)
+{
+	ASSERT( nSample < TOTAL_AUDIO_SAMPLES );
+	return m_aSamples[nSample].nSize >> 1;
+}
+
+bool cSampleManager::UpdateReverb(void)
+{
+	if ( !usingEAX && !_usingEFX )
+		return false;
+
+	if ( AudioManager.GetFrameCounter() & 15 )
+		return false;
+			
+	float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP)  + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM);
+	float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT);
+	float z = AudioManager.GetReflectionsDistance(REFLECTION_UP);
+	
+	float normy = norm(y, 5.0f, 40.0f);
+	float normx = norm(x, 5.0f, 40.0f);
+	float normz = norm(z, 5.0f, 40.0f);
+	
+	#define ZR(v, a, b) (((v)==0)?(a):(b))
+	#define CALCRATIO(x,y,z,min,max,val) (ZR(y, ZR(x, ZR(z, min, max), min), ZR(x, ZR(z, min, max), ZR(z, min, val))))
+	
+	float fRatio = CALCRATIO(normx, normy, normz, 0.3f, 0.5f, (normy+normx+normz)/3.0f);
+	
+	#undef CALCRATIO
+	#undef ZE
+	
+	fRatio = clamp(fRatio, usingEAX3==1 ? 0.0f : 0.30f, 1.0f);
+	
+	if ( fRatio == _fPrevEaxRatioDestination )
+		return false;
+	
+#ifdef JUICY_OAL
+	if ( usingEAX3 || _usingEFX )
+#else
+	if ( usingEAX3 )
+#endif
+	{
+		if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) )
+		{
+			EAX_SetAll(&EAX3Params);
+			
+			/*
+			if ( IsFXSupported() )
+			{
+				alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
+			
+				for ( int32 i = 0; i < MAXCHANNELS; i++ )
+					aChannel[i].UpdateReverb(ALEffectSlot);
+			}
+			*/
+			
+			_fEffectsLevel = 1.0f - fRatio * 0.5f;
+		}
+	}
+	else
+	{
+		if ( _usingEFX )
+			_fEffectsLevel = (1.0f - fRatio) * 0.4f;
+		else
+			_fEffectsLevel = (1.0f - fRatio) * 0.7f;
+	}
+
+	_fPrevEaxRatioDestination = fRatio;
+	
+	return true;
+}
+
+void
+cSampleManager::SetChannelReverbFlag(uint32 nChannel, uint8 nReverbFlag)
+{
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	if ( usingEAX || _usingEFX )
+	{
+		if ( IsFXSupported() )
+		{
+			alAuxiliaryEffectSloti(ALEffectSlot, AL_EFFECTSLOT_EFFECT, ALEffect);
+			
+			if ( nReverbFlag != 0 )
+				aChannel[nChannel].SetReverbMix(ALEffectSlot, _fEffectsLevel);
+			else
+				aChannel[nChannel].SetReverbMix(ALEffectSlot, 0.0f);
+		}
+	}
+}
+
+bool
+cSampleManager::InitialiseChannel(uint32 nChannel, uint32 nSfx, uint8 nBank)
+{
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	ALuint buffer;
+	
+	if ( nSfx < SAMPLEBANK_MAX )
+	{
+		if ( !IsSampleBankLoaded(nBank) )
+			return false;
+		
+		int32 addr = nSampleBankMemoryStartAddress[nBank] + m_aSamples[nSfx].nOffset - m_aSamples[BankStartOffset[nBank]].nOffset;
+	
+		if ( ALBuffers[nSfx].timer == 0 )
+		{
+			ALuint buf;
+			
+			alGenBuffers(1, &buf);
+			alBufferData(buf, AL_FORMAT_MONO16, (void *)addr, m_aSamples[nSfx].nSize, m_aSamples[nSfx].nFrequency);
+			ALBuffers[nSfx].buffer = buf;
+			ALBuffers[nSfx].timer  = 10000;
+		}
+		
+		buffer = ALBuffers[nSfx].buffer;
+	}
+	else
+	{
+		if ( !IsPedCommentLoaded(nSfx) )
+			return false;
+		
+		int32 slot = _GetPedCommentSlot(nSfx);
+		
+		buffer = pedBuffers[slot];
+	}
+	
+	if ( buffer == 0 )
+	{
+		TRACE("No buffer to play id %d", nSfx);
+		return false;
+	}
+	
+	if ( GetChannelUsedFlag(nChannel) )
+	{
+		TRACE("Stopping channel %d - really!!!", nChannel);
+		StopChannel(nChannel);
+	}
+	
+	aChannel[nChannel].Reset();
+	if ( aChannel[nChannel].HasSource() )
+	{	
+		aChannel[nChannel].SetSampleID     (nSfx);
+		aChannel[nChannel].SetFreq         (m_aSamples[nSfx].nFrequency);
+		aChannel[nChannel].SetLoopPoints   (0, -1);
+		aChannel[nChannel].SetBuffer       (buffer);
+		aChannel[nChannel].SetPitch        (1.0f);
+		return true;
+	}
+	
+	return false;
+}
+
+void
+cSampleManager::SetChannelEmittingVolume(uint32 nChannel, uint32 nVolume)
+{
+	ASSERT( nChannel != CHANNEL2D );
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	uint32 vol = nVolume;
+	if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+	
+	nChannelVolume[nChannel] = vol;
+	
+	// reduce channel volume when JB.MP3 or S4_BDBD.MP3 playing
+	if (   MusicManager.GetMusicMode()    == MUSICMODE_CUTSCENE
+		&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+		&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+	{
+		nChannelVolume[nChannel] >>= 2;
+	}
+
+	// no idea, does this one looks like a bug or it's SetChannelVolume ?
+	aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*nChannelVolume[nChannel]*m_nEffectsVolume >> 14);
+}
+
+void
+cSampleManager::SetChannel3DPosition(uint32 nChannel, float fX, float fY, float fZ)
+{
+	ASSERT( nChannel != CHANNEL2D );
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	aChannel[nChannel].SetPosition(-fX, fY, fZ);
+}
+
+void
+cSampleManager::SetChannel3DDistances(uint32 nChannel, float fMax, float fMin)
+{
+	ASSERT( nChannel != CHANNEL2D );
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	aChannel[nChannel].SetDistances(fMax, fMin);
+}
+
+void
+cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
+{
+	ASSERT( nChannel == CHANNEL2D );
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	if ( nChannel == CHANNEL2D )
+	{
+		uint32 vol = nVolume;
+		if ( vol > MAX_VOLUME ) vol = MAX_VOLUME;
+		
+		nChannelVolume[nChannel] = vol;
+		
+		// reduce the volume for JB.MP3 and S4_BDBD.MP3
+		if (   MusicManager.GetMusicMode()    == MUSICMODE_CUTSCENE
+			&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
+			&& MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+		{
+			nChannelVolume[nChannel] >>= 2;
+		}
+			
+		aChannel[nChannel].SetVolume(m_nEffectsFadeVolume*vol*m_nEffectsVolume >> 14);
+	}
+}
+
+void
+cSampleManager::SetChannelPan(uint32 nChannel, uint32 nPan)
+{
+	ASSERT(nChannel == CHANNEL2D);
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	if ( nChannel == CHANNEL2D )
+	{
+		aChannel[nChannel].SetPan(nPan);
+	}
+}
+
+void
+cSampleManager::SetChannelFrequency(uint32 nChannel, uint32 nFreq)
+{
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	aChannel[nChannel].SetCurrentFreq(nFreq);
+}
+
+void
+cSampleManager::SetChannelLoopPoints(uint32 nChannel, uint32 nLoopStart, int32 nLoopEnd)
+{
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	aChannel[nChannel].SetLoopPoints(nLoopStart / (DIGITALBITS / 8), nLoopEnd / (DIGITALBITS / 8));
+}
+
+void
+cSampleManager::SetChannelLoopCount(uint32 nChannel, uint32 nLoopCount)
+{
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	aChannel[nChannel].SetLoopCount(nLoopCount);
+}
+
+bool
+cSampleManager::GetChannelUsedFlag(uint32 nChannel)
+{
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	return aChannel[nChannel].IsUsed();
+}
+
+void
+cSampleManager::StartChannel(uint32 nChannel)
+{
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	aChannel[nChannel].Start();
+}
+
+void
+cSampleManager::StopChannel(uint32 nChannel)
+{
+	ASSERT( nChannel < MAXCHANNELS+MAX2DCHANNELS );
+	
+	aChannel[nChannel].Stop();
+}
+
+void
+cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+{
+	char filename[256];
+	
+	ASSERT( nStream < MAX_STREAMS );
+
+	if ( nFile < TOTAL_STREAMED_SOUNDS )
+	{
+		if ( aStream[nStream] )
+		{
+			delete aStream[nStream];
+			aStream[nStream] = NULL;
+		}
+		
+		strcpy(filename, StreamedNameTable[nFile]);
+		
+		CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
+		ASSERT(stream != NULL);
+		
+		aStream[nStream] = stream;
+		if ( !stream->IsOpened() )
+		{
+			delete stream;
+			aStream[nStream] = NULL;
+		}
+	}
+}
+
+void
+cSampleManager::PauseStream(uint8 nPauseFlag, uint8 nStream)
+{
+	ASSERT( nStream < MAX_STREAMS );
+	
+	CStream *stream = aStream[nStream];
+	
+	if ( stream )
+	{
+		stream->SetPause(nPauseFlag != 0);
+	}
+}
+
+void
+cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
+{
+	ASSERT( nStream < MAX_STREAMS );
+	
+	CStream *stream = aStream[nStream];
+	
+	if ( stream )
+	{
+		if ( stream->Setup() )
+		{
+			stream->Start();
+		}
+	}
+}
+
+bool
+cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+{
+	char filename[256];
+	
+	ASSERT( nStream < MAX_STREAMS );
+	
+	if ( nFile < TOTAL_STREAMED_SOUNDS )
+	{
+		if ( aStream[nStream] )
+		{
+			delete aStream[nStream];
+			aStream[nStream] = NULL;
+		}
+		
+		strcpy(filename, StreamedNameTable[nFile]);
+		
+		CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
+		ASSERT(stream != NULL);
+
+		aStream[nStream] = stream;
+		
+		if ( stream->IsOpened() )
+		{
+			nStreamLength[nFile] = stream->GetLength();
+			if ( stream->Setup() )
+			{
+				if ( nPos != 0 )
+					stream->SetPos(nPos);
+				
+				stream->Start();
+			}
+			
+			return true;
+		}
+		else
+		{
+			delete stream;
+			aStream[nStream] = NULL;
+		}
+	}
+	
+	return false;
+}
+
+void
+cSampleManager::StopStreamedFile(uint8 nStream)
+{
+	ASSERT( nStream < MAX_STREAMS );
+
+	CStream *stream = aStream[nStream];
+	
+	if ( stream )
+	{
+		delete stream;
+		aStream[nStream] = NULL;
+	}
+}
+
+int32
+cSampleManager::GetStreamedFilePosition(uint8 nStream)
+{
+	ASSERT( nStream < MAX_STREAMS );
+	
+	CStream *stream = aStream[nStream];
+	
+	if ( stream )
+	{
+		return stream->GetPos();
+	}
+	
+	return 0;
+}
+
+void
+cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream)
+{
+	ASSERT( nStream < MAX_STREAMS );
+	
+	if ( nVolume > MAX_VOLUME )
+		nVolume = MAX_VOLUME;
+	
+	if ( nPan > MAX_VOLUME )
+		nPan = MAX_VOLUME;
+		
+	nStreamVolume[nStream] = m_nMusicFadeVolume * nVolume;
+	nStreamPan   [nStream] = nPan;
+	
+	CStream *stream = aStream[nStream];
+	
+	if ( stream )
+	{
+		if ( nEffectFlag )
+			stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14);
+		else
+			stream->SetVolume(m_nMusicFadeVolume*nVolume*m_nMusicVolume >> 14);
+		
+		stream->SetPan(nPan);
+	}
+}
+
+int32
+cSampleManager::GetStreamedFileLength(uint8 nStream)
+{
+	ASSERT( nStream < TOTAL_STREAMED_SOUNDS );
+
+	return nStreamLength[nStream];
+}
+
+bool
+cSampleManager::IsStreamPlaying(uint8 nStream)
+{
+	ASSERT( nStream < MAX_STREAMS );
+	
+	CStream *stream = aStream[nStream];
+	
+	if ( stream )
+	{
+		if ( stream->IsPlaying() )
+			return true;
+	}
+	
+	return false;
+}
+
+void
+cSampleManager::Service(void)
+{
+	for ( int32 i = 0; i < MAX_STREAMS; i++ )
+	{
+		CStream *stream = aStream[i];
+		
+		if ( stream )
+			stream->Update();
+	}
+	
+	UpdateSoundBuffers();
+}
+
+bool
+cSampleManager::InitialiseSampleBanks(void)
+{
+	int32 nBank = SAMPLEBANK_MAIN;
+	
+	fpSampleDescHandle = fopen(SampleBankDescFilename, "rb");
+	if ( fpSampleDescHandle == NULL )
+		return false;
+	
+	fpSampleDataHandle = fopen(SampleBankDataFilename, "rb");
+	if ( fpSampleDataHandle == NULL )
+	{
+		fclose(fpSampleDescHandle);
+		fpSampleDescHandle = NULL;
+		
+		return false;
+	}
+	
+	fseek(fpSampleDataHandle, 0, SEEK_END);
+	int32 _nSampleDataEndOffset = ftell(fpSampleDataHandle);
+	rewind(fpSampleDataHandle);
+	
+	fread(m_aSamples, sizeof(tSample), TOTAL_AUDIO_SAMPLES, fpSampleDescHandle);
+	
+	fclose(fpSampleDescHandle);
+	fpSampleDescHandle = NULL;
+	
+	for ( int32 i = 0; i < TOTAL_AUDIO_SAMPLES; i++ )
+	{
+#ifdef FIX_BUGS
+		if (nBank >= MAX_SAMPLEBANKS) break;
+#endif
+		if ( BankStartOffset[nBank] == BankStartOffset[SAMPLEBANK_MAIN] + i )
+		{
+			nSampleBankDiscStartOffset[nBank] = m_aSamples[i].nOffset;
+			nBank++;
+		}
+	}
+
+	nSampleBankSize[SAMPLEBANK_MAIN] = nSampleBankDiscStartOffset[SAMPLEBANK_PED] - nSampleBankDiscStartOffset[SAMPLEBANK_MAIN];
+	nSampleBankSize[SAMPLEBANK_PED]  = _nSampleDataEndOffset                      - nSampleBankDiscStartOffset[SAMPLEBANK_PED];
+	
+	return true;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 8633d222..8ab12e3f 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -220,22 +220,9 @@ bool CGame::InitialiseOnceAfterRW(void)
 	if ( FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -99 || FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -2 )
 	{
 		CMenuManager::m_PrefsSpeakers = 0;
-		
-		for ( int32 i = 0; i < DMAudio.GetNum3DProvidersAvailable(); i++ )
-		{
-			wchar buff[64];
-			
-			char *name = DMAudio.Get3DProviderName(i);
-			AsciiToUnicode(name, buff);
-			char *providername = UnicodeToAscii(buff);
-			strupr(providername);
-			
-			if ( !strcmp(providername, "MILES FAST 2D POSITIONAL AUDIO") )
-			{
-				FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = i;
-				break;
-			}
-		}
+		int8 provider = DMAudio.AutoDetect3DProviders();
+		if ( provider != -1 )
+			FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = provider;
 	}
 
 	DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
diff --git a/src/core/config.h b/src/core/config.h
index 163af701..23fe9993 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -193,7 +193,8 @@ enum Config {
 #define DEFAULT_NATIVE_RESOLUTION	// Set default video mode to your native resolution (fixes Windows 10 launch) 
 #define USE_TXD_CDIMAGE		// generate and load textures from txd.img
 //#define USE_TEXTURE_POOL
-//#define OPENAL
+#define AUDIO_OAL
+//#define AUDIO_MSS
 
 // Particle
 //#define PC_PARTICLE
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index 288788c0..20e5c49c 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -1773,13 +1773,12 @@ WinMain(HINSTANCE instance,
 	StaticPatcher::Apply();
 	SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE);
 
-/*
+
 	// TODO: make this an option somewhere
 	AllocConsole();
 	freopen("CONIN$", "r", stdin);
 	freopen("CONOUT$", "w", stdout);
 	freopen("CONOUT$", "w", stderr);
-*/
 
 	/* 
 	 * Initialize the platform independent data.