diff --git a/VocaluxeLib/Songs/CVoice.cs b/VocaluxeLib/Songs/CVoice.cs index 7252074d..ebf826f6 100644 --- a/VocaluxeLib/Songs/CVoice.cs +++ b/VocaluxeLib/Songs/CVoice.cs @@ -15,6 +15,7 @@ // along with Vocaluxe. If not, see . #endregion +using System; using System.Collections.Generic; using System.Linq; @@ -67,7 +68,11 @@ namespace VocaluxeLib.Songs } #region Methods - //Find last line with StartBeat<=Beat + /// + /// Find last line with StartBeat<=Beat + /// + /// + /// public int FindPreviousLine(int beat) { //If no line -> No previous line @@ -92,15 +97,49 @@ namespace VocaluxeLib.Songs return start; } - public void AddLine(CSongLine line) + public bool AddLine(CSongLine line, bool updateTimings = true) { if (_Lines.Count == 0) _Lines.Add(line); else { int insPos = FindPreviousLine(line.StartBeat); + //Check if previous line ends before this one + if (insPos >= 0 && _Lines[insPos].LastNoteBeat > line.StartBeat) + return false; + //Check if next line starts before this one ends + if (insPos + 1 < _Lines.Count && _Lines[insPos + 1].FirstNoteBeat < line.LastNoteBeat) + return false; _Lines.Insert(insPos + 1, line); } + if (updateTimings) + UpdateTimings(); + return true; + } + + public bool AddLine(int startBeat) + { + int insPos = FindPreviousLine(startBeat); + //Check for actual notes (startbeat may be lower than first note) + while (insPos >= 0 && _Lines[insPos].NoteCount > 0 && _Lines[insPos].FirstNoteBeat > startBeat) + insPos--; + CSongLine line = new CSongLine {StartBeat = startBeat}; + if (insPos >= 0) + { + CSongLine prevLine = _Lines[insPos]; + //We already have a line break here + if (prevLine.StartBeat == startBeat && prevLine.FirstNoteBeat == startBeat) + return false; + //Maybe we have to split the previous line + while (prevLine.NoteCount > 0 && prevLine.LastNote.StartBeat >= startBeat) + { + throw new Exception("This should not happen on song loading!"); + line.AddNote(prevLine.LastNote); + prevLine.DeleteNote(prevLine.NoteCount - 1); + } + } + _Lines.Insert(insPos + 1, line); + return true; } public bool DeleteLine(int index) @@ -119,7 +158,7 @@ namespace VocaluxeLib.Songs _Lines.Clear(); } - public bool AddNote(CSongNote note, bool updateTimings = false) + public bool AddNote(CSongNote note, bool updateTimings = true) { int lineIndex = FindPreviousLine(note.StartBeat); if (lineIndex + 1 < _Lines.Count && _Lines[lineIndex + 1].FirstNoteBeat < note.EndBeat) //First note in next line starts before this one ends @@ -150,17 +189,19 @@ namespace VocaluxeLib.Songs return true; } - public bool InsertNote(CSongNote note, int lineIndex, bool updateTimings = false) + /*Check this first for consistency (next line might be affected) + * public bool InsertNote(CSongNote note, int lineIndex, bool updateTimings = false) { if (_Lines.Count > lineIndex && _Lines[lineIndex].StartBeat <= note.StartBeat) { - _Lines[lineIndex].AddNote(note); + if (!_Lines[lineIndex].AddNote(note)) + return false; if (updateTimings) UpdateTimings(); return true; } return false; - } + }*/ public void UpdateTimings() { @@ -203,11 +244,24 @@ namespace VocaluxeLib.Songs _Lines[i].StartBeat = s; _Lines[i - 1].EndBeat = min; } + else if (firstNote != null) + { + _Lines[i - 1].EndBeat = Math.Min(_Lines[i - 1].StartBeat, firstNote.StartBeat - 2); + _Lines[i].StartBeat = Math.Max(_Lines[i - 1].EndBeat, firstNote.StartBeat - 2); + } + else if (lastNote != null) + { + _Lines[i - 1].EndBeat = lastNote.EndBeat; + _Lines[i].StartBeat = Math.Max(lastNote.EndBeat, _Lines[i].StartBeat); //Prefer current setting + } + else + { + //No note + _Lines[i - 1].EndBeat = _Lines[i - 1].StartBeat; //Assume at least startbeats were set right + } } - lastNote = _Lines[_Lines.Count - 1].LastNote; - if (lastNote != null) - _Lines[_Lines.Count - 1].EndBeat = lastNote.EndBeat; + _Lines[_Lines.Count - 1].EndBeat = Math.Max(_Lines[_Lines.Count - 1].LastNoteBeat, _Lines[_Lines.Count - 1].StartBeat); //Use note or (when not set) start beat } public void SetMedley(int startBeat, int endBeat) diff --git a/VocaluxeLib/Songs/SongNotesLoader.cs b/VocaluxeLib/Songs/SongNotesLoader.cs index 71d85696..89096042 100644 --- a/VocaluxeLib/Songs/SongNotesLoader.cs +++ b/VocaluxeLib/Songs/SongNotesLoader.cs @@ -440,10 +440,7 @@ namespace VocaluxeLib.Songs if ((tmpPlayer & 1) != 0) { if (!_ParseNote(curPlayer, noteType, beat, length, tone, text)) - { - CBase.Log.LogError("Warning! Ignored note for player " + (curPlayer + 1) + " because it overlaps with other note. Line No.: " + - lineNr + ": " + filePath); - } + _LogReadError("Warning: Ignored note for player " + (curPlayer + 1) + " because it overlaps with other note", lineNr); } tmpPlayer >>= 1; curPlayer++; @@ -491,7 +488,10 @@ namespace VocaluxeLib.Songs while (tmpPlayer > 0) { if ((tmpPlayer & 1) != 0) - _NewSentence(curPlayer, beat); + { + if (_NewSentence(curPlayer, beat)) + _LogReadError("Warning: Ignored line break for player " + (curPlayer + 1) + " (Overlapping or duplicate)", lineNr); + } tmpPlayer >>= 1; curPlayer++; } @@ -536,14 +536,13 @@ namespace VocaluxeLib.Songs { var note = new CSongNote(start, length, tone, text, noteType); CVoice voice = Notes.GetVoice(player); - return voice.AddNote(note); + return voice.AddNote(note, false); } - private void _NewSentence(int player, int start) + private bool _NewSentence(int player, int start) { CVoice voice = Notes.GetVoice(player); - var line = new CSongLine {StartBeat = start}; - voice.AddLine(line); + return voice.AddLine(start); } } } \ No newline at end of file