From 9761c115b27028773add1776e9fba72c31ad8103 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Fri, 22 Feb 2013 23:04:26 +0100 Subject: [PATCH] Refactored song loading ~9% faster and a bit more stable --- Vocaluxe/Base/CSongs.cs | 8 +- Vocaluxe/Screens/CScreenLoad.cs | 4 +- VocaluxeLib/Menu/CHelper.cs | 7 +- VocaluxeLib/Menu/SongMenu/CSong.cs | 297 +++++++++++++++-------------- 4 files changed, 159 insertions(+), 157 deletions(-) diff --git a/Vocaluxe/Base/CSongs.cs b/Vocaluxe/Base/CSongs.cs index bfc46035..ac1b46ef 100644 --- a/Vocaluxe/Base/CSongs.cs +++ b/Vocaluxe/Base/CSongs.cs @@ -1022,8 +1022,8 @@ namespace Vocaluxe.Base CLog.StartBenchmark(2, "Read TXTs"); foreach (string file in files) { - CSong Song = new CSong(); - if (Song.ReadTXTSong(file)) + CSong Song = CSong.LoadSong(file); + if (Song != null) { Song.ID = _Songs.Count; _Songs.Add(Song); @@ -1039,7 +1039,7 @@ namespace Vocaluxe.Base if (CConfig.Renderer != ERenderer.TR_CONFIG_SOFTWARE && CConfig.CoverLoading == ECoverLoading.TR_CONFIG_COVERLOADING_ATSTART) { - CLog.StartBenchmark(2, "Load Cover"); + CLog.StartBenchmark(2, "Load Covers/Notes"); for (int i = 0; i < _Songs.Count; i++) { CSong song = _Songs[i]; @@ -1058,7 +1058,7 @@ namespace Vocaluxe.Base _CoverLoaded = true; CDataBase.CommitCovers(); - CLog.StopBenchmark(2, "Load Cover"); + CLog.StopBenchmark(2, "Load Covers/Notes"); } CLog.StopBenchmark(1, "Load Songs "); GC.Collect(); diff --git a/Vocaluxe/Screens/CScreenLoad.cs b/Vocaluxe/Screens/CScreenLoad.cs index f7e28732..53a6ba8d 100644 --- a/Vocaluxe/Screens/CScreenLoad.cs +++ b/Vocaluxe/Screens/CScreenLoad.cs @@ -137,7 +137,7 @@ namespace Vocaluxe.Screens } } - CLog.StartBenchmark(3, "Load Cover"); + CLog.StartBenchmark(0, "Load Songs Full"); _SongLoaderThread.IsBackground = true; _SongLoaderThread.Start(); _timer.Start(); @@ -221,7 +221,7 @@ namespace Vocaluxe.Screens CBackgroundMusic.CanSing = true; - CLog.StopBenchmark(3, "Load Cover"); + CLog.StopBenchmark(0, "Load Songs Full"); //Init Playlists CLog.StartBenchmark(0, "Init Playlists"); diff --git a/VocaluxeLib/Menu/CHelper.cs b/VocaluxeLib/Menu/CHelper.cs index 5d3fc59a..c6f49b82 100644 --- a/VocaluxeLib/Menu/CHelper.cs +++ b/VocaluxeLib/Menu/CHelper.cs @@ -58,12 +58,13 @@ namespace Vocaluxe.Menu try { - chr = (char)sr.Peek(); - while ((chr.CompareTo(' ') != 0) && ((int)chr != 19) && ((int)chr != 16) && ((int)chr != 13)) + int tmp = sr.Peek(); + //Check for ' ', ?, ?, \n, \r + while (tmp != 32 && tmp != 19 && tmp != 16 && tmp != 13 && tmp != 10) { chr = (char)sr.Read(); value += chr.ToString(); - chr = (char)sr.Peek(); + tmp = sr.Peek(); } } catch (Exception) diff --git a/VocaluxeLib/Menu/SongMenu/CSong.cs b/VocaluxeLib/Menu/SongMenu/CSong.cs index 81cb24d9..ab85b7b2 100644 --- a/VocaluxeLib/Menu/SongMenu/CSong.cs +++ b/VocaluxeLib/Menu/SongMenu/CSong.cs @@ -111,8 +111,9 @@ namespace Vocaluxe.Menu.SongMenu { if (!_CoverLoaded) { - if (!_NotesLoaded) - this.ReadNotes(); + //Why in hell would you load the notes to get the cover??? + //if (!_NotesLoaded) + // this.ReadNotes(); if (this.CoverFileName != String.Empty) { @@ -193,10 +194,19 @@ namespace Vocaluxe.Menu.SongMenu } } - public CSong() + //No point creating a song without a text file --> Use factory method LoadSong + private CSong() { } + public static CSong LoadSong(string FilePath) + { + CSong Song = new CSong(); + if (Song.ReadHeader(FilePath)) + return Song; + return null; + } + public CSong(CSong song) { this._CoverTextureSmall = song._CoverTextureSmall; @@ -286,18 +296,7 @@ namespace Vocaluxe.Menu.SongMenu return Path.Combine(Folder, VideoFileName); } - public bool ReadTXTSong(string FilePath) - { - if (!File.Exists(FilePath)) - return false; - - if (!ReadTXTHeader(FilePath)) - return false; - - return true; - } - - public bool ReadTXTHeader(string FilePath) + public bool ReadHeader(string FilePath) { if (!File.Exists(FilePath)) return false; @@ -314,17 +313,11 @@ namespace Vocaluxe.Menu.SongMenu { this.FolderName = this.Folder.Substring(folder.Length + 1, this.Folder.Length - folder.Length - 1); - string str = this.FolderName; - try - { - str = this.FolderName.Substring(0, this.FolderName.IndexOf("\\")); - } - catch (Exception) - { - - } - this.FolderName = str; + int pos = this.FolderName.IndexOf("\\"); + if (pos >= 0) + this.FolderName = this.FolderName.Substring(0, pos); } + break; } } @@ -337,16 +330,19 @@ namespace Vocaluxe.Menu.SongMenu sr = new StreamReader(FilePath, Encoding.Default, true); - string line = sr.ReadLine(); - if (line.Length == 0) - return false; + string line; int pos = -1; string Identifier = String.Empty; string Value = String.Empty; - while ((line.Length == 0) || (line[0].ToString().Equals("#"))) + while (!sr.EndOfStream) { + line = sr.ReadLine(); + if (line.Length == 0) + continue; + if (!line[0].ToString().Equals("#")) break; + pos = line.IndexOf(":"); if (pos > 0) @@ -362,26 +358,22 @@ namespace Vocaluxe.Menu.SongMenu this.Encoding = CEncoding.GetEncoding(Value); sr = new StreamReader(FilePath, this.Encoding); Identifier = String.Empty; - line = sr.ReadLine(); - while ((line.Length == 0) || (line[0].ToString().Equals("#")) && (Identifier != "ENCODING")) + //Scip everything till encoding + while (!sr.EndOfStream) { + line = sr.ReadLine(); + if (line.Length == 0) + continue; + if(!line[0].ToString().Equals("#")) break; + pos = line.IndexOf(":"); if (pos > 0) { Identifier = line.Substring(1, pos - 1).Trim().ToUpper(); - Value = line.Substring(pos + 1, line.Length - pos - 1).Trim(); - } - - if (!sr.EndOfStream) if (Identifier == "ENCODING") break; - else - line = sr.ReadLine(); - else - { - return false; } } break; @@ -481,8 +473,7 @@ namespace Vocaluxe.Menu.SongMenu if (File.Exists(Path.Combine(this.Folder, Value))) this.VideoFileName = Value; else - CBase.Base.Log.LogError("Can't find video file: " + Path.Combine(this.Folder, Value)); - + CBase.Base.Log.LogError("Can't find video file: " + Path.Combine(this.Folder, Value)); break; case "VIDEOGAP": CHelper.TryParse(Value, out this.VideoGap); @@ -520,21 +511,18 @@ namespace Vocaluxe.Menu.SongMenu if (Value.ToUpper() == "YES" && Value.ToUpper() != "NO") this.Relative = EOffOn.TR_CONFIG_ON; break; - default: - ; - break; } } } - - if (!sr.EndOfStream) - line = sr.ReadLine(); - else - { - return false; - } } //end of while + if (sr.EndOfStream) + { + //No other data then header + CBase.Base.Log.LogError("Lyrics/Notes missing: " + FilePath); + return false; + } + if ((HeaderFlags & EHeaderFlags.Title) == 0) { CBase.Base.Log.LogError("Title tag missing: " + FilePath); @@ -645,119 +633,132 @@ namespace Vocaluxe.Menu.SongMenu this.Notes.Reset(); //Search for Note Beginning - do + while(!sr.EndOfStream) { line = sr.ReadLine(); FileLineNo++; - if (sr.EndOfStream || (line.Length == 0)) + TempC = (char)sr.Peek(); + if ((TempC == '#') || (TempC == '\r') || (TempC == '\n')) + continue; + if ((TempC == ':') || (TempC == 'F') || (TempC == '*') || (TempC == 'P')) { - CBase.Base.Log.LogError("Error loading song. Line No.: " + FileLineNo.ToString() + ". The file is empty or it starts with an empty line: " + FilePath); - return false; + TempC = (char)sr.Read(); + break; } - - TempC = (char)sr.Read(); - } while ((TempC.CompareTo(':') != 0) && (TempC.CompareTo('F') != 0) && (TempC.CompareTo('*') != 0) && (TempC.CompareTo('P') != 0)); + } - while (!sr.EndOfStream && (TempC.CompareTo('E') != 0)) + if (sr.EndOfStream) { - FileLineNo++; - if (TempC.CompareTo('P') == 0) + CBase.Base.Log.LogError("Error loading song. Line No.: " + FileLineNo.ToString() + ". No lyrics/notes found: " + FilePath); + return false; + } + + do + { + + char chr; + switch (TempC) { - char chr; - while ((chr = (char)sr.Read()) == ' '){ } + case 'P': + while ((chr = (char)sr.Read()) == ' ') { } - int.TryParse(chr.ToString(), out Param1); - if (Param1 == 1) - Player = 0; - else if (Param1 == 2) - Player = 1; - else if (Param1 == 3) - Player = 2; - else - { - CBase.Base.Log.LogError("Error loading song. Line No.: " + FileLineNo.ToString() + ". Wrong or missing number after \"P\": " + FilePath); - return false; - } - } + int.TryParse(chr.ToString(), out Param1); + if (Param1 == 1) + Player = 0; + else if (Param1 == 2) + Player = 1; + else if (Param1 == 3) + Player = 2; + else + { + CBase.Base.Log.LogError("Error loading song. Line No.: " + FileLineNo.ToString() + ". Wrong or missing number after \"P\": " + FilePath); + return false; + } + sr.ReadLine(); + break; + case ':': + case '*': + case 'F': + sr.Read(); + Param1 = CHelper.TryReadInt(sr); - if ((TempC.CompareTo(':') == 0) || (TempC.CompareTo('*') == 0) || (TempC.CompareTo('F') == 0)) - { - char chr = (char)sr.Read(); - Param1 = CHelper.TryReadInt(sr); - - chr = (char)sr.Read(); - Param2 = CHelper.TryReadInt(sr); - - chr = (char)sr.Read(); - Param3 = CHelper.TryReadInt(sr); - - chr = (char)sr.Read(); - ParamS = sr.ReadLine(); - - ENoteType NoteType; - - if (TempC.CompareTo('*') == 0) - NoteType = ENoteType.Golden; - else if (TempC.CompareTo('F') == 0) - NoteType = ENoteType.Freestyle; - else - NoteType = ENoteType.Normal; - - if (this.Relative == EOffOn.TR_CONFIG_ON) - Param1 += currentPos; - - if (Player != 2) - // one singer - ParseNote(Player, NoteType, Param1, Param2, Param3, ParamS); - else - { - // both singer - ParseNote(0, NoteType, Param1, Param2, Param3, ParamS); - ParseNote(1, NoteType, Param1, Param2, Param3, ParamS); - } - isNewSentence = false; - } - - if (TempC.CompareTo('-') == 0) - { - if (isNewSentence) - { - CBase.Base.Log.LogError("Error loading song. Line No.: " + FileLineNo.ToString() + ". Double sentence break: " + FilePath); - return false; - } - - char chr = (char)sr.Read(); - Param1 = CHelper.TryReadInt(sr); - - if (this.Relative == EOffOn.TR_CONFIG_ON) - { - Param1 += currentPos; - chr = (char)sr.Read(); + sr.Read(); Param2 = CHelper.TryReadInt(sr); - currentPos += Param2; - } - - if(Player != 2) - // one singer - NewSentence(Player, Param1); - else - { - // both singer - NewSentence(0, Param1); - NewSentence(1, Param1); - } - - isNewSentence = true; - } + sr.Read(); + Param3 = CHelper.TryReadInt(sr); + + sr.Read(); + ParamS = sr.ReadLine(); + + ENoteType NoteType; + + if (TempC.CompareTo('*') == 0) + NoteType = ENoteType.Golden; + else if (TempC.CompareTo('F') == 0) + NoteType = ENoteType.Freestyle; + else + NoteType = ENoteType.Normal; + + if (this.Relative == EOffOn.TR_CONFIG_ON) + Param1 += currentPos; + + if (Player != 2) + // one singer + ParseNote(Player, NoteType, Param1, Param2, Param3, ParamS); + else + { + // both singer + ParseNote(0, NoteType, Param1, Param2, Param3, ParamS); + ParseNote(1, NoteType, Param1, Param2, Param3, ParamS); + } + isNewSentence = false; + break; + case '-': + if (isNewSentence) + { + CBase.Base.Log.LogError("Error loading song. Line No.: " + FileLineNo.ToString() + ". Double sentence break: " + FilePath); + return false; + } + + sr.Read(); + Param1 = CHelper.TryReadInt(sr); + + if (this.Relative == EOffOn.TR_CONFIG_ON) + { + Param1 += currentPos; + sr.Read(); + Param2 = CHelper.TryReadInt(sr); + currentPos += Param2; + } + + if (Player != 2) + // one singer + NewSentence(Player, Param1); + else + { + // both singer + NewSentence(0, Param1); + NewSentence(1, Param1); + } + + isNewSentence = true; + sr.ReadLine(); + break; + default: + CBase.Base.Log.LogError("Error loading song. Line No.: " + FileLineNo.ToString() + ". Unexpected or missing character (" + TempC + "): " + FilePath); + return false; + } int c = 0; do { c = sr.Read(); - TempC = (char)c; - } while ((TempC.CompareTo('E') != 0) && !sr.EndOfStream && (c == 19 || c == 16 || c == 13 || c==10)); - } + } while (!sr.EndOfStream && (c == 19 || c == 16 || c == 13 || c == 10)); + TempC = (char)c; + FileLineNo++; + }while(!sr.EndOfStream && (TempC != 'E')); + foreach(CLines lines in this.Notes.Lines) { lines.UpdateTimings();