diff --git a/RedBookPlayer/Discs/CompactDisc.cs b/RedBookPlayer/Discs/CompactDisc.cs
index 62d8728..f25a7ec 100644
--- a/RedBookPlayer/Discs/CompactDisc.cs
+++ b/RedBookPlayer/Discs/CompactDisc.cs
@@ -52,7 +52,7 @@ namespace RedBookPlayer.Discs
CurrentTrackIndex = track.Indexes.Keys.Min();
// If the track is playable, just return
- if(TrackType == TrackType.Audio || App.Settings.PlayDataTracks)
+ if(TrackType == TrackType.Audio || _loadDataTracks)
break;
// If we're not playing the track, skip
@@ -196,6 +196,16 @@ namespace RedBookPlayer.Discs
///
private ulong _currentSector = 0;
+ ///
+ /// Indicate if a TOC should be generated if missing
+ ///
+ private readonly bool _generateMissingToc = false;
+
+ ///
+ /// Indicate if data tracks should be loaded
+ ///
+ private bool _loadDataTracks = false;
+
///
/// Current disc table of contents
///
@@ -203,8 +213,19 @@ namespace RedBookPlayer.Discs
#endregion
+ ///
+ /// Constructor
+ ///
+ /// Generate a TOC if the disc is missing one
+ /// Load data tracks for playback
+ public CompactDisc(bool generateMissingToc, bool loadDataTracks)
+ {
+ _generateMissingToc = generateMissingToc;
+ _loadDataTracks = loadDataTracks;
+ }
+
///
- public override void Init(IOpticalMediaImage image, bool autoPlay = false)
+ public override void Init(IOpticalMediaImage image, bool autoPlay)
{
// If the image is null, we can't do anything
if(image == null)
@@ -260,7 +281,7 @@ namespace RedBookPlayer.Discs
}
///
- public override bool PreviousIndex(bool changeTrack)
+ public override bool PreviousIndex(bool changeTrack, bool playHiddenTrack)
{
if(_image == null)
return false;
@@ -269,7 +290,7 @@ namespace RedBookPlayer.Discs
{
if(changeTrack)
{
- PreviousTrack();
+ PreviousTrack(playHiddenTrack);
CurrentSector = (ulong)_image.Tracks[CurrentTrackNumber].Indexes.Values.Max();
return true;
}
@@ -293,6 +314,12 @@ namespace RedBookPlayer.Discs
LoadTrack(CurrentTrackNumber);
}
+ ///
+ /// Set the value for loading data tracks
+ ///
+ /// True to enable loading data tracks, false otherwise
+ public void SetLoadDataTracks(bool load) => _loadDataTracks = load;
+
///
public override void SetTotalIndexes()
{
@@ -329,7 +356,7 @@ namespace RedBookPlayer.Discs
if(_image.Info.ReadableMediaTags?.Contains(MediaTagType.CD_FullTOC) != true)
{
// Only generate the TOC if we have it set
- if(!App.Settings.GenerateMissingTOC)
+ if(!_generateMissingToc)
{
Console.WriteLine("Full TOC not found");
return false;
diff --git a/RedBookPlayer/Discs/OpticalDisc.cs b/RedBookPlayer/Discs/OpticalDisc.cs
index 701660a..3bc2443 100644
--- a/RedBookPlayer/Discs/OpticalDisc.cs
+++ b/RedBookPlayer/Discs/OpticalDisc.cs
@@ -90,7 +90,7 @@ namespace RedBookPlayer.Discs
///
/// Aaruformat image to load
/// True if playback should begin immediately, false otherwise
- public abstract void Init(IOpticalMediaImage image, bool autoPlay = false);
+ public abstract void Init(IOpticalMediaImage image, bool autoPlay);
#region Seeking
@@ -109,14 +109,15 @@ namespace RedBookPlayer.Discs
///
/// Try to move to the previous track, wrapping around if necessary
///
- public void PreviousTrack()
+ /// True to play the hidden track, if it exists
+ public void PreviousTrack(bool playHiddenTrack)
{
if(_image == null)
return;
if(CurrentSector < (ulong)_image.Tracks[CurrentTrackNumber].Indexes[1] + 75)
{
- if(App.Settings.AllowSkipHiddenTrack && CurrentTrackNumber == 0 && CurrentSector >= 75)
+ if(playHiddenTrack && CurrentTrackNumber == 0 && CurrentSector >= 75)
CurrentSector = 0;
else
CurrentTrackNumber--;
@@ -138,8 +139,9 @@ namespace RedBookPlayer.Discs
/// Try to move to the previous track index
///
/// True if index changes can trigger a track change, false otherwise
+ /// True to play the hidden track, if it exists
/// True if the track was changed, false otherwise
- public abstract bool PreviousIndex(bool changeTrack);
+ public abstract bool PreviousIndex(bool changeTrack, bool playHiddenTrack);
#endregion
diff --git a/RedBookPlayer/Discs/OpticalDiscFactory.cs b/RedBookPlayer/Discs/OpticalDiscFactory.cs
index 178a87a..76ab981 100644
--- a/RedBookPlayer/Discs/OpticalDiscFactory.cs
+++ b/RedBookPlayer/Discs/OpticalDiscFactory.cs
@@ -12,9 +12,11 @@ namespace RedBookPlayer.Discs
/// Generate an OpticalDisc from an input path
///
/// Path to load the image from
+ /// Generate a TOC if the disc is missing one [CompactDisc only]
+ /// Load data tracks for playback [CompactDisc only]
/// True if the image should be playable immediately, false otherwise
/// Instantiated OpticalDisc, if possible
- public static OpticalDisc GenerateFromPath(string path, bool autoPlay)
+ public static OpticalDisc GenerateFromPath(string path, bool generateMissingToc, bool loadDataTracks, bool autoPlay)
{
try
{
@@ -30,7 +32,7 @@ namespace RedBookPlayer.Discs
image.Open(filter);
// Generate and instantiate the disc
- return GenerateFromImage(image, autoPlay);
+ return GenerateFromImage(image, generateMissingToc, loadDataTracks, autoPlay);
}
catch
{
@@ -43,9 +45,11 @@ namespace RedBookPlayer.Discs
/// Generate an OpticalDisc from an input IOpticalMediaImage
///
/// IOpticalMediaImage to create from
+ /// Generate a TOC if the disc is missing one [CompactDisc only]
+ /// Load data tracks for playback [CompactDisc only]
/// True if the image should be playable immediately, false otherwise
/// Instantiated OpticalDisc, if possible
- public static OpticalDisc GenerateFromImage(IOpticalMediaImage image, bool autoPlay)
+ public static OpticalDisc GenerateFromImage(IOpticalMediaImage image, bool generateMissingToc, bool loadDataTracks, bool autoPlay)
{
// If the image is not usable, we don't do anything
if(!IsUsableImage(image))
@@ -59,7 +63,7 @@ namespace RedBookPlayer.Discs
{
case "Compact Disc":
case "GD":
- opticalDisc = new CompactDisc();
+ opticalDisc = new CompactDisc(generateMissingToc, loadDataTracks);
break;
default:
opticalDisc = null;
diff --git a/RedBookPlayer/GUI/MainWindow.xaml.cs b/RedBookPlayer/GUI/MainWindow.xaml.cs
index 9c46297..d95bb98 100644
--- a/RedBookPlayer/GUI/MainWindow.xaml.cs
+++ b/RedBookPlayer/GUI/MainWindow.xaml.cs
@@ -121,6 +121,7 @@ namespace RedBookPlayer.GUI
if(e.Key == App.Settings.OpenSettingsKey)
{
settingsWindow = new SettingsWindow(App.Settings);
+ settingsWindow.Closed += OnSettingsClosed;
settingsWindow.Show();
}
@@ -217,6 +218,12 @@ namespace RedBookPlayer.GUI
}
}
+ public void OnSettingsClosed(object sender, EventArgs e)
+ {
+ PlayerView playerView = ContentControl.Content as PlayerView;
+ playerView?.UpdateViewModel();
+ }
+
#endregion
}
}
\ No newline at end of file
diff --git a/RedBookPlayer/GUI/PlayerView.xaml.cs b/RedBookPlayer/GUI/PlayerView.xaml.cs
index 2319c97..1a31981 100644
--- a/RedBookPlayer/GUI/PlayerView.xaml.cs
+++ b/RedBookPlayer/GUI/PlayerView.xaml.cs
@@ -26,11 +26,16 @@ namespace RedBookPlayer.GUI
///
private Image[] _digits;
+ ///
+ /// Initialize the UI based on the default theme
+ ///
+ public PlayerView() : this(null) { }
+
///
/// Initialize the UI based on the currently selected theme
///
/// XAML data representing the theme, null for default
- public PlayerView(string xaml = null)
+ public PlayerView(string xaml)
{
DataContext = new PlayerViewModel();
PlayerViewModel.PropertyChanged += PlayerViewModelStateChanged;
@@ -41,23 +46,6 @@ namespace RedBookPlayer.GUI
#region Helpers
- ///
- /// Generate a path selection dialog box
- ///
- /// User-selected path, if possible
- public async Task GetPath()
- {
- var dialog = new OpenFileDialog { AllowMultiple = false };
- List knownExtensions = new Aaru.DiscImages.AaruFormat().KnownExtensions.ToList();
- dialog.Filters.Add(new FileDialogFilter()
- {
- Name = "Aaru Image Format (*" + string.Join(", *", knownExtensions) + ")",
- Extensions = knownExtensions.ConvertAll(e => e.TrimStart('.'))
- });
-
- return (await dialog.ShowAsync((Window)Parent.Parent))?.FirstOrDefault();
- }
-
///
/// Load an image from the path
///
@@ -66,7 +54,7 @@ namespace RedBookPlayer.GUI
{
return await Dispatcher.UIThread.InvokeAsync(() =>
{
- PlayerViewModel.Init(path, App.Settings.AutoPlay, App.Settings.Volume);
+ PlayerViewModel.Init(path, App.Settings.GenerateMissingTOC, App.Settings.PlayDataTracks, App.Settings.AutoPlay, App.Settings.Volume);
if (PlayerViewModel.Initialized)
MainWindow.Instance.Title = "RedBookPlayer - " + path.Split('/').Last().Split('\\').Last();
@@ -74,6 +62,11 @@ namespace RedBookPlayer.GUI
});
}
+ ///
+ /// Update the view model with new settings
+ ///
+ public void UpdateViewModel() => PlayerViewModel.SetLoadDataTracks(App.Settings.PlayDataTracks);
+
///
/// Generate the digit string to be interpreted by the frontend
///
@@ -107,21 +100,6 @@ namespace RedBookPlayer.GUI
return string.Join("", numbers.Select(i => i.ToString().PadLeft(2, '0').Substring(0, 2)));
}
- ///
- /// Get current sector time, accounting for offsets
- ///
- /// ulong representing the current sector time
- private ulong GetCurrentSectorTime()
- {
- ulong sectorTime = PlayerViewModel.CurrentSector;
- if(PlayerViewModel.SectionStartSector != 0)
- sectorTime -= PlayerViewModel.SectionStartSector;
- else
- sectorTime += PlayerViewModel.TimeOffset;
-
- return sectorTime;
- }
-
///
/// Load the png image for a given character based on the theme
///
@@ -150,6 +128,38 @@ namespace RedBookPlayer.GUI
}
}
+ ///
+ /// Get current sector time, accounting for offsets
+ ///
+ /// ulong representing the current sector time
+ private ulong GetCurrentSectorTime()
+ {
+ ulong sectorTime = PlayerViewModel.CurrentSector;
+ if(PlayerViewModel.SectionStartSector != 0)
+ sectorTime -= PlayerViewModel.SectionStartSector;
+ else
+ sectorTime += PlayerViewModel.TimeOffset;
+
+ return sectorTime;
+ }
+
+ ///
+ /// Generate a path selection dialog box
+ ///
+ /// User-selected path, if possible
+ private async Task GetPath()
+ {
+ var dialog = new OpenFileDialog { AllowMultiple = false };
+ List knownExtensions = new Aaru.DiscImages.AaruFormat().KnownExtensions.ToList();
+ dialog.Filters.Add(new FileDialogFilter()
+ {
+ Name = "Aaru Image Format (*" + string.Join(", *", knownExtensions) + ")",
+ Extensions = knownExtensions.ConvertAll(e => e.TrimStart('.'))
+ });
+
+ return (await dialog.ShowAsync((Window)Parent.Parent))?.FirstOrDefault();
+ }
+
///
/// Initialize the displayed digits array
///
@@ -250,11 +260,11 @@ namespace RedBookPlayer.GUI
public void NextTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextTrack();
- public void PreviousTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousTrack();
+ public void PreviousTrackButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousTrack(App.Settings.AllowSkipHiddenTrack);
public void NextIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.NextIndex(App.Settings.IndexButtonChangeTrack);
- public void PreviousIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousIndex(App.Settings.IndexButtonChangeTrack);
+ public void PreviousIndexButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.PreviousIndex(App.Settings.IndexButtonChangeTrack, App.Settings.AllowSkipHiddenTrack);
public void FastForwardButton_Click(object sender, RoutedEventArgs e) => PlayerViewModel.FastForward();
diff --git a/RedBookPlayer/GUI/PlayerViewModel.cs b/RedBookPlayer/GUI/PlayerViewModel.cs
index 654d3cd..87ebbb4 100644
--- a/RedBookPlayer/GUI/PlayerViewModel.cs
+++ b/RedBookPlayer/GUI/PlayerViewModel.cs
@@ -185,15 +185,17 @@ namespace RedBookPlayer.GUI
/// Initialize the view model with a given image path
///
/// Path to the disc image
+ /// Generate a TOC if the disc is missing one [CompactDisc only]
+ /// Load data tracks for playback [CompactDisc only]
/// True if playback should begin immediately, false otherwise
/// Default volume between 0 and 100 to use when starting playback
- public void Init(string path, bool autoPlay, int defaultVolume)
+ public void Init(string path, bool generateMissingToc, bool loadDataTracks, 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);
+ _player = new Player(path, generateMissingToc, loadDataTracks, autoPlay, defaultVolume);
if(Initialized)
{
_player.PropertyChanged += PlayerStateChanged;
@@ -226,7 +228,8 @@ namespace RedBookPlayer.GUI
///
/// Move to the previous playable track
///
- public void PreviousTrack() => _player?.PreviousTrack();
+ /// True to play the hidden track, if it exists
+ public void PreviousTrack(bool playHiddenTrack) => _player?.PreviousTrack(playHiddenTrack);
///
/// Move to the next index
@@ -238,7 +241,8 @@ namespace RedBookPlayer.GUI
/// Move to the previous index
///
/// True if index changes can trigger a track change, false otherwise
- public void PreviousIndex(bool changeTrack) => _player?.PreviousIndex(changeTrack);
+ /// True to play the hidden track, if it exists
+ public void PreviousIndex(bool changeTrack, bool playHiddenTrack) => _player?.PreviousIndex(changeTrack, playHiddenTrack);
///
/// Fast-forward playback by 75 sectors, if possible
@@ -260,6 +264,12 @@ namespace RedBookPlayer.GUI
///
public void SetDeEmphasis(bool apply) => _player?.SetDeEmphasis(apply);
+ ///
+ /// Set the value for loading data tracks [CompactDisc only]
+ ///
+ /// True to enable loading data tracks, false otherwise
+ public void SetLoadDataTracks(bool load) => _player?.SetLoadDataTracks(load);
+
///
/// Temporarily mute playback
///
diff --git a/RedBookPlayer/Hardware/Player.cs b/RedBookPlayer/Hardware/Player.cs
index 870200e..85c2263 100644
--- a/RedBookPlayer/Hardware/Player.cs
+++ b/RedBookPlayer/Hardware/Player.cs
@@ -187,9 +187,11 @@ namespace RedBookPlayer.Hardware
/// Create a new Player from a given image path
///
/// Path to the disc image
+ /// Generate a TOC if the disc is missing one [CompactDisc only]
+ /// Load data tracks for playback [CompactDisc only]
/// True if playback should begin immediately, false otherwise
/// Default volume between 0 and 100 to use when starting playback
- public Player(string path, bool autoPlay = false, int defaultVolume = 100)
+ public Player(string path, bool generateMissingToc, bool loadDataTracks, bool autoPlay, int defaultVolume)
{
// Set the internal state for initialization
Initialized = false;
@@ -197,7 +199,7 @@ namespace RedBookPlayer.Hardware
_soundOutput.SetDeEmphasis(false);
// Initalize the disc
- _opticalDisc = OpticalDiscFactory.GenerateFromPath(path, autoPlay);
+ _opticalDisc = OpticalDiscFactory.GenerateFromPath(path, generateMissingToc, loadDataTracks, autoPlay);
if(_opticalDisc == null || !_opticalDisc.Initialized)
return;
@@ -292,7 +294,8 @@ namespace RedBookPlayer.Hardware
///
/// Move to the previous playable track
///
- public void PreviousTrack()
+ /// True to play the hidden track, if it exists
+ public void PreviousTrack(bool playHiddenTrack)
{
if(_opticalDisc == null || !_opticalDisc.Initialized)
return;
@@ -300,7 +303,7 @@ namespace RedBookPlayer.Hardware
bool? wasPlaying = Playing;
if(wasPlaying == true) Pause();
- _opticalDisc.PreviousTrack();
+ _opticalDisc.PreviousTrack(playHiddenTrack);
if(_opticalDisc is CompactDisc compactDisc)
_soundOutput.SetDeEmphasis(compactDisc.TrackHasEmphasis);
@@ -334,7 +337,8 @@ namespace RedBookPlayer.Hardware
/// Move to the previous index
///
/// True if index changes can trigger a track change, false otherwise
- public void PreviousIndex(bool changeTrack)
+ /// True to play the hidden track, if it exists
+ public void PreviousIndex(bool changeTrack, bool playHiddenTrack)
{
if(_opticalDisc == null || !_opticalDisc.Initialized)
return;
@@ -342,7 +346,7 @@ namespace RedBookPlayer.Hardware
bool? wasPlaying = Playing;
if(wasPlaying == true) Pause();
- _opticalDisc.PreviousIndex(changeTrack);
+ _opticalDisc.PreviousIndex(changeTrack, playHiddenTrack);
if(_opticalDisc is CompactDisc compactDisc)
_soundOutput.SetDeEmphasis(compactDisc.TrackHasEmphasis);
@@ -387,6 +391,12 @@ namespace RedBookPlayer.Hardware
///
public void SetDeEmphasis(bool apply) => _soundOutput?.SetDeEmphasis(apply);
+ ///
+ /// Set the value for loading data tracks [CompactDisc only]
+ ///
+ /// True to enable loading data tracks, false otherwise
+ public void SetLoadDataTracks(bool load) => (_opticalDisc as CompactDisc)?.SetLoadDataTracks(load);
+
///
/// Update the player from the current OpticalDisc
///