Index: /trunk/nv/fmod/fmod_audio.hh
===================================================================
--- /trunk/nv/fmod/fmod_audio.hh	(revision 329)
+++ /trunk/nv/fmod/fmod_audio.hh	(revision 330)
@@ -32,11 +32,14 @@
 		public:
 			audio();
-			virtual channel play_sound( sound a_sound );
+			virtual channel play_sound( sound a_sound, float volume = 1.0f, float pan = 0.0f );
+			virtual channel play_sound( sound a_sound, vec3 position );
 			virtual sound load_sound( const std::string& a_path );
 			virtual void release( sound a_sound );
-			virtual void update();
+			virtual void set_orientation( vec3 forward, vec3 up );
+			virtual void update( vec3 position );
 			virtual ~audio();
 		private:
 			entity_store< sound_info, sound >     m_sounds;
+			vec3                                  m_position;
 			void* m_system;
 		};
Index: /trunk/nv/interface/audio.hh
===================================================================
--- /trunk/nv/interface/audio.hh	(revision 329)
+++ /trunk/nv/interface/audio.hh	(revision 330)
@@ -28,9 +28,11 @@
 	{
 	public:
-		virtual channel play_sound( sound a_sound ) = 0;
+		virtual channel play_sound( sound a_sound, float volume = 1.0f, float pan = 0.0f ) = 0;
+		virtual channel play_sound( sound a_sound, vec3 position ) = 0;
 		// temporary - use streams later
 		virtual sound load_sound( const std::string& a_path ) = 0;
 		virtual void release( sound a_sound ) = 0;
-		virtual void update() {}
+		virtual void set_orientation( vec3 forward, vec3 up ) = 0;
+		virtual void update( vec3 ) {}
 		virtual ~audio() {}
 	};
Index: /trunk/nv/sdl/sdl_audio.hh
===================================================================
--- /trunk/nv/sdl/sdl_audio.hh	(revision 329)
+++ /trunk/nv/sdl/sdl_audio.hh	(revision 330)
@@ -30,10 +30,15 @@
 		public:
 			audio();
-			virtual channel play_sound( sound a_sound );
+			virtual channel play_sound( sound a_sound, float volume = 1.0f, float pan = 0.0f );
+			virtual channel play_sound( sound a_sound, vec3 position );
 			virtual sound load_sound( const std::string& a_path );
 			virtual void release( sound a_sound );
-			virtual void update();
+			virtual void set_orientation( vec3 forward, vec3 up );
+			virtual void update( vec3 position );
 			virtual ~audio();
 		private:
+			vec3                                  m_position;
+			vec3                                  m_forward;
+			vec3                                  m_up;
 			entity_store< sound_info, sound >     m_sounds;
 		};
Index: /trunk/src/fmod/fmod_audio.cc
===================================================================
--- /trunk/src/fmod/fmod_audio.cc	(revision 329)
+++ /trunk/src/fmod/fmod_audio.cc	(revision 330)
@@ -27,5 +27,5 @@
 		return;
 	}
-	result = FMOD_System_Init( system, 64, FMOD_INIT_NORMAL, 0 );
+	result = FMOD_System_Init( system, 64, FMOD_3D | FMOD_INIT_3D_RIGHTHANDED, 0 );
 	if ( result != FMOD_OK )
 	{
@@ -36,16 +36,22 @@
 }
 
-
-nv::channel fmod::audio::play_sound( nv::sound a_sound )
+nv::channel nv::fmod::audio::play_sound( sound a_sound, float volume, float pan /*= 0.0f */ )
 {
 	sound_info* info = m_sounds.get( a_sound );
 	if ( info )
 	{
-		FMOD_SYSTEM* system = (FMOD_SYSTEM*)m_system;
-		FMOD_SOUND* sample  = (FMOD_SOUND*)( info->fmod_sound );
-		FMOD_RESULT result  = FMOD_System_PlaySound( system, FMOD_CHANNEL_FREE, sample, false, 0 );
+		FMOD_SYSTEM* system   = (FMOD_SYSTEM*)m_system;
+		FMOD_SOUND* sample    = (FMOD_SOUND*)( info->fmod_sound );
+		FMOD_CHANNEL* channel = nullptr;
+		FMOD_RESULT result    = FMOD_System_PlaySound( system, FMOD_CHANNEL_FREE, sample, true, &channel );
 		if ( result != FMOD_OK )
 		{
 			NV_LOG( LOG_WARNING, "FMOD failed to play sound -- " << FMOD_ErrorString( result ) );
+		}
+		else
+		{
+			FMOD_Channel_SetVolume( channel, volume );
+			FMOD_Channel_SetPan( channel, pan );
+			FMOD_Channel_SetPaused( channel, false );
 		}
 	}
@@ -53,9 +59,38 @@
 }
 
