Index: source/ps/GameSetup/Config.cpp
===================================================================
--- source/ps/GameSetup/Config.cpp	(revision 12542)
+++ source/ps/GameSetup/Config.cpp	(working copy)
@@ -84,6 +84,7 @@
 	CFG_GET_USER_VAL("silhouettes", Bool, g_Silhouettes);
 	CFG_GET_USER_VAL("showsky", Bool, g_ShowSky);
 
+ #if CONFIG2_AUDIO
 	float gain = 0.5f;
 	float musicGain = 0.5f;
 	float ambientGain = 0.5f;
@@ -99,12 +100,15 @@
 	CFG_GET_USER_VAL("sound.bufferCount", Int, bufferCount);
 	CFG_GET_USER_VAL("sound.bufferSize", UnsignedLong, bufferSize);
 
-	g_SoundManager->SetMasterGain(gain);
-	g_SoundManager->SetMusicGain(musicGain);
-	g_SoundManager->SetAmbientGain(ambientGain);
-	g_SoundManager->SetActionGain(actionGain);
+	if ( g_SoundManager ) {
+		g_SoundManager->SetMasterGain(gain);
+		g_SoundManager->SetMusicGain(musicGain);
+		g_SoundManager->SetAmbientGain(ambientGain);
+		g_SoundManager->SetActionGain(actionGain);
 
-	g_SoundManager->SetMemoryUsage(bufferSize, bufferCount);
+		g_SoundManager->SetMemoryUsage(bufferSize, bufferCount);
+	}
+#endif
 }
 
 
Index: source/ps/GameSetup/GameSetup.cpp
===================================================================
--- source/ps/GameSetup/GameSetup.cpp	(revision 12542)
+++ source/ps/GameSetup/GameSetup.cpp	(working copy)
@@ -190,8 +190,10 @@
 {
 	PROFILE3("render");
 
-	g_SoundManager->IdleTask();
-
+ #if CONFIG2_AUDIO
+	if ( g_SoundManager )
+		g_SoundManager->IdleTask();
+#endif
 	ogl_WarnIfError();
 
 	g_Profiler2.RecordGPUFrameStart();
@@ -685,7 +687,10 @@
 	// resource
 	// first shut down all resource owners, and then the handle manager.
 	TIMER_BEGIN(L"resource modules");
-		delete g_SoundManager;
+#if CONFIG2_AUDIO
+		if ( g_SoundManager )
+			delete g_SoundManager;
+#endif
 
 		g_VFS.reset();
 
@@ -862,7 +867,7 @@
 	g_ScriptStatsTable = new CScriptStatsTable;
 	g_ProfileViewer.AddRootTable(g_ScriptStatsTable);
 
-	g_SoundManager = new CSoundManager();
+	CSoundManager::CreateSoundManager();
 
 	InitScripting();	// before GUI
 
@@ -926,7 +931,7 @@
 		// speed up startup by disabling all sound
 		// (OpenAL init will be skipped).
 		// must be called before first snd_open.
-		g_SoundManager->SetEnabled(false);
+		CSoundManager::SetEnabled(false);
 	}
 
 	g_GUI = new CGUIManager(g_ScriptingHost.GetScriptInterface());
Index: source/ps/Game.cpp
===================================================================
--- source/ps/Game.cpp	(revision 12542)
+++ source/ps/Game.cpp	(working copy)
@@ -294,7 +294,10 @@
 	if (doInterpolate)
 	{
 		m_TurnManager->Interpolate(deltaSimTime, deltaRealTime);
-		g_SoundManager->IdleTask();
+#if CONFIG2_AUDIO
+		if ( g_SoundManager )
+			g_SoundManager->IdleTask();
+#endif
 	}
 	
 	// TODO: maybe we should add a CCmpParticleInterface that passes the interpolation commands
Index: source/soundmanager/items/CSoundItem.h
===================================================================
--- source/soundmanager/items/CSoundItem.h	(revision 12542)
+++ source/soundmanager/items/CSoundItem.h	(working copy)
@@ -21,6 +21,7 @@
 #include "CSoundBase.h"
 #include "soundmanager/data/SoundData.h"
 
+#if CONFIG2_AUDIO
 
 class CSoundItem : public CSoundBase
 {
@@ -34,4 +35,5 @@
 
 };
 
+#endif
 #endif // INCLUDED_CSOUNDITEM_H
Index: source/soundmanager/items/CBufferItem.h
===================================================================
--- source/soundmanager/items/CBufferItem.h	(revision 12542)
+++ source/soundmanager/items/CBufferItem.h	(working copy)
@@ -18,6 +18,10 @@
 #ifndef INCLUDED_CBUFFERITEM_H
 #define INCLUDED_CBUFFERITEM_H
 
+#include "lib/config2.h"
+
+#if CONFIG2_AUDIO
+
 #include "CSoundBase.h"
 
 class CBufferItem : public CSoundBase
@@ -35,5 +39,5 @@
 	
 };
 
-
+#endif
 #endif // INCLUDED_CBUFFERITEM_H
Index: source/soundmanager/items/CStreamItem.h
===================================================================
--- source/soundmanager/items/CStreamItem.h	(revision 12542)
+++ source/soundmanager/items/CStreamItem.h	(working copy)
@@ -21,6 +21,8 @@
 #include "soundmanager/data/SoundData.h"
 #include "CSoundBase.h"
 
+#if CONFIG2_AUDIO
+
 class CStreamItem : public CSoundBase
 {
 public:
@@ -35,4 +37,5 @@
 
 };
 
+#endif
 #endif // INCLUDED_CSTREAMITEM_H
Index: source/soundmanager/items/ISoundItem.h
===================================================================
--- source/soundmanager/items/ISoundItem.h	(revision 12542)
+++ source/soundmanager/items/ISoundItem.h	(working copy)
@@ -19,9 +19,11 @@
 #define INCLUDED_ISOUNDITEM_H
 
 #include "lib/external_libraries/openal.h"
+#include "lib/config2.h"
 #include "maths/Vector3D.h"
 
 #include <string>
+#if CONFIG2_AUDIO
 
 class ISoundItem
 {
@@ -56,5 +58,5 @@
 	virtual void SetRollOff(ALfloat gain) = 0;
 };
 
-
+#endif
 #endif // INCLUDED_ISOUNDITEM_H
\ No newline at end of file
Index: source/soundmanager/items/CSoundBase.cpp
===================================================================
--- source/soundmanager/items/CSoundBase.cpp	(revision 12542)
+++ source/soundmanager/items/CSoundBase.cpp	(working copy)
@@ -22,8 +22,10 @@
 #include "lib/timer.h"
 #include "soundmanager/SoundManager.h"
 #include "soundmanager/data/SoundData.h"
+#include "ps/CLogger.h"
 
 #include <iostream>
