-                    
+					
+						Controls the main volume of the game.
+					
+                    
                         Controls the overall volume of background music.
                     
-                    
+                    
                         Toggles whether or not the low-health beeping sound plays.
                     
                 
diff --git a/include/recomp_sound.h b/include/recomp_sound.h
index 04408e0..f33ed4a 100644
--- a/include/recomp_sound.h
+++ b/include/recomp_sound.h
@@ -3,6 +3,8 @@
 
 namespace recomp {
     void reset_sound_settings();
+    void set_main_volume(int volume);
+    int get_main_volume();
     void set_bgm_volume(int volume);
     int get_bgm_volume();
     void set_low_health_beeps_enabled(bool enabled);
diff --git a/src/game/config.cpp b/src/game/config.cpp
index 7c37d2a..2ea2646 100644
--- a/src/game/config.cpp
+++ b/src/game/config.cpp
@@ -344,6 +344,7 @@ void load_controls_config(const std::filesystem::path& path) {
 void save_sound_config(const std::filesystem::path& path) {
     nlohmann::json config_json{};
 
+    config_json["main_volume"] = recomp::get_main_volume();
     config_json["bgm_volume"] = recomp::get_bgm_volume();
     config_json["low_health_beeps"] = recomp::get_low_health_beeps_enabled();
     
@@ -357,8 +358,8 @@ void load_sound_config(const std::filesystem::path& path) {
 
     config_file >> config_json;
 
-    
     recomp::reset_sound_settings();
+    call_if_key_exists(recomp::set_main_volume, config_json, "main_volume");
     call_if_key_exists(recomp::set_bgm_volume, config_json, "bgm_volume");
     call_if_key_exists(recomp::set_low_health_beeps_enabled, config_json, "low_health_beeps");
 }
diff --git a/src/game/recomp_api.cpp b/src/game/recomp_api.cpp
index 84d7000..5563501 100644
--- a/src/game/recomp_api.cpp
+++ b/src/game/recomp_api.cpp
@@ -78,7 +78,6 @@ extern "C" void recomp_get_targeting_mode(uint8_t* rdram, recomp_context* ctx) {
     _return(ctx, static_cast
(recomp::get_targeting_mode()));
 }
 
-
 extern "C" void recomp_get_bgm_volume(uint8_t* rdram, recomp_context* ctx) {
     _return(ctx, recomp::get_bgm_volume() / 100.0f);
 }
diff --git a/src/main/main.cpp b/src/main/main.cpp
index 42b382f..e2a60f5 100644
--- a/src/main/main.cpp
+++ b/src/main/main.cpp
@@ -23,6 +23,7 @@
 #include "recomp_input.h"
 #include "recomp_config.h"
 #include "recomp_game.h"
+#include "recomp_sound.h"
 
 #ifdef _WIN32
 #define WIN32_LEAN_AND_MEAN
@@ -191,9 +192,10 @@ void queue_samples(int16_t* audio_data, size_t sample_count) {
 
     // Convert the audio from 16-bit values to floats and swap the audio channels into the
     // swap buffer to correct for the address xor caused by endianness handling.
+    float cur_main_volume = recomp::get_main_volume() / 100.0f; // Get the current main volume, normalized to 0.0-1.0.
     for (size_t i = 0; i < sample_count; i += input_channels) {
-        swap_buffer[i + 0 + duplicated_input_frames * input_channels] = audio_data[i + 1] * (0.5f / 32768.0f);
-        swap_buffer[i + 1 + duplicated_input_frames * input_channels] = audio_data[i + 0] * (0.5f / 32768.0f);
+        swap_buffer[i + 0 + duplicated_input_frames * input_channels] = audio_data[i + 1] * (0.5f / 32768.0f) * cur_main_volume;
+        swap_buffer[i + 1 + duplicated_input_frames * input_channels] = audio_data[i + 0] * (0.5f / 32768.0f) * cur_main_volume;
     }
     
     // TODO handle cases where a chunk is smaller than the duplicated frame count.
diff --git a/src/ui/ui_config.cpp b/src/ui/ui_config.cpp
index 1891fec..a436120 100644
--- a/src/ui/ui_config.cpp
+++ b/src/ui/ui_config.cpp
@@ -354,10 +354,12 @@ void recomp::set_autosave_mode(recomp::AutosaveMode mode) {
 }
 
 struct SoundOptionsContext {
+	std::atomic main_volume; // Option to control the volume of all sound
 	std::atomic bgm_volume;
 	std::atomic low_health_beeps_enabled; // RmlUi doesn't seem to like "true"/"false" strings for setting variants so an int is used here instead.
 	void reset() {
 		bgm_volume = 100;
+		main_volume = 100;
 		low_health_beeps_enabled = (int)true;
 	}
 	SoundOptionsContext() {
@@ -374,6 +376,17 @@ void recomp::reset_sound_settings() {
 	}
 }
 
+void recomp::set_main_volume(int volume) {
+	sound_options_context.main_volume.store(volume);
+	if (sound_options_model_handle) {
+		sound_options_model_handle.DirtyVariable("main_volume");
+	}
+}
+
+int recomp::get_main_volume() {
+	return sound_options_context.main_volume.load();
+}
+
 void recomp::set_bgm_volume(int volume) {
     sound_options_context.bgm_volume.store(volume);
 	if (sound_options_model_handle) {
@@ -852,6 +865,7 @@ public:
 		
 		sound_options_model_handle = constructor.GetModelHandle();
 
+		bind_atomic(constructor, sound_options_model_handle, "main_volume", &sound_options_context.main_volume);
 		bind_atomic(constructor, sound_options_model_handle, "bgm_volume", &sound_options_context.bgm_volume);
 		bind_atomic(constructor, sound_options_model_handle, "low_health_beeps_enabled", &sound_options_context.low_health_beeps_enabled);
 	}