diff --git a/LEGO1/lego/legoomni/include/lego3dsound.h b/LEGO1/lego/legoomni/include/lego3dsound.h
index a6f4bb02..14be04ee 100644
--- a/LEGO1/lego/legoomni/include/lego3dsound.h
+++ b/LEGO1/lego/legoomni/include/lego3dsound.h
@@ -6,6 +6,7 @@
 
 #include <dsound.h>
 
+class LegoActor;
 class LegoROI;
 
 // VTABLE: LEGO1 0x100d5778
@@ -16,7 +17,7 @@ public:
 	virtual ~Lego3DSound();
 
 	void Init();
-	MxResult Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char*, MxS32 p_volume);
+	MxResult Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name, MxS32 p_volume);
 	void Destroy();
 	undefined4 FUN_100118e0(LPDIRECTSOUNDBUFFER p_directSoundBuffer);
 	void FUN_10011ca0();
@@ -26,15 +27,18 @@ public:
 	// Lego3DSound::`scalar deleting destructor'
 
 private:
-	undefined m_unk0x04[4];         // 0x04
-	LPDIRECTSOUNDBUFFER m_dsBuffer; // 0x08
-	LegoROI* m_unk0x0c;             // 0x0c
-	undefined4 m_unk0x10;           // 0x10
-	MxBool m_unk0x14;               // 0x14
-	MxBool m_unk0x15;               // 0x15
-	undefined4 m_unk0x18;           // 0x18
-	undefined m_unk0x1c[0x10];      // 0x1c
-	MxS32 m_volume;                 // 0x2c
+	LPDIRECTSOUND3DBUFFER m_ds3dBuffer; // 0x08
+	LegoROI* m_roi;                     // 0x0c
+	LegoROI* m_positionROI;             // 0x10
+	MxBool m_enabled;                   // 0x14
+	MxBool m_isActor;                   // 0x15
+	LegoActor* m_actor;                 // 0x18
+	double m_frequencyFactor;           // 0x20
+	DWORD m_dwFrequency;                // 0x28
+	MxS32 m_volume;                     // 0x2c
 };
 
+// GLOBAL: LEGO1 0x100db6c0
+// IID_IDirectSound3DBuffer
+
 #endif // LEGO3DSOUND_H
diff --git a/LEGO1/lego/legoomni/include/legoactor.h b/LEGO1/lego/legoomni/include/legoactor.h
index ebde373c..267de5a0 100644
--- a/LEGO1/lego/legoomni/include/legoactor.h
+++ b/LEGO1/lego/legoomni/include/legoactor.h
@@ -30,10 +30,13 @@ public:
 	void SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) override; // vtable+0x24
 
 	// FUNCTION: LEGO1 0x10002cc0
-	virtual MxFloat VTable0x50() { return m_unk0x68; } // vtable+0x50
+	virtual MxFloat GetSoundFrequencyFactor() { return m_frequencyFactor; } // vtable+0x50
 
 	// FUNCTION: LEGO1 0x10002cd0
-	virtual void VTable0x54(MxFloat p_unk0x68) { m_unk0x68 = p_unk0x68; } // vtable+0x54
+	virtual void SetSoundFrequencyFactor(MxFloat p_frequencyFactor)
+	{
+		m_frequencyFactor = p_frequencyFactor;
+	} // vtable+0x54
 
 	// FUNCTION: LEGO1 0x10002ce0
 	virtual void VTable0x58(MxFloat p_unk0x70) { m_unk0x70 = p_unk0x70; } // vtable+0x58
@@ -52,10 +55,10 @@ public:
 protected:
 	void FUN_1002d6e0(MxBool);
 
-	MxFloat m_unk0x68;       // 0x68
-	LegoCacheSound* m_sound; // 0x6c
-	MxFloat m_unk0x70;       // 0x70
-	MxU8 m_actorId;          // 0x74
+	MxFloat m_frequencyFactor; // 0x68
+	LegoCacheSound* m_sound;   // 0x6c
+	MxFloat m_unk0x70;         // 0x70
+	MxU8 m_actorId;            // 0x74
 };
 
 // SYNTHETIC: LEGO1 0x1002d300
diff --git a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp
index 23b7a8c5..bc68915b 100644
--- a/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp
+++ b/LEGO1/lego/legoomni/src/audio/lego3dsound.cpp
@@ -1,5 +1,6 @@
 #include "lego3dsound.h"
 
+#include "legoactor.h"
 #include "legocharactermanager.h"
 #include "misc.h"
 #include "mxomni.h"
@@ -21,31 +22,83 @@ Lego3DSound::~Lego3DSound()
 // FUNCTION: LEGO1 0x10011680
 void Lego3DSound::Init()
 {
-	m_dsBuffer = NULL;
-	m_unk0x0c = NULL;
-	m_unk0x10 = 0;
-	m_unk0x18 = 0;
-	m_unk0x14 = FALSE;
-	m_unk0x15 = FALSE;
+	m_ds3dBuffer = NULL;
+	m_roi = NULL;
+	m_positionROI = NULL;
+	m_actor = NULL;
+	m_enabled = FALSE;
+	m_isActor = FALSE;
 	m_volume = 79;
 }
 