+#if CONFIG2_AUDIO
 
 CSoundBase::CSoundBase()
 {
@@ -73,12 +75,17 @@
 
 void CSoundBase::SetGain(ALfloat gain)
 {
+	AL_CHECK
+
 	alSourcef(m_ALSource, AL_GAIN, gain);
+
+	AL_CHECK
 }
 
 void CSoundBase::SetRollOff(ALfloat rolls)
 {
    alSourcef(m_ALSource, AL_ROLLOFF_FACTOR, rolls);
+	AL_CHECK
 }
 
 void CSoundBase::EnsurePlay()
@@ -89,19 +96,25 @@
 
 void CSoundBase::SetCone(ALfloat innerCone, ALfloat outerCone, ALfloat coneGain)
 {
-	alSourcef(m_ALSource, innerCone, AL_CONE_INNER_ANGLE);
-	alSourcef(m_ALSource, outerCone, AL_CONE_OUTER_ANGLE);
-	alSourcef(m_ALSource, coneGain, AL_CONE_OUTER_GAIN);
+	AL_CHECK	
+	alSourcef(m_ALSource, AL_CONE_INNER_ANGLE, innerCone);
+	AL_CHECK
+	alSourcef(m_ALSource, AL_CONE_OUTER_ANGLE, outerCone);
+	AL_CHECK
+	alSourcef(m_ALSource, AL_CONE_OUTER_GAIN, coneGain);
+	AL_CHECK
 }
 
 void CSoundBase::SetPitch(ALfloat pitch)
 {
 	alSourcef(m_ALSource, AL_PITCH, pitch);
+	AL_CHECK
 }
 
 void CSoundBase::SetDirection(const CVector3D& direction)
 {
 	alSourcefv(m_ALSource, AL_DIRECTION, direction.GetFloatArray());
+	AL_CHECK
 }
 
 bool CSoundBase::InitOpenAL()
@@ -109,12 +122,11 @@
 	alGetError(); /* clear error */
 	alGenSources(1, &m_ALSource);
 	long anErr = alGetError();
-	if (anErr != AL_NO_ERROR) 
+
+	AL_CHECK
+
+	if (anErr == AL_NO_ERROR) 
 	{
-		printf("- Error creating sources %ld !!\n", anErr);
-	}
-	else
-	{
 		ALfloat source0Pos[]={ -2.0, 0.0, 0.0};
 		ALfloat source0Vel[]={ 0.0, 0.0, 0.0};
 		
@@ -123,6 +135,8 @@
 		alSourcefv(m_ALSource,AL_POSITION,source0Pos);
 		alSourcefv(m_ALSource,AL_VELOCITY,source0Vel);
 		alSourcei(m_ALSource,AL_LOOPING,AL_FALSE);
+		AL_CHECK
+
 		return true;
 	}
 	return false;
@@ -132,6 +146,7 @@
 {
 	int proc_state;
 	alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
+	AL_CHECK
 
 	return (proc_state == AL_PLAYING);
 }
@@ -149,10 +164,12 @@
 void CSoundBase::SetLocation (const CVector3D& position)
 {
 	alSourcefv(m_ALSource,AL_POSITION, position.GetFloatArray());
+	AL_CHECK
 }
 
 bool CSoundBase::HandleFade()
 {
+	AL_CHECK
 	if (m_StartFadeTime != 0)
 	{
 		double currTime = timer_Time();
@@ -169,6 +186,8 @@
 		}
 		else
 			alSourcef(m_ALSource, AL_GAIN, curGain);	 
+
+		AL_CHECK
 	}
 	return true;
 }
@@ -182,6 +201,7 @@
 {
 	m_Looping = loops;
 	alSourcei(m_ALSource, AL_LOOPING, loops ? AL_TRUE : AL_FALSE);
+	AL_CHECK
 }
 
 void CSoundBase::Play()
@@ -189,6 +209,7 @@
 	m_ShouldBePlaying = true;
 	if (m_ALSource != 0)
 		alSourcePlay(m_ALSource);
+	AL_CHECK
 }
 
 void CSoundBase::PlayAndDelete()
@@ -215,6 +236,7 @@
 	{
 		SetLooping(true);
 		Play();
+		AL_CHECK
 	}
 }
 
@@ -229,6 +251,7 @@
 		alGetSourcef(m_ALSource, AL_GAIN, &m_StartVolume);
 		m_EndVolume = newVolume;
 	}
+	AL_CHECK
 }
 
 void CSoundBase::PlayAsMusic()
@@ -251,6 +274,8 @@
 		alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
 		if (proc_state == AL_PLAYING)
 			alSourceStop(m_ALSource);
+
+		AL_CHECK
 	}
 }
 
@@ -274,3 +299,4 @@
 		m_Name->assign(anst.begin(), anst.end());
 }
 
+#endif
\ No newline at end of file
Index: source/soundmanager/items/CSoundItem.cpp
===================================================================
--- source/soundmanager/items/CSoundItem.cpp	(revision 12542)
+++ source/soundmanager/items/CSoundItem.cpp	(working copy)
@@ -20,9 +20,11 @@
 #include "CSoundItem.h"
 
 #include "soundmanager/data/SoundData.h"
+#include "soundmanager/SoundManager.h"
 
 #include <iostream>
 
+#if CONFIG2_AUDIO
 
 CSoundItem::CSoundItem()
 {
@@ -38,10 +40,12 @@
 
 CSoundItem::~CSoundItem()
 {
+	AL_CHECK
 	ALuint al_buf;
 	
 	Stop();
 	alSourceUnqueueBuffers(m_ALSource, 1, &al_buf);
+	AL_CHECK
 }
 
 bool CSoundItem::IdleTask()
@@ -52,6 +56,7 @@
 	{
 		int proc_state;
 		alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
+		AL_CHECK
 		return (proc_state != AL_STOPPED);
 	}
 	return true;
@@ -63,5 +68,9 @@
 	{
 		m_SoundData = itemData->IncrementCount();
 		alSourcei(m_ALSource, AL_BUFFER, m_SoundData->GetBuffer());
+		
+		AL_CHECK
 	}
 }
+
+#endif
\ No newline at end of file
Index: source/soundmanager/items/CBufferItem.cpp
===================================================================
--- source/soundmanager/items/CBufferItem.cpp	(revision 12542)
+++ source/soundmanager/items/CBufferItem.cpp	(working copy)
@@ -20,9 +20,13 @@
 #include "CBufferItem.h"
 
 #include "soundmanager/data/SoundData.h"
+#include "soundmanager/SoundManager.h"
 
 #include <iostream>
 
+ #if CONFIG2_AUDIO
+
+
 CBufferItem::CBufferItem(CSoundData* sndData)
 {
 	ResetVars();
@@ -33,6 +37,8 @@
 
 CBufferItem::~CBufferItem()
 {
+	AL_CHECK
+
 	Stop();
 	int num_processed;
 	alGetSourcei(m_ALSource, AL_BUFFERS_PROCESSED, &num_processed);
@@ -41,7 +47,8 @@
 	{
 		ALuint* al_buf = new ALuint[num_processed];
 		alSourceUnqueueBuffers(m_ALSource, num_processed, al_buf);
-
+		
+		AL_CHECK
 		delete[] al_buf;
 	}
 }
@@ -67,7 +74,9 @@
 		{
 			ALuint al_buf;
 			alSourceUnqueueBuffers(m_ALSource, 1, &al_buf);
+			AL_CHECK
 			alSourceQueueBuffers(m_ALSource, 1, &al_buf);
+			AL_CHECK
 		}
 	}
 
@@ -76,10 +85,12 @@
 
 void CBufferItem::Attach(CSoundData* itemData)
 {
+AL_CHECK
 	if (itemData != NULL)
 	{
 		m_SoundData = itemData->IncrementCount();
 		alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(),(const ALuint *) m_SoundData->GetBufferPtr());
+		AL_CHECK
 	}
 }
 
@@ -88,3 +99,4 @@
 	m_Looping = loops;
 }
 
+#endif
\ No newline at end of file
Index: source/soundmanager/items/CSoundBase.h
===================================================================
--- source/soundmanager/items/CSoundBase.h	(revision 12542)
+++ source/soundmanager/items/CSoundBase.h	(working copy)
@@ -24,6 +24,8 @@
 
 #include <string>
 