+nv::channel nv::fmod::audio::play_sound( sound a_sound, vec3 position )
+{
+	sound_info* info = m_sounds.get( a_sound );
+	if ( info )
+	{
+		FMOD_SYSTEM* system   = (FMOD_SYSTEM*)m_system;
+		FMOD_SOUND* sample    = (FMOD_SOUND*)( info->fmod_sound );
+		FMOD_CHANNEL* channel = nullptr;
+		FMOD_RESULT result    = FMOD_System_PlaySound( system, FMOD_CHANNEL_FREE, sample, true, &channel );
+		if ( result != FMOD_OK )
+		{
+			NV_LOG( LOG_WARNING, "FMOD failed to play sound -- " << FMOD_ErrorString( result ) );
+		}
+		else
+		{
+			FMOD_VECTOR fmod_position;
+			fmod_position.x = position.x;
+			fmod_position.y = position.y;
+			fmod_position.z = position.z;
+			FMOD_Channel_Set3DMinMaxDistance( channel, 1, 100000 );
+			FMOD_Channel_Set3DAttributes( channel, &fmod_position, 0 );
+			FMOD_Channel_SetPaused( channel, false );
+		}
+	}
+	return channel();
+}
+
+
+
 nv::sound fmod::audio::load_sound( const std::string& a_path )
 {
 	FMOD_SYSTEM* system = (FMOD_SYSTEM*)m_system;
 	FMOD_SOUND* sample;
-	FMOD_RESULT fm_result = FMOD_System_CreateSound( system, a_path.c_str(), FMOD_DEFAULT, 0, &sample );
+	FMOD_RESULT fm_result = FMOD_System_CreateSound( system, a_path.c_str(), FMOD_3D, 0, &sample );
 	if ( fm_result != FMOD_OK )
 	{
@@ -79,8 +114,32 @@
 }
 
-void fmod::audio::update()
+void nv::fmod::audio::set_orientation( vec3 forward, vec3 up )
 {
+ 	FMOD_VECTOR fmod_forward;
+	fmod_forward.x = forward.x;
+	fmod_forward.y = forward.y;
+	fmod_forward.z = forward.z;
+	FMOD_VECTOR fmod_up;
+	fmod_up.x = up.x;
+	fmod_up.y = up.y;
+	fmod_up.z = up.z;
+	// TODO: we also need to setup orientation!
+	FMOD_System_Set3DListenerAttributes( (FMOD_SYSTEM*)m_system, 0, 0, 0, &fmod_forward, &fmod_up );
+}
+
+void fmod::audio::update( vec3 position )
+{
+	m_position = position;
+	FMOD_VECTOR fmod_position;
+	fmod_position.x = position.x;
+	fmod_position.y = position.y;
+	fmod_position.z = position.z;
+// 	FMOD_VECTOR fmod_up;
+// 	fmod_up.x = 0.0f;
+// 	fmod_up.y = 0.0f;
+// 	fmod_up.z = 0.0f;
+	// TODO: we also need to setup orientation!
+	FMOD_System_Set3DListenerAttributes( (FMOD_SYSTEM*)m_system, 0, &fmod_position, 0, 0, 0 );
 	FMOD_System_Update( (FMOD_SYSTEM*)m_system );
-	// no-op
 }
 
Index: /trunk/src/sdl/sdl_audio.cc
===================================================================
--- /trunk/src/sdl/sdl_audio.cc	(revision 329)
+++ /trunk/src/sdl/sdl_audio.cc	(revision 330)
@@ -7,4 +7,5 @@
 #include "nv/sdl/sdl_audio.hh"
 
+#include <glm/gtx/vector_angle.hpp>
 #include "nv/lib/sdl.hh"
 #include "nv/lib/sdl_mixer.hh"
@@ -31,13 +32,53 @@
 }
 
-
-nv::channel sdl::audio::play_sound( sound a_sound )
+nv::channel nv::sdl::audio::play_sound( sound a_sound, float volume, float pan /*= 0.0f */ )
 {
 	sound_info* info = m_sounds.get( a_sound );
 	if ( info )
 	{
-		if ( Mix_PlayChannel(-1, (Mix_Chunk*)( info->sdl_sound), 0) == -1 )
+		int channel = Mix_PlayChannel(-1, (Mix_Chunk*)( info->sdl_sound), 0);
+		if ( channel == -1 )
 		{
 			NV_LOG( LOG_WARNING, "SDL_mixer failed to play -- " << Mix_GetError() );
+		}
+		else
+		{
+			Mix_Volume( channel, int( volume * 128.0f ) );
+			if ( pan != 0.0f) 
+			{
+				uint8 right = (uint8)( (pan + 1.0f) * 127.0f ); 
+				Mix_SetPanning( channel, 254-right, right );
+			}
+			else
+			{
+				Mix_SetPanning( channel, 255, 255 );
+			}
+		}
+	}
+	return channel();
+}
+
+nv::channel nv::sdl::audio::play_sound( sound a_sound, vec3 position )
+{
+	sound_info* info = m_sounds.get( a_sound );
+	if ( info )
+	{
+		int channel = Mix_PlayChannel(-1, (Mix_Chunk*)( info->sdl_sound), 0);
+		if ( channel == -1 )
+		{
+			NV_LOG( LOG_WARNING, "SDL_mixer failed to play -- " << Mix_GetError() );
+		}
+		else
+		{
+			vec3 relative = position - m_position;
+			float angle = 0;
+			float distance = 0;
+			if ( relative != vec3() )
+			{
+				angle = -glm::orientedAngle( m_forward, glm::normalize( relative ), m_up );
+				distance = glm::clamp( 20.0f * glm::length( relative ), 0.0f, 255.0f );
+			}
+			if ( angle < 0.0f ) angle += 360.0f;
+			Mix_SetPosition( channel, sint16(angle), uint8(distance) );
 		}
 	}
@@ -47,5 +88,5 @@
 nv::sound nv::sdl::audio::load_sound( const std::string& a_path )
 {
-	// TODO: this is a really wierd error - if we remove this check, all hell gets loose
+	// TODO: this is a really weird error - if we remove this check, all hell gets loose
 	if ( Mix_LoadWAV_RW == nullptr || SDL_RWFromFile == nullptr ) 
 	{
@@ -64,7 +105,7 @@
 }
 
-void nv::sdl::audio::update()
+void nv::sdl::audio::update( vec3 position )
 {
-	// no-op
+	m_position = position;
 }
 
@@ -88,2 +129,8 @@
 }
 
+void nv::sdl::audio::set_orientation( vec3 forward, vec3 up )
+{
+	m_forward = forward;
+	m_up      = up;
+}
+
