From 7377b4f2ab0549e11d39212ec06519e7be73a00b Mon Sep 17 00:00:00 2001 From: Frank Becker Date: Mon, 22 Feb 2021 12:10:36 -0800 Subject: [PATCH] Add a LinearVolume wrapper for mediaElement.Volume (#834) Co-authored-by: Frank Becker --- .../ViewerPanel.xaml | 4 +- .../ViewerPanel.xaml.cs | 39 +++++++++++++++---- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml index a50fec1..0943992 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml +++ b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml @@ -162,7 +162,7 @@ @@ -198,7 +198,7 @@ + Value="{Binding ElementName=viewerPanel, Path=LinearVolume}" /> diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml.cs index eacf0b1..f26b9cb 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml.cs @@ -145,7 +145,7 @@ namespace QuickLook.Plugin.VideoViewer public void Dispose() { // old plugin use an int-typed "Volume" config key ranged from 0 to 100. Let's use a new one here. - SettingHelper.Set("VolumeDouble", mediaElement.Volume); + SettingHelper.Set("VolumeDouble", LinearVolume); SettingHelper.Set("ShouldLoop", ShouldLoop); try @@ -280,13 +280,38 @@ namespace QuickLook.Plugin.VideoViewer : Visibility.Visible; } + // Newer .net has Math.Clamp + private T Clamp(T val, T min, T max) where T : IComparable + { + if (val.CompareTo(min) < 0) return min; + else if (val.CompareTo(max) > 0) return max; + else return val; + } + + // A change in amplitude by a factor of 10 corresponds to a 20 dB change + private const double DecibelAmplitudeMult = 20.0; + public double LinearVolume + { + // mediaElement.Volume returns [0,1] where 0 = -100db, 1 = 0db + // Decibel is logarithmic. See amplitude table https://en.wikipedia.org/wiki/Decibel + get + { + var dbVol = 100.0 * (mediaElement.Volume - 1.0); + var linearVol = Math.Pow(10, dbVol / DecibelAmplitudeMult); + return linearVol; + } + set + { + var linearVol = Clamp(value, 0.00001, 1.0); + var dbVol = DecibelAmplitudeMult * Math.Log10(linearVol); + mediaElement.Volume = dbVol / 100.0 + 1.0; + OnPropertyChanged(); + } + } + private void ChangeVolume(double delta) { - var newVol = mediaElement.Volume + delta; - newVol = Math.Max(newVol, 0); - newVol = Math.Min(newVol, 1); - - mediaElement.Volume = newVol; + LinearVolume = LinearVolume + delta; // setter will clamp } private void TogglePlayPause(object sender, EventArgs e) @@ -316,7 +341,7 @@ namespace QuickLook.Plugin.VideoViewer mediaElement.Source = new Uri(path); // old plugin use an int-typed "Volume" config key ranged from 0 to 100. Let's use a new one here. - mediaElement.Volume = SettingHelper.Get("VolumeDouble", 1d); + LinearVolume = SettingHelper.Get("VolumeDouble", 1d); mediaElement.Play(); }