private static void PrintDiatonicScales(DiatonicMode diatonicMode) { var scale = new DiatonicScale(Note.GFlat, Major); var notes = scale.GetPitchesAscending().Select(pitch => pitch.Note).Take(scale.DegreeCount + 1).ToArray(); var keyNote = notes[diatonicMode - Ionian]; var title = $"Circle of {diatonicMode.GetCombinedName()} scales"; Console.WriteLine(title); Console.WriteLine(new string('-', title.Length)); Console.WriteLine(); var sb = new StringBuilder(); for (var i = -SemitonesPerOctave / 2; i <= SemitonesPerOctave / 2; i++) { scale = new DiatonicScale(keyNote, diatonicMode); notes = scale.GetPitchesAscending().Select(pitch => pitch.Note).Take(scale.DegreeCount + 1).ToArray(); sb.Clear(); if (i < 0) { sb.AppendFormat("[{0}b] ", -i); } else if (i > 0) { sb.AppendFormat("[{0}#] ", i); } else { sb.Append(' ', 5); } string note = notes[0].ToString(); sb.Append(note); for (var j = 1; j < notes.Length; j++) { sb.Append(',').Append(' ', 3 - note.Length); note = notes[j].ToString(); sb.Append(note); } Console.WriteLine(sb.ToString()); keyNote = (new Pitch(keyNote, 4) + PerfectFifth).Note; } }
private static int FillFretNumbers(int[][] fretNumbers, Guitar guitar, int stringNumber, DiatonicScale scale) { int fretNumber = 0; int minFretNumber = fretNumber; int maxFretNumber = fretNumber; using (IEnumerator <Interval> intervalEnumerator = scale.GetIntervalsAscending().GetEnumerator()) { for (var i = 0; i < fretNumbers.Length; i++) { for (var j = 0; j < fretNumbers[i].Length; j++) { fretNumbers[i][j] = fretNumber; if (fretNumber > maxFretNumber) { maxFretNumber = fretNumber; } intervalEnumerator.MoveNext(); fretNumber += intervalEnumerator.Current.Semitones; } if (stringNumber < guitar.StringIntervals.Count) { fretNumber -= guitar.StringIntervals[stringNumber].Semitones; if (fretNumber < minFretNumber) { minFretNumber = fretNumber; } } stringNumber++; } } if (minFretNumber < 0) { ShiftFretNumbers(fretNumbers, -minFretNumber); maxFretNumber -= minFretNumber; } return(maxFretNumber); }
private static void Practice() { s_practiceStats = new PracticeStats(); Console.CancelKeyPress += (s, e) => PrintPracticeStats(); var guitar = new Guitar(); var random = new Random(); for (; ;) { var mode = (DiatonicMode)random.Next(DiatonicScale.NumberOfDegrees); var scale = new DiatonicScale(Note.C, mode); var pattern = (Pattern)random.Next(numberOfPatterns); int[][] fretNumbers = CreateFretNumbers(pattern); int stringNumber = random.Next(guitar.NumberOfStrings - fretNumbers.Length + 1); int maxFretNumber = FillFretNumbers(fretNumbers, guitar, stringNumber, scale); int questionStringIndex; int questionFretIndex; if (random.Next(10) != 0) { questionStringIndex = random.Next(fretNumbers.Length); questionFretIndex = random.Next(fretNumbers[questionStringIndex].Length); } else { questionStringIndex = questionFretIndex = -1; } int position = random.Next(guitar.NumberOfFrets - maxFretNumber + 1); PrintExcercise(guitar, stringNumber, fretNumbers, maxFretNumber, questionStringIndex, questionFretIndex, position); Console.WriteLine(); Console.Write(questionStringIndex >= 0 ? "Enter scale degree: " : "Enter scale name: "); Console.WriteLine($"({s_practiceStats.Stopwatch.Elapsed:hh':'mm':'ss})"); for (; ;) { var answer = Console.ReadLine()?.ToLowerInvariant(); if (answer == null || answer == "q" || answer == "quit") { PrintPracticeStats(); return; } bool isCorrectAnswer; if (questionStringIndex >= 0) { DiatonicMode degree = mode; for (var i = 0; i < fretNumbers.Length; i++) { for (var j = 0; j < fretNumbers[i].Length; j++) { if (i < questionStringIndex || j < questionFretIndex) { degree++; if (degree - Ionian >= DiatonicScale.NumberOfDegrees) { degree -= DiatonicScale.NumberOfDegrees; } } else { goto EndOfLoop; } } } EndOfLoop: isCorrectAnswer = EvaluateDegreeAnswer(degree, answer); } else { isCorrectAnswer = EvaluateModeAnswer(mode, guitar, stringNumber, position, fretNumbers, answer); } if (isCorrectAnswer) { s_practiceStats.NumberOfCorrectAnswers++; Console.WriteLine("Correct!"); break; } else { s_practiceStats.NumberOfWrongAnswers++; Console.WriteLine("Wrong!"); } } Console.WriteLine(); } }