diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index 40d2a062..5de5c61a 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -111,6 +111,9 @@ namespace Vocaluxe.Base public const float LyricHelperMoveTime = 1.5f; public const float LyricHelperMinTime = 0.2f; + public const float DefaultMedleyFadeInTime = 8f; + public const float DefaultMedleyFadeOutTIme = 2f; + public static bool TabNavigation = false; public const float BackgroundMusicFadeTime = 0.5f; diff --git a/Vocaluxe/Lib/Song/CSong.cs b/Vocaluxe/Lib/Song/CSong.cs index 1327363b..6ad4c2e5 100644 --- a/Vocaluxe/Lib/Song/CSong.cs +++ b/Vocaluxe/Lib/Song/CSong.cs @@ -13,13 +13,38 @@ namespace Vocaluxe.Lib.Song [Flags] enum EHeaderFlags { - Title, - Artist, - MP3, - BPM, - PreviewStart, - MedleyStartBeat, - MedleyEndBeat + Title = 1, + Artist = 2, + MP3 = 4, + BPM = 8, + PreviewStart = 16, + MedleyStartBeat = 32, + MedleyEndBeat = 64 + } + + enum EMedleySource + { + None, + Calculated, + Tag + } + + struct SMedley + { + public EMedleySource Source; + public int StartBeat; + public int EndBeat; + public float FadeInTime; + public float FadeOutTime; + + public SMedley(int dummy) + { + Source = EMedleySource.None; + StartBeat = 0; + EndBeat = 0; + FadeInTime = 0f; + FadeOutTime = 0f; + } } class CSong @@ -28,6 +53,11 @@ namespace Vocaluxe.Lib.Song private STexture _CoverTextureSmall = new STexture(-1); private STexture _CoverTextureBig = new STexture(-1); + private SMedley Medley = new SMedley(0); + + public bool CalculateMedley = true; + public float PreviewStart = 0f; + public Encoding Encoding = Encoding.Default; public string Folder = String.Empty; public string FolderName = String.Empty; @@ -305,6 +335,25 @@ namespace Vocaluxe.Lib.Song if (CHelper.TryParse(Value, out this.Finish)) this.Finish /= 1000f; break; + case "PREVIEWSTART": + if (CHelper.TryParse(Value, out this.PreviewStart)) + if (this.PreviewStart < 0f) + this.PreviewStart = 0f; + else + HeaderFlags |= EHeaderFlags.PreviewStart; + break; + case "MEDLEYSTARTBEAT": + if (int.TryParse(Value, out this.Medley.StartBeat)) + HeaderFlags |= EHeaderFlags.MedleyStartBeat; + break; + case "MEDLEYENDBEAT": + if (int.TryParse(Value, out this.Medley.EndBeat)) + HeaderFlags |= EHeaderFlags.MedleyEndBeat; + break; + case "CALCMEDLEY": + if (Value.ToUpper() == "OFF") + this.CalculateMedley = false; + break; default: ; break; @@ -320,13 +369,64 @@ namespace Vocaluxe.Lib.Song } } //end of while - if (HeaderFlags != (EHeaderFlags.Title | EHeaderFlags.Artist | EHeaderFlags.MP3 | EHeaderFlags.BPM)) + if ((HeaderFlags & EHeaderFlags.Title) == 0) + { + CLog.LogError("Title tag missing: " + FilePath); return false; + } + + if ((HeaderFlags & EHeaderFlags.Artist) == 0) + { + CLog.LogError("Artist tag missing: " + FilePath); + return false; + } + + if ((HeaderFlags & EHeaderFlags.MP3) == 0) + { + CLog.LogError("MP3 tag missing: " + FilePath); + return false; + } + + if ((HeaderFlags & EHeaderFlags.BPM) == 0) + { + CLog.LogError("BPM tag missing: " + FilePath); + return false; + } + + #region check medley tags + if ((HeaderFlags & EHeaderFlags.MedleyStartBeat) != 0 && (HeaderFlags & EHeaderFlags.MedleyEndBeat) != 0) + { + if (this.Medley.StartBeat > this.Medley.EndBeat) + { + CLog.LogError("MedleyStartBeat is bigger than MedleyEndBeat in file: " + FilePath); + HeaderFlags = HeaderFlags - EHeaderFlags.MedleyStartBeat - EHeaderFlags.MedleyEndBeat; + } + } + + if ((HeaderFlags & EHeaderFlags.PreviewStart) == 0 || this.PreviewStart == 0f) + { + //PreviewStart is not set or <=0 + if ((HeaderFlags & EHeaderFlags.MedleyStartBeat) != 0) + //fallback to MedleyStart + this.PreviewStart = CGame.GetTimeFromBeats(this.Medley.StartBeat, this.BPM); + else + //else set to 0, it will be set in FindRefrainStart + this.PreviewStart = 0f; + } + + if ((HeaderFlags & EHeaderFlags.MedleyStartBeat) != 0 && (HeaderFlags & EHeaderFlags.MedleyEndBeat) != 0) + { + this.Medley.Source = EMedleySource.Tag; + this.Medley.FadeInTime = CSettings.DefaultMedleyFadeInTime; + this.Medley.FadeOutTime = CSettings.DefaultMedleyFadeOutTIme; + } + #endregion check medley tags this.Encoding = sr.CurrentEncoding; } - catch (Exception) + catch (Exception e) { + CLog.LogError("Error reading txt header in file \"" + FilePath + "\": " + e.Message); return false; } @@ -466,6 +566,9 @@ namespace Vocaluxe.Lib.Song CLog.LogError("Error loading song. Line No.: " + FileLineNo.ToString() + ". An unhandled exception occured (" + e.Message + "): " + FilePath); return false; } + + FindRefrain(); + return true; } @@ -531,5 +634,24 @@ namespace Vocaluxe.Lib.Song } } } + + private void FindRefrain() + { + if (this.Medley.Source == EMedleySource.Tag) + return; + + if (!this.CalculateMedley) + return; + + + + + + if (this.PreviewStart == 0f) + { + if (this.Medley.Source == EMedleySource.Calculated) + this.PreviewStart = CGame.GetTimeFromBeats(this.Medley.StartBeat, this.BPM); + } + } } } diff --git a/Vocaluxe/Menu/SongMenu/CSongMenuFramework.cs b/Vocaluxe/Menu/SongMenu/CSongMenuFramework.cs index 43cd6f28..5682c1c9 100644 --- a/Vocaluxe/Menu/SongMenu/CSongMenuFramework.cs +++ b/Vocaluxe/Menu/SongMenu/CSongMenuFramework.cs @@ -551,7 +551,13 @@ namespace Vocaluxe.Menu.SongMenu int _stream = CSound.Load(Path.Combine(CSongs.VisibleSongs[_actsong].Folder, CSongs.VisibleSongs[_actsong].MP3FileName), true); CSound.SetStreamVolume(_stream, 0f); - CSound.SetPosition(_stream, CSound.GetLength(_stream) / 4f); + + float startposition = CSongs.VisibleSongs[_actsong].PreviewStart; + + if (startposition == 0f) + startposition = CSound.GetLength(_stream) / 4f; + + CSound.SetPosition(_stream, startposition); CSound.Play(_stream); CSound.Fade(_stream, 100f, 3f); _streams.Add(_stream); @@ -562,7 +568,7 @@ namespace Vocaluxe.Menu.SongMenu _video = CVideo.VdLoad(Path.Combine(CSongs.VisibleSongs[_actsong].Folder, CSongs.VisibleSongs[_actsong].VideoFileName)); if (_video == -1) return; - CVideo.VdSkip(_video, CSound.GetLength(_stream) / 4f, CSongs.VisibleSongs[_actsong].VideoGap); + CVideo.VdSkip(_video, startposition, CSongs.VisibleSongs[_actsong].VideoGap); _VideoFadeTimer.Stop(); _VideoFadeTimer.Reset(); _VideoFadeTimer.Start();