+#if CONFIG2_AUDIO
+
 class CSoundBase : public ISoundItem
 {
 protected:
@@ -86,4 +88,5 @@
 	
 };
 
+#endif
 #endif // INCLUDED_CSOUNDBASE_H
Index: source/soundmanager/items/CStreamItem.cpp
===================================================================
--- source/soundmanager/items/CStreamItem.cpp	(revision 12542)
+++ source/soundmanager/items/CStreamItem.cpp	(working copy)
@@ -20,9 +20,12 @@
 #include "CStreamItem.h"
 
 #include "soundmanager/data/OggData.h"
+#include "soundmanager/SoundManager.h"
 
 #include <iostream>
 
+#if CONFIG2_AUDIO
+
 CStreamItem::CStreamItem(CSoundData* sndData)
 {
 	ResetVars();
@@ -41,16 +44,20 @@
 	{
 		ALuint* al_buf = new ALuint[num_processed];
 		alSourceUnqueueBuffers(m_ALSource, num_processed, al_buf);
+		AL_CHECK
 		delete[] al_buf;
 	}
 }
 
 bool CStreamItem::IdleTask()
 {
+	AL_CHECK
 	HandleFade();
+	AL_CHECK
 
 	int proc_state;
 	alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
+	AL_CHECK
 	
 	if (proc_state == AL_STOPPED)
 	{
@@ -65,13 +72,16 @@
 		{
 			int num_processed;
 			alGetSourcei(m_ALSource, AL_BUFFERS_PROCESSED, &num_processed);
+			AL_CHECK
 			
 			if (num_processed > 0)
 			{
 				ALuint* al_buf = new ALuint[num_processed];
 				alSourceUnqueueBuffers(m_ALSource, num_processed, al_buf);
+				AL_CHECK
 				int didWrite = tmp->FetchDataIntoBuffer(num_processed, al_buf);
 				alSourceQueueBuffers(m_ALSource, didWrite, al_buf);
+				AL_CHECK
 				delete[] al_buf;
 			}
 		}
@@ -89,6 +99,7 @@
 	{
 		m_SoundData = itemData->IncrementCount();
 		alSourceQueueBuffers(m_ALSource, m_SoundData->GetBufferCount(), (const ALuint *)m_SoundData->GetBufferPtr());
+		AL_CHECK
 	}
 }
 
@@ -97,3 +108,4 @@
 	m_Looping = loops;
 }
 
+#endif
\ No newline at end of file
Index: source/soundmanager/SoundManager.cpp
===================================================================
--- source/soundmanager/SoundManager.cpp	(revision 12542)
+++ source/soundmanager/SoundManager.cpp	(working copy)
@@ -27,9 +27,13 @@
 #include "soundmanager/js/AmbientSound.h"
 #include "soundmanager/js/MusicSound.h"
 #include "soundmanager/js/Sound.h"
+#include "ps/CLogger.h"
 
-CSoundManager* g_SoundManager;
+CSoundManager* g_SoundManager = NULL;
 
+
+
+
 void CSoundManager::ScriptingInit()
 {
 	JAmbientSound::ScriptingInit();
@@ -38,6 +42,44 @@
 	JSoundPlayer::ScriptingInit();
 }
 
+void CSoundManager::CreateSoundManager()
+{
+#if CONFIG2_AUDIO
+	g_SoundManager = new CSoundManager();
+#endif
+}
+
+void CSoundManager::SetEnabled(bool doEnable)
+{
+#if CONFIG2_AUDIO
+
+	if ( g_SoundManager && !doEnable ) 
+	{
+		delete g_SoundManager;
+
+		g_SoundManager = NULL;
+	}
+	else if ( ! g_SoundManager && doEnable ) 
+	{
+		CSoundManager::CreateSoundManager();
+	}
+#endif
+}
+
+#if CONFIG2_AUDIO
+
+void CSoundManager::al_ReportError(ALenum err, const char* caller, int line)
+{
+	LOGERROR(L"OpenAL error: %hs; called from %hs (line %d)\n", alGetString(err), caller, line);
+}
+
+void CSoundManager::al_check(const char* caller, int line)
+{
+	ALenum err = alGetError();
+	if (err != AL_NO_ERROR)
+		al_ReportError(err, caller, line);
+}
+
 CSoundManager::CSoundManager()
 {
 	m_Items = new ItemsList;
@@ -47,11 +89,10 @@
 	m_MusicGain			= 1;
 	m_AmbientGain		= 1;
 	m_ActionGain		= 1;
-	m_Enabled			= true;
 	m_BufferCount		= 50;
 	m_BufferSize		= 65536;
 	m_MusicEnabled		= true;
-	AlcInit();
+	m_Enabled			= AlcInit() == INFO::OK;
 }
 
 CSoundManager::~CSoundManager()
@@ -78,6 +119,8 @@
 {	
 	Status ret = INFO::OK;
 
+	AL_CHECK
+
 	m_Device = alcOpenDevice(NULL);
 	if(m_Device)
 	{
@@ -93,10 +136,10 @@
 	const char* dev_name = (const char*)alcGetString(m_Device, ALC_DEVICE_SPECIFIER);
 
 	if(err == ALC_NO_ERROR && m_Device && m_Context)
-		debug_printf(L"Sound: AlcInit success, using %hs\n", dev_name);
+		LOGERROR(L"Sound: AlcInit success, using %hs\n", dev_name);
 	else
 	{
-		debug_printf(L"Sound: AlcInit failed, m_Device=%p m_Context=%p dev_name=%hs err=%d\n", m_Device, m_Context, dev_name, err);
+		LOGERROR(L"Sound: AlcInit failed, m_Device=%p m_Context=%p dev_name=%hs err=%d\n", m_Device, m_Context, dev_name, err);
 // FIXME Hack to get around exclusive access to the sound device
 #if OS_UNIX
 		ret = INFO::OK;
@@ -142,8 +185,12 @@
 
 ISoundItem* CSoundManager::LoadItem(const VfsPath& itemPath)
 {	
+	AL_CHECK
+
 	CSoundData* itemData = CSoundData::SoundDataFromFile(itemPath);
 	ISoundItem* answer = NULL;
+
+	AL_CHECK
 	
 	if (itemData != NULL)
 	{
@@ -198,10 +245,12 @@
 			deadItems++;
 		}
 	}
+	AL_CHECK
 	if (m_CurrentTune)
 		m_CurrentTune->EnsurePlay();
 	if (m_CurrentEnvirons)
 		m_CurrentEnvirons->EnsurePlay();
+	AL_CHECK
 }
 
 void CSoundManager::DeleteItem(long itemNum)
@@ -232,11 +281,6 @@
 	alDistanceModel(AL_EXPONENT_DISTANCE);
 }
 
-void CSoundManager::SetEnabled(bool doEnable)
-{
-	m_Enabled = doEnable;
-}
-
 void CSoundManager::PlayActionItem(ISoundItem* anItem)
 {
 	if (anItem)
@@ -245,6 +289,7 @@
 		{
 			anItem->SetGain(m_Gain * m_ActionGain);
 			anItem->Play();
+			AL_CHECK
 		}
 	}
 }
@@ -255,6 +300,7 @@
 		if (m_Enabled && (m_ActionGain > 0)) {
 			anItem->SetGain(m_Gain * groupGain);
 			anItem->Play();
+			AL_CHECK
 		}
 	}
 }
@@ -271,6 +317,7 @@
 
 void CSoundManager::SetMusicItem(ISoundItem* anItem)
 {
+	AL_CHECK
 	if (m_CurrentTune)
 	{
 		m_CurrentTune->FadeAndDelete(3.00);
@@ -291,6 +338,7 @@
 			anItem->StopAndDelete();
 		}
 	}
