diff --git a/LEGO1/lego/legoomni/include/lego3dsound.h b/LEGO1/lego/legoomni/include/lego3dsound.h
index 14be04ee..315858d0 100644
--- a/LEGO1/lego/legoomni/include/lego3dsound.h
+++ b/LEGO1/lego/legoomni/include/lego3dsound.h
@@ -19,7 +19,7 @@ public:
 	void Init();
 	MxResult Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name, MxS32 p_volume);
 	void Destroy();
-	undefined4 FUN_100118e0(LPDIRECTSOUNDBUFFER p_directSoundBuffer);
+	MxU32 UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer);
 	void FUN_10011ca0();
 	MxS32 FUN_10011cf0(undefined4, undefined4);
 
diff --git a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp
index eef3aa86..d93e0c6d 100644
--- a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp
+++ b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp
@@ -2,9 +2,13 @@
 
 #include "legoactor.h"
 #include "legocharactermanager.h"
+#include "legosoundmanager.h"
+#include "legovideomanager.h"
 #include "misc.h"
 #include "mxomni.h"
 
+#include <vec.h>
+
 DECOMP_SIZE_ASSERT(Lego3DSound, 0x30)
 
 // FUNCTION: LEGO1 0x10011630
@@ -123,12 +127,61 @@ void Lego3DSound::Destroy()
 	Init();
 }
 
-// STUB: LEGO1 0x100118e0
+// FUNCTION: LEGO1 0x100118e0
 // FUNCTION: BETA10 0x10039a2a
-undefined4 Lego3DSound::FUN_100118e0(LPDIRECTSOUNDBUFFER p_directSoundBuffer)
+MxU32 Lego3DSound::UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer)
 {
-	// TODO
-	return 0;
+	MxU32 updated = FALSE;
+
+	if (m_positionROI != NULL) {
+		const float* position = m_positionROI->GetWorldPosition();
+
+		ViewROI* pov = VideoManager()->GetViewROI();
+		assert(pov);
+
+		const float* povPosition = pov->GetWorldPosition();
+		float distance = DISTSQRD3(povPosition, position);
+
+		if (distance > 10000.0f) {
+			return FALSE;
+		}
+
+		if (m_ds3dBuffer != NULL) {
+			m_ds3dBuffer->SetPosition(position[0], position[1], position[2], 0);
+		}
+		else {
+			MxS32 newVolume = m_volume;
+
+			if (distance < 100.0f) {
+				newVolume = m_volume;
+			}
+			else if (distance < 400.0f) {
+				newVolume *= 0.4;
+			}
+			else if (distance < 3600.0f) {
+				newVolume *= 0.1;
+			}
+			else if (distance < 10000.0f) {
+				newVolume = 0;
+			}
+
+			newVolume = newVolume * SoundManager()->GetVolume() / 100;
+			newVolume = SoundManager()->GetAttenuation(newVolume);
+			p_directSoundBuffer->SetVolume(newVolume);
+		}
+
+		updated = TRUE;
+	}
+
+	if (m_actor != NULL) {
+		if (abs(m_frequencyFactor - m_actor->GetSoundFrequencyFactor()) > 0.0001) {
+			m_frequencyFactor = m_actor->GetSoundFrequencyFactor();
+			p_directSoundBuffer->SetFrequency(m_frequencyFactor * m_dwFrequency);
+			updated = TRUE;
+		}
+	}
+
+	return updated;
 }
 
 // STUB: LEGO1 0x10011ca0
diff --git a/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp b/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp
index 10b79146..8083822e 100644
--- a/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp
+++ b/LEGO1/lego/legoomni/src/audio/lego3dwavepresenter.cpp
@@ -62,5 +62,5 @@ void Lego3DWavePresenter::StartingTickle()
 void Lego3DWavePresenter::StreamingTickle()
 {
 	MxWavePresenter::StreamingTickle();
-	m_sound.FUN_100118e0(m_dsBuffer);
+	m_sound.UpdatePosition(m_dsBuffer);
 }
diff --git a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp
index 7d4f565c..3c2ab5f1 100644
--- a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp
+++ b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp
@@ -134,7 +134,7 @@ void LegoCacheSound::FUN_10006be0()
 	}
 
 	if (m_string0x74.GetLength() != 0 && !m_unk0x84) {
-		if (!m_unk0x10.FUN_100118e0(m_dsBuffer)) {
+		if (!m_unk0x10.UpdatePosition(m_dsBuffer)) {
 			if (m_unk0x6a) {
 				return;
 			}