From bf1c00b5d1aa23db7992e15d8c9cb53081a566fd Mon Sep 17 00:00:00 2001 From: Flamefire Date: Tue, 8 Oct 2013 20:15:34 +0200 Subject: [PATCH] Some fixes and support for more than 2 voices --- Vocaluxe/Base/CMain.cs | 2 +- Vocaluxe/Screens/CScreenNames.cs | 8 +++-- Vocaluxe/Screens/CScreenScore.cs | 6 ++-- Vocaluxe/Screens/CScreenSing.cs | 9 ++--- VocaluxeLib/Extensions.cs | 52 +++++++++++++++++++++++++++ VocaluxeLib/IBasic.cs | 2 +- VocaluxeLib/Songs/CNotes.cs | 61 ++++++++++++++++++++++++++------ VocaluxeLib/Songs/CSong.cs | 56 ++++++++++++----------------- VocaluxeLib/Songs/CSongLine.cs | 7 ++-- VocaluxeLib/VocaluxeLib.csproj | 3 +- 10 files changed, 144 insertions(+), 62 deletions(-) create mode 100644 VocaluxeLib/Extensions.cs diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs index 2d2a9ea9..8a40c555 100644 --- a/Vocaluxe/Base/CMain.cs +++ b/Vocaluxe/Base/CMain.cs @@ -110,7 +110,7 @@ namespace Vocaluxe.Base return CConfig.CoverSize; } - public IEnumerable GetSongFolder() + public IEnumerable GetSongFolders() { return CConfig.SongFolder; } diff --git a/Vocaluxe/Screens/CScreenNames.cs b/Vocaluxe/Screens/CScreenNames.cs index f1f548ab..62a99c37 100644 --- a/Vocaluxe/Screens/CScreenNames.cs +++ b/Vocaluxe/Screens/CScreenNames.cs @@ -22,6 +22,7 @@ using Vocaluxe.Base; using VocaluxeLib; using VocaluxeLib.Draw; using VocaluxeLib.Menu; +using VocaluxeLib.Songs; namespace Vocaluxe.Screens { @@ -597,6 +598,8 @@ namespace Vocaluxe.Screens _CheckMics(); _CheckPlayers(); + CSong firstSong = CGame.GetSong(0); + for (int i = 0; i < CSettings.MaxNumPlayer; i++) { _Statics[_StaticPlayerAvatar[i]].Texture = CProfiles.IsProfileIDValid(CGame.Players[i].ProfileID) ? @@ -607,8 +610,9 @@ namespace Vocaluxe.Screens { _SelectSlides[_SelectSlideDuetPlayer[i]].Clear(); _SelectSlides[_SelectSlideDuetPlayer[i]].Visible = i + 1 <= CGame.NumPlayer; - _SelectSlides[_SelectSlideDuetPlayer[i]].AddValue(CGame.GetSong(1).DuetPart1); - _SelectSlides[_SelectSlideDuetPlayer[i]].AddValue(CGame.GetSong(1).DuetPart2); + + for (int j = 0; j < firstSong.Notes.VoiceCount; j++) + _SelectSlides[_SelectSlideDuetPlayer[i]].AddValue(firstSong.Notes.VoiceNames[j]); _SelectSlides[_SelectSlideDuetPlayer[i]].Selection = i % 2; } else diff --git a/Vocaluxe/Screens/CScreenScore.cs b/Vocaluxe/Screens/CScreenScore.cs index fac4c499..b1e06b1e 100644 --- a/Vocaluxe/Screens/CScreenScore.cs +++ b/Vocaluxe/Screens/CScreenScore.cs @@ -297,10 +297,8 @@ namespace Vocaluxe.Screens string name = CProfiles.GetPlayerName(players[p].ProfileID, p); if (song != null && song.IsDuet) { - if (players[p].VoiceNr == 0 && song.DuetPart1 != "Part 1") - name += " (" + song.DuetPart1 + ")"; - else if (players[p].VoiceNr == 1 && song.DuetPart2 != "Part 2") - name += " (" + song.DuetPart2 + ")"; + if (song.Notes.VoiceNames.IsSet(players[p].VoiceNr)) + name += " (" + song.Notes.VoiceNames[players[p].VoiceNr] + ")"; } _Texts[_TextNames[p, CGame.NumPlayer - 1]].Text = name; diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index e485c684..08cf762a 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -634,8 +634,9 @@ namespace Vocaluxe.Screens if (song.IsDuet) { - _Texts[_TextDuetName1].Text = song.DuetPart1; - _Texts[_TextDuetName2].Text = song.DuetPart2; + //TODO: Show more than 2 voicenames + _Texts[_TextDuetName1].Text = song.Notes.VoiceNames[0]; + _Texts[_TextDuetName2].Text = song.Notes.VoiceNames[1]; //More than one song: Player is not assigned to line by user //Otherwise, this is done by CScreenNames if (CGame.GetNumSongs() > 1) @@ -781,7 +782,7 @@ namespace Vocaluxe.Screens _CurrentBeat = CGame.CurrentBeat; - for (int i = 0; i < song.Notes.LinesCount; i++) + for (int i = 0; i < song.Notes.VoiceCount; i++) { if (i > 1) break; // for later @@ -1093,7 +1094,7 @@ namespace Vocaluxe.Screens var alpha = new float[song.Notes.Voices.Length * 2]; float currentTime = _CurrentTime - song.Gap; - for (int i = 0; i < song.Notes.LinesCount; i++) + for (int i = 0; i < song.Notes.VoiceCount; i++) { CVoice voice = song.Notes.GetVoice(i); CSongLine[] lines = voice.Lines; diff --git a/VocaluxeLib/Extensions.cs b/VocaluxeLib/Extensions.cs new file mode 100644 index 00000000..b970b6bc --- /dev/null +++ b/VocaluxeLib/Extensions.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace VocaluxeLib +{ + public static class Extensions + { + /// + /// Resizes the given list to the given size. Removes elements or adds default values + /// + /// + /// + /// + /// + public static void Resize(this List list, int size, T defaultValue = default(T)) + { + int curSize = list.Count; + if (size < curSize) + list.RemoveRange(size, curSize - size); + else if (size > curSize) + list.AddRange(Enumerable.Repeat(defaultValue, size - curSize)); + } + + /// + /// Makes the list at least the given size adding the given default values. + /// + /// + /// + /// + /// + public static void EnsureSize(this List list, int size, T defaultValue) + { + int curSize = list.Count; + if (size > curSize) + list.AddRange(Enumerable.Repeat(defaultValue, size - curSize)); + } + + /// + /// Makes the list at least the given size adding a new instance of T + /// + /// + /// + /// + public static void EnsureSize(this List list, int size) where T : new() + { + if (size > list.Count) + list.Add(new T()); + } + } +} \ No newline at end of file diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs index 2c34490b..c6893634 100644 --- a/VocaluxeLib/IBasic.cs +++ b/VocaluxeLib/IBasic.cs @@ -45,7 +45,7 @@ namespace VocaluxeLib int GetCoverSize(); - IEnumerable GetSongFolder(); + IEnumerable GetSongFolders(); ESongSorting GetSongSorting(); EOffOn GetTabs(); EOffOn GetIgnoreArticles(); diff --git a/VocaluxeLib/Songs/CNotes.cs b/VocaluxeLib/Songs/CNotes.cs index f1ab9cbb..66750715 100644 --- a/VocaluxeLib/Songs/CNotes.cs +++ b/VocaluxeLib/Songs/CNotes.cs @@ -21,26 +21,65 @@ namespace VocaluxeLib.Songs { public class CNotes { + public class CVoiceNames + { + private readonly List _Names = new List(); + + public CVoiceNames() {} + + public CVoiceNames(CVoiceNames names) + { + _Names.AddRange(names._Names); + } + + public string this[int index] + { + get + { + if (IsSet(index)) + return _Names[index]; + return "Part " + (index + 1); + } + set + { + _Names.EnsureSize(index + 1, null); + _Names[index] = value; + } + } + + public bool IsSet(int index) + { + return _Names.Count > index && !string.IsNullOrEmpty(_Names[index]); + } + + public void Reset() + { + _Names.Clear(); + } + } + private readonly List _Voices = new List(); + public readonly CVoiceNames VoiceNames = new CVoiceNames(); + + public CNotes() {} + + public CNotes(CNotes notes) + { + foreach (CVoice voice in notes._Voices) + _Voices.Add(new CVoice(voice)); + VoiceNames = new CVoiceNames(notes.VoiceNames); + } public CVoice[] Voices { get { return _Voices.ToArray(); } } - public CNotes() {} - - public int LinesCount + public int VoiceCount { get { return _Voices.Count; } } - public CNotes(CNotes notes) - { - foreach (CVoice voice in notes._Voices) - _Voices.Add(new CVoice(voice)); - } - public CVoice GetVoice(int index) { while (index >= _Voices.Count) @@ -79,9 +118,11 @@ namespace VocaluxeLib.Songs return true; } - public void Reset() + public void Reset(bool resetVoices = false) { _Voices.Clear(); + if (resetVoices) + VoiceNames.Reset(); } public void SetMedley(int startBeat, int endBeat) diff --git a/VocaluxeLib/Songs/CSong.cs b/VocaluxeLib/Songs/CSong.cs index 35e15d34..3a820b76 100644 --- a/VocaluxeLib/Songs/CSong.cs +++ b/VocaluxeLib/Songs/CSong.cs @@ -124,9 +124,6 @@ namespace VocaluxeLib.Songs public float Gap; public float VideoGap; - public string DuetPart1 = String.Empty; - public string DuetPart2 = String.Empty; - private readonly List _Comment = new List(); // Sorting @@ -192,8 +189,6 @@ namespace VocaluxeLib.Songs PreviewStart = song.PreviewStart; ShortEnd = song.ShortEnd; - DuetPart1 = song.DuetPart1; - DuetPart2 = song.DuetPart2; Encoding = song.Encoding; Folder = song.Folder; @@ -268,7 +263,7 @@ namespace VocaluxeLib.Songs if (Folder == null) return false; - foreach (string folder in CBase.Config.GetSongFolder()) + foreach (string folder in CBase.Config.GetSongFolders()) { if (!Folder.Contains(folder)) continue; @@ -318,7 +313,7 @@ namespace VocaluxeLib.Songs sr = null; sr = new StreamReader(filePath, Encoding); - //Scip everything till encoding + //Skip everything till encoding while (!sr.EndOfStream) { line = sr.ReadLine(); @@ -362,12 +357,12 @@ namespace VocaluxeLib.Songs case "DUETSINGERP1": case "P1": if (value != "") - DuetPart1 = value; + Notes.VoiceNames[0] = value; break; case "DUETSINGERP2": case "P2": if (value != "") - DuetPart2 = value; + Notes.VoiceNames[1] = value; break; case "MP3": if (File.Exists(Path.Combine(Folder, value))) @@ -462,7 +457,7 @@ namespace VocaluxeLib.Songs CalculateMedley = false; break; case "RELATIVE": - if (value.ToUpper() == "YES" && value.ToUpper() != "NO") + if (value.ToUpper() == "YES") Relative = EOffOn.TR_CONFIG_ON; break; } @@ -569,7 +564,7 @@ namespace VocaluxeLib.Songs int currentPos = 0; bool isNewSentence = false; - int player = 0; + int player = 1; int fileLineNo = 0; StreamReader sr = null; @@ -611,14 +606,7 @@ namespace VocaluxeLib.Songs char chr; 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 + if (!int.TryParse(chr.ToString(), out player)) { CBase.Log.LogError("Error loading song. Line No.: " + fileLineNo + ". Wrong or missing number after \"P\": " + filePath); return false; @@ -652,14 +640,19 @@ namespace VocaluxeLib.Songs if (Relative == EOffOn.TR_CONFIG_ON) param1 += currentPos; - if (player != 2) - // one singer - _ParseNote(player, noteType, param1, param2, param3, paramS); - else + int curPlayer = 0; + int tmpPlayer = player; + //Evaluate as bitset + while (tmpPlayer > 0) { - // both singer - _ParseNote(0, noteType, param1, param2, param3, paramS); - _ParseNote(1, noteType, param1, param2, param3, paramS); + if ((tmpPlayer & 1) != 0) + { + if (!_ParseNote(curPlayer, noteType, param1, param2, param3, paramS)) + CBase.Log.LogError("Warning! Ignored note for player " + (curPlayer + 1) + " in song because it overlaps with other note. Line No.: " + + fileLineNo + ": " + filePath); + } + tmpPlayer >>= 1; + curPlayer++; } isNewSentence = false; break; @@ -789,15 +782,10 @@ namespace VocaluxeLib.Songs private void _CheckDuet() { - if (DuetPart1 == "") + for (int i = 0; i < Notes.VoiceCount; i++) { - DuetPart1 = "Part 1"; - CBase.Log.LogError("Warning: Can't find #P1-tag for duets in \"" + Artist + " - " + Title + "\"."); - } - if (DuetPart2 == "") - { - DuetPart2 = "Part 2"; - CBase.Log.LogError("Warning: Can't find #P2-tag for duets in \"" + Artist + " - " + Title + "\"."); + if (!Notes.VoiceNames.IsSet(i)) + CBase.Log.LogError("Warning: Can't find #P" + (i + 1) + "-tag for duets in \"" + Artist + " - " + Title + "\"."); } } diff --git a/VocaluxeLib/Songs/CSongLine.cs b/VocaluxeLib/Songs/CSongLine.cs index 9f678a5c..19a94238 100644 --- a/VocaluxeLib/Songs/CSongLine.cs +++ b/VocaluxeLib/Songs/CSongLine.cs @@ -90,11 +90,8 @@ namespace VocaluxeLib.Songs public void SetMedley(int startBeat, int endBeat) { - foreach (CSongNote note in _Notes) - { - if (note.StartBeat < startBeat || note.EndBeat > endBeat) - note.NoteType = ENoteType.Freestyle; - } + foreach (CSongNote note in _Notes.Where(note => note.StartBeat < startBeat || note.EndBeat > endBeat)) + note.NoteType = ENoteType.Freestyle; VisibleInTimeLine = FirstNoteBeat >= startBeat && LastNoteBeat <= endBeat; } diff --git a/VocaluxeLib/VocaluxeLib.csproj b/VocaluxeLib/VocaluxeLib.csproj index 5b895271..0fb808a3 100644 --- a/VocaluxeLib/VocaluxeLib.csproj +++ b/VocaluxeLib/VocaluxeLib.csproj @@ -130,6 +130,7 @@ + @@ -195,4 +196,4 @@ --> - + \ No newline at end of file