-// STUB: LEGO1 0x100116a0
+// FUNCTION: LEGO1 0x100116a0
 // FUNCTION: BETA10 0x10039647
-MxResult Lego3DSound::Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char*, MxS32 p_volume)
+MxResult Lego3DSound::Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name, MxS32 p_volume)
 {
 	m_volume = p_volume;
 
 	if (MxOmni::IsSound3D()) {
-		p_directSoundBuffer->QueryInterface(IID_IDirectSoundBuffer, (LPVOID*) &m_dsBuffer);
-		if (m_dsBuffer == NULL) {
+		p_directSoundBuffer->QueryInterface(IID_IDirectSound3DBuffer, (LPVOID*) &m_ds3dBuffer);
+		if (m_ds3dBuffer == NULL) {
 			return FAILURE;
 		}
 
-		// TODO
+		m_ds3dBuffer->SetMinDistance(15.0f, 0);
+		m_ds3dBuffer->SetMaxDistance(100.0f, 0);
+		m_ds3dBuffer->SetPosition(0.0f, 0.0f, -40.0f, 0);
+		m_ds3dBuffer->SetConeOutsideVolume(-10000, 0);
 	}
 
-	// TODO
+	if (m_ds3dBuffer == NULL || p_name == NULL) {
+		return SUCCESS;
+	}
+
+	if (CharacterManager()->Exists(p_name)) {
+		m_roi = CharacterManager()->GetROI(p_name, TRUE);
+		m_enabled = m_isActor = TRUE;
+	}
+	else {
+		m_roi = FindROI(p_name);
+	}
+
+	if (m_roi == NULL) {
+		m_roi = CharacterManager()->FUN_10085210(NULL, p_name, TRUE);
+
+		if (m_roi != NULL) {
+			m_enabled = TRUE;
+		}
+	}
+
+	if (m_roi == NULL) {
+		return SUCCESS;
+	}
+
+	if (m_isActor) {
+		m_positionROI = m_roi->FindChildROI("head", m_roi);
+	}
+	else {
+		m_positionROI = m_roi;
+	}
+
+	if (MxOmni::IsSound3D()) {
+		const float* position = m_positionROI->GetWorldPosition();
+		m_ds3dBuffer->SetPosition(position[0], position[1], position[2], 0);
+	}
+
+	LegoEntity* entity = m_roi->GetEntity();
+	if (entity != NULL && entity->IsA("LegoActor") && ((LegoActor*) entity)->GetSoundFrequencyFactor() != 0.0f) {
+		m_actor = ((LegoActor*) entity);
+	}
+
+	p_directSoundBuffer->GetFrequency(&m_dwFrequency);
+
+	if (m_actor != NULL) {
+		m_frequencyFactor = m_actor->GetSoundFrequencyFactor();
+
+		if (m_frequencyFactor != 0.0) {
+			p_directSoundBuffer->SetFrequency(m_frequencyFactor * m_dwFrequency);
+		}
+	}
 
 	return SUCCESS;
 }
@@ -53,17 +106,17 @@ MxResult Lego3DSound::Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char
 // FUNCTION: LEGO1 0x10011880
 void Lego3DSound::Destroy()
 {
-	if (m_dsBuffer) {
-		m_dsBuffer->Release();
-		m_dsBuffer = NULL;
+	if (m_ds3dBuffer) {
+		m_ds3dBuffer->Release();
+		m_ds3dBuffer = NULL;
 	}
 
-	if (m_unk0x14 && m_unk0x0c && CharacterManager()) {
-		if (m_unk0x15) {
-			CharacterManager()->FUN_10083db0(m_unk0x0c);
+	if (m_enabled && m_roi && CharacterManager()) {
+		if (m_isActor) {
+			CharacterManager()->FUN_10083db0(m_roi);
 		}
 		else {
-			CharacterManager()->FUN_10083f10(m_unk0x0c);
+			CharacterManager()->FUN_10083f10(m_roi);
 		}
 	}
 
diff --git a/LEGO1/lego/legoomni/src/entity/legoactor.cpp b/LEGO1/lego/legoomni/src/entity/legoactor.cpp
index 6c455909..79c6571e 100644
--- a/LEGO1/lego/legoomni/src/entity/legoactor.cpp
+++ b/LEGO1/lego/legoomni/src/entity/legoactor.cpp
@@ -15,7 +15,7 @@ const char* g_actorNames[] = {"none", "pepper", "mama", "papa", "nick", "laura",
 // FUNCTION: LEGO1 0x1002d110
 LegoActor::LegoActor()
 {
-	m_unk0x68 = 0.0f;
+	m_frequencyFactor = 0.0f;
 	m_sound = NULL;
 	m_unk0x70 = 0.0f;
 	m_unk0x10 = 0;
diff --git a/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp
index 33c04798..af8c95b0 100644
--- a/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp
+++ b/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp
@@ -30,7 +30,7 @@ LegoCarRaceActor::LegoCarRaceActor()
 	m_unk0x70 = 0.0f;
 	m_unk0x0c = 0;
 	m_unk0x13c = 0.0f;
-	m_unk0x68 = 1.0f;
+	m_frequencyFactor = 1.0f;
 	m_unk0x1c = 0;
 	m_unk0x10 = 0.65f;
 	m_unk0x14 = 0.03f;