From 4540100fdce5a46dbf872d275f07d87cb376cb4d Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 30 Jun 2021 13:26:41 -0700 Subject: [PATCH 01/24] Fix a couple oddities in PlayerView --- RedBookPlayer/GUI/PlayerView.xaml.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index 533e076..105ed38 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -64,6 +64,9 @@ namespace RedBookPlayer.GUI /// Path to the image to load public async Task LoadImage(string path) { + // If the player is currently running, stop it + if(Player.Playing) Player.Stop(); + bool result = await Task.Run(() => { Player.Init(path, App.Settings.AutoPlay); @@ -202,7 +205,7 @@ namespace RedBookPlayer.GUI if (path == null) return; - LoadImage(path); + await LoadImage(path); } public void PlayButton_Click(object sender, RoutedEventArgs e) => Player.TogglePlayPause(true); @@ -229,6 +232,8 @@ namespace RedBookPlayer.GUI public void DisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => Player.ToggleDeEmphasis(false); + public void EnableDisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => Player.ToggleDeEmphasis(!Player.ApplyDeEmphasis); + #endregion } } \ No newline at end of file From a25626648fd332c1a89d4b0bb0b43b9367cd7065 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 30 Jun 2021 13:55:49 -0700 Subject: [PATCH 02/24] Add hardcoded navigation buttons --- README.md | 16 +++++++ RedBookPlayer/GUI/MainWindow.xaml.cs | 63 ++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/README.md b/README.md index 6ccbb4b..e42107b 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,19 @@ [Audio CD](https://en.wikipedia.org/wiki/Compact_Disc_Digital_Audio) player for [Aaru format](https://github.com/aaru-dps/Aaru). * This project is fully sponsored by the [Game Preservation Society](https://www.gamepres.org/en/). + +## Default Player Controls + +| Key | Action | +| --- | ------ | +| `F1` | Open Settings Window | +| `F2` / `Enter` | Load New Image | +| `Space` | Toggle Play / Pause | +| `Esc` | Stop Playback | +| `→` | Next Track | +| `←` | Previous Track | +| `]` | Next Index | +| `[` | Previous Index | +| `.` | Fast Forward | +| `,` | Rewind | +| `E` | Toggle Emphasis | \ No newline at end of file diff --git a/RedBookPlayer/GUI/MainWindow.xaml.cs b/RedBookPlayer/GUI/MainWindow.xaml.cs index 474037b..5cff6d5 100644 --- a/RedBookPlayer/GUI/MainWindow.xaml.cs +++ b/RedBookPlayer/GUI/MainWindow.xaml.cs @@ -115,11 +115,74 @@ namespace RedBookPlayer.GUI public void OnKeyDown(object sender, KeyEventArgs e) { + PlayerView playerView = ContentControl.Content as PlayerView; + + // Open settings window if(e.Key == Key.F1) { settingsWindow = new SettingsWindow(App.Settings); settingsWindow.Show(); } + + // Load image + else if (e.Key == Key.F2 || e.Key == Key.Enter) + { + playerView?.LoadButton_Click(this, null); + } + + // Toggle playback + else if(e.Key == Key.Space || e.Key == Key.MediaPlayPause) + { + playerView?.PlayPauseButton_Click(this, null); + } + + // Stop playback + else if(e.Key == Key.Escape || e.Key == Key.MediaStop) + { + playerView?.StopButton_Click(this, null); + } + + // Next Track + else if(e.Key == Key.Right || e.Key == Key.MediaNextTrack) + { + playerView?.NextTrackButton_Click(this, null); + } + + // Previous Track + else if(e.Key == Key.Left || e.Key == Key.MediaPreviousTrack) + { + playerView?.PreviousTrackButton_Click(this, null); + } + + // Next Index + else if(e.Key == Key.OemCloseBrackets) + { + playerView?.NextIndexButton_Click(this, null); + } + + // Previous Index + else if(e.Key == Key.OemOpenBrackets) + { + playerView?.PreviousIndexButton_Click(this, null); + } + + // Fast Foward + else if(e.Key == Key.OemPeriod) + { + playerView?.FastForwardButton_Click(this, null); + } + + // Rewind + else if(e.Key == Key.OemComma) + { + playerView?.RewindButton_Click(this, null); + } + + // Emphasis Toggle + else if(e.Key == Key.E) + { + playerView?.EnableDisableDeEmphasisButton_Click(this, null); + } } #endregion From cfb2d316d7baf5e19e37ba9a9ea4eb018fbc427a Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 30 Jun 2021 13:56:42 -0700 Subject: [PATCH 03/24] Fix and surface de-emphasis flag --- RedBookPlayer/Hardware/Player.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/RedBookPlayer/Hardware/Player.cs b/RedBookPlayer/Hardware/Player.cs index 4e60b65..362e7df 100644 --- a/RedBookPlayer/Hardware/Player.cs +++ b/RedBookPlayer/Hardware/Player.cs @@ -23,6 +23,11 @@ namespace RedBookPlayer.Hardware /// public bool Playing => _soundOutput?.Playing ?? false; + /// + /// Indicates if de-emphasis should be applied + /// + public bool ApplyDeEmphasis => _soundOutput?.ApplyDeEmphasis ?? false; + #endregion #region Private State Variables @@ -258,7 +263,7 @@ namespace RedBookPlayer.Hardware /// Toggle de-emphasis processing /// /// True to apply de-emphasis, false otherwise - public void ToggleDeEmphasis(bool enable) => _soundOutput.ToggleDeEmphasis(enable); + public void ToggleDeEmphasis(bool enable) => _soundOutput?.ToggleDeEmphasis(enable); /// /// Update the data context for the frontend From afa064e4292d1dd2b6737969464d4407742a6592 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 30 Jun 2021 16:06:09 -0700 Subject: [PATCH 04/24] Make loading custom XAML safer --- RedBookPlayer/GUI/PlayerView.xaml.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index 105ed38..dbf1a55 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -117,10 +117,17 @@ namespace RedBookPlayer.GUI DataContext = new PlayerViewModel(); // Load the theme - if (xaml != null) - new AvaloniaXamlLoader().Load(xaml, null, this); - else + try + { + if(xaml != null) + new AvaloniaXamlLoader().Load(xaml, null, this); + else + AvaloniaXamlLoader.Load(this); + } + catch + { AvaloniaXamlLoader.Load(this); + } InitializeDigits(); From 7c940e157680fa94865b032283a45ad2a3fcdb3b Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 30 Jun 2021 16:16:49 -0700 Subject: [PATCH 05/24] Move hardcoded key values to settings --- README.md | 2 +- RedBookPlayer/GUI/MainWindow.xaml.cs | 22 +++++----- RedBookPlayer/Settings.cs | 64 ++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e42107b..76e4ced 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ | Key | Action | | --- | ------ | | `F1` | Open Settings Window | -| `F2` / `Enter` | Load New Image | +| `F2` | Load New Image | | `Space` | Toggle Play / Pause | | `Esc` | Stop Playback | | `→` | Next Track | diff --git a/RedBookPlayer/GUI/MainWindow.xaml.cs b/RedBookPlayer/GUI/MainWindow.xaml.cs index 5cff6d5..235ff12 100644 --- a/RedBookPlayer/GUI/MainWindow.xaml.cs +++ b/RedBookPlayer/GUI/MainWindow.xaml.cs @@ -118,68 +118,68 @@ namespace RedBookPlayer.GUI PlayerView playerView = ContentControl.Content as PlayerView; // Open settings window - if(e.Key == Key.F1) + if(e.Key == App.Settings.OpenSettingsKey) { settingsWindow = new SettingsWindow(App.Settings); settingsWindow.Show(); } // Load image - else if (e.Key == Key.F2 || e.Key == Key.Enter) + else if (e.Key == App.Settings.LoadImageKey) { playerView?.LoadButton_Click(this, null); } // Toggle playback - else if(e.Key == Key.Space || e.Key == Key.MediaPlayPause) + else if(e.Key == App.Settings.TogglePlaybackKey || e.Key == Key.MediaPlayPause) { playerView?.PlayPauseButton_Click(this, null); } // Stop playback - else if(e.Key == Key.Escape || e.Key == Key.MediaStop) + else if(e.Key == App.Settings.StopPlaybackKey || e.Key == Key.MediaStop) { playerView?.StopButton_Click(this, null); } // Next Track - else if(e.Key == Key.Right || e.Key == Key.MediaNextTrack) + else if(e.Key == App.Settings.NextTrackKey || e.Key == Key.MediaNextTrack) { playerView?.NextTrackButton_Click(this, null); } // Previous Track - else if(e.Key == Key.Left || e.Key == Key.MediaPreviousTrack) + else if(e.Key == App.Settings.PreviousTrackKey || e.Key == Key.MediaPreviousTrack) { playerView?.PreviousTrackButton_Click(this, null); } // Next Index - else if(e.Key == Key.OemCloseBrackets) + else if(e.Key == App.Settings.NextIndexKey) { playerView?.NextIndexButton_Click(this, null); } // Previous Index - else if(e.Key == Key.OemOpenBrackets) + else if(e.Key == App.Settings.PreviousIndexKey) { playerView?.PreviousIndexButton_Click(this, null); } // Fast Foward - else if(e.Key == Key.OemPeriod) + else if(e.Key == App.Settings.FastForwardPlaybackKey) { playerView?.FastForwardButton_Click(this, null); } // Rewind - else if(e.Key == Key.OemComma) + else if(e.Key == App.Settings.RewindPlaybackKey) { playerView?.RewindButton_Click(this, null); } // Emphasis Toggle - else if(e.Key == Key.E) + else if(e.Key == App.Settings.ToggleDeEmphasisKey) { playerView?.EnableDisableDeEmphasisButton_Click(this, null); } diff --git a/RedBookPlayer/Settings.cs b/RedBookPlayer/Settings.cs index fe144a0..2e2e607 100644 --- a/RedBookPlayer/Settings.cs +++ b/RedBookPlayer/Settings.cs @@ -1,12 +1,15 @@ using System; using System.IO; using System.Text.Json; +using Avalonia.Input; using RedBookPlayer.GUI; namespace RedBookPlayer { public class Settings { + #region Player Settings + /// /// Indicates if discs should start playing on load /// @@ -42,6 +45,67 @@ namespace RedBookPlayer /// public string SelectedTheme { get; set; } = "default"; + #endregion + + #region Key Mappings + + /// + /// Key assigned to open settings + /// + public Key OpenSettingsKey { get; set; } = Key.F1; + + /// + /// Key assigned to load a new image + /// + public Key LoadImageKey { get; set; } = Key.F2; + + /// + /// Key assigned to toggle play and pause + /// + public Key TogglePlaybackKey { get; set; } = Key.Space; + + /// + /// Key assigned to stop playback + /// + public Key StopPlaybackKey { get; set; } = Key.Escape; + + /// + /// Key assigned to move to the next track + /// + public Key NextTrackKey { get; set; } = Key.Right; + + /// + /// Key assigned to move to the previous track + /// + public Key PreviousTrackKey { get; set; } = Key.Left; + + /// + /// Key assigned to move to the next index + /// + public Key NextIndexKey { get; set; } = Key.OemCloseBrackets; + + /// + /// Key assigned to move to the previous index + /// + public Key PreviousIndexKey { get; set; } = Key.OemOpenBrackets; + + /// + /// Key assigned to fast forward playback + /// + public Key FastForwardPlaybackKey { get; set; } = Key.OemPeriod; + + /// + /// Key assigned to rewind playback + /// + public Key RewindPlaybackKey { get; set; } = Key.OemComma; + + /// + /// Key assigned to toggle de-emphasis + /// + public Key ToggleDeEmphasisKey { get; set; } = Key.E; + + #endregion + /// /// Path to the settings file /// From 565b289a45ea1fba61b16543cbec2040531ad032 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 30 Jun 2021 17:22:37 -0700 Subject: [PATCH 06/24] Make keybinds UI-accessible --- RedBookPlayer/GUI/SettingsWindow.xaml | 172 ++++++++++++++++++----- RedBookPlayer/GUI/SettingsWindow.xaml.cs | 86 ++++++++++++ 2 files changed, 222 insertions(+), 36 deletions(-) diff --git a/RedBookPlayer/GUI/SettingsWindow.xaml b/RedBookPlayer/GUI/SettingsWindow.xaml index 7f5c54a..e846afe 100644 --- a/RedBookPlayer/GUI/SettingsWindow.xaml +++ b/RedBookPlayer/GUI/SettingsWindow.xaml @@ -1,40 +1,140 @@ - - Themes - - - - Auto-play CD on load - - - - Index navigation can change track - - - - Treat index 0 of track 1 as track 0 (hidden track) - - - - Play data tracks like old, non-compliant players - - - - Generate a TOC if the disc is missing one - - - Volume - - - - - - - - + d:DesignHeight="450" x:Class="RedBookPlayer.GUI.SettingsWindow" Title="Settings" SizeToContent="WidthAndHeight"> + + + + + Themes + + + + Auto-play CD on load + + + + Index navigation can change track + + + + Treat index 0 of track 1 as track 0 (hidden track) + + + + Play data tracks like old, non-compliant players + + + + Generate a TOC if the disc is missing one + + + Volume + + + + + + + + + + + + + + + + + Load Image + + + + + + + + + Toggle Play/Pause + + + + + + + + + Stop Playback + + + + + + + + + Next Track + + + + + + + + + Previous Track + + + + + + + + + Next Index + + + + + + + + + Previous Index + + + + + + + + + Fast-Forward + + + + + + + + + Rewind + + + + + + + + + Toggle De-Emphasis + + + + + + + \ No newline at end of file diff --git a/RedBookPlayer/GUI/SettingsWindow.xaml.cs b/RedBookPlayer/GUI/SettingsWindow.xaml.cs index cfe293e..a4424a0 100644 --- a/RedBookPlayer/GUI/SettingsWindow.xaml.cs +++ b/RedBookPlayer/GUI/SettingsWindow.xaml.cs @@ -1,6 +1,8 @@ +using System; using System.Collections.Generic; using System.IO; using Avalonia.Controls; +using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; @@ -36,6 +38,7 @@ namespace RedBookPlayer.GUI MainWindow.ApplyTheme(_selectedTheme); } + SaveKeyboardList(); _settings.Save(); } @@ -46,6 +49,7 @@ namespace RedBookPlayer.GUI AvaloniaXamlLoader.Load(this); PopulateThemes(); + PopulateKeyboardList(); this.FindControl diff --git a/RedBookPlayer/GUI/SettingsWindow.xaml.cs b/RedBookPlayer/GUI/SettingsWindow.xaml.cs index a4424a0..3f1d226 100644 --- a/RedBookPlayer/GUI/SettingsWindow.xaml.cs +++ b/RedBookPlayer/GUI/SettingsWindow.xaml.cs @@ -92,41 +92,50 @@ namespace RedBookPlayer.GUI private void PopulateKeyboardList() { // Access all of the combo boxes - ComboBox LoadImageKeyBind = this.FindControl("LoadImageKeyBind"); - ComboBox TogglePlaybackKeyBind = this.FindControl("TogglePlaybackKeyBind"); - ComboBox StopPlaybackKeyBind = this.FindControl("StopPlaybackKeyBind"); - ComboBox NextTrackKeyBind = this.FindControl("NextTrackKeyBind"); - ComboBox PreviousTrackKeyBind = this.FindControl("PreviousTrackKeyBind"); - ComboBox NextIndexKeyBind = this.FindControl("NextIndexKeyBind"); - ComboBox PreviousIndexKeyBind = this.FindControl("PreviousIndexKeyBind"); - ComboBox FastForwardPlaybackKeyBind = this.FindControl("FastForwardPlaybackKeyBind"); - ComboBox RewindPlaybackKeyBind = this.FindControl("RewindPlaybackKeyBind"); - ComboBox ToggleDeEmphasisKeyBind = this.FindControl("ToggleDeEmphasisKeyBind"); + ComboBox loadImageKeyBind = this.FindControl("LoadImageKeyBind"); + ComboBox togglePlaybackKeyBind = this.FindControl("TogglePlaybackKeyBind"); + ComboBox stopPlaybackKeyBind = this.FindControl("StopPlaybackKeyBind"); + ComboBox nextTrackKeyBind = this.FindControl("NextTrackKeyBind"); + ComboBox previousTrackKeyBind = this.FindControl("PreviousTrackKeyBind"); + ComboBox nextIndexKeyBind = this.FindControl("NextIndexKeyBind"); + ComboBox previousIndexKeyBind = this.FindControl("PreviousIndexKeyBind"); + ComboBox fastForwardPlaybackKeyBind = this.FindControl("FastForwardPlaybackKeyBind"); + ComboBox rewindPlaybackKeyBind = this.FindControl("RewindPlaybackKeyBind"); + ComboBox volumeUpKeyBind = this.FindControl("VolumeUpKeyBind"); + ComboBox volumeDownKeyBind = this.FindControl("VolumeDownKeyBind"); + ComboBox toggleMuteKeyBind = this.FindControl("ToggleMuteKeyBind"); + ComboBox toggleDeEmphasisKeyBind = this.FindControl("ToggleDeEmphasisKeyBind"); // Assign the list of values to all of them Array keyboardList = GenerateKeyboardList(); - LoadImageKeyBind.Items = keyboardList; - TogglePlaybackKeyBind.Items = keyboardList; - StopPlaybackKeyBind.Items = keyboardList; - NextTrackKeyBind.Items = keyboardList; - PreviousTrackKeyBind.Items = keyboardList; - NextIndexKeyBind.Items = keyboardList; - PreviousIndexKeyBind.Items = keyboardList; - FastForwardPlaybackKeyBind.Items = keyboardList; - RewindPlaybackKeyBind.Items = keyboardList; - ToggleDeEmphasisKeyBind.Items = keyboardList; + loadImageKeyBind.Items = keyboardList; + togglePlaybackKeyBind.Items = keyboardList; + stopPlaybackKeyBind.Items = keyboardList; + nextTrackKeyBind.Items = keyboardList; + previousTrackKeyBind.Items = keyboardList; + nextIndexKeyBind.Items = keyboardList; + previousIndexKeyBind.Items = keyboardList; + fastForwardPlaybackKeyBind.Items = keyboardList; + rewindPlaybackKeyBind.Items = keyboardList; + volumeUpKeyBind.Items = keyboardList; + volumeDownKeyBind.Items = keyboardList; + toggleMuteKeyBind.Items = keyboardList; + toggleDeEmphasisKeyBind.Items = keyboardList; // Set all of the currently selected items - LoadImageKeyBind.SelectedItem = _settings.LoadImageKey; - TogglePlaybackKeyBind.SelectedItem = _settings.TogglePlaybackKey; - StopPlaybackKeyBind.SelectedItem = _settings.StopPlaybackKey; - NextTrackKeyBind.SelectedItem = _settings.NextTrackKey; - PreviousTrackKeyBind.SelectedItem = _settings.PreviousTrackKey; - NextIndexKeyBind.SelectedItem = _settings.NextIndexKey; - PreviousIndexKeyBind.SelectedItem = _settings.PreviousIndexKey; - FastForwardPlaybackKeyBind.SelectedItem = _settings.FastForwardPlaybackKey; - RewindPlaybackKeyBind.SelectedItem = _settings.RewindPlaybackKey; - ToggleDeEmphasisKeyBind.SelectedItem = _settings.ToggleDeEmphasisKey; + loadImageKeyBind.SelectedItem = _settings.LoadImageKey; + togglePlaybackKeyBind.SelectedItem = _settings.TogglePlaybackKey; + stopPlaybackKeyBind.SelectedItem = _settings.StopPlaybackKey; + nextTrackKeyBind.SelectedItem = _settings.NextTrackKey; + previousTrackKeyBind.SelectedItem = _settings.PreviousTrackKey; + nextIndexKeyBind.SelectedItem = _settings.NextIndexKey; + previousIndexKeyBind.SelectedItem = _settings.PreviousIndexKey; + fastForwardPlaybackKeyBind.SelectedItem = _settings.FastForwardPlaybackKey; + rewindPlaybackKeyBind.SelectedItem = _settings.RewindPlaybackKey; + volumeUpKeyBind.SelectedItem = _settings.VolumeUpKey; + volumeDownKeyBind.SelectedItem = _settings.VolumeDownKey; + toggleMuteKeyBind.SelectedItem = _settings.ToggleMuteKey; + toggleDeEmphasisKeyBind.SelectedItem = _settings.ToggleDeEmphasisKey; } /// @@ -135,28 +144,34 @@ namespace RedBookPlayer.GUI private void SaveKeyboardList() { // Access all of the combo boxes - ComboBox LoadImageKeyBind = this.FindControl("LoadImageKeyBind"); - ComboBox TogglePlaybackKeyBind = this.FindControl("TogglePlaybackKeyBind"); - ComboBox StopPlaybackKeyBind = this.FindControl("StopPlaybackKeyBind"); - ComboBox NextTrackKeyBind = this.FindControl("NextTrackKeyBind"); - ComboBox PreviousTrackKeyBind = this.FindControl("PreviousTrackKeyBind"); - ComboBox NextIndexKeyBind = this.FindControl("NextIndexKeyBind"); - ComboBox PreviousIndexKeyBind = this.FindControl("PreviousIndexKeyBind"); - ComboBox FastForwardPlaybackKeyBind = this.FindControl("FastForwardPlaybackKeyBind"); - ComboBox RewindPlaybackKeyBind = this.FindControl("RewindPlaybackKeyBind"); - ComboBox ToggleDeEmphasisKeyBind = this.FindControl("ToggleDeEmphasisKeyBind"); + ComboBox loadImageKeyBind = this.FindControl("LoadImageKeyBind"); + ComboBox togglePlaybackKeyBind = this.FindControl("TogglePlaybackKeyBind"); + ComboBox stopPlaybackKeyBind = this.FindControl("StopPlaybackKeyBind"); + ComboBox nextTrackKeyBind = this.FindControl("NextTrackKeyBind"); + ComboBox previousTrackKeyBind = this.FindControl("PreviousTrackKeyBind"); + ComboBox nextIndexKeyBind = this.FindControl("NextIndexKeyBind"); + ComboBox previousIndexKeyBind = this.FindControl("PreviousIndexKeyBind"); + ComboBox fastForwardPlaybackKeyBind = this.FindControl("FastForwardPlaybackKeyBind"); + ComboBox rewindPlaybackKeyBind = this.FindControl("RewindPlaybackKeyBind"); + ComboBox volumeUpKeyBind = this.FindControl("VolumeUpKeyBind"); + ComboBox volumeDownKeyBind = this.FindControl("VolumeDownKeyBind"); + ComboBox toggleMuteKeyBind = this.FindControl("ToggleMuteKeyBind"); + ComboBox toggleDeEmphasisKeyBind = this.FindControl("ToggleDeEmphasisKeyBind"); // Set all of the currently selected items - _settings.LoadImageKey = (Key)LoadImageKeyBind.SelectedItem; - _settings.TogglePlaybackKey = (Key)TogglePlaybackKeyBind.SelectedItem; - _settings.StopPlaybackKey = (Key)StopPlaybackKeyBind.SelectedItem; - _settings.NextTrackKey = (Key)NextTrackKeyBind.SelectedItem; - _settings.PreviousTrackKey = (Key)PreviousTrackKeyBind.SelectedItem; - _settings.NextIndexKey = (Key)NextIndexKeyBind.SelectedItem; - _settings.PreviousIndexKey = (Key)PreviousIndexKeyBind.SelectedItem; - _settings.FastForwardPlaybackKey = (Key)FastForwardPlaybackKeyBind.SelectedItem; - _settings.RewindPlaybackKey = (Key)RewindPlaybackKeyBind.SelectedItem; - _settings.ToggleDeEmphasisKey = (Key)ToggleDeEmphasisKeyBind.SelectedItem; + _settings.LoadImageKey = (Key)loadImageKeyBind.SelectedItem; + _settings.TogglePlaybackKey = (Key)togglePlaybackKeyBind.SelectedItem; + _settings.StopPlaybackKey = (Key)stopPlaybackKeyBind.SelectedItem; + _settings.NextTrackKey = (Key)nextTrackKeyBind.SelectedItem; + _settings.PreviousTrackKey = (Key)previousTrackKeyBind.SelectedItem; + _settings.NextIndexKey = (Key)nextIndexKeyBind.SelectedItem; + _settings.PreviousIndexKey = (Key)previousIndexKeyBind.SelectedItem; + _settings.FastForwardPlaybackKey = (Key)fastForwardPlaybackKeyBind.SelectedItem; + _settings.RewindPlaybackKey = (Key)rewindPlaybackKeyBind.SelectedItem; + _settings.VolumeUpKey = (Key)volumeUpKeyBind.SelectedItem; + _settings.VolumeDownKey = (Key)volumeDownKeyBind.SelectedItem; + _settings.ToggleMuteKey = (Key)toggleMuteKeyBind.SelectedItem; + _settings.ToggleDeEmphasisKey = (Key)toggleDeEmphasisKeyBind.SelectedItem; } /// diff --git a/RedBookPlayer/Settings.cs b/RedBookPlayer/Settings.cs index 2e2e607..44889d9 100644 --- a/RedBookPlayer/Settings.cs +++ b/RedBookPlayer/Settings.cs @@ -99,6 +99,21 @@ namespace RedBookPlayer /// public Key RewindPlaybackKey { get; set; } = Key.OemComma; + /// + /// Key assigned to raise volume + /// + public Key VolumeUpKey { get; set; } = Key.OemPlus; + + /// + /// Key assigned to lower volume + /// + public Key VolumeDownKey { get; set; } = Key.OemMinus; + + /// + /// Key assigned to toggle mute + /// + public Key ToggleMuteKey { get; set; } = Key.M; + /// /// Key assigned to toggle de-emphasis /// From fe6b3523c326a450c67fd18d9974565e4ce73598 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 1 Jul 2021 11:38:08 -0700 Subject: [PATCH 08/24] Change default volume change keys --- README.md | 4 ++-- RedBookPlayer/Settings.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dc011b5..10ecce4 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ | **[** | Previous Index | | **.** | Fast Forward | | **,** | Rewind | -| **+** | Volume Up | -| **-** | Volume Down | +| **Numpad +** | Volume Up | +| **Numpad -** | Volume Down | | **M** | Mute | | **E** | Toggle Emphasis | \ No newline at end of file diff --git a/RedBookPlayer/Settings.cs b/RedBookPlayer/Settings.cs index 44889d9..cc2d0ff 100644 --- a/RedBookPlayer/Settings.cs +++ b/RedBookPlayer/Settings.cs @@ -102,12 +102,12 @@ namespace RedBookPlayer /// /// Key assigned to raise volume /// - public Key VolumeUpKey { get; set; } = Key.OemPlus; + public Key VolumeUpKey { get; set; } = Key.Add; /// /// Key assigned to lower volume /// - public Key VolumeDownKey { get; set; } = Key.OemMinus; + public Key VolumeDownKey { get; set; } = Key.Subtract; /// /// Key assigned to toggle mute From abd81d255b97a14230aae76ce9b98de76b0455ea Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 1 Jul 2021 11:50:38 -0700 Subject: [PATCH 09/24] Make volume setting safer --- RedBookPlayer/GUI/PlayerView.xaml.cs | 12 ++---------- RedBookPlayer/Settings.cs | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index b36a556..2c47cb0 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -240,17 +240,9 @@ namespace RedBookPlayer.GUI public void RewindButton_Click(object sender, RoutedEventArgs e) => Player.Rewind(); - public void VolumeUpButton_Click(object sender, RoutedEventArgs e) - { - if(App.Settings.Volume < 100) - App.Settings.Volume++; - } + public void VolumeUpButton_Click(object sender, RoutedEventArgs e) => App.Settings.Volume++; - public void VolumeDownButton_Click(object sender, RoutedEventArgs e) - { - if(App.Settings.Volume > 0) - App.Settings.Volume--; - } + public void VolumeDownButton_Click(object sender, RoutedEventArgs e) => App.Settings.Volume--; public void MuteToggleButton_Click(object sender, RoutedEventArgs e) { diff --git a/RedBookPlayer/Settings.cs b/RedBookPlayer/Settings.cs index cc2d0ff..36e95fb 100644 --- a/RedBookPlayer/Settings.cs +++ b/RedBookPlayer/Settings.cs @@ -38,7 +38,19 @@ namespace RedBookPlayer /// /// Indicates the default playback volume /// - public int Volume { get; set; } = 100; + public int Volume + { + get => _volume; + set + { + if(value > 100) + _volume = 100; + else if(value < 0) + _volume = 0; + else + _volume = value; + } + } /// /// Indicates the currently selected theme @@ -126,6 +138,11 @@ namespace RedBookPlayer /// private string _filePath; + /// + /// Internal value for the volume + /// + private int _volume = 100; + public Settings() {} public Settings(string filePath) => _filePath = filePath; From 2b0de556a168a02f35e8010e3a95efbd19b2f0c1 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 1 Jul 2021 15:18:59 -0700 Subject: [PATCH 10/24] Add modifiers for keyboard volume changes --- README.md | 7 ++++++- RedBookPlayer/GUI/MainWindow.xaml.cs | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 10ecce4..7b0ec36 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,9 @@ | **Numpad +** | Volume Up | | **Numpad -** | Volume Down | | **M** | Mute | -| **E** | Toggle Emphasis | \ No newline at end of file +| **E** | Toggle Emphasis | + +For both Volume Up and Volume Down: +- Holding **Ctrl** will move in increments of 2 +- Holding **Shift** will move in increments of 5 +- Holding both will move in increments of 10 \ No newline at end of file diff --git a/RedBookPlayer/GUI/MainWindow.xaml.cs b/RedBookPlayer/GUI/MainWindow.xaml.cs index 67e4583..031d78e 100644 --- a/RedBookPlayer/GUI/MainWindow.xaml.cs +++ b/RedBookPlayer/GUI/MainWindow.xaml.cs @@ -181,13 +181,25 @@ namespace RedBookPlayer.GUI // Volume Up else if(e.Key == App.Settings.VolumeUpKey || e.Key == Key.VolumeUp) { - playerView?.VolumeUpButton_Click(this, null); + int increment = 1; + if(e.KeyModifiers.HasFlag(KeyModifiers.Control)) + increment *= 2; + if(e.KeyModifiers.HasFlag(KeyModifiers.Shift)) + increment *= 5; + + App.Settings.Volume += increment; } // Volume Down else if(e.Key == App.Settings.VolumeDownKey || e.Key == Key.VolumeDown) { - playerView?.VolumeDownButton_Click(this, null); + int decrement = 1; + if(e.KeyModifiers.HasFlag(KeyModifiers.Control)) + decrement *= 2; + if(e.KeyModifiers.HasFlag(KeyModifiers.Shift)) + decrement *= 5; + + App.Settings.Volume -= decrement; } // Mute Toggle From d2e489e63c093b927c0a9fec650f91dd16d9b7bc Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Thu, 1 Jul 2021 23:04:20 -0700 Subject: [PATCH 11/24] Add volume to the view model for access --- RedBookPlayer/GUI/PlayerViewModel.cs | 7 +++++++ RedBookPlayer/Hardware/Player.cs | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index 5090377..6910ecd 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -4,6 +4,13 @@ namespace RedBookPlayer.GUI { public class PlayerViewModel : ReactiveObject { + private int _volume; + public int Volume + { + get => _volume; + set => this.RaiseAndSetIfChanged(ref _volume, value); + } + private bool _applyDeEmphasis; public bool ApplyDeEmphasis { diff --git a/RedBookPlayer/Hardware/Player.cs b/RedBookPlayer/Hardware/Player.cs index 362e7df..edfb8ad 100644 --- a/RedBookPlayer/Hardware/Player.cs +++ b/RedBookPlayer/Hardware/Player.cs @@ -274,8 +274,9 @@ namespace RedBookPlayer.Hardware if(!Initialized || dataContext == null) return; - dataContext.HiddenTrack = _opticalDisc.TimeOffset > 150; + dataContext.Volume = App.Settings.Volume; dataContext.ApplyDeEmphasis = _soundOutput.ApplyDeEmphasis; + dataContext.HiddenTrack = _opticalDisc.TimeOffset > 150; if(_opticalDisc is CompactDisc compactDisc) { From 9829f342275c5f395230cd0a9ea79f759c3dcb80 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 2 Jul 2021 09:35:56 -0700 Subject: [PATCH 12/24] Add playing status and times to view model --- RedBookPlayer/GUI/PlayerViewModel.cs | 37 ++++++++++++++++++++++++++++ RedBookPlayer/Hardware/Player.cs | 25 +++++++++++++++---- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index 6910ecd..bd285fb 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -4,6 +4,37 @@ namespace RedBookPlayer.GUI { public class PlayerViewModel : ReactiveObject { + #region Player Status + + private bool _playing; + public bool Playing + { + get => _playing; + set => this.RaiseAndSetIfChanged(ref _playing, value); + } + + private ulong _currentSector; + public ulong CurrentSector + { + get => _currentSector; + set => this.RaiseAndSetIfChanged(ref _currentSector, value); + } + + public int CurrentFrame => (int)(_currentSector / (75 * 60)); + public int CurrentSecond => (int)(_currentSector / 75 % 60); + public int CurrentMinute => (int)(_currentSector % 75); + + private ulong _totalSectors; + public ulong TotalSectors + { + get => _totalSectors; + set => this.RaiseAndSetIfChanged(ref _totalSectors, value); + } + + public int TotalFrames => (int)(_totalSectors / (75 * 60)); + public int TotalSeconds => (int)(_totalSectors / 75 % 60); + public int TotalMinutes => (int)(_totalSectors % 75); + private int _volume; public int Volume { @@ -11,6 +42,10 @@ namespace RedBookPlayer.GUI set => this.RaiseAndSetIfChanged(ref _volume, value); } + #endregion + + #region Disc Flags + private bool _applyDeEmphasis; public bool ApplyDeEmphasis { @@ -52,5 +87,7 @@ namespace RedBookPlayer.GUI get => _hiddenTrack; set => this.RaiseAndSetIfChanged(ref _hiddenTrack, value); } + + #endregion } } \ No newline at end of file diff --git a/RedBookPlayer/Hardware/Player.cs b/RedBookPlayer/Hardware/Player.cs index edfb8ad..ec7e7e9 100644 --- a/RedBookPlayer/Hardware/Player.cs +++ b/RedBookPlayer/Hardware/Player.cs @@ -233,11 +233,7 @@ namespace RedBookPlayer.Hardware return string.Empty.PadLeft(20, '-'); // Otherwise, take the current time into account - ulong sectorTime = _opticalDisc.CurrentSector; - if(_opticalDisc.SectionStartSector != 0) - sectorTime -= _opticalDisc.SectionStartSector; - else - sectorTime += _opticalDisc.TimeOffset; + ulong sectorTime = GetCurrentSectorTime(); int[] numbers = new int[] { @@ -274,7 +270,11 @@ namespace RedBookPlayer.Hardware if(!Initialized || dataContext == null) return; + dataContext.Playing = Playing; + dataContext.CurrentSector = GetCurrentSectorTime(); + dataContext.TotalSectors = _opticalDisc.TotalTime; dataContext.Volume = App.Settings.Volume; + dataContext.ApplyDeEmphasis = _soundOutput.ApplyDeEmphasis; dataContext.HiddenTrack = _opticalDisc.TimeOffset > 150; @@ -294,6 +294,21 @@ namespace RedBookPlayer.Hardware } } + /// + /// Get current sector time, accounting for offsets + /// + /// ulong representing the current sector time + private ulong GetCurrentSectorTime() + { + ulong sectorTime = _opticalDisc.CurrentSector; + if(_opticalDisc.SectionStartSector != 0) + sectorTime -= _opticalDisc.SectionStartSector; + else + sectorTime += _opticalDisc.TimeOffset; + + return sectorTime; + } + #endregion } } \ No newline at end of file From c714abc9465d13897bf4e17acfb5f2815ac6bb47 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Fri, 2 Jul 2021 16:49:15 -0700 Subject: [PATCH 13/24] Use safer accessor --- RedBookPlayer/Hardware/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RedBookPlayer/Hardware/Player.cs b/RedBookPlayer/Hardware/Player.cs index ec7e7e9..eff5894 100644 --- a/RedBookPlayer/Hardware/Player.cs +++ b/RedBookPlayer/Hardware/Player.cs @@ -275,7 +275,7 @@ namespace RedBookPlayer.Hardware dataContext.TotalSectors = _opticalDisc.TotalTime; dataContext.Volume = App.Settings.Volume; - dataContext.ApplyDeEmphasis = _soundOutput.ApplyDeEmphasis; + dataContext.ApplyDeEmphasis = ApplyDeEmphasis; dataContext.HiddenTrack = _opticalDisc.TimeOffset > 150; if(_opticalDisc is CompactDisc compactDisc) From f2053d5a4499598a72ff2ab0755f759db02b2e96 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 14:18:04 -0700 Subject: [PATCH 14/24] Add currently-unused player update from UI --- RedBookPlayer/GUI/PlayerView.xaml.cs | 13 +++++++++++++ RedBookPlayer/Hardware/Player.cs | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index 2c47cb0..3454bd7 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -120,6 +121,7 @@ namespace RedBookPlayer.GUI private void InitializeComponent(string xaml) { DataContext = new PlayerViewModel(); + (DataContext as PlayerViewModel).PropertyChanged += UpdateModel; // Load the theme try @@ -189,6 +191,17 @@ namespace RedBookPlayer.GUI }; } + /// + /// Update the Player with the most recent information from the UI + /// + private void UpdateModel(object sender, PropertyChangedEventArgs e) + { + Dispatcher.UIThread.InvokeAsync(() => + { + Player.UpdateModel(DataContext as PlayerViewModel); + }); + } + /// /// Update the UI with the most recent information from the Player /// diff --git a/RedBookPlayer/Hardware/Player.cs b/RedBookPlayer/Hardware/Player.cs index eff5894..2e822ee 100644 --- a/RedBookPlayer/Hardware/Player.cs +++ b/RedBookPlayer/Hardware/Player.cs @@ -294,6 +294,19 @@ namespace RedBookPlayer.Hardware } } + /// + /// Update the internal values from the frontend + /// + /// Data context to update from + public void UpdateModel(PlayerViewModel dataContext) + { + if(!Initialized || dataContext == null) + return; + + App.Settings.Volume = dataContext.Volume; + ToggleDeEmphasis(dataContext.ApplyDeEmphasis); + } + /// /// Get current sector time, accounting for offsets /// From c2b063301acd1892e05e2ef6c9aac17a02294880 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 14:46:40 -0700 Subject: [PATCH 15/24] Move ApplyDeEmphasis in model --- RedBookPlayer/GUI/PlayerViewModel.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index bd285fb..4a8c78d 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -42,10 +42,6 @@ namespace RedBookPlayer.GUI set => this.RaiseAndSetIfChanged(ref _volume, value); } - #endregion - - #region Disc Flags - private bool _applyDeEmphasis; public bool ApplyDeEmphasis { @@ -53,6 +49,10 @@ namespace RedBookPlayer.GUI set => this.RaiseAndSetIfChanged(ref _applyDeEmphasis, value); } + #endregion + + #region Disc Flags + private bool _quadChannel; public bool QuadChannel { From 83fc88ff6a5c920b91ffdc35bbcef66bb9009ded Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 15:00:51 -0700 Subject: [PATCH 16/24] Disconnect some more UI -> Model --- RedBookPlayer/GUI/MainWindow.xaml.cs | 2 +- RedBookPlayer/GUI/PlayerView.xaml.cs | 27 ++++++++------- RedBookPlayer/GUI/PlayerViewModel.cs | 36 ++++++++++--------- RedBookPlayer/Hardware/Player.cs | 52 +++++++++++----------------- 4 files changed, 55 insertions(+), 62 deletions(-) diff --git a/RedBookPlayer/GUI/MainWindow.xaml.cs b/RedBookPlayer/GUI/MainWindow.xaml.cs index 031d78e..563e733 100644 --- a/RedBookPlayer/GUI/MainWindow.xaml.cs +++ b/RedBookPlayer/GUI/MainWindow.xaml.cs @@ -90,7 +90,7 @@ namespace RedBookPlayer.GUI Closing += (e, f) => { - PlayerView.Player.Stop(); + ((PlayerView)ContentControl.Content).StopButton_Click(this, null); }; AddHandler(DragDrop.DropEvent, MainWindow_Drop); diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index 3454bd7..b3c4166 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -71,7 +71,8 @@ namespace RedBookPlayer.GUI public async Task LoadImage(string path) { // If the player is currently running, stop it - if(Player.Playing) Player.Stop(); + if((DataContext as PlayerViewModel).Playing != true) + (DataContext as PlayerViewModel).Playing = null; bool result = await Task.Run(() => { @@ -233,13 +234,13 @@ namespace RedBookPlayer.GUI await LoadImage(path); } - public void PlayButton_Click(object sender, RoutedEventArgs e) => Player.TogglePlayPause(true); + public void PlayButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Playing = true; - public void PauseButton_Click(object sender, RoutedEventArgs e) => Player.TogglePlayPause(false); + public void PauseButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Playing = false; - public void PlayPauseButton_Click(object sender, RoutedEventArgs e) => Player.TogglePlayPause(!Player.Playing); + public void PlayPauseButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Playing = !(DataContext as PlayerViewModel).Playing; - public void StopButton_Click(object sender, RoutedEventArgs e) => Player.Stop(); + public void StopButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Playing = null; public void NextTrackButton_Click(object sender, RoutedEventArgs e) => Player.NextTrack(); @@ -253,29 +254,29 @@ namespace RedBookPlayer.GUI public void RewindButton_Click(object sender, RoutedEventArgs e) => Player.Rewind(); - public void VolumeUpButton_Click(object sender, RoutedEventArgs e) => App.Settings.Volume++; + public void VolumeUpButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Volume++; - public void VolumeDownButton_Click(object sender, RoutedEventArgs e) => App.Settings.Volume--; + public void VolumeDownButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Volume--; public void MuteToggleButton_Click(object sender, RoutedEventArgs e) { if (_lastVolume == null) { - _lastVolume = App.Settings.Volume; - App.Settings.Volume = 0; + _lastVolume = (DataContext as PlayerViewModel).Volume; + (DataContext as PlayerViewModel).Volume = 0; } else { - App.Settings.Volume = _lastVolume.Value; + (DataContext as PlayerViewModel).Volume = _lastVolume.Value; _lastVolume = null; } } - public void EnableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => Player.ToggleDeEmphasis(true); + public void EnableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).ApplyDeEmphasis = true; - public void DisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => Player.ToggleDeEmphasis(false); + public void DisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).ApplyDeEmphasis = false; - public void EnableDisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => Player.ToggleDeEmphasis(!Player.ApplyDeEmphasis); + public void EnableDisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).ApplyDeEmphasis = !(DataContext as PlayerViewModel).ApplyDeEmphasis; #endregion } diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index 4a8c78d..55cb5d3 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -6,13 +6,31 @@ namespace RedBookPlayer.GUI { #region Player Status - private bool _playing; - public bool Playing + private bool? _playing; + public bool? Playing { get => _playing; set => this.RaiseAndSetIfChanged(ref _playing, value); } + private int _volume; + public int Volume + { + get => _volume; + set => this.RaiseAndSetIfChanged(ref _volume, value); + } + + private bool _applyDeEmphasis; + public bool ApplyDeEmphasis + { + get => _applyDeEmphasis; + set => this.RaiseAndSetIfChanged(ref _applyDeEmphasis, value); + } + + #endregion + + #region Model-Provided Playback Information + private ulong _currentSector; public ulong CurrentSector { @@ -35,20 +53,6 @@ namespace RedBookPlayer.GUI public int TotalSeconds => (int)(_totalSectors / 75 % 60); public int TotalMinutes => (int)(_totalSectors % 75); - private int _volume; - public int Volume - { - get => _volume; - set => this.RaiseAndSetIfChanged(ref _volume, value); - } - - private bool _applyDeEmphasis; - public bool ApplyDeEmphasis - { - get => _applyDeEmphasis; - set => this.RaiseAndSetIfChanged(ref _applyDeEmphasis, value); - } - #endregion #region Disc Flags diff --git a/RedBookPlayer/Hardware/Player.cs b/RedBookPlayer/Hardware/Player.cs index 2e822ee..5e63a79 100644 --- a/RedBookPlayer/Hardware/Player.cs +++ b/RedBookPlayer/Hardware/Player.cs @@ -90,35 +90,28 @@ namespace RedBookPlayer.Hardware #region Playback /// - /// Toggle audio playback + /// Set the current audio playback state /// - /// True to start playback, false to pause - public void TogglePlayPause(bool start) + /// True to start playback, false to pause, null to stop + private void SetPlayingState(bool? start) { if(_opticalDisc == null || !_opticalDisc.Initialized) return; - if(start) + if(start == true) { _soundOutput.Play(); _opticalDisc.SetTotalIndexes(); } - else + else if(start == false) { _soundOutput.Stop(); } - } - - /// - /// Stop the current audio playback - /// - public void Stop() - { - if(_opticalDisc == null || !_opticalDisc.Initialized) - return; - - _soundOutput.Stop(); - _opticalDisc.LoadFirstTrack(); + else + { + _soundOutput.Stop(); + _opticalDisc.LoadFirstTrack(); + } } /// @@ -130,13 +123,13 @@ namespace RedBookPlayer.Hardware return; bool wasPlaying = Playing; - if(wasPlaying) TogglePlayPause(false); + if(wasPlaying) SetPlayingState(false); _opticalDisc.NextTrack(); if(_opticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying) TogglePlayPause(true); + if(wasPlaying) SetPlayingState(true); } /// @@ -148,13 +141,13 @@ namespace RedBookPlayer.Hardware return; bool wasPlaying = Playing; - if(wasPlaying) TogglePlayPause(false); + if(wasPlaying) SetPlayingState(false); _opticalDisc.PreviousTrack(); if(_opticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying) TogglePlayPause(true); + if(wasPlaying) SetPlayingState(true); } /// @@ -167,13 +160,13 @@ namespace RedBookPlayer.Hardware return; bool wasPlaying = Playing; - if(wasPlaying) TogglePlayPause(false); + if(wasPlaying) SetPlayingState(false); _opticalDisc.NextIndex(changeTrack); if(_opticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying) TogglePlayPause(true); + if(wasPlaying) SetPlayingState(true); } /// @@ -186,13 +179,13 @@ namespace RedBookPlayer.Hardware return; bool wasPlaying = Playing; - if(wasPlaying) TogglePlayPause(false); + if(wasPlaying) SetPlayingState(false); _opticalDisc.PreviousIndex(changeTrack); if(_opticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying) TogglePlayPause(true); + if(wasPlaying) SetPlayingState(true); } /// @@ -255,12 +248,6 @@ namespace RedBookPlayer.Hardware return string.Join("", numbers.Select(i => i.ToString().PadLeft(2, '0').Substring(0, 2))); } - /// - /// Toggle de-emphasis processing - /// - /// True to apply de-emphasis, false otherwise - public void ToggleDeEmphasis(bool enable) => _soundOutput?.ToggleDeEmphasis(enable); - /// /// Update the data context for the frontend /// @@ -303,8 +290,9 @@ namespace RedBookPlayer.Hardware if(!Initialized || dataContext == null) return; + SetPlayingState(dataContext.Playing); App.Settings.Volume = dataContext.Volume; - ToggleDeEmphasis(dataContext.ApplyDeEmphasis); + _soundOutput?.ToggleDeEmphasis(dataContext.ApplyDeEmphasis); } /// From faba0ffadab237ef490c98c6b14bcfa34943e007 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 15:36:51 -0700 Subject: [PATCH 17/24] Fix index seeking with tracks with no index 0 --- RedBookPlayer/Discs/CompactDisc.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RedBookPlayer/Discs/CompactDisc.cs b/RedBookPlayer/Discs/CompactDisc.cs index 87b670a..21e8fc8 100644 --- a/RedBookPlayer/Discs/CompactDisc.cs +++ b/RedBookPlayer/Discs/CompactDisc.cs @@ -79,8 +79,8 @@ namespace RedBookPlayer.Discs // Ensure that the value is valid, wrapping around if necessary if(value > track.Indexes.Keys.Max()) - _currentTrackIndex = 0; - else if(value < 0) + _currentTrackIndex = track.Indexes.Keys.Min(); + else if(value < track.Indexes.Keys.Min()) _currentTrackIndex = track.Indexes.Keys.Max(); else _currentTrackIndex = value; From 0d7681543a57ea6bbbb54d09023e102732227546 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 15:37:56 -0700 Subject: [PATCH 18/24] Remove direct access of Player from UI code --- RedBookPlayer/GUI/PlayerView.xaml.cs | 64 ++++----- RedBookPlayer/GUI/PlayerViewModel.cs | 143 ++++++++++++++++++++ RedBookPlayer/Hardware/Player.cs | 187 ++++++++------------------- 3 files changed, 234 insertions(+), 160 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index b3c4166..6989a33 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -12,16 +12,15 @@ using Avalonia.Markup.Xaml; using Avalonia.Media.Imaging; using Avalonia.Platform; using Avalonia.Threading; -using RedBookPlayer.Hardware; namespace RedBookPlayer.GUI { public class PlayerView : UserControl { /// - /// Player representing the internal state + /// Read-only access to the view model /// - public static Player Player = new Player(); + public PlayerViewModel PlayerViewModel => DataContext as PlayerViewModel; /// /// Set of images representing the digits for the UI @@ -71,13 +70,12 @@ namespace RedBookPlayer.GUI public async Task LoadImage(string path) { // If the player is currently running, stop it - if((DataContext as PlayerViewModel).Playing != true) - (DataContext as PlayerViewModel).Playing = null; + if(PlayerViewModel.Playing != true) PlayerViewModel.Playing = null; - bool result = await Task.Run(() => + bool result = await Dispatcher.UIThread.InvokeAsync(() => { - Player.Init(path, App.Settings.AutoPlay); - return Player.Initialized; + PlayerViewModel.Init(path, App.Settings.AutoPlay); + return PlayerViewModel.Initialized; }); if(result) @@ -122,7 +120,7 @@ namespace RedBookPlayer.GUI private void InitializeComponent(string xaml) { DataContext = new PlayerViewModel(); - (DataContext as PlayerViewModel).PropertyChanged += UpdateModel; + PlayerViewModel.PropertyChanged += UpdateModel; // Load the theme try @@ -199,7 +197,7 @@ namespace RedBookPlayer.GUI { Dispatcher.UIThread.InvokeAsync(() => { - Player.UpdateModel(DataContext as PlayerViewModel); + PlayerViewModel.UpdateModel(); }); } @@ -210,14 +208,14 @@ namespace RedBookPlayer.GUI { Dispatcher.UIThread.InvokeAsync(() => { - string digitString = Player.GenerateDigitString(); + string digitString = PlayerViewModel.GenerateDigitString(); for (int i = 0; i < _digits.Length; i++) { if (_digits[i] != null) _digits[i].Source = GetBitmap(digitString[i]); } - Player.UpdateDataContext(DataContext as PlayerViewModel); + PlayerViewModel?.UpdateView(); }); } @@ -234,49 +232,55 @@ namespace RedBookPlayer.GUI await LoadImage(path); } - public void PlayButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Playing = true; + public void PlayButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = true; - public void PauseButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Playing = false; + public void PauseButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = false; - public void PlayPauseButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Playing = !(DataContext as PlayerViewModel).Playing; + public void PlayPauseButton_Click(object sender, RoutedEventArgs e) + { + if(PlayerViewModel.Playing == true) + PlayerViewModel.Playing = false; + else + PlayerViewModel.Playing = true; + } - public void StopButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Playing = null; + public void StopButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = null; - public void NextTrackButton_Click(object sender, RoutedEventArgs e) => Player.NextTrack(); + public void NextTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextTrack(); - public void PreviousTrackButton_Click(object sender, RoutedEventArgs e) => Player.PreviousTrack(); + public void PreviousTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousTrack(); - public void NextIndexButton_Click(object sender, RoutedEventArgs e) => Player.NextIndex(App.Settings.IndexButtonChangeTrack); + public void NextIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextIndex(App.Settings.IndexButtonChangeTrack); - public void PreviousIndexButton_Click(object sender, RoutedEventArgs e) => Player.PreviousIndex(App.Settings.IndexButtonChangeTrack); + public void PreviousIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousIndex(App.Settings.IndexButtonChangeTrack); - public void FastForwardButton_Click(object sender, RoutedEventArgs e) => Player.FastForward(); + public void FastForwardButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.FastForward(); - public void RewindButton_Click(object sender, RoutedEventArgs e) => Player.Rewind(); + public void RewindButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Rewind(); - public void VolumeUpButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Volume++; + public void VolumeUpButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Volume++; - public void VolumeDownButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).Volume--; + public void VolumeDownButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Volume--; public void MuteToggleButton_Click(object sender, RoutedEventArgs e) { if (_lastVolume == null) { - _lastVolume = (DataContext as PlayerViewModel).Volume; - (DataContext as PlayerViewModel).Volume = 0; + _lastVolume = PlayerViewModel.Volume; + PlayerViewModel.Volume = 0; } else { - (DataContext as PlayerViewModel).Volume = _lastVolume.Value; + PlayerViewModel.Volume = _lastVolume.Value; _lastVolume = null; } } - public void EnableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).ApplyDeEmphasis = true; + public void EnableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ApplyDeEmphasis = true; - public void DisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).ApplyDeEmphasis = false; + public void DisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ApplyDeEmphasis = false; - public void EnableDisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => (DataContext as PlayerViewModel).ApplyDeEmphasis = !(DataContext as PlayerViewModel).ApplyDeEmphasis; + public void EnableDisableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ApplyDeEmphasis = !PlayerViewModel.ApplyDeEmphasis; #endregion } diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index 55cb5d3..a01caf9 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -1,11 +1,22 @@ +using System.Linq; +using Aaru.CommonTypes.Enums; using ReactiveUI; +using RedBookPlayer.Discs; +using RedBookPlayer.Hardware; namespace RedBookPlayer.GUI { public class PlayerViewModel : ReactiveObject { + /// + /// Player representing the internal state + /// + private Player _player; + #region Player Status + public bool Initialized => _player?.Initialized ?? false; + private bool? _playing; public bool? Playing { @@ -93,5 +104,137 @@ namespace RedBookPlayer.GUI } #endregion + + /// + /// Initialize the view model with a given image path + /// + /// Path to the disc image + /// True if playback should begin immediately, false otherwise + public void Init(string path, bool autoPlay) + { + _player = new Player(); + _player.Init(path, autoPlay); + + if(Initialized) + UpdateModel(); + } + + #region Playback + + /// + /// Move to the next playable track + /// + public void NextTrack() => _player?.NextTrack(); + + /// + /// Move to the previous playable track + /// + public void PreviousTrack() => _player?.PreviousTrack(); + + /// + /// Move to the next index + /// + /// True if index changes can trigger a track change, false otherwise + public void NextIndex(bool changeTrack) => _player?.NextIndex(changeTrack); + + /// + /// Move to the previous index + /// + /// True if index changes can trigger a track change, false otherwise + public void PreviousIndex(bool changeTrack) => _player?.PreviousIndex(changeTrack); + + /// + /// Fast-forward playback by 75 sectors, if possible + /// + public void FastForward() => _player?.FastForward(); + + /// + /// Rewind playback by 75 sectors, if possible + /// + public void Rewind() => _player?.Rewind(); + + #endregion + + #region Helpers + + /// + /// Generate the digit string to be interpreted by the frontend + /// + /// String representing the digits for the frontend + public string GenerateDigitString() + { + // If the disc isn't initialized, return all '-' characters + if(_player?.OpticalDisc == null || !_player.OpticalDisc.Initialized) + return string.Empty.PadLeft(20, '-'); + + // Otherwise, take the current time into account + ulong sectorTime = _player.GetCurrentSectorTime(); + + int[] numbers = new int[] + { + _player.OpticalDisc.CurrentTrackNumber + 1, + _player.OpticalDisc.CurrentTrackIndex, + + (int)(sectorTime / (75 * 60)), + (int)(sectorTime / 75 % 60), + (int)(sectorTime % 75), + + _player.OpticalDisc.TotalTracks, + _player.OpticalDisc.TotalIndexes, + + (int)(_player.OpticalDisc.TotalTime / (75 * 60)), + (int)(_player.OpticalDisc.TotalTime / 75 % 60), + (int)(_player.OpticalDisc.TotalTime % 75), + }; + + return string.Join("", numbers.Select(i => i.ToString().PadLeft(2, '0').Substring(0, 2))); + } + + /// + /// Update the UI from the internal player + /// + public void UpdateView() + { + if(_player?.Initialized != true) + return; + + Playing = _player.Playing; + CurrentSector = _player.GetCurrentSectorTime(); + TotalSectors = _player.OpticalDisc.TotalTime; + Volume = App.Settings.Volume; + + ApplyDeEmphasis = _player.ApplyDeEmphasis; + HiddenTrack = _player.OpticalDisc.TimeOffset > 150; + + if(_player.OpticalDisc is CompactDisc compactDisc) + { + QuadChannel = compactDisc.QuadChannel; + IsDataTrack = compactDisc.IsDataTrack; + CopyAllowed = compactDisc.CopyAllowed; + TrackHasEmphasis = compactDisc.TrackHasEmphasis; + } + else + { + QuadChannel = false; + IsDataTrack = _player.OpticalDisc.TrackType != TrackType.Audio; + CopyAllowed = false; + TrackHasEmphasis = false; + } + } + + /// + /// Update the internal player from the UI + /// + public void UpdateModel() + { + if(_player?.Initialized != true) + return; + + _player.SetPlayingState(Playing); + App.Settings.Volume = Volume; + _player.SetDeEmphasis(ApplyDeEmphasis); + } + + #endregion } } \ No newline at end of file diff --git a/RedBookPlayer/Hardware/Player.cs b/RedBookPlayer/Hardware/Player.cs index 5e63a79..c18628e 100644 --- a/RedBookPlayer/Hardware/Player.cs +++ b/RedBookPlayer/Hardware/Player.cs @@ -1,11 +1,8 @@ using System; using System.IO; -using System.Linq; -using Aaru.CommonTypes.Enums; using Aaru.DiscImages; using Aaru.Filters; using RedBookPlayer.Discs; -using RedBookPlayer.GUI; namespace RedBookPlayer.Hardware { @@ -18,10 +15,15 @@ namespace RedBookPlayer.Hardware /// public bool Initialized { get; private set; } = false; + /// + /// OpticalDisc object + /// + public OpticalDisc OpticalDisc { get; private set; } + /// /// Indicate if the disc is playing /// - public bool Playing => _soundOutput?.Playing ?? false; + public bool? Playing => _soundOutput?.Playing; /// /// Indicates if de-emphasis should be applied @@ -32,11 +34,6 @@ namespace RedBookPlayer.Hardware #region Private State Variables - /// - /// OpticalDisc object - /// - private OpticalDisc _opticalDisc; - /// /// Sound output handling class /// @@ -55,7 +52,7 @@ namespace RedBookPlayer.Hardware Initialized = false; _soundOutput = new SoundOutput(); _soundOutput.ApplyDeEmphasis = false; - _opticalDisc = null; + OpticalDisc = null; try { @@ -70,7 +67,7 @@ namespace RedBookPlayer.Hardware image.Open(filter); // Generate and instantiate the disc - _opticalDisc = OpticalDiscFactory.GenerateFromImage(image, App.Settings.AutoPlay); + OpticalDisc = OpticalDiscFactory.GenerateFromImage(image, App.Settings.AutoPlay); } catch { @@ -79,7 +76,7 @@ namespace RedBookPlayer.Hardware } // Initialize the sound output - _soundOutput.Init(_opticalDisc, autoPlay); + _soundOutput.Init(OpticalDisc, autoPlay); if(_soundOutput == null || !_soundOutput.Initialized) return; @@ -93,15 +90,19 @@ namespace RedBookPlayer.Hardware /// Set the current audio playback state /// /// True to start playback, false to pause, null to stop - private void SetPlayingState(bool? start) + public void SetPlayingState(bool? start) { - if(_opticalDisc == null || !_opticalDisc.Initialized) + if(OpticalDisc == null || !OpticalDisc.Initialized) + return; + + // If the playing state has not changed, do nothing + if(start == Playing) return; if(start == true) { _soundOutput.Play(); - _opticalDisc.SetTotalIndexes(); + OpticalDisc.SetTotalIndexes(); } else if(start == false) { @@ -110,7 +111,7 @@ namespace RedBookPlayer.Hardware else { _soundOutput.Stop(); - _opticalDisc.LoadFirstTrack(); + OpticalDisc.LoadFirstTrack(); } } @@ -119,17 +120,17 @@ namespace RedBookPlayer.Hardware /// public void NextTrack() { - if(_opticalDisc == null || !_opticalDisc.Initialized) + if(OpticalDisc == null || !OpticalDisc.Initialized) return; - bool wasPlaying = Playing; - if(wasPlaying) SetPlayingState(false); + bool? wasPlaying = Playing; + if(wasPlaying == true) SetPlayingState(false); - _opticalDisc.NextTrack(); - if(_opticalDisc is CompactDisc compactDisc) + OpticalDisc.NextTrack(); + if(OpticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying) SetPlayingState(true); + if(wasPlaying == true) SetPlayingState(true); } /// @@ -137,17 +138,17 @@ namespace RedBookPlayer.Hardware /// public void PreviousTrack() { - if(_opticalDisc == null || !_opticalDisc.Initialized) + if(OpticalDisc == null || !OpticalDisc.Initialized) return; - bool wasPlaying = Playing; - if(wasPlaying) SetPlayingState(false); + bool? wasPlaying = Playing; + if(wasPlaying == true) SetPlayingState(false); - _opticalDisc.PreviousTrack(); - if(_opticalDisc is CompactDisc compactDisc) + OpticalDisc.PreviousTrack(); + if(OpticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying) SetPlayingState(true); + if(wasPlaying == true) SetPlayingState(true); } /// @@ -156,17 +157,17 @@ namespace RedBookPlayer.Hardware /// True if index changes can trigger a track change, false otherwise public void NextIndex(bool changeTrack) { - if(_opticalDisc == null || !_opticalDisc.Initialized) + if(OpticalDisc == null || !OpticalDisc.Initialized) return; - bool wasPlaying = Playing; - if(wasPlaying) SetPlayingState(false); + bool? wasPlaying = Playing; + if(wasPlaying == true) SetPlayingState(false); - _opticalDisc.NextIndex(changeTrack); - if(_opticalDisc is CompactDisc compactDisc) + OpticalDisc.NextIndex(changeTrack); + if(OpticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying) SetPlayingState(true); + if(wasPlaying == true) SetPlayingState(true); } /// @@ -175,17 +176,17 @@ namespace RedBookPlayer.Hardware /// True if index changes can trigger a track change, false otherwise public void PreviousIndex(bool changeTrack) { - if(_opticalDisc == null || !_opticalDisc.Initialized) + if(OpticalDisc == null || !OpticalDisc.Initialized) return; - bool wasPlaying = Playing; - if(wasPlaying) SetPlayingState(false); + bool? wasPlaying = Playing; + if(wasPlaying == true) SetPlayingState(false); - _opticalDisc.PreviousIndex(changeTrack); - if(_opticalDisc is CompactDisc compactDisc) + OpticalDisc.PreviousIndex(changeTrack); + if(OpticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying) SetPlayingState(true); + if(wasPlaying == true) SetPlayingState(true); } /// @@ -193,10 +194,10 @@ namespace RedBookPlayer.Hardware /// public void FastForward() { - if(_opticalDisc == null || !_opticalDisc.Initialized) + if(OpticalDisc == null || !OpticalDisc.Initialized) return; - _opticalDisc.CurrentSector = Math.Min(_opticalDisc.TotalSectors, _opticalDisc.CurrentSector + 75); + OpticalDisc.CurrentSector = Math.Min(OpticalDisc.TotalSectors, OpticalDisc.CurrentSector + 75); } /// @@ -204,112 +205,38 @@ namespace RedBookPlayer.Hardware /// public void Rewind() { - if(_opticalDisc == null || !_opticalDisc.Initialized) + if(OpticalDisc == null || !OpticalDisc.Initialized) return; - if(_opticalDisc.CurrentSector >= 75) - _opticalDisc.CurrentSector -= 75; + if(OpticalDisc.CurrentSector >= 75) + OpticalDisc.CurrentSector -= 75; } #endregion #region Helpers - /// - /// Generate the digit string to be interpreted by the frontend - /// - /// String representing the digits for the frontend - public string GenerateDigitString() - { - // If the disc isn't initialized, return all '-' characters - if(_opticalDisc == null || !_opticalDisc.Initialized) - return string.Empty.PadLeft(20, '-'); - - // Otherwise, take the current time into account - ulong sectorTime = GetCurrentSectorTime(); - - int[] numbers = new int[] - { - _opticalDisc.CurrentTrackNumber + 1, - _opticalDisc.CurrentTrackIndex, - - (int)(sectorTime / (75 * 60)), - (int)(sectorTime / 75 % 60), - (int)(sectorTime % 75), - - _opticalDisc.TotalTracks, - _opticalDisc.TotalIndexes, - - (int)(_opticalDisc.TotalTime / (75 * 60)), - (int)(_opticalDisc.TotalTime / 75 % 60), - (int)(_opticalDisc.TotalTime % 75), - }; - - return string.Join("", numbers.Select(i => i.ToString().PadLeft(2, '0').Substring(0, 2))); - } - - /// - /// Update the data context for the frontend - /// - /// Data context to be updated - public void UpdateDataContext(PlayerViewModel dataContext) - { - if(!Initialized || dataContext == null) - return; - - dataContext.Playing = Playing; - dataContext.CurrentSector = GetCurrentSectorTime(); - dataContext.TotalSectors = _opticalDisc.TotalTime; - dataContext.Volume = App.Settings.Volume; - - dataContext.ApplyDeEmphasis = ApplyDeEmphasis; - dataContext.HiddenTrack = _opticalDisc.TimeOffset > 150; - - if(_opticalDisc is CompactDisc compactDisc) - { - dataContext.QuadChannel = compactDisc.QuadChannel; - dataContext.IsDataTrack = compactDisc.IsDataTrack; - dataContext.CopyAllowed = compactDisc.CopyAllowed; - dataContext.TrackHasEmphasis = compactDisc.TrackHasEmphasis; - } - else - { - dataContext.QuadChannel = false; - dataContext.IsDataTrack = _opticalDisc.TrackType != TrackType.Audio; - dataContext.CopyAllowed = false; - dataContext.TrackHasEmphasis = false; - } - } - - /// - /// Update the internal values from the frontend - /// - /// Data context to update from - public void UpdateModel(PlayerViewModel dataContext) - { - if(!Initialized || dataContext == null) - return; - - SetPlayingState(dataContext.Playing); - App.Settings.Volume = dataContext.Volume; - _soundOutput?.ToggleDeEmphasis(dataContext.ApplyDeEmphasis); - } - /// /// Get current sector time, accounting for offsets /// /// ulong representing the current sector time - private ulong GetCurrentSectorTime() + public ulong GetCurrentSectorTime() { - ulong sectorTime = _opticalDisc.CurrentSector; - if(_opticalDisc.SectionStartSector != 0) - sectorTime -= _opticalDisc.SectionStartSector; + ulong sectorTime = OpticalDisc.CurrentSector; + if (OpticalDisc.SectionStartSector != 0) + sectorTime -= OpticalDisc.SectionStartSector; else - sectorTime += _opticalDisc.TimeOffset; + sectorTime += OpticalDisc.TimeOffset; return sectorTime; } + /// + /// Set if de-emphasis should be applied + /// + /// True to enable, false to disable + public void SetDeEmphasis(bool apply) => _soundOutput?.ToggleDeEmphasis(apply); + #endregion } } \ No newline at end of file From 09f4adad5106f0be7843322887419dae4361333b Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 16:04:18 -0700 Subject: [PATCH 19/24] Less direct coupling of volume from setting --- RedBookPlayer/GUI/MainWindow.xaml.cs | 8 +- RedBookPlayer/GUI/PlayerView.xaml.cs | 2 +- RedBookPlayer/GUI/PlayerViewModel.cs | 15 ++-- RedBookPlayer/Hardware/Player.cs | 106 +++++++++++++++----------- RedBookPlayer/Hardware/SoundOutput.cs | 32 +++++++- 5 files changed, 103 insertions(+), 60 deletions(-) diff --git a/RedBookPlayer/GUI/MainWindow.xaml.cs b/RedBookPlayer/GUI/MainWindow.xaml.cs index 563e733..9c46297 100644 --- a/RedBookPlayer/GUI/MainWindow.xaml.cs +++ b/RedBookPlayer/GUI/MainWindow.xaml.cs @@ -186,8 +186,9 @@ namespace RedBookPlayer.GUI increment *= 2; if(e.KeyModifiers.HasFlag(KeyModifiers.Shift)) increment *= 5; - - App.Settings.Volume += increment; + + if(playerView?.PlayerViewModel?.Volume != null) + playerView.PlayerViewModel.Volume += increment; } // Volume Down @@ -199,7 +200,8 @@ namespace RedBookPlayer.GUI if(e.KeyModifiers.HasFlag(KeyModifiers.Shift)) decrement *= 5; - App.Settings.Volume -= decrement; + if (playerView?.PlayerViewModel?.Volume != null) + playerView.PlayerViewModel.Volume -= decrement; } // Mute Toggle diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index 6989a33..47bbc07 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -74,7 +74,7 @@ namespace RedBookPlayer.GUI bool result = await Dispatcher.UIThread.InvokeAsync(() => { - PlayerViewModel.Init(path, App.Settings.AutoPlay); + PlayerViewModel.Init(path, App.Settings.AutoPlay, App.Settings.Volume); return PlayerViewModel.Initialized; }); diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index a01caf9..6996e2e 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -110,11 +110,10 @@ namespace RedBookPlayer.GUI /// /// Path to the disc image /// True if playback should begin immediately, false otherwise - public void Init(string path, bool autoPlay) + /// Default volume between 0 and 100 to use when starting playback + public void Init(string path, bool autoPlay, int defaultVolume) { - _player = new Player(); - _player.Init(path, autoPlay); - + _player = new Player(path, autoPlay, defaultVolume); if(Initialized) UpdateModel(); } @@ -201,7 +200,7 @@ namespace RedBookPlayer.GUI Playing = _player.Playing; CurrentSector = _player.GetCurrentSectorTime(); TotalSectors = _player.OpticalDisc.TotalTime; - Volume = App.Settings.Volume; + Volume = _player.Volume; ApplyDeEmphasis = _player.ApplyDeEmphasis; HiddenTrack = _player.OpticalDisc.TimeOffset > 150; @@ -230,9 +229,9 @@ namespace RedBookPlayer.GUI if(_player?.Initialized != true) return; - _player.SetPlayingState(Playing); - App.Settings.Volume = Volume; - _player.SetDeEmphasis(ApplyDeEmphasis); + _player.Playing = Playing; + _player.Volume = Volume; + _player.ApplyDeEmphasis = ApplyDeEmphasis; } #endregion diff --git a/RedBookPlayer/Hardware/Player.cs b/RedBookPlayer/Hardware/Player.cs index c18628e..2850f89 100644 --- a/RedBookPlayer/Hardware/Player.cs +++ b/RedBookPlayer/Hardware/Player.cs @@ -23,12 +23,56 @@ namespace RedBookPlayer.Hardware /// /// Indicate if the disc is playing /// - public bool? Playing => _soundOutput?.Playing; + public bool? Playing + { + get => _soundOutput?.Playing; + set + { + if(OpticalDisc == null || !OpticalDisc.Initialized) + return; + + // If the playing state has not changed, do nothing + if(value == _soundOutput?.Playing) + return; + + if(value == true) + { + _soundOutput.Play(); + OpticalDisc.SetTotalIndexes(); + } + else if(value == false) + { + _soundOutput.Stop(); + } + else + { + _soundOutput.Stop(); + OpticalDisc.LoadFirstTrack(); + } + } + } + + /// + /// Indicate the current playback volume + /// + public int Volume + { + get => _soundOutput?.Volume ?? 100; + set + { + if(_soundOutput != null) + _soundOutput.Volume = value; + } + } /// /// Indicates if de-emphasis should be applied /// - public bool ApplyDeEmphasis => _soundOutput?.ApplyDeEmphasis ?? false; + public bool ApplyDeEmphasis + { + get => _soundOutput?.ApplyDeEmphasis ?? false; + set => _soundOutput?.SetDeEmphasis(value); + } #endregion @@ -42,13 +86,14 @@ namespace RedBookPlayer.Hardware #endregion /// - /// Initialize the player with a given image path + /// Create a new Player from a given image path /// /// Path to the disc image /// True if playback should begin immediately, false otherwise - public void Init(string path, bool autoPlay = false) + /// Default volume between 0 and 100 to use when starting playback + public Player(string path, bool autoPlay = false, int defaultVolume = 100) { - // Reset the internal state for initialization + // Set the internal state for initialization Initialized = false; _soundOutput = new SoundOutput(); _soundOutput.ApplyDeEmphasis = false; @@ -67,7 +112,7 @@ namespace RedBookPlayer.Hardware image.Open(filter); // Generate and instantiate the disc - OpticalDisc = OpticalDiscFactory.GenerateFromImage(image, App.Settings.AutoPlay); + OpticalDisc = OpticalDiscFactory.GenerateFromImage(image, autoPlay); } catch { @@ -76,7 +121,7 @@ namespace RedBookPlayer.Hardware } // Initialize the sound output - _soundOutput.Init(OpticalDisc, autoPlay); + _soundOutput.Init(OpticalDisc, autoPlay, defaultVolume); if(_soundOutput == null || !_soundOutput.Initialized) return; @@ -86,35 +131,6 @@ namespace RedBookPlayer.Hardware #region Playback - /// - /// Set the current audio playback state - /// - /// True to start playback, false to pause, null to stop - public void SetPlayingState(bool? start) - { - if(OpticalDisc == null || !OpticalDisc.Initialized) - return; - - // If the playing state has not changed, do nothing - if(start == Playing) - return; - - if(start == true) - { - _soundOutput.Play(); - OpticalDisc.SetTotalIndexes(); - } - else if(start == false) - { - _soundOutput.Stop(); - } - else - { - _soundOutput.Stop(); - OpticalDisc.LoadFirstTrack(); - } - } - /// /// Move to the next playable track /// @@ -124,13 +140,13 @@ namespace RedBookPlayer.Hardware return; bool? wasPlaying = Playing; - if(wasPlaying == true) SetPlayingState(false); + if(wasPlaying == true) Playing = false; OpticalDisc.NextTrack(); if(OpticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying == true) SetPlayingState(true); + if(wasPlaying == true) Playing = true; } /// @@ -142,13 +158,13 @@ namespace RedBookPlayer.Hardware return; bool? wasPlaying = Playing; - if(wasPlaying == true) SetPlayingState(false); + if(wasPlaying == true) Playing = false; OpticalDisc.PreviousTrack(); if(OpticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying == true) SetPlayingState(true); + if(wasPlaying == true) Playing = true; } /// @@ -161,13 +177,13 @@ namespace RedBookPlayer.Hardware return; bool? wasPlaying = Playing; - if(wasPlaying == true) SetPlayingState(false); + if(wasPlaying == true) Playing = false; OpticalDisc.NextIndex(changeTrack); if(OpticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying == true) SetPlayingState(true); + if(wasPlaying == true) Playing = true; } /// @@ -180,13 +196,13 @@ namespace RedBookPlayer.Hardware return; bool? wasPlaying = Playing; - if(wasPlaying == true) SetPlayingState(false); + if(wasPlaying == true) Playing = false; OpticalDisc.PreviousIndex(changeTrack); if(OpticalDisc is CompactDisc compactDisc) _soundOutput.ApplyDeEmphasis = compactDisc.TrackHasEmphasis; - if(wasPlaying == true) SetPlayingState(true); + if(wasPlaying == true) Playing = true; } /// @@ -235,7 +251,7 @@ namespace RedBookPlayer.Hardware /// Set if de-emphasis should be applied /// /// True to enable, false to disable - public void SetDeEmphasis(bool apply) => _soundOutput?.ToggleDeEmphasis(apply); + public void SetDeEmphasis(bool apply) => _soundOutput?.SetDeEmphasis(apply); #endregion } diff --git a/RedBookPlayer/Hardware/SoundOutput.cs b/RedBookPlayer/Hardware/SoundOutput.cs index a88dab7..b2ec0d3 100644 --- a/RedBookPlayer/Hardware/SoundOutput.cs +++ b/RedBookPlayer/Hardware/SoundOutput.cs @@ -27,6 +27,23 @@ namespace RedBookPlayer.Hardware /// public bool Playing => _soundOut.PlaybackState == PlaybackState.Playing; + /// + /// Current playback volume + /// + public int Volume + { + get => _volume; + set + { + if(value > 100) + _volume = 100; + else if(value < 0) + _volume = 0; + else + _volume = value; + } + } + #endregion #region Private State Variables @@ -44,6 +61,11 @@ namespace RedBookPlayer.Hardware /// private OpticalDisc _opticalDisc; + /// + /// Internal value for the volume + /// + private int _volume = 100; + /// /// Data provider for sound output /// @@ -76,7 +98,8 @@ namespace RedBookPlayer.Hardware /// /// OpticalDisc to load from /// True if playback should begin immediately, false otherwise - public void Init(OpticalDisc opticalDisc, bool autoPlay = false) + /// Default volume between 0 and 100 to use when starting playback + public void Init(OpticalDisc opticalDisc, bool autoPlay = false, int defaultVolume = 100) { // If we have an unusable disc, just return if(opticalDisc == null || !opticalDisc.Initialized) @@ -85,6 +108,9 @@ namespace RedBookPlayer.Hardware // Save a reference to the disc _opticalDisc = opticalDisc; + // Set the initial playback volume + Volume = defaultVolume; + // Enable de-emphasis for CDs, if necessary if(opticalDisc is CompactDisc compactDisc) ApplyDeEmphasis = compactDisc.TrackHasEmphasis; @@ -116,7 +142,7 @@ namespace RedBookPlayer.Hardware public int ProviderRead(byte[] buffer, int offset, int count) { // Set the current volume - _soundOut.Volume = (float)App.Settings.Volume / 100; + _soundOut.Volume = (float)Volume / 100; // Determine how many sectors we can read ulong sectorsToRead; @@ -243,7 +269,7 @@ namespace RedBookPlayer.Hardware /// Toggle de-emphasis processing /// /// True to apply de-emphasis, false otherwise - public void ToggleDeEmphasis(bool enable) => ApplyDeEmphasis = enable; + public void SetDeEmphasis(bool enable) => ApplyDeEmphasis = enable; /// /// Sets or resets the de-emphasis filters From 701d4e7c1c55164fcc468782fec656878d345a3f Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 16:21:14 -0700 Subject: [PATCH 20/24] Move mute toggling to view-model --- RedBookPlayer/GUI/PlayerView.xaml.cs | 19 +------------------ RedBookPlayer/GUI/PlayerViewModel.cs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index 47bbc07..957bc4c 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -35,11 +35,6 @@ namespace RedBookPlayer.GUI /// private Timer _updateTimer; - /// - /// Last volume for mute toggling - /// - private int? _lastVolume = null; - public PlayerView() => InitializeComponent(null); public PlayerView(string xaml) => InitializeComponent(xaml); @@ -262,19 +257,7 @@ namespace RedBookPlayer.GUI public void VolumeDownButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Volume--; - public void MuteToggleButton_Click(object sender, RoutedEventArgs e) - { - if (_lastVolume == null) - { - _lastVolume = PlayerViewModel.Volume; - PlayerViewModel.Volume = 0; - } - else - { - PlayerViewModel.Volume = _lastVolume.Value; - _lastVolume = null; - } - } + public void MuteToggleButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ToggleMute(); public void EnableDeEmphasisButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.ApplyDeEmphasis = true; diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index 6996e2e..6699a18 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -13,6 +13,11 @@ namespace RedBookPlayer.GUI /// private Player _player; + /// + /// Last volume for mute toggling + /// + private int? _lastVolume = null; + #region Player Status public bool Initialized => _player?.Initialized ?? false; @@ -189,6 +194,23 @@ namespace RedBookPlayer.GUI return string.Join("", numbers.Select(i => i.ToString().PadLeft(2, '0').Substring(0, 2))); } + /// + /// Temporarily mute playback + /// + public void ToggleMute() + { + if(_lastVolume == null) + { + _lastVolume = Volume; + Volume = 0; + } + else + { + Volume = _lastVolume.Value; + _lastVolume = null; + } + } + /// /// Update the UI from the internal player /// From 4b5d0af58d7ce2f7e36c94b73e74df59ce83a0e0 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 16:23:08 -0700 Subject: [PATCH 21/24] Simplify play/pause toggle logic --- RedBookPlayer/GUI/PlayerView.xaml.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index 957bc4c..ad7af05 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -231,13 +231,7 @@ namespace RedBookPlayer.GUI public void PauseButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = false; - public void PlayPauseButton_Click(object sender, RoutedEventArgs e) - { - if(PlayerViewModel.Playing == true) - PlayerViewModel.Playing = false; - else - PlayerViewModel.Playing = true; - } + public void PlayPauseButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = !(PlayerViewModel.Playing ?? false); public void StopButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.Playing = null; From 416772ab35d1876b1394b91d77538226968fea1f Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 16:25:56 -0700 Subject: [PATCH 22/24] Make view-model stop playback --- RedBookPlayer/GUI/PlayerView.xaml.cs | 3 --- RedBookPlayer/GUI/PlayerViewModel.cs | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index ad7af05..149225e 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -64,9 +64,6 @@ namespace RedBookPlayer.GUI /// Path to the image to load public async Task LoadImage(string path) { - // If the player is currently running, stop it - if(PlayerViewModel.Playing != true) PlayerViewModel.Playing = null; - bool result = await Dispatcher.UIThread.InvokeAsync(() => { PlayerViewModel.Init(path, App.Settings.AutoPlay, App.Settings.Volume); diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index 6699a18..c57f9fa 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -118,6 +118,10 @@ namespace RedBookPlayer.GUI /// Default volume between 0 and 100 to use when starting playback public void Init(string path, bool autoPlay, int defaultVolume) { + // Stop current playback, if necessary + if(Playing != null) Playing = null; + + // Create and attempt to initialize new Player _player = new Player(path, autoPlay, defaultVolume); if(Initialized) UpdateModel(); From e86896045becd184cd290a0432abfc482c029fb7 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 21:00:14 -0700 Subject: [PATCH 23/24] Fix volume setting bug --- RedBookPlayer/GUI/PlayerViewModel.cs | 2 +- RedBookPlayer/Hardware/SoundOutput.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index c57f9fa..8a47f7b 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -124,7 +124,7 @@ namespace RedBookPlayer.GUI // Create and attempt to initialize new Player _player = new Player(path, autoPlay, defaultVolume); if(Initialized) - UpdateModel(); + UpdateView(); } #region Playback diff --git a/RedBookPlayer/Hardware/SoundOutput.cs b/RedBookPlayer/Hardware/SoundOutput.cs index b2ec0d3..d31b68c 100644 --- a/RedBookPlayer/Hardware/SoundOutput.cs +++ b/RedBookPlayer/Hardware/SoundOutput.cs @@ -64,7 +64,7 @@ namespace RedBookPlayer.Hardware /// /// Internal value for the volume /// - private int _volume = 100; + private int _volume; /// /// Data provider for sound output From 9a787270a20f4d67671c86eb81852a4acca967d7 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 3 Jul 2021 21:15:23 -0700 Subject: [PATCH 24/24] Fix stopping playback --- RedBookPlayer/GUI/PlayerView.xaml.cs | 13 ------- RedBookPlayer/GUI/PlayerViewModel.cs | 55 +++++++++++++++------------- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs index 149225e..7dabeae 100644 --- a/RedBookPlayer/GUI/PlayerView.xaml.cs +++ b/RedBookPlayer/GUI/PlayerView.xaml.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -112,7 +111,6 @@ namespace RedBookPlayer.GUI private void InitializeComponent(string xaml) { DataContext = new PlayerViewModel(); - PlayerViewModel.PropertyChanged += UpdateModel; // Load the theme try @@ -182,17 +180,6 @@ namespace RedBookPlayer.GUI }; } - /// - /// Update the Player with the most recent information from the UI - /// - private void UpdateModel(object sender, PropertyChangedEventArgs e) - { - Dispatcher.UIThread.InvokeAsync(() => - { - PlayerViewModel.UpdateModel(); - }); - } - /// /// Update the UI with the most recent information from the Player /// diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs index 8a47f7b..4030ba5 100644 --- a/RedBookPlayer/GUI/PlayerViewModel.cs +++ b/RedBookPlayer/GUI/PlayerViewModel.cs @@ -20,27 +20,48 @@ namespace RedBookPlayer.GUI #region Player Status + /// + /// Indicate if the model is ready to be used + /// public bool Initialized => _player?.Initialized ?? false; - private bool? _playing; + /// + /// Indicate the player state + /// public bool? Playing { - get => _playing; - set => this.RaiseAndSetIfChanged(ref _playing, value); + get => _player?.Playing ?? false; + set + { + if(_player != null) + _player.Playing = value; + } } - private int _volume; + /// + /// Indicate the current playback volume + /// public int Volume { - get => _volume; - set => this.RaiseAndSetIfChanged(ref _volume, value); + get => _player?.Volume ?? 100; + set + { + if(_player != null) + _player.Volume = value; + } } - private bool _applyDeEmphasis; + /// + /// Indicates if de-emphasis should be applied + /// public bool ApplyDeEmphasis { - get => _applyDeEmphasis; - set => this.RaiseAndSetIfChanged(ref _applyDeEmphasis, value); + get => _player?.ApplyDeEmphasis ?? false; + set + { + if(_player != null) + _player.ApplyDeEmphasis = value; + } } #endregion @@ -223,12 +244,9 @@ namespace RedBookPlayer.GUI if(_player?.Initialized != true) return; - Playing = _player.Playing; CurrentSector = _player.GetCurrentSectorTime(); TotalSectors = _player.OpticalDisc.TotalTime; - Volume = _player.Volume; - ApplyDeEmphasis = _player.ApplyDeEmphasis; HiddenTrack = _player.OpticalDisc.TimeOffset > 150; if(_player.OpticalDisc is CompactDisc compactDisc) @@ -247,19 +265,6 @@ namespace RedBookPlayer.GUI } } - /// - /// Update the internal player from the UI - /// - public void UpdateModel() - { - if(_player?.Initialized != true) - return; - - _player.Playing = Playing; - _player.Volume = Volume; - _player.ApplyDeEmphasis = ApplyDeEmphasis; - } - #endregion } } \ No newline at end of file