+	AL_CHECK
 }
 
 void CSoundManager::SetAmbientItem(ISoundItem* anItem)
@@ -312,5 +360,7 @@
 			m_CurrentEnvirons->FadeToIn(m_Gain * m_AmbientGain, 2.00);
 		}
 	}
+	AL_CHECK
 }
 
+#endif
Index: source/soundmanager/data/ogg.h
===================================================================
--- source/soundmanager/data/ogg.h	(revision 0)
+++ source/soundmanager/data/ogg.h	(revision 0)
@@ -0,0 +1,54 @@
+/* Copyright (C) 2012 Wildfire Games.
+ * This file is part of 0 A.D.
+ *
+ * 0 A.D. is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0 A.D. is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef INCLUDED_OGG
+#define INCLUDED_OGG
+
+#include "lib/config2.h"
+
+#if CONFIG2_AUDIO
+
+#include "lib/external_libraries/openal.h"
+#include "lib/file/vfs/vfs.h"
+
+class OggStream
+{
+public:
+	virtual ~OggStream() { }
+	virtual ALenum Format() = 0;
+	virtual ALsizei SamplingRate() = 0;
+	virtual bool atFileEOF() = 0;
+	virtual Status ResetFile() = 0;
+
+	/**
+	 * @return bytes read (<= size) or a (negative) Status
+	 **/
+	virtual Status GetNextChunk(u8* buffer, size_t size) = 0;
+};
+
+typedef shared_ptr<OggStream> OggStreamPtr;
+
+extern Status OpenOggStream(const OsPath& pathname, OggStreamPtr& stream);
+
+/**
+ * A non-streaming OggStream (reading the whole file in advance)
+ * that can cope with archived/compressed files.
+ */
+extern Status OpenOggNonstream(const PIVFS& vfs, const VfsPath& pathname, OggStreamPtr& stream);
+
+#endif	// CONFIG2_AUDIO
+
+#endif // INCLUDED_OGG
Index: source/soundmanager/data/SoundData.cpp
===================================================================
--- source/soundmanager/data/SoundData.cpp	(revision 12542)
+++ source/soundmanager/data/SoundData.cpp	(working copy)
@@ -20,11 +20,11 @@
 #include "SoundData.h"
 
 #include "OggData.h"
-#include "lib/file/vfs/vfs_util.h"
-#include "ps/Filesystem.h"
 
 #include <iostream>
 
+#if CONFIG2_AUDIO
+
 DataMap* CSoundData::sSoundData = NULL;
 
 CSoundData::CSoundData()
@@ -96,15 +96,9 @@
 	CSoundData* answer = NULL;
 	COggData* oggAnswer = new COggData();
 
-	OsPath realPath;
-	Status ret = g_VFS->GetRealPath(itemPath, realPath);
-	if (ret == INFO::OK)
-	{
-		if (oggAnswer->InitOggFile(realPath.string().c_str()))
-		{
-			answer = oggAnswer;
-		}
-	}	
+	if (oggAnswer->InitOggFile(itemPath))
+		answer = oggAnswer;
+
 	return answer;
 }
 
@@ -140,3 +134,4 @@
 	return &m_ALBuffer;
 }
 
+#endif
\ No newline at end of file
Index: source/soundmanager/data/OggData.cpp
===================================================================
--- source/soundmanager/data/OggData.cpp	(revision 12542)
+++ source/soundmanager/data/OggData.cpp	(working copy)
@@ -20,9 +20,9 @@
 #include "OggData.h"
 
 #include "soundmanager/SoundManager.h"
+#include "ps/Filesystem.h"
 
-#include <wchar.h>
-#include <iostream>
+#if CONFIG2_AUDIO
 
 COggData::COggData()
 {
@@ -32,7 +32,6 @@
 COggData::~COggData()
 {
 	alDeleteBuffers(m_BuffersUsed, m_Buffer);
-	ov_clear(&m_vf);
 }
 
 void COggData::SetFormatAndFreq(int form, ALsizei freq)
@@ -41,26 +40,15 @@
 	m_Frequency = freq;
 }
 
