private void CalculatePositionsAndLengths(IEnumerable <string> tabLines) { var offset = TabNotes[0].PositionInCharacters; var tabWidth = GetLastDashPosition(tabLines); var stepLength = 1M / Convert.ToDecimal(NoteDivision); tabWidth -= offset; foreach (var tabNote in TabNotes) { tabNote.PositionInCharacters -= offset; tabNote.TabWidth = tabWidth; } for (var i = 0; i < TabNotes.Count; i++) { var tabNote = TabNotes[i]; var nextTabNote = (i < TabNotes.Count - 1) ? TabNotes[i + 1] : null; if (nextTabNote != null) { tabNote.LengthInCharacters = nextTabNote.PositionInCharacters - tabNote.PositionInCharacters; } else { tabNote.LengthInCharacters = tabNote.TabWidth - tabNote.PositionInCharacters; } } foreach (var tabNote in TabNotes) { tabNote.Length = Math.Round(tabNote.IdealLengthPercent * NoteDivision, 0) / Convert.ToDecimal(NoteDivision); if (tabNote.Length == 0) { tabNote.Length = stepLength; } } CalculatePositions(TabNotes); var remainder = 1M - TabNotes.Sum(x => x.Length); var stepsToDistribute = Convert.ToInt32(remainder / stepLength); var removeSteps = stepsToDistribute < 0; while (Math.Abs(remainder) >= stepLength) { var possibilities = new Dictionary <TabNote, List <TabNote> >(); foreach (var tabNote in TabNotes) { var possibility = TabNotes.Select(x => x.Clone()).ToList(); var changedTabNote = possibility.FirstOrDefault(x => x.PositionInCharacters == tabNote.PositionInCharacters); if (changedTabNote == null) { continue; } if (removeSteps) { if (changedTabNote.Length > stepLength) { changedTabNote.Length -= stepLength; possibilities.Add(tabNote, possibility); } } else { changedTabNote.Length += stepLength; possibilities.Add(tabNote, possibility); } CalculatePositions(possibility); } var tabNoteToChange = possibilities.OrderBy(x => x.Value.Sum(y => y.DifferenceFromIdeal)).FirstOrDefault(); var tentativeChangedTabNote = tabNoteToChange.Value.FirstOrDefault(x => x.PositionInCharacters == tabNoteToChange.Key.PositionInCharacters); if (tentativeChangedTabNote != null) { tabNoteToChange.Key.Length = tentativeChangedTabNote.Length; } CalculatePositions(TabNotes); remainder = 1M - TabNotes.Sum(x => x.Length); } foreach (var tabNote in TabNotes) { tabNote.Length *= NoteDivision; } }
public List <int> GetDistinctNoteNumbers() { return(TabNotes.Select(x => x.Number).Distinct().OrderBy(x => x).ToList()); }