public Progression Parse(string input, int pitchOffset) { input = this.Sanitize(input); string[] tokens = input.Split(" "); bool isExpectedChord = true; Progression progression = new Progression(); foreach (string token in tokens) { if (isExpectedChord) { ChordType chordType = this.chordTypeParser.Parse(token); Chord chord = new Chord(chordType, (NoteType)pitchOffset); progression.AddChord(chord); } else { IntervalType interval = this.intervalParser.Parse(token); pitchOffset += (int)interval; while (pitchOffset >= 12) { pitchOffset -= 12; } while (pitchOffset < 0) { pitchOffset += 12; } } isExpectedChord = !isExpectedChord; } return progression; }
static void Main(string[] args) { Random random = new Random(); ProgressionBuilder progressionBuilder = new ProgressionBuilder(random, 2, false, false); InputParser inputParser = new InputParser(new IntervalParser(), new ChordTypeParser()); ConfusionManager confusionManager = new ConfusionManager(); // m3 or 6th: confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.Sixth, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.MinorThird, ChordType.Major)); // m3 or Flat 6: confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.FlatSixth, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.MinorThird, ChordType.Major)); // Major 3rd or sixth: confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.Sixth, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.MajorThird, ChordType.Major)); // Major 3rd or Flat 6: Done confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.FlatSixth, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.MajorThird, ChordType.Major)); // All diatonic minor to minor + extras: Done confusionManager.AddConfusion(new ProgressionType(ChordType.Minor, IntervalType.MajorSecond, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.FlatSeventh, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.PerfectFifth, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.PerfectFourth, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.FlatSixth, ChordType.Minor)); // Flat 6 minor (hm's relative major's plagal minor) // All diatonic major to major + extras: Done confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.MajorSecond, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.FlatSeventh, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.PerfectFifth, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.PerfectFourth, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.MinorSecond, ChordType.Major), // Phrygian Dominant new ProgressionType(ChordType.Major, IntervalType.FlatSixth, ChordType.Major), // Mixolydian b6 new ProgressionType(ChordType.Major, IntervalType.MajorThird, ChordType.Major)); // Creep // All diatonic major to minor + extras confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.MajorSecond, ChordType.Minor), new ProgressionType(ChordType.Major, IntervalType.Sixth, ChordType.Minor), new ProgressionType(ChordType.Major, IntervalType.MajorThird, ChordType.Minor), new ProgressionType(ChordType.Major, IntervalType.PerfectFifth, ChordType.Minor), // Mixolydian v new ProgressionType(ChordType.Major, IntervalType.MajorSeventh, ChordType.Minor), // Lydian vii new ProgressionType(ChordType.Major, IntervalType.PerfectFourth, ChordType.Minor)); // Minor plagal // Perfect fifth or perfect fourth: Done!!! confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.PerfectFifth, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.PerfectFourth, ChordType.Major)); // Aeolian v or iv: Done!!! confusionManager.AddConfusion(new ProgressionType(ChordType.Minor, IntervalType.PerfectFifth, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.PerfectFourth, ChordType.Minor)); // Space, mixolydian b6 hindu or Major3 or phrygian dominant or Ionadimic confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.FlatSixth, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.AugmentedFourthDiminishedFifthTritone, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.MajorThird, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.MinorSecond, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.AugmentedFourthDiminishedFifthTritone, ChordType.Minor)); // Phrygian or Batman 1989 reversed phrygian dominant viib confusionManager.AddConfusion(new ProgressionType(ChordType.Minor, IntervalType.MinorSecond, ChordType.Major), new ProgressionType(ChordType.Minor, IntervalType.MajorSecond, ChordType.Major)); // Batman 2008 or Batman 1989 confusionManager.AddConfusion(new ProgressionType(ChordType.Minor, IntervalType.MajorSeventh, ChordType.Major), new ProgressionType(ChordType.Minor, IntervalType.MajorSecond, ChordType.Major)); // Ionadimic or Relative minor space confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.AugmentedFourthDiminishedFifthTritone, ChordType.Minor), new ProgressionType(ChordType.Major, IntervalType.MinorThird, ChordType.Minor)); // Thacrimic or augmented minor to major or minor to parallel major or time reversed 'major to relative minor of space / petrushka' or minor third third minor third confusionManager.AddConfusion(new ProgressionType(ChordType.Minor, IntervalType.AugmentedFourthDiminishedFifthTritone, ChordType.Major), new ProgressionType(ChordType.Minor, IntervalType.MajorThird, ChordType.Major), new ProgressionType(ChordType.Minor, IntervalType.Sixth, ChordType.Major), new ProgressionType(ChordType.Minor, IntervalType.MinorThird, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.UnisonOctave, ChordType.Major)); // Time reversed ultraphrygian minor, ultraphrygian minor or vader confusionManager.AddConfusion(new ProgressionType(ChordType.Minor, IntervalType.MajorSeventh, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.MinorSecond, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.FlatSixth, ChordType.Minor)); // Midgar or evil danger confusionManager.AddConfusion(new ProgressionType(ChordType.Minor, IntervalType.Sixth, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.AugmentedFourthDiminishedFifthTritone, ChordType.Minor)); // Deceptive cadence or aeolian iv or aeolian v or dorian IV confusionManager.AddConfusion(new ProgressionType(ChordType.Minor, IntervalType.FlatSeventh, ChordType.Major), new ProgressionType(ChordType.Minor, IntervalType.PerfectFourth, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.PerfectFifth, ChordType.Minor), new ProgressionType(ChordType.Minor, IntervalType.PerfectFourth, ChordType.Major)); // Dorian VI or dorian ii or rock IIIb confusionManager.AddConfusion(new ProgressionType(ChordType.Minor, IntervalType.PerfectFourth, ChordType.Major), new ProgressionType(ChordType.Minor, IntervalType.MajorSecond, ChordType.Minor), new ProgressionType(ChordType.Major, IntervalType.MinorThird, ChordType.Major)); // Mixolydian v or plagal confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.PerfectFifth, ChordType.Minor), new ProgressionType(ChordType.Major, IntervalType.PerfectFourth, ChordType.Major)); // Mixolydian b6 (hindu) or plagal minor or phrygian dominant viib confusionManager.AddConfusion(new ProgressionType(ChordType.Major, IntervalType.FlatSixth, ChordType.Major), new ProgressionType(ChordType.Major, IntervalType.PerfectFourth, ChordType.Minor), new ProgressionType(ChordType.Major, IntervalType.FlatSeventh, ChordType.Minor)); Instrument instrument = new Piano(); MusicPlayer musicPlayer = new MusicPlayer(random, instrument); while (true) { ProgressionType[] progressionTypes = confusionManager.GetProgressionTypes(0); #warning Activate, set or deactivate confusion manager here //Progression progression = progressionBuilder.BuildProgression(); Progression progression = progressionBuilder.BuildProgression(progressionTypes); if (isShowAnswerFirst) { Console.Clear(); Console.WriteLine(progression); } else { Console.WriteLine("Intervals: 0, 2b, 2, 3m, 3M, 4, 4A, 5, 6b, 6, 7m, 7M"); Console.WriteLine("Chord types: M, m, M7, m7, 7, dim7, aug, hdim, dim"); Console.WriteLine("Type something like M 4 m (for minor plagal cadence), exit to quit"); } musicPlayer.Play(progression); if (isAutoPlay) { musicPlayer.WaitUntilFinishedRepeat(2); } else { string input = Console.ReadLine(); musicPlayer.Stop(); if (input.ToUpperInvariant().Contains("EXIT")) { break; } if (!string.IsNullOrWhiteSpace(input)) { Progression parsedInput = inputParser.Parse(input, progression.PitchOffset); Console.WriteLine("Parsed as " + parsedInput.ToString()); if (progression.ToString() == parsedInput.ToString()) { Console.WriteLine("MATCH!"); } else { Console.WriteLine("WRONG, it is " + progression.ToString()); } } else if (!isShowAnswerFirst) { Console.WriteLine("It was"); Console.WriteLine(progression.ToString()); Console.WriteLine("Ready? press enter to continue"); Console.ReadLine(); } Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine(""); } } }
public void Play(Progression progression) { this.Stop(); lock (this.playerLock) { this.isPlaying = true; this.isFinishedPlaying = false; } int chordLength; int noteLength; /*if (random.Next(0, 2) == 0) * {*/ chordLength = 8; noteLength = 200 - 25 + random.Next(0, 50); /*} * else * { * chordLength = 12; * noteLength = 150 - 19 + random.Next(0, 38); * }*/ int octaveOffset = (random.Next(0, 2) + 2) * 12; int rythmSeed = random.Next(); Thread playerThread = new Thread(() => { while (isPlaying) { for (int loopIndex = 0; loopIndex < 1; ++loopIndex) { foreach (Chord chord in progression) { int[] notes = chord.GetNotes(); Shuffle(notes, rythmSeed); this.Play(chordLength, noteLength, octaveOffset, rythmSeed, notes); if (!isPlaying) { break; } } } int[] lastNotes = progression.First().GetNotes(); Shuffle(lastNotes, rythmSeed); this.Play(chordLength + 1, noteLength, octaveOffset, rythmSeed, lastNotes); this.Silence(chordLength - 2, noteLength); ++this.currentPlayCount; this.Silence(1, noteLength); } lock (this.playerLock) { this.isFinishedPlaying = true; } }); playerThread.IsBackground = true; playerThread.Start(); }