diff --git a/Output/Languages/English.xml b/Output/Languages/English.xml index 1cafa62a..6554f2dc 100644 --- a/Output/Languages/English.xml +++ b/Output/Languages/English.xml @@ -76,6 +76,7 @@ Own Music and Background Music No own Music Only own Music + Only selected song All Only names and avatars Nothing diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs index 70337917..1182b700 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs @@ -379,7 +379,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe { base.OnClose(); CBase.BackgroundMusic.SetDisabled(false); - CBase.Sound.FadeAndClose(_PreviewStream, 0f, 0.5f); + CBase.Sound.Fade(_PreviewStream, 0f, 0.5f, EStreamAction.Close); } private void _CreateFields() @@ -574,7 +574,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe { _GameData.NumJokerRandom[teamNr]--; if (!CBase.Sound.IsFinished(_PreviewStream)) - CBase.Sound.FadeAndClose(_PreviewStream, 0, 1); + CBase.Sound.Fade(_PreviewStream, 0, 1, EStreamAction.Close); _FieldSelected(true); } break; @@ -586,7 +586,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe _GameData.NumJokerRetry[teamNr]--; _GameData.Team = teamNr; if (!CBase.Sound.IsFinished(_PreviewStream)) - CBase.Sound.FadeAndClose(_PreviewStream, 0, 1); + CBase.Sound.Fade(_PreviewStream, 0, 1, EStreamAction.Close); _Status = EStatus.JokerRetry; _OldSelectedField = _SelectedField; _SelectedField = -1; @@ -627,7 +627,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe private void _NextRound() { - CBase.Sound.FadeAndClose(_PreviewStream, 0f, 0.5f); + CBase.Sound.Fade(_PreviewStream, 0f, 0.5f, EStreamAction.Close); _Data.ScreenMain.Rounds = _GameData.Rounds; _Data.ScreenMain.FadeToNameSelection = false; _Data.ScreenMain.FadeToSinging = true; @@ -640,7 +640,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe private void _EndParty() { - CBase.Sound.FadeAndClose(_PreviewStream, 0f, 0.5f); + CBase.Sound.Fade(_PreviewStream, 0f, 0.5f, EStreamAction.Close); _FadeTo(EScreens.ScreenParty); } @@ -659,7 +659,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe private void _Back() { - CBase.Sound.FadeAndClose(_PreviewStream, 0f, 0.5f); + CBase.Sound.Fade(_PreviewStream, 0f, 0.5f, EStreamAction.Close); _Data.ScreenMain.FadeToNameSelection = true; _Data.ScreenMain.FadeToSinging = false; _Data.ScreenMain.SingRoundNr = _SelectedField; diff --git a/Vocaluxe/Base/CBackgroundMusic.cs b/Vocaluxe/Base/CBackgroundMusic.cs index 86023cad..d34d5432 100644 --- a/Vocaluxe/Base/CBackgroundMusic.cs +++ b/Vocaluxe/Base/CBackgroundMusic.cs @@ -22,6 +22,7 @@ using System.IO; using VocaluxeLib; using VocaluxeLib.Songs; using VocaluxeLib.Draw; +using VocaluxeLib.Utils.Player; namespace Vocaluxe.Base { @@ -29,89 +30,98 @@ namespace Vocaluxe.Base { private static bool _Initialized; + private static CSongPlayer _SongPlayer; + private static CSongPlayer _PreviewPlayer; + private static bool _OwnSongsAvailable; private static EBackgroundMusicSource _MusicSource; private static bool _VideoEnabled; private static CPlaylistElement _CurrentPlaylistElement; //Currently played music - private static int _CurrentMusicStream = -1; //Current active music stream - private static int _PreviousMusicIndex; //Index of _CurrentPlaylistElement in _PreviousFiles (kept for performance) + private static int _PreviousMusicIndex = -1; private static readonly List _BGMusicFiles = new List(); //Background music files private static readonly List _NotPlayedFiles = new List(); //Not played files private static readonly List _PreviousFiles = new List(); //Played files - private static int _Video = -1; - private static CTexture _CurrentVideoTexture; - private static CFading _VideoFading; - private static bool _OwnMusicAdded; private static bool _BackgroundMusicAdded; private static bool _Disabled; + private static bool _PlaysPreview; public static bool VideoEnabled { - get { return _VideoEnabled; } - set - { - if (_VideoEnabled == value) - return; - _VideoEnabled = value; - if (_VideoEnabled) - _LoadVideo(); - else if (_Video != -1) - { - CVideo.Close(_Video); - CDraw.RemoveTexture(ref _CurrentVideoTexture); - _Video = -1; - } + get { return _PlaysPreview ? _PreviewPlayer.VideoEnabled : _SongPlayer.VideoEnabled; } + set { + if(_PlaysPreview) + _PreviewPlayer.VideoEnabled = value; + else + _SongPlayer.VideoEnabled = value; } } - public static bool CanSing { get; private set; } + public static bool CanSing + { + get + { + if (_PlaysPreview) + return false; + else + if (_BGMusicFiles.Contains(_CurrentPlaylistElement)) + return false; + else return true; + } + } public static bool Disabled { get { return _Disabled; } set { + if (Disabled == value) + return; _Disabled = value; - if (_Disabled) - Pause(); - else - Play(); + Pause(); } } - public static bool RepeatSong { get; set; } + public static bool RepeatSong { + get { return _SongPlayer.RepeatSong; } + set { _SongPlayer.RepeatSong = value; } + } public static int SongID { - get { return _CurrentPlaylistElement == null ? -1 : _CurrentPlaylistElement.SongID; } + get { return _SongPlayer.SongID; } } public static bool SongHasVideo { - get { return _CurrentPlaylistElement != null && File.Exists(_CurrentPlaylistElement.VideoFilePath); } + get { return _SongPlayer.SongHasVideo; } } - public static bool IsPlaying { get; private set; } + public static bool IsPlaying { get { return _PlaysPreview ? _PreviewPlayer.IsPlaying : _SongPlayer.IsPlaying; } } + + public static bool IsPlayingPreview { get { return _PlaysPreview; } } public static string ArtistAndTitle { - get - { - if (_CurrentPlaylistElement == null) - return ""; - if (_CurrentPlaylistElement.Artist != "" && _CurrentPlaylistElement.Title != "") - return _CurrentPlaylistElement.Artist + " - " + _CurrentPlaylistElement.Title; - return Path.GetFileNameWithoutExtension(_CurrentPlaylistElement.MusicFilePath); + get { + if (_PlaysPreview) + return _PreviewPlayer.ArtistAndTitle; + else + return _BGMusicFiles.Contains(_CurrentPlaylistElement) ? Path.GetFileNameWithoutExtension(_CurrentPlaylistElement.MusicFilePath) : _SongPlayer.ArtistAndTitle; } } + public static float Length + { + get { return _PlaysPreview ? _PreviewPlayer.Length : _SongPlayer.Length; } + } + public static CTexture Cover { - get { return _CurrentPlaylistElement == null ? CCover.NoCover : _CurrentPlaylistElement.Cover; } + get { return _PlaysPreview ? _PreviewPlayer.Cover : _SongPlayer.Cover; } } //Use this to set whether own songs are available for access @@ -143,8 +153,13 @@ namespace Vocaluxe.Base _MusicSource = EBackgroundMusicSource.TR_CONFIG_NO_OWN_MUSIC; _AddBackgroundMusic(); - _PreviousMusicIndex = -1; - IsPlaying = false; + _SongPlayer = new CSongPlayer(); + _SongPlayer.Volume = CConfig.BackgroundMusicVolume; + + _PreviewPlayer = new CSongPlayer(); + _PreviewPlayer.Volume = CConfig.PreviewMusicVolume; + _PreviewPlayer.RepeatSong = true; + _VideoEnabled = (CConfig.VideoBackgrounds == EOffOn.TR_CONFIG_ON && CConfig.VideosToBackground == EOffOn.TR_CONFIG_ON); SetMusicSource(CConfig.BackgroundMusicSource); _Initialized = true; @@ -152,42 +167,29 @@ namespace Vocaluxe.Base public static void Close() { - if (_CurrentMusicStream >= 0) - { - CSound.Close(_CurrentMusicStream); - _CurrentMusicStream = -1; - } - if (_Video != -1) - { - CVideo.Close(_Video); - CDraw.RemoveTexture(ref _CurrentVideoTexture); - _Video = -1; - } + _SongPlayer.Stop(); + _PreviewPlayer.Stop(); + _BGMusicFiles.Clear(); _NotPlayedFiles.Clear(); _PreviousFiles.Clear(); - IsPlaying = false; _Initialized = false; } public static void Play() { - if (IsPlaying || CConfig.BackgroundMusic == EOffOn.TR_CONFIG_OFF) + if (IsPlaying || (CConfig.BackgroundMusic != EBackgroundMusicOffOn.TR_CONFIG_ON && !_PlaysPreview)) return; - if (_CurrentMusicStream != -1) - { - //Resume - CSound.SetStreamVolume(_CurrentMusicStream, 0f); - CSound.Fade(_CurrentMusicStream, 100f, CSettings.BackgroundMusicFadeTime); - CSound.Play(_CurrentMusicStream); - if (_VideoEnabled && _Video != -1) - CVideo.Resume(_Video); - IsPlaying = true; - } - else - Next(); + if (_PlaysPreview) + _PreviewPlayer.Play(); + else if(CConfig.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_OFF) + if (_SongPlayer.SongLoaded) + //Resume + _SongPlayer.TogglePause(); + else + Next(); } public static void Stop() @@ -195,121 +197,103 @@ namespace Vocaluxe.Base if (!IsPlaying) return; - if (_Video != -1) + if (_PlaysPreview) { - CVideo.Close(_Video); - CDraw.RemoveTexture(ref _CurrentVideoTexture); - _Video = -1; + _PreviewPlayer.Stop(); + _PlaysPreview = false; + Pause(); + } + else + { + _SongPlayer.Stop(); + _CurrentPlaylistElement = null; } - CSound.FadeAndClose(_CurrentMusicStream, 0f, CSettings.BackgroundMusicFadeTime); - _CurrentMusicStream = -1; - - _CurrentPlaylistElement = null; - IsPlaying = false; } public static void Pause() { - if (!IsPlaying) - return; - - if (_Video != -1) + if (_PlaysPreview) { - CVideo.Pause(_Video); - CVideo.Skip(_Video, CSound.GetPosition(_CurrentMusicStream) + CSettings.BackgroundMusicFadeTime, _CurrentPlaylistElement.VideoGap); + if (!_PreviewPlayer.SongLoaded) + return; + _PreviewPlayer.TogglePause(); + } + else if (CConfig.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_ON) + { + if (!_SongPlayer.SongLoaded) + Next(); + else + _SongPlayer.TogglePause(); } - CSound.FadeAndPause(_CurrentMusicStream, 0f, CSettings.BackgroundMusicFadeTime); - IsPlaying = false; } public static void Next() { - Stop(); //stop last song if any - if (_PreviousMusicIndex < _PreviousFiles.Count - 2) + if (!_PlaysPreview) { - //We are in the previous list and next element exists - _PreviousMusicIndex++; - _CurrentPlaylistElement = _PreviousFiles[_PreviousMusicIndex]; - } - else - { - //We are not in the previous list (anymore) - if (_NotPlayedFiles.Count == 0) + Stop(); //stop last song if any + if (_PreviousMusicIndex < _PreviousFiles.Count - 2) { - if (_PreviousFiles.Count == 0) - return; //No songs to play - _NotPlayedFiles.AddRange(_PreviousFiles); + //We are in the previous list and next element exists + _PreviousMusicIndex++; + _CurrentPlaylistElement = _PreviousFiles[_PreviousMusicIndex]; } + else + { + //We are not in the previous list (anymore) + if (_NotPlayedFiles.Count == 0) + { + if (_PreviousFiles.Count == 0) + return; //No songs to play + _NotPlayedFiles.AddRange(_PreviousFiles); + } - _CurrentPlaylistElement = _NotPlayedFiles[CGame.Rand.Next(_NotPlayedFiles.Count)]; - _NotPlayedFiles.Remove(_CurrentPlaylistElement); + _CurrentPlaylistElement = _NotPlayedFiles[CGame.Rand.Next(_NotPlayedFiles.Count)]; + _NotPlayedFiles.Remove(_CurrentPlaylistElement); - _PreviousFiles.Add(_CurrentPlaylistElement); - _PreviousMusicIndex = _PreviousFiles.Count - 1; + _PreviousFiles.Add(_CurrentPlaylistElement); + _PreviousMusicIndex = _PreviousFiles.Count - 1; + } + _StartSong(); } - _StartSong(); - CanSing = !_IsBackgroundFile(_CurrentPlaylistElement); } public static void Previous() { - if (_PreviousMusicIndex < 0) - return; - Debug.Assert(_CurrentMusicStream != -1 && _CurrentPlaylistElement != null); - if (CSound.GetPosition(_CurrentMusicStream) <= 1.5f && _PreviousMusicIndex > 0) + if (!_PlaysPreview) { - Stop(); //stop last song - _PreviousMusicIndex--; + if (_PreviousMusicIndex < 0) + return; + Debug.Assert(_CurrentPlaylistElement != null); + if (_SongPlayer.Position <= 1.5f && _PreviousMusicIndex > 0) + { + Stop(); //stop last song + _PreviousMusicIndex--; - _CurrentPlaylistElement = _PreviousFiles[_PreviousMusicIndex]; - CanSing = !_IsBackgroundFile(_CurrentPlaylistElement); + _CurrentPlaylistElement = _PreviousFiles[_PreviousMusicIndex]; + } + _StartSong(); } - _StartSong(); } public static void Update() { - if (!IsPlaying) + if (!IsPlaying && (!_SongPlayer.SongLoaded || !_PreviewPlayer.SongLoaded) ) return; - Debug.Assert(_CurrentMusicStream != -1 && _CurrentPlaylistElement != null); - float timeToPlay; - if (Math.Abs(_CurrentPlaylistElement.Finish) < 0.001) + if (_PlaysPreview) + _PreviewPlayer.Update(); + else { - //No End-Tag defined - float len = CSound.GetLength(_CurrentMusicStream); - timeToPlay = (len > 0f) ? len - CSound.GetPosition(_CurrentMusicStream) : CSettings.BackgroundMusicFadeTime + 1f; - } - else //End-Tag found - timeToPlay = _CurrentPlaylistElement.Finish - CSound.GetPosition(_CurrentMusicStream); - - bool finished = CSound.IsFinished(_CurrentMusicStream); - if (timeToPlay <= CSettings.BackgroundMusicFadeTime || finished) - { - if (RepeatSong) - _StartSong(); - else + _SongPlayer.Update(); + if (_SongPlayer.IsFinished) Next(); } } public static CTexture GetVideoTexture() { - if (_Video == -1) - return null; - float vtime; - if (CVideo.GetFrame(_Video, ref _CurrentVideoTexture, CSound.GetPosition(_CurrentMusicStream), out vtime)) - { - if (_VideoFading != null) - { - bool finished; - _CurrentVideoTexture.Color.A = _VideoFading.GetValue(out finished); - if (finished) - _VideoFading = null; - } - return _CurrentVideoTexture; - } - return null; + return _PlaysPreview ? _PreviewPlayer.GetVideoTexture() : _SongPlayer.GetVideoTexture(); } public static void SetMusicSource(EBackgroundMusicSource source) @@ -335,37 +319,74 @@ namespace Vocaluxe.Base } } + public static void LoadPreview(CSong song, float start = 0f) + { + if (!_PlaysPreview) + Pause(); + else + StopPreview(); + + if (song == null) + return; + + if (start == 0f) + start = song.Preview.StartTime; + + _PlaysPreview = true; + _PreviewPlayer.Load(song, start); + + float startposition = song.Preview.StartTime; + + float length = _PreviewPlayer.Length; + + if (song.Preview.Source == EDataSource.None) + startposition = length / 4f; + else if (startposition > length - 5f) + startposition = Math.Max(0f, Math.Min(length / 4f, length - 5f)); + + if (startposition >= 0.5f) + startposition -= 0.5f; + + _PreviewPlayer.Position = startposition; + + Play(); + } + + public static void PlayPreview(float start = -1f) + { + if (start > -1f) + _PreviewPlayer.Position = start; + + Play(); + } + + public static void StopPreview() + { + _PreviewPlayer.Stop(); + _PlaysPreview = false; + } + /// /// (Re-)Starts the _CurrentPlaylistElement /// private static void _StartSong() { Debug.Assert(_CurrentPlaylistElement != null); - //If we have an active stream, reuse it - if (_CurrentMusicStream < 0) - { - //otherwhise load - _CurrentMusicStream = CSound.Load(_CurrentPlaylistElement.MusicFilePath); - if (_CurrentMusicStream < 0) - return; - CSound.SetStreamVolume(_CurrentMusicStream, 0f); - CSound.Fade(_CurrentMusicStream, 100f, CSettings.BackgroundMusicFadeTime); - } - //Seek to #Start-Tag, if found - if (_CurrentPlaylistElement.Start > 0.001 && CConfig.BackgroundMusicUseStart == EOffOn.TR_CONFIG_ON) - CSound.SetPosition(_CurrentMusicStream, _CurrentPlaylistElement.Start); - if (_VideoEnabled) + //If current song same as loaded restart only + if (_CurrentPlaylistElement.SongID == _SongPlayer.SongID && _SongPlayer.SongLoaded) + _SongPlayer.Play(); + + //otherwhise load + if (_BGMusicFiles.Contains(_CurrentPlaylistElement)) + _SongPlayer.LoadFile(_CurrentPlaylistElement.MusicFilePath, 0f, true); + else { - if (_Video != -1) - { - if (_CurrentPlaylistElement.Start > 0.001 && CConfig.BackgroundMusicUseStart == EOffOn.TR_CONFIG_ON) - CVideo.Skip(_Video, 0f, _CurrentPlaylistElement.VideoGap + _CurrentPlaylistElement.Start); - else - CVideo.Skip(_Video, 0f, _CurrentPlaylistElement.VideoGap); - } - else - _LoadVideo(); + //Seek to #Start-Tag, if found + float start = 0f; + if (_CurrentPlaylistElement.Start > 0.001 && CConfig.BackgroundMusicUseStart == EOffOn.TR_CONFIG_ON) + start = _CurrentPlaylistElement.Start; + _SongPlayer.Load(CBase.Songs.GetSongByID(_CurrentPlaylistElement.SongID), start, true); } } @@ -419,16 +440,5 @@ namespace Vocaluxe.Base return _BGMusicFiles.Contains(element); } - private static void _LoadVideo() - { - if (_Video != -1 || String.IsNullOrEmpty(_CurrentPlaylistElement.VideoFilePath)) - return; - _Video = CVideo.Load(_CurrentPlaylistElement.VideoFilePath); - if (CConfig.BackgroundMusicUseStart == EOffOn.TR_CONFIG_ON) - CVideo.Skip(_Video, 0f, _CurrentPlaylistElement.VideoGap + _CurrentPlaylistElement.Start); //Use gap, otherwhise we will overwrite position in GetVideoTexture - else - CVideo.Skip(_Video, 0f, _CurrentPlaylistElement.VideoGap); - _VideoFading = new CFading(0f, 1f, 3f); - } } } \ No newline at end of file diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs index 2e73bc8e..5b42d5aa 100644 --- a/Vocaluxe/Base/CConfig.cs +++ b/Vocaluxe/Base/CConfig.cs @@ -97,7 +97,7 @@ namespace Vocaluxe.Base public static EBufferSize AudioBufferSize = EBufferSize.B2048; public static int AudioLatency; private static int _BackgroundMusicVolume = 30; - public static EOffOn BackgroundMusic = EOffOn.TR_CONFIG_ON; + public static EBackgroundMusicOffOn BackgroundMusic = EBackgroundMusicOffOn.TR_CONFIG_ON; public static EBackgroundMusicSource BackgroundMusicSource = EBackgroundMusicSource.TR_CONFIG_NO_OWN_MUSIC; public static EOffOn BackgroundMusicUseStart = EOffOn.TR_CONFIG_ON; private static int _PreviewMusicVolume = 50; @@ -478,8 +478,8 @@ namespace Vocaluxe.Base writer.WriteComment("AudioLatency from -500 to 500 ms"); writer.WriteElementString("AudioLatency", AudioLatency.ToString()); - writer.WriteComment("Background Music: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); - writer.WriteElementString("BackgroundMusic", Enum.GetName(typeof(EOffOn), BackgroundMusic)); + writer.WriteComment("Background Music: " + CHelper.ListStrings(Enum.GetNames(typeof(EBackgroundMusicOffOn)))); + writer.WriteElementString("BackgroundMusic", Enum.GetName(typeof(EBackgroundMusicOffOn), BackgroundMusic)); writer.WriteComment("Background Music Volume from 0 to 100"); writer.WriteElementString("BackgroundMusicVolume", BackgroundMusicVolume.ToString()); diff --git a/Vocaluxe/Base/CGraphics.cs b/Vocaluxe/Base/CGraphics.cs index eb53d99a..69bf1c51 100644 --- a/Vocaluxe/Base/CGraphics.cs +++ b/Vocaluxe/Base/CGraphics.cs @@ -60,6 +60,11 @@ namespace Vocaluxe.Base get { return _CurrentScreen; } } + public static EScreens NextScreen + { + get { return _NextScreen; } + } + #region public methods public static void Init() { @@ -335,7 +340,7 @@ namespace Vocaluxe.Base bool popupVolumeControlAllowed = _CurrentScreen != EScreens.ScreenCredits && _CurrentScreen != EScreens.ScreenOptionsRecord; //Hide volume control for bg-music if bg-music is disabled if (popupVolumeControlAllowed && (_CurrentScreen != EScreens.ScreenSong || CSongs.Category == -1) - && _CurrentScreen != EScreens.ScreenSing && CConfig.BackgroundMusic == EOffOn.TR_CONFIG_OFF) + && _CurrentScreen != EScreens.ScreenSing && CConfig.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_OFF) popupVolumeControlAllowed = false; @@ -391,13 +396,13 @@ namespace Vocaluxe.Base if (popupPlayerControlAllowed && keyEvent.Key == Keys.Tab) { - if (_CurrentPopupScreen == EPopupScreens.NoPopup && CConfig.BackgroundMusic == EOffOn.TR_CONFIG_ON) + if (_CurrentPopupScreen == EPopupScreens.NoPopup && CConfig.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_ON) ShowPopup(EPopupScreens.PopupPlayerControl); else HidePopup(EPopupScreens.PopupPlayerControl); } - if (popupPlayerControlAllowed && CConfig.BackgroundMusic == EOffOn.TR_CONFIG_ON) + if (popupPlayerControlAllowed && CConfig.BackgroundMusic != EBackgroundMusicOffOn.TR_CONFIG_OFF) { if (keyEvent.Key == Keys.MediaNextTrack) CBackgroundMusic.Next(); @@ -497,7 +502,7 @@ namespace Vocaluxe.Base bool isOverPopupPlayerControl = CHelper.IsInBounds(_PopupScreens[(int)EPopupScreens.PopupPlayerControl].ScreenArea, mouseEvent); if (popupPlayerControlAllowed && isOverPopupPlayerControl) { - if (_CurrentPopupScreen == EPopupScreens.NoPopup && CConfig.BackgroundMusic == EOffOn.TR_CONFIG_ON) + if (_CurrentPopupScreen == EPopupScreens.NoPopup && CConfig.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_ON) ShowPopup(EPopupScreens.PopupPlayerControl); } diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs index 5856bab5..cf99c472 100644 --- a/Vocaluxe/Base/CMain.cs +++ b/Vocaluxe/Base/CMain.cs @@ -76,6 +76,11 @@ namespace Vocaluxe.Base return CConfig.BackgroundMusicVolume; } + public EBackgroundMusicOffOn GetBackgroundMusicStatus() + { + return CConfig.BackgroundMusic; + } + public int GetPreviewMusicVolume() { return CConfig.PreviewMusicVolume; @@ -243,6 +248,11 @@ namespace Vocaluxe.Base { return CSettings.SlideShowFadeTime; } + + public float GetSoundPlayerFadeTime() + { + return CSettings.SoundPlayerFadeTime; + } } class CBtheme : ITheme @@ -335,11 +345,21 @@ namespace Vocaluxe.Base return CBackgroundMusic.VideoEnabled; } + public bool IsPlayingPreview() + { + return CBackgroundMusic.IsPlayingPreview; + } + public void SetDisabled(bool disabled) { CBackgroundMusic.Disabled = disabled; } + public float GetLength() + { + return CBackgroundMusic.Length; + } + public void Next() { CBackgroundMusic.Next(); @@ -360,6 +380,26 @@ namespace Vocaluxe.Base CBackgroundMusic.Play(); } + public void Stop() + { + CBackgroundMusic.Stop(); + } + + public void LoadPreview(CSong song, float start = 0f) + { + CBackgroundMusic.LoadPreview(song, start); + } + + public void PlayPreview(float start = -1f) + { + CBackgroundMusic.PlayPreview(start); + } + + public void StopPreview() + { + CBackgroundMusic.StopPreview(); + } + public CTexture GetVideoTexture() { return CBackgroundMusic.GetVideoTexture(); @@ -430,6 +470,11 @@ namespace Vocaluxe.Base { return CGraphics.GlobalAlpha; } + + public EScreens GetNextScreen() + { + return CGraphics.NextScreen; + } } class CBlog : ILog @@ -784,6 +829,16 @@ namespace Vocaluxe.Base { CVideo.SetLoop(streamID, loop); } + + public void Pause(int streamID) + { + CVideo.Pause(streamID); + } + + public void Resume(int streamID) + { + CVideo.Resume(streamID); + } } class CBsound : ISound @@ -803,9 +858,14 @@ namespace Vocaluxe.Base CSound.Play(soundStream); } - public void Fade(int soundStream, float targetVolume, float duration) + public void Fade(int soundStream, float targetVolume, float duration, EStreamAction afterFadeAction = EStreamAction.Nothing) { - CSound.Fade(soundStream, targetVolume, duration); + CSound.Fade(soundStream, targetVolume, duration, afterFadeAction); + } + + public void Close(int soundStream) + { + CSound.Close(soundStream); } public bool IsFinished(int soundStream) @@ -823,11 +883,6 @@ namespace Vocaluxe.Base return CSound.GetLength(soundStream); } - public void FadeAndClose(int soundStream, float targetVolume, float duration) - { - CSound.FadeAndClose(soundStream, targetVolume, duration); - } - public void SetStreamVolume(int soundStream, float volume) { CSound.SetStreamVolume(soundStream, volume); diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index 828a49a0..b419e7b1 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -151,6 +151,8 @@ namespace Vocaluxe.Base public const float BackgroundMusicFadeTime = 0.5f; public const float PauseResetTime = 1f; + public const float SoundPlayerFadeTime = 0.5f; + public const float SlideShowImageTime = 3500f; public const float SlideShowFadeTime = 500f; diff --git a/Vocaluxe/Lib/Sound/Playback/IAudioStream.cs b/Vocaluxe/Lib/Sound/Playback/IAudioStream.cs index 8ec763fe..15d88270 100644 --- a/Vocaluxe/Lib/Sound/Playback/IAudioStream.cs +++ b/Vocaluxe/Lib/Sound/Playback/IAudioStream.cs @@ -16,6 +16,7 @@ #endregion using System; +using VocaluxeLib; namespace Vocaluxe.Lib.Sound.Playback { diff --git a/Vocaluxe/Lib/Sound/Playback/IPlayback.cs b/Vocaluxe/Lib/Sound/Playback/IPlayback.cs index 04d9be75..a022d455 100644 --- a/Vocaluxe/Lib/Sound/Playback/IPlayback.cs +++ b/Vocaluxe/Lib/Sound/Playback/IPlayback.cs @@ -15,15 +15,10 @@ // along with Vocaluxe. If not, see . #endregion +using VocaluxeLib; + namespace Vocaluxe.Lib.Sound.Playback { - public enum EStreamAction - { - Nothing, - Pause, - Stop, - Close - } interface IPlayback { diff --git a/Vocaluxe/Screens/CPopupScreenPlayerControl.cs b/Vocaluxe/Screens/CPopupScreenPlayerControl.cs index 9ffe1779..e0c1cdf2 100644 --- a/Vocaluxe/Screens/CPopupScreenPlayerControl.cs +++ b/Vocaluxe/Screens/CPopupScreenPlayerControl.cs @@ -115,7 +115,7 @@ namespace Vocaluxe.Screens if (_Buttons[_ButtonPrevious].Selected) CBackgroundMusic.Previous(); if (_Buttons[_ButtonPlay].Selected) - CBackgroundMusic.Play(); + CBackgroundMusic.Pause(); if (_Buttons[_ButtonPause].Selected) CBackgroundMusic.Pause(); if (_Buttons[_ButtonRepeat].Selected) @@ -143,7 +143,7 @@ namespace Vocaluxe.Screens if (_Buttons[_ButtonPrevious].Selected) CBackgroundMusic.Previous(); if (_Buttons[_ButtonPlay].Selected) - CBackgroundMusic.Play(); + CBackgroundMusic.Pause(); if (_Buttons[_ButtonPause].Selected) CBackgroundMusic.Pause(); if (_Buttons[_ButtonRepeat].Selected) @@ -168,6 +168,17 @@ namespace Vocaluxe.Screens return true; } + public override void OnShow() + { + base.OnShow(); + _Buttons[_ButtonNext].Visible = !CBackgroundMusic.IsPlayingPreview; + _Buttons[_ButtonPause].Visible = !CBackgroundMusic.IsPlayingPreview; + _Buttons[_ButtonPlay].Visible = !CBackgroundMusic.IsPlayingPreview; + _Buttons[_ButtonPrevious].Visible = !CBackgroundMusic.IsPlayingPreview; + _Buttons[_ButtonRepeat].Visible = !CBackgroundMusic.IsPlayingPreview; + _Buttons[_ButtonSing].Visible = !CBackgroundMusic.IsPlayingPreview; + } + public override bool UpdateGame() { _Statics[_StaticCover].Visible = !_VideoPreviewInt || !CBackgroundMusic.SongHasVideo; diff --git a/Vocaluxe/Screens/CScreenLoad.cs b/Vocaluxe/Screens/CScreenLoad.cs index 5bcc054d..50c57008 100644 --- a/Vocaluxe/Screens/CScreenLoad.cs +++ b/Vocaluxe/Screens/CScreenLoad.cs @@ -152,6 +152,9 @@ namespace Vocaluxe.Screens { CBackgroundMusic.OwnSongsAvailable = true; + if (CConfig.VideoBackgrounds == EOffOn.TR_CONFIG_ON || CConfig.VideosToBackground == EOffOn.TR_CONFIG_ON) + CBackgroundMusic.VideoEnabled = true; + CBackgroundMusic.Play(); } diff --git a/Vocaluxe/Screens/CScreenOptionsSound.cs b/Vocaluxe/Screens/CScreenOptionsSound.cs index 502f4c28..0d711fd0 100644 --- a/Vocaluxe/Screens/CScreenOptionsSound.cs +++ b/Vocaluxe/Screens/CScreenOptionsSound.cs @@ -52,7 +52,7 @@ namespace Vocaluxe.Screens public override void LoadTheme(string xmlPath) { base.LoadTheme(xmlPath); - _SelectSlides[_SelectSlideBackgroundMusic].SetValues((int)CConfig.BackgroundMusic); + _SelectSlides[_SelectSlideBackgroundMusic].SetValues((int)CConfig.BackgroundMusic); _SelectSlides[_SelectSlideBackgroundMusicVolume].AddValues(new string[] {"0", "5", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95", "100"}); _SelectSlides[_SelectSlideBackgroundMusicVolume].Selection = CConfig.BackgroundMusicVolume / 5; @@ -150,14 +150,14 @@ namespace Vocaluxe.Screens { CConfig.GameMusicVolume = _SelectSlides[_SelectSlideGameMusicVolume].Selection * 5; CConfig.PreviewMusicVolume = _SelectSlides[_SelectSlidePreviewMusicVolume].Selection * 5; - CConfig.BackgroundMusic = (EOffOn)_SelectSlides[_SelectSlideBackgroundMusic].Selection; + CConfig.BackgroundMusic = (EBackgroundMusicOffOn)_SelectSlides[_SelectSlideBackgroundMusic].Selection; CConfig.BackgroundMusicSource = (EBackgroundMusicSource)_SelectSlides[_SelectSlideBackgroundMusicSource].Selection; CConfig.BackgroundMusicVolume = _SelectSlides[_SelectSlideBackgroundMusicVolume].Selection * 5; CConfig.SaveConfig(); CBackgroundMusic.SetMusicSource(CConfig.BackgroundMusicSource); CSound.SetGlobalVolume(CConfig.BackgroundMusicVolume); - if (CConfig.BackgroundMusic == EOffOn.TR_CONFIG_ON) + if (CConfig.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_ON) CBackgroundMusic.Play(); else CBackgroundMusic.Pause(); diff --git a/Vocaluxe/Screens/CScreenScore.cs b/Vocaluxe/Screens/CScreenScore.cs index 39754156..bbf4aaf4 100644 --- a/Vocaluxe/Screens/CScreenScore.cs +++ b/Vocaluxe/Screens/CScreenScore.cs @@ -123,6 +123,8 @@ namespace Vocaluxe.Screens public override void OnShow() { + CBackgroundMusic.Disabled = false; + base.OnShow(); //-1 --> Show average _Round = CGame.NumRounds > 1 ? -1 : 0; diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index d9a44b1a..ff4416f8 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -537,8 +537,6 @@ namespace Vocaluxe.Screens _CloseSong(); if (_Webcam) CWebcam.Stop(); - CBackgroundMusic.Disabled = false; - CSound.SetGlobalVolume(CConfig.BackgroundMusicVolume); } private void _CloseSong() @@ -569,6 +567,8 @@ namespace Vocaluxe.Screens _Texts[_TextSongName].Text = String.Empty; _Texts[_TextDuetName1].Text = String.Empty; _Texts[_TextDuetName2].Text = String.Empty; + _Texts[_TextMedleyCountdown].Visible = false; + _Texts[_TextMedleyCountdown].Text = String.Empty; } private void _LoadNextSong() diff --git a/Vocaluxe/Screens/CScreenSong.cs b/Vocaluxe/Screens/CScreenSong.cs index b70017d5..ace7503d 100644 --- a/Vocaluxe/Screens/CScreenSong.cs +++ b/Vocaluxe/Screens/CScreenSong.cs @@ -662,11 +662,6 @@ namespace Vocaluxe.Screens _Texts[_TextCategory].Text = CSongs.GetCurrentCategoryName(); - if (CSongs.IsInCategory || CConfig.Tabs == EOffOn.TR_CONFIG_OFF) - CBackgroundMusic.Disabled = true; - else - CBackgroundMusic.Disabled = false; - string selectionText = ""; if (CSongs.IsInCategory) { @@ -716,9 +711,14 @@ namespace Vocaluxe.Screens public override void OnClose() { base.OnClose(); - CBackgroundMusic.Disabled = false; - CSound.SetGlobalVolume(CConfig.BackgroundMusicVolume); + _SongMenu.OnHide(); + + if (CGraphics.NextScreen != EScreens.ScreenNames) + { + CBackgroundMusic.Disabled = false; + CSound.SetGlobalVolume(CConfig.BackgroundMusicVolume); + } } private void _HandlePartySongSelection(int songNr) diff --git a/VocaluxeLib/Enums.cs b/VocaluxeLib/Enums.cs index 0df1d888..4db6424c 100644 --- a/VocaluxeLib/Enums.cs +++ b/VocaluxeLib/Enums.cs @@ -248,6 +248,13 @@ namespace VocaluxeLib // ReSharper restore InconsistentNaming } + public enum EBackgroundMusicOffOn + { + TR_CONFIG_OFF, + TR_CONFIG_ONLY_SONG, + TR_CONFIG_ON + } + public enum EPlayerInfo { // ReSharper disable InconsistentNaming @@ -288,6 +295,14 @@ namespace VocaluxeLib } #endregion Config + public enum EStreamAction + { + Nothing, + Pause, + Stop, + Close + } + public enum EProgramState { Start, diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs index ef14e905..0583e189 100644 --- a/VocaluxeLib/IBasic.cs +++ b/VocaluxeLib/IBasic.cs @@ -35,6 +35,8 @@ namespace VocaluxeLib void SetBackgroundMusicVolume(int newVolume); int GetBackgroundMusicVolume(); + EBackgroundMusicOffOn GetBackgroundMusicStatus(); + int GetPreviewMusicVolume(); EOffOn GetVideosToBackground(); @@ -89,6 +91,8 @@ namespace VocaluxeLib float GetSlideShowImageTime(); float GetSlideShowFadeTime(); + + float GetSoundPlayerFadeTime(); } public interface ITheme @@ -115,16 +119,24 @@ namespace VocaluxeLib { bool IsDisabled(); bool IsPlaying(); + bool IsPlayingPreview(); bool SongHasVideo(); bool VideoEnabled(); + float GetLength(); void SetDisabled(bool disabled); void Next(); void Previous(); void Pause(); void Play(); + void Stop(); CTexture GetVideoTexture(); + + void LoadPreview(CSong song, float start = 0f); + void PlayPreview(float start = -1f); + void StopPreview(); + } public interface IDrawing @@ -148,6 +160,8 @@ namespace VocaluxeLib void FadeTo(EScreens nextScreen); float GetGlobalAlpha(); + + EScreens GetNextScreen(); } public interface ILog @@ -255,6 +269,8 @@ namespace VocaluxeLib bool IsFinished(int streamID); bool Close(int streamID); void SetLoop(int streamID, bool loop = true); + void Resume(int streamID); + void Pause(int streamID); } public interface ISound @@ -262,12 +278,12 @@ namespace VocaluxeLib int Load(string soundFile, bool loop = false, bool prescan = false); void SetPosition(int soundStream, float newPosition); void Play(int soundStream); - void Fade(int soundStream, float targetVolume, float duration); + void Fade(int soundStream, float targetVolume, float duration, EStreamAction afterFadeAction = EStreamAction.Nothing); + void Close(int soundStream); bool IsFinished(int soundStream); float GetPosition(int soundStream); float GetLength(int soundStream); - void FadeAndClose(int soundStream, float targetVolume, float duration); void SetStreamVolume(int soundStream, float volume); } @@ -311,4 +327,17 @@ namespace VocaluxeLib int GetSongCount(int playlistID); CPlaylistSong GetSong(int playlistID, int songIndex); } + + public interface IPreviewPlayer + { + void Play(float start = -1); + void Load(CSong song, float start = 0f); + void Stop(); + void TogglePause(); + CTexture GetCover(); + CTexture GetVideoTexture(); + bool IsPlaying(); + float GetLength(); + + } } \ No newline at end of file diff --git a/VocaluxeLib/Menu/CBackground.cs b/VocaluxeLib/Menu/CBackground.cs index 7138d3f3..67ba0755 100644 --- a/VocaluxeLib/Menu/CBackground.cs +++ b/VocaluxeLib/Menu/CBackground.cs @@ -194,7 +194,7 @@ namespace VocaluxeLib.Menu if (!String.IsNullOrEmpty(_Theme.TextureName) && (_Theme.Type == EBackgroundTypes.Texture || - (_Theme.Type == EBackgroundTypes.Video && (CBase.Config.GetVideoBackgrounds() == EOffOn.TR_CONFIG_OFF || !ok)))) + (_Theme.Type == EBackgroundTypes.Video && CBase.Config.GetVideoBackgrounds() == EOffOn.TR_CONFIG_OFF))) ok = _DrawTexture(); if (_Theme.Type == EBackgroundTypes.Color || _Theme.Type == EBackgroundTypes.Texture && !ok || diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs index b3ab25d5..7ab54122 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs @@ -115,18 +115,15 @@ namespace VocaluxeLib.Menu.SongMenu _PlaySong(value); } else if (value >= CBase.Songs.GetNumCategories()) + { value = -1; + CBase.BackgroundMusic.Stop(); + } _PreviewNrInternal = value; } } - protected int _PreviewSongStream { get; private set; } - - protected int _PreviewVideoStream { get; private set; } - private CFading _VideoFading; - protected CTexture _Vidtex; - private SColorF _ColorInternal; protected SColorF _Color { @@ -160,8 +157,6 @@ namespace VocaluxeLib.Menu.SongMenu { Visible = true; _PartyModeID = partyModeID; - _PreviewVideoStream = -1; - _PreviewSongStream = -1; _Theme = new SThemeSongMenu { SongMenuTileBoard = @@ -346,7 +341,7 @@ namespace VocaluxeLib.Menu.SongMenu public virtual void Init() { - _ResetPreview(); + _ResetPreview(false); _Initialized = true; } @@ -354,40 +349,14 @@ namespace VocaluxeLib.Menu.SongMenu { if (!_Initialized) return; - - if (_PreviewSongStream == -1 || _PreviewVideoStream == -1) - return; - - if (CBase.Video.IsFinished(_PreviewVideoStream) || CBase.Sound.IsFinished(_PreviewSongStream)) - { - CBase.Video.Close(_PreviewVideoStream); - _PreviewVideoStream = -1; - return; - } - - float time = CBase.Sound.GetPosition(_PreviewSongStream); - - float vtime; - if (CBase.Video.GetFrame(_PreviewVideoStream, ref _Vidtex, time, out vtime)) - { - if (_Vidtex != null) - { - if (_VideoFading != null) - { - bool finished; - _Vidtex.Color.A = _VideoFading.GetValue(out finished); - if (finished) - _VideoFading = null; - } - } - } } public virtual void OnShow() {} - + public virtual void OnHide() { - _ResetPreview(); + if(CBase.Graphics.GetNextScreen() != EScreens.ScreenNames) + _ResetPreview(); } public abstract bool HandleInput(ref SKeyEvent keyEvent, SScreenSongOptions options); @@ -399,8 +368,8 @@ namespace VocaluxeLib.Menu.SongMenu if (!_Initialized || !Visible) return; - if (_PreviewVideoStream != -1) - CBase.Drawing.DrawTexture(_Vidtex, new SRectF(0, 0, 1280, 720, 0)); + if (CBase.BackgroundMusic.IsPlaying()) + CBase.Drawing.DrawTexture(CBase.BackgroundMusic.GetVideoTexture(), new SRectF(0, 0, 1280, 720, 0)); } public bool IsMouseOverSelectedSong(SMouseEvent mEvent) @@ -486,7 +455,7 @@ namespace VocaluxeLib.Menu.SongMenu if (categoryNr >= CBase.Songs.GetNumCategories()) return; - _ResetPreview(); + _ResetPreview(false); CBase.Songs.SetCategory(categoryNr); } @@ -504,50 +473,24 @@ namespace VocaluxeLib.Menu.SongMenu private void _PlaySong(int nr) { - _ResetPreview(); + _PreviewNrInternal = -1; CSong song = CBase.Songs.GetVisibleSong(nr); if (song == null) return; - //TODO: Using prescan here causes Vocaluxe to hang a bit on loading the song but we need the length below - _PreviewSongStream = CBase.Sound.Load(Path.Combine(song.Folder, song.MP3FileName), true, true); - - float startposition = song.Preview.StartTime; - float length = CBase.Sound.GetLength(_PreviewSongStream); - - if (song.Preview.Source == EDataSource.None) - startposition = length / 4f; - else if (startposition > length - 5f) - startposition = Math.Max(0f, Math.Min(length / 4f, length - 5f)); - - CBase.Sound.SetPosition(_PreviewSongStream, startposition); - CBase.Sound.Play(_PreviewSongStream); - CBase.Sound.SetStreamVolume(_PreviewSongStream, 0f); - CBase.Sound.Fade(_PreviewSongStream, 100f, 3f); - - if (song.VideoFileName != "" && CBase.Config.GetVideoPreview() == EOffOn.TR_CONFIG_ON) - { - _PreviewVideoStream = CBase.Video.Load(Path.Combine(song.Folder, song.VideoFileName)); - if (_PreviewVideoStream == -1) - return; - CBase.Video.SetLoop(_PreviewVideoStream); - CBase.Video.Skip(_PreviewVideoStream, startposition, song.VideoGap); - _VideoFading = new CFading(0f, 1f, 3f); - } + CBase.BackgroundMusic.LoadPreview(song); } - protected void _ResetPreview() + protected void _ResetPreview(bool playBGagain = true) { - if (_PreviewSongStream >= 0) - CBase.Sound.FadeAndClose(_PreviewSongStream, 0f, 0.75f); + if (_PreviewNrInternal == -1) + return; - _PreviewSongStream = -1; + CBase.BackgroundMusic.StopPreview(); - CBase.Video.Close(_PreviewVideoStream); - _PreviewVideoStream = -1; - - CBase.Drawing.RemoveTexture(ref _Vidtex); + if (playBGagain) + CBase.BackgroundMusic.Play(); //Make sure we don't have a preview here otherwise a change won't be recognized //(e.g. leave a category with one song and set preview to 0 --> previewOld=previewNew=0 --> No change --> Old data shown diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs index 2683f6f8..b33a1d16 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs @@ -110,7 +110,11 @@ namespace VocaluxeLib.Menu.SongMenu set { if (value == base._PreviewNr) + { + if (!CBase.BackgroundMusic.IsPlaying() && value != -1) + CBase.BackgroundMusic.PlayPreview(); return; + } base._PreviewNr = value; _UpdatePreview(); } @@ -179,7 +183,7 @@ namespace VocaluxeLib.Menu.SongMenu if (songOptions.Selection.RandomOnly) _PreviewNr = _SelectionNr; - if (_Length < 0 && CBase.Songs.IsInCategory() && CBase.Sound.GetLength(_PreviewSongStream) > 0) + if (_Length < 0 && CBase.Songs.IsInCategory() && CBase.BackgroundMusic.GetLength() > 0) _UpdateLength(CBase.Songs.GetVisibleSong(_PreviewNr)); } @@ -244,7 +248,7 @@ namespace VocaluxeLib.Menu.SongMenu { if (song == null) return; - float time = CBase.Sound.GetLength(_PreviewSongStream); + float time = CBase.BackgroundMusic.GetLength(); if (Math.Abs(song.Finish) > 0.001) time = song.Finish; @@ -463,18 +467,20 @@ namespace VocaluxeLib.Menu.SongMenu _TextBG.Draw(); - if (_Vidtex != null && _PreviewVideoStream != -1) + CTexture vidtex = CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null; + + if (vidtex != null) { - if (_Vidtex.Color.A < 1) + if (vidtex.Color.A < 1) _CoverBig.Draw(EAspect.Crop); var bounds = new RectangleF(_CoverBig.Rect.X, _CoverBig.Rect.Y, _CoverBig.Rect.W, _CoverBig.Rect.H); RectangleF rect; - CHelper.SetRect(bounds, out rect, _Vidtex.OrigAspect, EAspect.Crop); + CHelper.SetRect(bounds, out rect, vidtex.OrigAspect, EAspect.Crop); var vidRect = new SRectF(rect.X, rect.Y, rect.Width, rect.Height, _CoverBig.Rect.Z); var vidRectBounds = new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f); - CBase.Drawing.DrawTexture(_Vidtex, vidRect, _Vidtex.Color, vidRectBounds); - CBase.Drawing.DrawTextureReflection(_Vidtex, vidRect, _Vidtex.Color, vidRectBounds, _CoverBig.ReflectionSpace, _CoverBig.ReflectionHeight); + CBase.Drawing.DrawTexture(vidtex, vidRect, vidtex.Color, vidRectBounds); + CBase.Drawing.DrawTextureReflection(vidtex, vidRect, vidtex.Color, vidRectBounds, _CoverBig.ReflectionSpace, _CoverBig.ReflectionHeight); } else _CoverBig.Draw(EAspect.Crop); diff --git a/VocaluxeLib/Songs/CSong.cs b/VocaluxeLib/Songs/CSong.cs index 26d1d6fd..665beac4 100644 --- a/VocaluxeLib/Songs/CSong.cs +++ b/VocaluxeLib/Songs/CSong.cs @@ -458,7 +458,10 @@ namespace VocaluxeLib.Songs if (Preview.Source == EDataSource.None) { if (Medley.Source != EDataSource.None) + { Preview.StartTime = CBase.Game.GetTimeFromBeats(Medley.StartBeat, BPM); + Preview.Source = EDataSource.Calculated; + } } } diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs index 334089d2..cd4cf834 100644 --- a/VocaluxeLib/Songs/CSongLoader.cs +++ b/VocaluxeLib/Songs/CSongLoader.cs @@ -416,6 +416,7 @@ namespace VocaluxeLib.Songs { //PreviewStart is not set or <=0 _Song.Preview.StartTime = (headerFlags & EHeaderFlags.MedleyStartBeat) != 0 ? CBase.Game.GetTimeFromBeats(_Song.Medley.StartBeat, _Song.BPM) : 0f; + _Song.Preview.Source = _Song.Preview.StartTime == 0 ? EDataSource.None : EDataSource.Calculated; } if ((headerFlags & EHeaderFlags.MedleyStartBeat) != 0 && (headerFlags & EHeaderFlags.MedleyEndBeat) != 0) diff --git a/VocaluxeLib/Utils/Player/CSongPlayer.cs b/VocaluxeLib/Utils/Player/CSongPlayer.cs new file mode 100644 index 00000000..078be067 --- /dev/null +++ b/VocaluxeLib/Utils/Player/CSongPlayer.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.IO; + +using VocaluxeLib.Draw; +using VocaluxeLib.Songs; + +namespace VocaluxeLib.Utils.Player +{ + public class CSongPlayer : CSoundPlayer + { + private CSong _Song; + private bool _VideoEnabled; + private int _Video = -1; + private CTexture _CurrentVideoTexture; + private CFading _VideoFading; + + public bool VideoEnabled + { + get { return _VideoEnabled; } + set + { + if (_VideoEnabled == value) + return; + _VideoEnabled = value; + if (_VideoEnabled) + _LoadVideo(); + else if (_Video != -1) + { + CBase.Video.Close(_Video); + CBase.Drawing.RemoveTexture(ref _CurrentVideoTexture); + _Video = -1; + } + } + } + public int SongID + { + get { return _Song == null ? -1 : _Song.ID; } + } + public bool SongHasVideo + { + get { return _Song != null && File.Exists(Path.Combine(_Song.Folder,_Song.VideoFileName)); } + } + + public string ArtistAndTitle + { + get + { + if (_Song == null) + return ""; + if (_Song.Artist != "" && _Song.Title != "") + return _Song.Artist + " - " + _Song.Title; + return Path.GetFileNameWithoutExtension(_Song.MP3FileName); + } + } + + public CTexture Cover + { + get { return _Song == null ? CBase.Cover.GetNoCover() : _Song.CoverTextureBig; } + } + + public bool SongLoaded + { + get { return _StreamID != -1; } + } + + + public CSongPlayer(bool loop = false) : base(loop) { } + + public CSongPlayer(CSong song, bool loop = false, float position = 0f, bool autoplay = false) + : base(Path.Combine(song.Folder,song.MP3FileName), loop, position, autoplay) + { + _Song = song; + _LoadVideo(); + } + + public CSongPlayer(string file, bool loop = false, float position = 0f, bool autoplay = false) + : base(file, loop, position, autoplay) + { + _Song = null; + } + + public CTexture GetVideoTexture() + { + if (_Video == -1 || _Song == null) + return null; + float vtime; + if (CBase.Video.GetFrame(_Video, ref _CurrentVideoTexture, CBase.Sound.GetPosition(_StreamID), out vtime)) + { + if (_VideoFading != null) + { + bool finished; + _CurrentVideoTexture.Color.A = _VideoFading.GetValue(out finished); + if (finished) + _VideoFading = null; + } + return _CurrentVideoTexture; + } + return null; + } + + public void Load(CSong song, float position = 0f, bool autoplay = false) + { + if (song == null) + return; + + Stop(); + + _Song = song; + + base.Load(Path.Combine(song.Folder, song.MP3FileName), position, false); + _LoadVideo(); + + if (autoplay) + Play(); + } + + public void LoadFile(string file, float position = 0f, bool autoplay = false) + { + if (String.IsNullOrEmpty(file)) + return; + + Stop(); + + base.Load(file, position, autoplay); + } + + public new void Play() + { + CBase.Sound.SetPosition(_StreamID, _StartPosition); + CBase.Video.Skip(_Video, _StartPosition, _Song.VideoGap); + TogglePause(); + } + + public new void Stop() + { + base.Stop(); + + _Song = null; + + if (_Video != -1) + { + CBase.Video.Close(_Video); + CBase.Drawing.RemoveTexture(ref _CurrentVideoTexture); + _Video = -1; + } + } + + public new void TogglePause() + { + if (IsPlaying && _Video != -1) + { + CBase.Video.Pause(_Video); + CBase.Video.Skip(_Video, CBase.Sound.GetPosition(_StreamID) + _FadeTime, _Song.VideoGap); + } + else if(_Video != -1) + { + CBase.Video.Resume(_Video); + } + base.TogglePause(); + } + + + private void _LoadVideo() + { + if (_Song == null) + return; + + string videoFilePath = Path.Combine(_Song.Folder, _Song.VideoFileName); + if (_Video != -1 || String.IsNullOrEmpty(videoFilePath)) + return; + _Video = CBase.Video.Load(videoFilePath); + CBase.Video.Skip(_Video, 0f, _Song.VideoGap); //Use gap, otherwhise we will overwrite position in GetVideoTexture + _VideoFading = new CFading(0f, 1f, 3f); + + if (IsPlaying) + { + CBase.Video.Skip(_Video, Position, _Song.VideoGap); + CBase.Video.Resume(_Video); + } + } + } +} diff --git a/VocaluxeLib/Utils/Player/CSoundPlayer.cs b/VocaluxeLib/Utils/Player/CSoundPlayer.cs new file mode 100644 index 00000000..4bbbd602 --- /dev/null +++ b/VocaluxeLib/Utils/Player/CSoundPlayer.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace VocaluxeLib.Utils.Player +{ + public class CSoundPlayer + { + protected int _StreamID = -1; + protected float _Volume; + protected float _StartPosition; + protected float _FadeTime = CBase.Settings.GetSoundPlayerFadeTime(); + + public float Volume + { + set + { + _Volume = value; + _ApplyVolume(); + } + get { return _Volume; } + } + public bool Loop; + + public float Position + { + set { + if(_StreamID == -1) + return; + _StartPosition = value; + } + get { + if(_StreamID == -1) + return -1; + return CBase.Sound.GetPosition(_StreamID); + } + } + + public float Length + { + get + { + if (_StreamID == -1) + return 0; + return CBase.Sound.GetLength(_StreamID); + } + } + + public bool RepeatSong; + public bool IsPlaying { get; protected set; } + + public bool IsFinished { get { return RepeatSong ? false : CBase.Sound.IsFinished(_StreamID); } } + + public CSoundPlayer(bool loop = false) + { + Loop = loop; + } + + public CSoundPlayer(string file, bool loop = false, float position = 0f, bool autoplay = false) + { + _StreamID = CBase.Sound.Load(file, false, true); + if(position > 0f) + Position = position; + Loop = loop; + if (autoplay) + Play(); + } + + public void Load(string file, float position = 0f, bool autoplay = false) + { + if (IsPlaying) + Stop(); + + _StreamID = CBase.Sound.Load(file, false, true); + if (position > 0f) + Position = position; + if (autoplay) + Play(); + } + + public void Play() + { + if (_StreamID == -1 || IsPlaying) + return; + + CBase.Sound.SetPosition(_StreamID, _StartPosition); + CBase.Sound.SetStreamVolume(_StreamID, 0f); + CBase.Sound.Fade(_StreamID, Volume, _FadeTime); + CBase.Sound.Play(_StreamID); + IsPlaying = true; + } + + public void TogglePause() + { + if (_StreamID == -1) + return; + + if(IsPlaying) + CBase.Sound.Fade(_StreamID, 0f, _FadeTime, EStreamAction.Pause); + else + { + CBase.Sound.Fade(_StreamID, Volume, _FadeTime); + CBase.Sound.Play(_StreamID); + } + + IsPlaying = !IsPlaying; + } + + public void Stop() + { + if (_StreamID == -1 || !IsPlaying) + return; + + CBase.Sound.Fade(_StreamID, 0f, _FadeTime, EStreamAction.Close); + _StreamID = -1; + + IsPlaying = false; + } + + public void Update() + { + if (_StreamID == -1 || !IsPlaying) + return; + + float timeToPlay; + float len = CBase.Sound.GetLength(_StreamID); + timeToPlay = (len > 0f) ? len - CBase.Sound.GetPosition(_StreamID) : _FadeTime + 1f; + + bool finished = CBase.Sound.IsFinished(_StreamID); + if (timeToPlay <= _FadeTime || finished) + { + if (RepeatSong) + { + //Set to false for restarting + IsPlaying = false; + Play(); + } + else + Stop(); + } + + } + + private void _ApplyVolume() + { + if (_StreamID == -1) + return; + + CBase.Sound.SetStreamVolume(_StreamID, Volume); + } + } +} diff --git a/VocaluxeLib/VocaluxeLib.csproj b/VocaluxeLib/VocaluxeLib.csproj index 3e17ea26..a367e8e1 100644 --- a/VocaluxeLib/VocaluxeLib.csproj +++ b/VocaluxeLib/VocaluxeLib.csproj @@ -135,6 +135,8 @@ + +