-bool COggData::InitOggFile(const wchar_t* fileLoc)
+bool COggData::InitOggFile(const VfsPath& itemPath)
 {
-	int buffersToStart = g_SoundManager->GetBufferCount();
-	char nameH[300];
-	sprintf(nameH, "%ls", fileLoc);
-	
-	FILE* f = fopen(nameH, "rb");
-	m_current_section = 0;
-	int err = ov_open_callbacks(f, &m_vf, NULL, 0, OV_CALLBACKS_DEFAULT);
-	if (err < 0)
-	{
-		fprintf(stderr,"Input does not appear to be an Ogg bitstream :%d :%d.\n", err, ferror(f));
-		return false;
-	}
+	int buffersToStart = g_SoundManager->GetBufferCount();	
+	OpenOggNonstream( g_VFS, itemPath, ogg);
 
-	m_FileName = CStrW(fileLoc);
-
 	m_FileFinished = false;
-	SetFormatAndFreq((m_vf.vi->channels == 1)? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16 , (ALsizei)m_vf.vi->rate);
 
+	SetFormatAndFreq(ogg->Format(), ogg->SamplingRate() );
+
 	alGetError(); /* clear error */
 	alGenBuffers(buffersToStart, m_Buffer);
 	
@@ -96,8 +84,7 @@
 
 void COggData::ResetFile()
 {
-	ov_time_seek(&m_vf, 0);
-	m_current_section = 0;
+	ogg->ResetFile();
 	m_FileFinished = false;
 }
 
@@ -110,32 +97,13 @@
 {
 	long bufferSize = g_SoundManager->GetBufferSize();
 	
-	char* pcmout = new char[bufferSize + 5000];
+	u8* pcmout = new u8[bufferSize + 5000];
 	int buffersWritten = 0;
 	
 	for (int i = 0; (i < count) && !m_FileFinished; i++)
 	{
-		char* readDest = pcmout;
-		long totalRet = 0;
-		while (totalRet < bufferSize)
-		{
-			long ret=ov_read(&m_vf,readDest, 4096,0,2,1, &m_current_section);
-			if (ret == 0)
-			{
-				m_FileFinished=true;
-				break;
-			}
-			else if (ret < 0)
-			{
-				/* error in the stream.  Not a problem, just reporting it in
-				 case we (the app) cares.  In this case, we don't. */
-			}
-			else
-			{
-				totalRet += ret;
-				readDest += ret;
-			}
-		}
+		Status totalRet = ogg->GetNextChunk( pcmout, bufferSize);
+		m_FileFinished = ogg->atFileEOF();
 		if (totalRet > 0)
 		{
 			buffersWritten++;
@@ -157,7 +125,7 @@
 	return m_Buffer;
 }
 
+#endif
 
 
 
-
Index: source/soundmanager/data/SoundData.h
===================================================================
--- source/soundmanager/data/SoundData.h	(revision 12542)
+++ source/soundmanager/data/SoundData.h	(working copy)
@@ -20,11 +20,13 @@
 
 #include "lib/external_libraries/openal.h"
 #include "lib/file/vfs/vfs_path.h"
-#include "lib/os_path.h"
+#include "lib/config2.h"
 
 #include <string>
 #include <map>
 
+#if CONFIG2_AUDIO
+
 class CSoundData;
 typedef std::map<std::wstring, CSoundData*> DataMap;
 
@@ -61,4 +63,5 @@
 
 };
 
+#endif
 #endif // INCLUDED_SOUNDDATA_H
Index: source/soundmanager/data/OggData.h
===================================================================
--- source/soundmanager/data/OggData.h	(revision 12542)
+++ source/soundmanager/data/OggData.h	(working copy)
@@ -20,7 +20,8 @@
 
 #include "SoundData.h"
 #include "lib/external_libraries/openal.h"
-#include "vorbis/vorbisfile.h"
+#include "ogg.h"
+ #if CONFIG2_AUDIO
 
 class COggData : public CSoundData
 {
@@ -31,7 +32,7 @@
 	COggData();
 	virtual ~COggData();
 
-	virtual bool InitOggFile(const wchar_t* fileLoc);
+	virtual bool InitOggFile(const VfsPath& itemPath);
 	virtual bool IsFileFinished();
 	virtual bool IsOneShot();
 
@@ -39,8 +40,8 @@
 	virtual void ResetFile();
 
 protected:
-	OggVorbis_File  m_vf;
-	int m_current_section;
+	OggStreamPtr  ogg;
+//	int m_current_section;
 	bool m_FileFinished;
 	bool m_OneShot;
 	ALuint m_Buffer[100];
@@ -53,5 +54,5 @@
 	ALuint* GetBufferPtr();
 };
 
-
+#endif
 #endif // INCLUDED_OGGDATA_H
Index: source/soundmanager/data/ogg.cpp
===================================================================
--- source/soundmanager/data/ogg.cpp	(revision 0)
+++ source/soundmanager/data/ogg.cpp	(revision 0)
@@ -0,0 +1,320 @@
+/* Copyright (C) 2012 Wildfire Games.
+ * This file is part of 0 A.D.
+ *
+ * 0 A.D. is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0 A.D. is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "precompiled.h"
+#include "ogg.h"
+
+#if CONFIG2_AUDIO
+
+#include "lib/external_libraries/openal.h"
+#include "lib/external_libraries/vorbis.h"
+
+#include "lib/byte_order.h"
+#include "lib/file/io/io.h"
+#include "lib/file/file_system.h"
+
+#include "lib/file/vfs/vfs_util.h"
+#include "ps/Filesystem.h"
+
+
+static Status LibErrorFromVorbis(int err)
+{
+	switch(err)
+	{
+	case 0:
+		return INFO::OK;
+	case OV_HOLE:
+		return ERR::AGAIN;
+	case OV_EREAD:
+		return ERR::IO;
+	case OV_EFAULT:
+		return ERR::LOGIC;
+	case OV_EIMPL:
+		return ERR::NOT_SUPPORTED;
+	case OV_EINVAL:
+		return ERR::INVALID_PARAM;
+	case OV_ENOTVORBIS:
+		return ERR::NOT_SUPPORTED;
+	case OV_EBADHEADER:
+		return ERR::CORRUPTED;
+	case OV_EVERSION:
+		return ERR::INVALID_VERSION;
+	case OV_ENOTAUDIO:
+		return ERR::_1;
+	case OV_EBADPACKET:
+		return ERR::_2;
+	case OV_EBADLINK:
+		return ERR::_3;
+	case OV_ENOSEEK:
+		return ERR::_4;
+	default:
+		return ERR::FAIL;
+	}
+}
+
+
+//-----------------------------------------------------------------------------
+
+class VorbisFileAdapter
+{
+public:
+	VorbisFileAdapter(const PFile& openedFile)
+		: file(openedFile)
+		, size(FileSize(openedFile->Pathname()))
+		, offset(0)
+	{
+	}
+
+	static size_t Read(void* bufferToFill, size_t itemSize, size_t numItems, void* context)
+	{
+		VorbisFileAdapter* adapter = (VorbisFileAdapter*)context;
+		const off_t sizeRequested = numItems*itemSize;
+		const off_t sizeRemaining = adapter->size - adapter->offset;
+		const size_t sizeToRead = (size_t)std::min(sizeRequested, sizeRemaining);
+
+		io::Operation op(*adapter->file.get(), bufferToFill, sizeToRead, adapter->offset);
+		if(io::Run(op) == INFO::OK)
+		{
+			adapter->offset += sizeToRead;
+			return sizeToRead;
+		}
+
+		errno = EIO;
+		return 0;
+	}
+
+	static int Seek(void* context, ogg_int64_t offset, int whence)
+	{
+		VorbisFileAdapter* adapter = (VorbisFileAdapter*)context;
+
+		off_t origin = 0;
+		switch(whence)
+		{
+		case SEEK_SET:
+			origin = 0;
+			break;
+		case SEEK_CUR:
+			origin = adapter->offset;
+			break;
+		case SEEK_END:
+			origin = adapter->size+1;
+			break;
+			NODEFAULT;
+		}
+
+		adapter->offset = Clamp(off_t(origin+offset), off_t(0), adapter->size);
+		return 0;
+	}
+
+	static int Close(void* context)
+	{
+		VorbisFileAdapter* adapter = (VorbisFileAdapter*)context;
+		adapter->file.reset();
+		return 0;	// return value is ignored
+	}
+
+	static long Tell(void* context)
+	{
+		VorbisFileAdapter* adapter = (VorbisFileAdapter*)context;
+		return adapter->offset;
+	}
+
+private:
+	PFile file;
+	off_t size;
+	off_t offset;
+};
+
+//-----------------------------------------------------------------------------
+
+class VorbisBufferAdapter
+{
+public:
+	VorbisBufferAdapter(const shared_ptr<u8>& buffer, size_t size)
+		: buffer(buffer)
+		, size(size)
+		, offset(0)
+	{
+	}
+
+	static size_t Read(void* bufferToFill, size_t itemSize, size_t numItems, void* context)
+	{
+		VorbisBufferAdapter* adapter = (VorbisBufferAdapter*)context;
+		const off_t sizeRequested = numItems*itemSize;
+		const off_t sizeRemaining = adapter->size - adapter->offset;
+		const size_t sizeToRead = (size_t)std::min(sizeRequested, sizeRemaining);
+
+		memcpy(bufferToFill, adapter->buffer.get() + adapter->offset, sizeToRead);
+
+		adapter->offset += sizeToRead;
+		return sizeToRead;
+	}
+
+	static int Seek(void* context, ogg_int64_t offset, int whence)
+	{
+		VorbisBufferAdapter* adapter = (VorbisBufferAdapter*)context;
+
+		off_t origin = 0;
+		switch(whence)
+		{
+		case SEEK_SET:
+			origin = 0;
+			break;
+		case SEEK_CUR:
+			origin = adapter->offset;
+			break;
+		case SEEK_END:
+			origin = adapter->size+1;
+			break;
+			NODEFAULT;
+		}
+
+		adapter->offset = Clamp(off_t(origin+offset), off_t(0), adapter->size);
+		return 0;
+	}
+
+	static int Close(void* context)
+	{
+		VorbisBufferAdapter* adapter = (VorbisBufferAdapter*)context;
+		adapter->buffer.reset();
+		return 0;	// return value is ignored
+	}
+
+	static long Tell(void* context)
+	{
+		VorbisBufferAdapter* adapter = (VorbisBufferAdapter*)context;
+		return adapter->offset;
+	}
+
+private:
+	shared_ptr<u8> buffer;
+	off_t size;
+	off_t offset;
+};
+
+
+//-----------------------------------------------------------------------------
+
+template <typename Adapter>
+class OggStreamImpl : public OggStream
+{
+public:
+	OggStreamImpl(const Adapter& adapter)
+		: adapter(adapter)
+	{
+		m_fileEOF = false;
+	}
+
+	Status Open()
+	{
+		ov_callbacks callbacks;
+		callbacks.read_func = Adapter::Read;
+		callbacks.close_func = Adapter::Close;
+		callbacks.seek_func = Adapter::Seek;
+		callbacks.tell_func = Adapter::Tell;
+		const int ret = ov_open_callbacks(&adapter, &vf, 0, 0, callbacks);
+		if(ret != 0)
+			WARN_RETURN(LibErrorFromVorbis(ret));
+
+		const int link = -1;	// retrieve info for current bitstream
+		info = ov_info(&vf, link);
+		if(!info)
+			WARN_RETURN(ERR::INVALID_HANDLE);
+
+		return INFO::OK;
+	}
+
+	virtual ALenum Format()
+	{
+		return (info->channels == 1)? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
+	}
+
+	virtual ALsizei SamplingRate()
+	{
+		return info->rate;
+	}
+	virtual bool atFileEOF()
+	{
+		return m_fileEOF;
+	}
+
+	virtual Status ResetFile()
+	{
+	    ov_time_seek( &vf, 0 );
+	    m_fileEOF = false;
+	}
+
+	virtual Status GetNextChunk(u8* buffer, size_t size)
+	{
+		// we may have to call ov_read multiple times because it
+		// treats the buffer size "as a limit and not a request"
+		size_t bytesRead = 0;
+		for(;;)
+		{
+			const int isBigEndian = (BYTE_ORDER == BIG_ENDIAN);
+			const int wordSize = sizeof(i16);
+			const int isSigned = 1;
+			int bitstream;	// unused
+			const int ret = ov_read(&vf, (char*)buffer+bytesRead, int(size-bytesRead), isBigEndian, wordSize, isSigned, &bitstream);
+			if(ret == 0) {	// EOF
+				m_fileEOF = true;
+				return (Status)bytesRead;
+			}
+			else if(ret < 0)
+				WARN_RETURN(LibErrorFromVorbis(ret));
+			else	// success
+			{
+				bytesRead += ret;
+				if(bytesRead == size)
+					return (Status)bytesRead;
+			}
+		}
+	}
+
+private:
+	Adapter adapter;
+	OggVorbis_File vf;
+	vorbis_info* info;
+	bool m_fileEOF;
+};
+
+
+//-----------------------------------------------------------------------------
+
+Status OpenOggStream(const OsPath& pathname, OggStreamPtr& stream)
+{
+	PFile file(new File);
+    RETURN_STATUS_IF_ERR(file->Open(pathname, L'r'));
+
+	shared_ptr<OggStreamImpl<VorbisFileAdapter> > tmp(new OggStreamImpl<VorbisFileAdapter>(VorbisFileAdapter(file)));
+	RETURN_STATUS_IF_ERR(tmp->Open());
+	stream = tmp;
+	return INFO::OK;
+}
+
+Status OpenOggNonstream(const PIVFS& vfs, const VfsPath& pathname, OggStreamPtr& stream)
+{
+	shared_ptr<u8> contents;
+	size_t size;
+	RETURN_STATUS_IF_ERR(vfs->LoadFile(pathname, contents, size));
+
+	shared_ptr<OggStreamImpl<VorbisBufferAdapter> > tmp(new OggStreamImpl<VorbisBufferAdapter>(VorbisBufferAdapter(contents, size)));
+	RETURN_STATUS_IF_ERR(tmp->Open());
+	stream = tmp;
+	return INFO::OK;
+}
+
+#endif	// CONFIG2_AUDIO
Index: source/soundmanager/SoundManager.h
===================================================================
--- source/soundmanager/SoundManager.h	(revision 12542)
+++ source/soundmanager/SoundManager.h	(working copy)
@@ -23,7 +23,11 @@
 
 #include <vector>
 #include <map>
+#if CONFIG2_AUDIO
 
+
+#define AL_CHECK CSoundManager::al_check(__func__, __LINE__);
+
 typedef std::vector<ISoundItem*> ItemsList;
 
 
@@ -45,6 +49,7 @@
 	long m_BufferSize;
 	int m_BufferCount;
 	bool m_MusicEnabled;
+	bool m_SoundEnabled;
 
 public:
 	CSoundManager();
@@ -53,8 +58,14 @@
 	ISoundItem* LoadItem(const VfsPath& itemPath);
 
 	static void ScriptingInit();
+	static void CreateSoundManager();
+	static void SetEnabled(bool doEnable);
+	
+	static void al_ReportError(ALenum err, const char* caller, int line);
+	static void al_check(const char* caller, int line);
 
 	void SetMusicEnabled (bool isEnabled);
+	void setSoundEnabled( bool enabled );
 
 	ISoundItem* ItemFromWAV(VfsPath& fname);
 	ISoundItem* ItemFromOgg(VfsPath& fname);
@@ -78,14 +89,23 @@
 	void SetAmbientGain(float gain);
 	void SetActionGain(float gain);
 	
-	void SetEnabled(bool doEnable);
 protected:
 	void InitListener();
 	virtual Status AlcInit();
 
 };
 
+#else
+class CSoundManager
+{
+public:
+	static void ScriptingInit();
+	static void CreateSoundManager();
+	static void SetEnabled(bool doEnable);
+};
+#endif
+
+
 extern CSoundManager*  g_SoundManager;
 
-
 #endif // INCLUDED_SOUNDMANAGER_H
Index: source/soundmanager/js/SoundGroup.cpp
===================================================================
--- source/soundmanager/js/SoundGroup.cpp	(revision 12542)
+++ source/soundmanager/js/SoundGroup.cpp	(working copy)
@@ -41,6 +41,7 @@
 
 #include <algorithm>
 
+
 extern CGame *g_Game;
 
 #define PI 3.14126f
@@ -155,43 +156,47 @@
 
 void CSoundGroup::UploadPropertiesAndPlay(int theIndex, const CVector3D& position)
 {
-	bool	isOnscreen;
-	ALfloat	initialRolllOff = 0.02f;
-	ALfloat	itemRollOff = initialRolllOff;
+#if CONFIG2_AUDIO
+	if ( g_SoundManager ) {
+		bool	isOnscreen;
+		ALfloat	initialRolllOff = 0.02f;
+		ALfloat	itemRollOff = initialRolllOff;
 
-	float 	offSet = RadiansOffCenter(position, isOnscreen, itemRollOff);
+		float 	offSet = RadiansOffCenter(position, isOnscreen, itemRollOff);
 
-	if (isOnscreen || TestFlag(eDistanceless) || TestFlag(eOmnipresent))
-	{
-		if (snd_group.size() == 0)
-			Reload();
+		if (isOnscreen || TestFlag(eDistanceless) || TestFlag(eOmnipresent))
+		{
+			if (snd_group.size() == 0)
+				Reload();
 
-		ISoundItem* hSound = snd_group[theIndex];
-		CVector3D origin = g_Game->GetView()->GetCamera()->GetOrientation().GetTranslation();
-		float sndDist = origin.Y;
+			ISoundItem* hSound = snd_group[theIndex];
+			CVector3D origin = g_Game->GetView()->GetCamera()->GetOrientation().GetTranslation();
+			float sndDist = origin.Y;
 
-		if (!TestFlag(eOmnipresent))
-		{
-			hSound->SetLocation(CVector3D((sndDist * sin(offSet)), 0, sndDist * cos(offSet)));
-			if (TestFlag(eDistanceless))
-				hSound->SetRollOff(initialRolllOff);
+			if (!TestFlag(eOmnipresent))
+			{
+				hSound->SetLocation(CVector3D((sndDist * sin(offSet)), 0, sndDist * cos(offSet)));
+				if (TestFlag(eDistanceless))
+					hSound->SetRollOff(initialRolllOff);
+				else
+					hSound->SetRollOff(itemRollOff);
+			}
+
+			if (TestFlag(eRandPitch))
+				hSound->SetPitch(RandFloat(m_PitchLower, m_PitchUpper));
 			else
-				hSound->SetRollOff(itemRollOff);
-		}
+				hSound->SetPitch(m_Pitch);
 
-		if (TestFlag(eRandPitch))
-			hSound->SetPitch(RandFloat(m_PitchLower, m_PitchUpper));
-		else
-			hSound->SetPitch(m_Pitch);
+			ALfloat theGain = m_Gain;
+			if (TestFlag(eRandGain))
+				theGain = RandFloat(m_GainLower, m_GainUpper);
 
-		ALfloat theGain = m_Gain;
-		if (TestFlag(eRandGain))
-			theGain = RandFloat(m_GainLower, m_GainUpper);
+			hSound->SetCone(m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain);
 
-		hSound->SetCone(m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain);
-
-		g_SoundManager->PlayGroupItem(hSound, theGain);
+			g_SoundManager->PlayGroupItem(hSound, theGain);
+		}
 	}
+#endif
 }
 
 
@@ -216,30 +221,36 @@
 {
 	m_index = 0; // reset our index
 
+#if CONFIG2_AUDIO
 	snd_group.clear();
 
-	for (size_t i = 0; i < filenames.size(); i++)
-	{
-		VfsPath  thePath =  m_filepath/filenames[i];
-		ISoundItem* temp = g_SoundManager->LoadItem(thePath);
+	if ( g_SoundManager ) {
+		for (size_t i = 0; i < filenames.size(); i++)
+		{
+			VfsPath  thePath =  m_filepath/filenames[i];
+			ISoundItem* temp = g_SoundManager->LoadItem(thePath);
 
-		if (temp == NULL)
-			HandleError(L"error loading sound", thePath, ERR::FAIL);
-		else
-			snd_group.push_back(temp);
+			if (temp == NULL)
+				HandleError(L"error loading sound", thePath, ERR::FAIL);
+			else
+				snd_group.push_back(temp);
+		}
+
+		if (TestFlag(eRandOrder))
+			random_shuffle(snd_group.begin(), snd_group.end());	
 	}
-
-	if (TestFlag(eRandOrder))
-		random_shuffle(snd_group.begin(), snd_group.end());
+#endif
 }
 
 void CSoundGroup::ReleaseGroup()
 {
+#if CONFIG2_AUDIO
 	for (size_t i = 0; i < snd_group.size(); i++)
 	{
 		snd_group[i]->FadeAndDelete(0.2);
 	}
 	snd_group.clear();
+#endif
 }
 
 void CSoundGroup::Update(float UNUSED(TimeSinceLastFrame))
Index: source/soundmanager/js/SoundPlayer.cpp
===================================================================
--- source/soundmanager/js/SoundPlayer.cpp	(revision 12542)
+++ source/soundmanager/js/SoundPlayer.cpp	(working copy)
@@ -34,15 +34,20 @@
 
 bool JSoundPlayer::StartMusic(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
-	g_SoundManager->SetMusicEnabled(true);
-
+#if CONFIG2_AUDIO
+	if ( g_SoundManager )
+		g_SoundManager->SetMusicEnabled(true);
+#endif
 	return true;
 }
 
 // request the sound be played until free() is called. returns immediately.
 bool JSoundPlayer::StopMusic(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
-	g_SoundManager->SetMusicEnabled(false);
+#if CONFIG2_AUDIO
+	if ( g_SoundManager )
+		g_SoundManager->SetMusicEnabled(false);
+#endif
 
 	return true;
 }
@@ -61,7 +66,7 @@
 	JSoundPlayer* newObject = new JSoundPlayer();
 	newObject->m_EngineOwned = false;
 	JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
-	
+
 	return JS_TRUE;
 }
 
Index: source/soundmanager/js/AmbientSound.cpp
===================================================================
--- source/soundmanager/js/AmbientSound.cpp	(revision 12542)
+++ source/soundmanager/js/AmbientSound.cpp	(working copy)
@@ -32,31 +32,40 @@
 // start playing the sound, all ambient sounds loop
 bool JAmbientSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
-	ISoundItem*	aSnd = g_SoundManager->LoadItem(m_FileName);
+ #if CONFIG2_AUDIO
+	if ( g_SoundManager ) {
+		ISoundItem*	aSnd = g_SoundManager->LoadItem(m_FileName);
 
-	if (aSnd)
-		aSnd->PlayAsAmbient();
-	else
-		debug_printf(L"sound item could not be loaded to play: %ls\n", m_FileName.string().c_str());
-
+		if (aSnd)
+			aSnd->PlayAsAmbient();
+		else
+			debug_printf(L"sound item could not be loaded to play: %ls\n", m_FileName.string().c_str());
+	}
+#endif
 	return true;
 }
 
 // start playing the sound, all ambient sounds loop
 bool JAmbientSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
-	ISoundItem*	aSnd = g_SoundManager->LoadItem(m_FileName);
+ #if CONFIG2_AUDIO
+	if ( g_SoundManager ) {
+		ISoundItem*	aSnd = g_SoundManager->LoadItem(m_FileName);
 
-	if (aSnd)
-		aSnd->PlayAsAmbient();
-	else
-		debug_printf(L"sound item could not be loaded to loop: %ls\n", m_FileName.string().c_str());
-
+		if (aSnd)
+			aSnd->PlayAsAmbient();
+		else
+			debug_printf(L"sound item could not be loaded to loop: %ls\n", m_FileName.string().c_str());
+	}
+#endif
 	return true;
 }
 bool JAmbientSound::Free(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
-	g_SoundManager->SetAmbientItem(0L);
+ #if CONFIG2_AUDIO
+	if ( g_SoundManager )
+		g_SoundManager->SetAmbientItem(0L);
+#endif
 
 	return true;
 }
@@ -90,11 +99,12 @@
 	CStrW filename;
 	if (! ToPrimitive<CStrW>(cx, JS_ARGV(cx, vp)[0], filename))
 		return JS_FALSE;
-	
+
 	JAmbientSound* newObject = new JAmbientSound(filename);
 	newObject->m_EngineOwned = false;
 
 	JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
-	
+
 	return JS_TRUE;
 }
+
Index: source/soundmanager/js/Sound.cpp
===================================================================
--- source/soundmanager/js/Sound.cpp	(revision 12542)
+++ source/soundmanager/js/Sound.cpp	(working copy)
@@ -27,26 +27,34 @@
 
 JSound::JSound(const VfsPath& pathname)
 {
-	m_SndItem = g_SoundManager->LoadItem(pathname);
+#if CONFIG2_AUDIO
+	if ( g_SoundManager )
+		m_SndItem = g_SoundManager->LoadItem(pathname);
+#endif
 }
 
 JSound::~JSound()
 {
+#if CONFIG2_AUDIO
 	if (m_SndItem)
 	{
 		m_SndItem->FadeAndDelete(0.2);
 		m_SndItem = 0;
 	}
+#endif
 }
 
 bool JSound::ClearSoundItem()
 {
+#if CONFIG2_AUDIO
 	m_SndItem = 0L;
+#endif
 	return true;
 }
 
 bool JSound::SetGain(JSContext* cx, uintN UNUSED(argc), jsval* argv)
 {
+#if CONFIG2_AUDIO
 	if (! m_SndItem)
 		return false;
 
@@ -54,12 +62,14 @@
 	if (! ToPrimitive<float>(cx, argv[0], gain))
 		return false;
 	
-	m_SndItem->SetGain(gain);	
+	m_SndItem->SetGain(gain);
+#endif
 	return true;
 }
 
 bool JSound::SetPitch(JSContext* cx, uintN UNUSED(argc), jsval* argv)
 {
+#if CONFIG2_AUDIO
 	if (! m_SndItem)
 		return false;
 
@@ -68,11 +78,13 @@
 		return false;
 	
 	m_SndItem->SetPitch(pitch);
+#endif
 	return true;
 }
 
 bool JSound::SetPosition(JSContext* cx, uintN argc, jsval* argv)
 {
+#if CONFIG2_AUDIO
 	if (! m_SndItem)
 		return false;
 	
@@ -84,13 +96,14 @@
 		return false;
 
 	m_SndItem->SetLocation(pos);
-	
+#endif
 	return true;
 }
 
 
 bool JSound::Fade(JSContext* cx, uintN UNUSED(argc), jsval* argv)
 {
+#if CONFIG2_AUDIO
 	if (! m_SndItem)
 		return false;
 	
@@ -104,38 +117,41 @@
 	
 	m_SndItem->SetGain(initial_gain);
 	m_SndItem->FadeToIn(final_gain, length);
-
+#endif
 	return true;
 }
 
 bool JSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
+#if CONFIG2_AUDIO
 	if (! m_SndItem)
 		return false;
 
 	m_SndItem->Play();
-
+#endif
 	return true;
 }
 
 bool JSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
+#if CONFIG2_AUDIO
 	if (! m_SndItem)
 		return false;
 
 	m_SndItem->PlayLoop();
-
+#endif
 	return true;
 }
 
 bool JSound::Free(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
+#if CONFIG2_AUDIO
 	if (m_SndItem)
 	{
 		m_SndItem->FadeAndDelete(0.2);
 		m_SndItem = 0;
 	}
-
+#endif
 	return true;
 }
 
@@ -155,7 +171,11 @@
 
 CStr JSound::ToString(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
+#if CONFIG2_AUDIO
 	return "[object Sound: " + (m_SndItem ? m_SndItem->GetName() : "(null)") + "]";
+#else
+	return "[object Sound: audio disabled]";
+#endif
 }
 
 JSBool JSound::Construct(JSContext* cx, uintN UNUSED(argc), jsval* vp)
@@ -169,6 +189,6 @@
 	JSound* newObject = new JSound(filename);
 	newObject->m_EngineOwned = false;
 	JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
-	
+
 	return JS_TRUE;
 }
Index: source/soundmanager/js/MusicSound.cpp
===================================================================
--- source/soundmanager/js/MusicSound.cpp	(revision 12542)
+++ source/soundmanager/js/MusicSound.cpp	(working copy)
@@ -31,20 +31,26 @@
 
 bool JMusicSound::Play(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
-	ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
-	if (aSnd != NULL)
-		aSnd->PlayAsMusic();
-
+ #if CONFIG2_AUDIO
+	if ( g_SoundManager ) {
+		ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
+		if (aSnd != NULL)
+			aSnd->PlayAsMusic();
+	}
+#endif
 	return true;
 }
 
 // request the sound be played until free() is called. returns immediately.
 bool JMusicSound::Loop(JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(argv))
 {
-	ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
-	if (aSnd != NULL)
-		aSnd->PlayAsMusic();
-
+ #if CONFIG2_AUDIO
+	if ( g_SoundManager ) {
+		ISoundItem* aSnd = g_SoundManager->LoadItem(m_FileName);
+		if (aSnd != NULL)
+			aSnd->PlayAsMusic();
+	}
+#endif
 	return true;
 }
 
@@ -75,6 +81,8 @@
 	JMusicSound* newObject = new JMusicSound(filename);
 	newObject->m_EngineOwned = false;
 	JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(newObject->GetScript()));
-	
+
 	return JS_TRUE;
 }
+
+
Index: source/soundmanager/js/SoundGroup.h
===================================================================
--- source/soundmanager/js/SoundGroup.h	(revision 12542)
+++ source/soundmanager/js/SoundGroup.h	(working copy)
@@ -53,10 +53,13 @@
 #define INCLUDED_SOUNDGROUP_H
 
 #include "lib/file/vfs/vfs_path.h"
+#include "lib/config2.h"
 
 #include <vector>
 
 class CVector3D;
+
+
 class ISoundItem;
 
 enum eSndGrpFlags
@@ -109,7 +112,9 @@
 
 	size_t m_index;  // index of the next sound to play
 		
+#if CONFIG2_AUDIO
 	std::vector<ISoundItem*> snd_group;  // we store the handles so we can load now and play later
+#endif
 	std::vector<std::wstring> filenames; // we need the filenames so we can reload when necessary.
 
 	VfsPath m_filepath; // the file path for the list of sound file resources
Index: source/soundmanager/js/Sound.h
===================================================================
--- source/soundmanager/js/Sound.h	(revision 12542)
+++ source/soundmanager/js/Sound.h	(working copy)
@@ -35,6 +35,7 @@
 #include "scripting/ScriptableObject.h"
 #include "soundmanager/items/ISoundItem.h"
 
+
 class JSound : public CJSObject<JSound>
 {
 public:
@@ -61,7 +62,9 @@
 	static void ScriptingInit();
 
 protected:
+#if CONFIG2_AUDIO
 	ISoundItem* m_SndItem;
+#endif
 };
 
 #endif	// #ifndef INCLUDED_JSOUND
Index: source/simulation2/components/CCmpSoundManager.cpp
===================================================================
--- source/simulation2/components/CCmpSoundManager.cpp	(revision 12542)
+++ source/simulation2/components/CCmpSoundManager.cpp	(working copy)
@@ -36,7 +36,9 @@
 
 	DEFAULT_COMPONENT_ALLOCATOR(SoundManager)
 
+#if CONFIG2_AUDIO
 	std::map<std::wstring, CSoundGroup*> m_SoundGroups;
+#endif
 
 	static std::string GetSchema()
 	{
@@ -49,9 +51,11 @@
 
 	virtual void Deinit()
 	{
+#if CONFIG2_AUDIO
 		for (std::map<std::wstring, CSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)
 			delete it->second;
 		m_SoundGroups.clear();
+#endif
 	}
 
 	virtual void Serialize(ISerializer& UNUSED(serialize))
@@ -76,9 +80,11 @@
 			// or on some other timer?
 			const CMessageUpdate& msgData = static_cast<const CMessageUpdate&> (msg);
 			float t = msgData.turnLength.ToFloat();
+#if CONFIG2_AUDIO
 			for (std::map<std::wstring, CSoundGroup*>::iterator it = m_SoundGroups.begin(); it != m_SoundGroups.end(); ++it)
 				if (it->second)
 					it->second->Update(t);
+#endif
 			break;
 		}
 		}
@@ -86,6 +92,7 @@
 
 	virtual void PlaySoundGroup(std::wstring name, entity_id_t source)
 	{
+#if CONFIG2_AUDIO
 		// Make sure the sound group is loaded
 		CSoundGroup* group;
 		if (m_SoundGroups.find(name) == m_SoundGroups.end())
@@ -127,7 +134,10 @@
 
 			group->PlayNext(sourcePos);
 		}
+#endif
 	}
 };
 
 REGISTER_COMPONENT_TYPE(SoundManager)
+
+
