diff --git a/Configuration/UserConfig.cs b/Configuration/UserConfig.cs
index 112fba29..f88ce6a6 100644
--- a/Configuration/UserConfig.cs
+++ b/Configuration/UserConfig.cs
@@ -66,6 +66,16 @@ public bool MuteNotifications{
             }
         }
 
+        public string NotificationSoundPath{
+            get{
+                return !string.IsNullOrEmpty(notificationSoundPath) && File.Exists(notificationSoundPath) ? notificationSoundPath : string.Empty;
+            }
+
+            set{
+                notificationSoundPath = value;
+            }
+        }
+
         public TrayIcon.Behavior TrayBehavior{
             get{
                 return trayBehavior;
@@ -95,6 +105,7 @@ public TrayIcon.Behavior TrayBehavior{
 
         private int fileVersion;
         private bool muteNotifications;
+        private string notificationSoundPath;
         private TrayIcon.Behavior trayBehavior;
 
         private UserConfig(string file){
diff --git a/Core/FormBrowser.cs b/Core/FormBrowser.cs
index 9bb75b55..6bd8f79a 100644
--- a/Core/FormBrowser.cs
+++ b/Core/FormBrowser.cs
@@ -14,6 +14,7 @@
 using TweetDck.Plugins;
 using TweetDck.Plugins.Enums;
 using TweetDck.Plugins.Events;
+using System.Media;
 
 namespace TweetDck.Core{
     sealed partial class FormBrowser : Form{
@@ -37,6 +38,8 @@ private static UserConfig Config{
 
         private FormWindowState prevState;
 
+        private SoundPlayer notificationSound;
+
         public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings){
             InitializeComponent();
 
@@ -67,7 +70,13 @@ public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings)
 
             Controls.Add(browser);
 
-            Disposed += (sender, args) => browser.Dispose();
+            Disposed += (sender, args) => {
+                browser.Dispose();
+
+                if (notificationSound != null){
+                    notificationSound.Dispose();
+                }
+            };
 
             this.trayIcon.ClickRestore += trayIcon_ClickRestore;
             this.trayIcon.ClickClose += trayIcon_ClickClose;
@@ -287,12 +296,28 @@ public void OpenPlugins(){
             }
         }
 
-        public void OnTweetNotification(){
+        public void OnTweetNotification(){ // may be called multiple times, once for each type of notification
             if (Config.EnableTrayHighlight && !ContainsFocus){
                 trayIcon.HasNotifications = true;
             }
         }
 
+        public void PlayNotificationSound(){
+            if (string.IsNullOrEmpty(Config.NotificationSoundPath)){
+                return;
+            }
+
+            if (notificationSound == null){
+                notificationSound = new SoundPlayer();
+            }
+
+            if (notificationSound.SoundLocation != Config.NotificationSoundPath){
+                notificationSound.SoundLocation = Config.NotificationSoundPath;
+            }
+
+            notificationSound.Play();
+        }
+
         public void OnTweetScreenshotReady(string html, int width, int height){
             FormNotification dummyWindow = CreateNotificationForm(NotificationFlags.DisableScripts | NotificationFlags.DisableContextMenu | NotificationFlags.TopMost);
 
diff --git a/Core/Handling/TweetDeckBridge.cs b/Core/Handling/TweetDeckBridge.cs
index b4669bc6..72edecfe 100644
--- a/Core/Handling/TweetDeckBridge.cs
+++ b/Core/Handling/TweetDeckBridge.cs
@@ -34,6 +34,12 @@ public bool MuteNotifications{
             }
         }
 
+        public bool HasCustomNotificationSound{
+            get{
+                return !string.IsNullOrEmpty(Program.UserConfig.NotificationSoundPath);
+            }
+        }
+
         public bool ExpandLinksOnHover{
             get{
                 return Program.UserConfig.ExpandLinksOnHover;
@@ -100,7 +106,10 @@ public void OnTweetPopup(string tweetHtml, string tweetUrl, int tweetCharacters)
         }
 
         public void OnTweetSound(){
-            form.InvokeSafe(form.OnTweetNotification);
+            form.InvokeSafe(() => {
+                form.OnTweetNotification();
+                form.PlayNotificationSound();
+            });
         }
 
         public void OnNotificationReady(){
diff --git a/Core/Other/FormSettings.cs b/Core/Other/FormSettings.cs
index 55b1a144..4e85e5c1 100644
--- a/Core/Other/FormSettings.cs
+++ b/Core/Other/FormSettings.cs
@@ -42,6 +42,10 @@ private void SelectTab<T>(Func<T> constructor) where T : BaseTabSettings{
         }
 
         private void FormSettings_FormClosing(object sender, FormClosingEventArgs e){
+            foreach(BaseTabSettings control in tabs.Values){
+                control.OnClosing();
+            }
+
             Program.UserConfig.Save();
 
             foreach(BaseTabSettings control in tabs.Values){
diff --git a/Core/Other/Settings/BaseTabSettings.cs b/Core/Other/Settings/BaseTabSettings.cs
index b25aa945..1028c43f 100644
--- a/Core/Other/Settings/BaseTabSettings.cs
+++ b/Core/Other/Settings/BaseTabSettings.cs
@@ -15,6 +15,8 @@ public BaseTabSettings(){
             Padding = new Padding(6);
         }
 
+        public virtual void OnClosing(){}
+
         protected static void PromptRestart(){
             if (MessageBox.Show("The application must restart for the setting to take place. Do you want to restart now?", Program.BrandName+" Settings", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes){
                 Program.Restart();
diff --git a/Core/Other/Settings/TabSettingsNotifications.Designer.cs b/Core/Other/Settings/TabSettingsNotifications.Designer.cs
index 8908ec09..c55ba154 100644
--- a/Core/Other/Settings/TabSettingsNotifications.Designer.cs
+++ b/Core/Other/Settings/TabSettingsNotifications.Designer.cs
@@ -47,12 +47,17 @@ private void InitializeComponent() {
             this.checkLegacyLoad = new System.Windows.Forms.CheckBox();
             this.checkNotificationTimer = new System.Windows.Forms.CheckBox();
             this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+            this.groupCustomSound = new System.Windows.Forms.GroupBox();
+            this.tbCustomSound = new System.Windows.Forms.TextBox();
+            this.btnBrowseSound = new System.Windows.Forms.Button();
+            this.btnResetSound = new System.Windows.Forms.Button();
             this.groupNotificationLocation.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.trackBarEdgeDistance)).BeginInit();
             this.groupNotificationDuration.SuspendLayout();
             this.tableLayoutDurationButtons.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.trackBarDuration)).BeginInit();
             this.groupUserInterface.SuspendLayout();
+            this.groupCustomSound.SuspendLayout();
             this.SuspendLayout();
             // 
             // groupNotificationLocation
@@ -349,10 +354,54 @@ private void InitializeComponent() {
             this.checkNotificationTimer.UseVisualStyleBackColor = true;
             this.checkNotificationTimer.CheckedChanged += new System.EventHandler(this.checkNotificationTimer_CheckedChanged);
             // 
+            // groupCustomSound
+            // 
+            this.groupCustomSound.Controls.Add(this.btnResetSound);
+            this.groupCustomSound.Controls.Add(this.btnBrowseSound);
+            this.groupCustomSound.Controls.Add(this.tbCustomSound);
+            this.groupCustomSound.Location = new System.Drawing.Point(9, 201);
+            this.groupCustomSound.Name = "groupCustomSound";
+            this.groupCustomSound.Size = new System.Drawing.Size(183, 72);
+            this.groupCustomSound.TabIndex = 11;
+            this.groupCustomSound.TabStop = false;
+            this.groupCustomSound.Text = "Custom Sound";
+            // 
+            // tbCustomSound
+            // 
+            this.tbCustomSound.Location = new System.Drawing.Point(6, 19);
+            this.tbCustomSound.Name = "tbCustomSound";
+            this.tbCustomSound.Size = new System.Drawing.Size(170, 20);
+            this.tbCustomSound.TabIndex = 0;
+            // 
+            // btnBrowseSound
+            // 
+            this.btnBrowseSound.AutoSize = true;
+            this.btnBrowseSound.Location = new System.Drawing.Point(53, 43);
+            this.btnBrowseSound.Name = "btnBrowseSound";
+            this.btnBrowseSound.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
+            this.btnBrowseSound.Size = new System.Drawing.Size(67, 23);
+            this.btnBrowseSound.TabIndex = 1;
+            this.btnBrowseSound.Text = "Browse...";
+            this.btnBrowseSound.UseVisualStyleBackColor = true;
+            this.btnBrowseSound.Click += new System.EventHandler(this.btnBrowseSound_Click);
+            // 
+            // btnResetSound
+            // 
+            this.btnResetSound.AutoSize = true;
+            this.btnResetSound.Location = new System.Drawing.Point(126, 43);
+            this.btnResetSound.Name = "btnResetSound";
+            this.btnResetSound.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
+            this.btnResetSound.Size = new System.Drawing.Size(51, 23);
+            this.btnResetSound.TabIndex = 2;
+            this.btnResetSound.Text = "Reset";
+            this.btnResetSound.UseVisualStyleBackColor = true;
+            this.btnResetSound.Click += new System.EventHandler(this.btnResetSound_Click);
+            // 
             // TabSettingsNotifications
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.Controls.Add(this.groupCustomSound);
             this.Controls.Add(this.groupUserInterface);
             this.Controls.Add(this.groupNotificationDuration);
             this.Controls.Add(this.groupNotificationLocation);
@@ -368,6 +417,8 @@ private void InitializeComponent() {
             ((System.ComponentModel.ISupportInitialize)(this.trackBarDuration)).EndInit();
             this.groupUserInterface.ResumeLayout(false);
             this.groupUserInterface.PerformLayout();
+            this.groupCustomSound.ResumeLayout(false);
+            this.groupCustomSound.PerformLayout();
             this.ResumeLayout(false);
 
         }
@@ -397,5 +448,9 @@ private void InitializeComponent() {
         private TweetDck.Core.Controls.FlatButton btnDurationMedium;
         private TweetDck.Core.Controls.FlatButton btnDurationLong;
         private TweetDck.Core.Controls.FlatButton btnDurationShort;
+        private System.Windows.Forms.GroupBox groupCustomSound;
+        private System.Windows.Forms.Button btnResetSound;
+        private System.Windows.Forms.Button btnBrowseSound;
+        private System.Windows.Forms.TextBox tbCustomSound;
     }
 }
diff --git a/Core/Other/Settings/TabSettingsNotifications.cs b/Core/Other/Settings/TabSettingsNotifications.cs
index 494d490f..349e331e 100644
--- a/Core/Other/Settings/TabSettingsNotifications.cs
+++ b/Core/Other/Settings/TabSettingsNotifications.cs
@@ -53,9 +53,15 @@ public TabSettingsNotifications(FormNotification notification){
             trackBarEdgeDistance.SetValueSafe(Config.NotificationEdgeDistance);
             labelEdgeDistanceValue.Text = trackBarEdgeDistance.Value.ToString(CultureInfo.InvariantCulture)+" px";
 
+            tbCustomSound.Text = Config.NotificationSoundPath ?? string.Empty;
+
             Disposed += (sender, args) => this.notification.Dispose();
         }
 
+        public override void OnClosing(){
+            Config.NotificationSoundPath = tbCustomSound.Text;
+        }
+
         private void TabSettingsNotifications_ParentChanged(object sender, EventArgs e){
             if (Parent == null){
                 notification.HideNotification(false);
@@ -146,5 +152,22 @@ private void trackBarEdgeDistance_ValueChanged(object sender, EventArgs e){
             Config.NotificationEdgeDistance = trackBarEdgeDistance.Value;
             notification.ShowNotificationForSettings(false);
         }
+
+        private void btnBrowseSound_Click(object sender, EventArgs e){
+            using(OpenFileDialog dialog = new OpenFileDialog{
+                AutoUpgradeEnabled = true,
+                DereferenceLinks = true,
+                Title = "Custom Notification Sound",
+                Filter = "Wave file (*.wav)|*.wav"
+            }){
+                if (dialog.ShowDialog() == DialogResult.OK){
+                    tbCustomSound.Text = dialog.FileName;
+                }
+            }
+        }
+
+        private void btnResetSound_Click(object sender, EventArgs e){
+            tbCustomSound.Text = string.Empty;
+        }
     }
 }
diff --git a/Resources/Scripts/code.js b/Resources/Scripts/code.js
index fdb666a8..cbed65a4 100644
--- a/Resources/Scripts/code.js
+++ b/Resources/Scripts/code.js
@@ -117,8 +117,9 @@
       
       $TD.onTweetPopup(html.html(), url, tweet.text.length); // TODO column
     }
-    else if (column.model.getHasSound()){
-      $TD.onTweetSound(); // TODO disable original
+    
+    if (column.model.getHasSound()){
+      $TD.onTweetSound();
     }
   };
   
@@ -255,7 +256,7 @@
     var soundEle = document.getElementById("update-sound");
     
     soundEle.play = prependToFunction(soundEle.play, function(){
-      return $TD.muteNotifications;
+      return $TD.muteNotifications || $TD.hasCustomNotificationSound;
     });
   })();