public static CellState[,] GenerateSong(Automatone automatone, Random random, MusicTheory theory) { InputParameters.Instance.Tempo = (ushort)(theory.MIN_TEMPO + InputParameters.Instance.SongSpeed * (theory.MAX_TEMPO - theory.MIN_TEMPO)); InputParameters.Instance.TimeSignatureN = (int)(2 + random.NextDouble() / 4 * (13 - 2)); InputParameters.Instance.TimeSignatureD = (int)Math.Pow(2, (int)(1 + random.NextDouble() * 2)); Song s = new Song(theory, random); NoteThread thread = new NoteThread(s.Notes, InputParameters.Instance.TimeSignature); int gridWidth = s.MeasureCount * s.MeasureLength; CellState[,] grid = new CellState[Automatone.PIANO_SIZE,gridWidth]; foreach (List<Note> nts in s.Notes) { foreach (Note n in nts) { grid[n.GetOctave() * MusicTheory.OCTAVE_SIZE + n.GetNoteName().ChromaticIndex - Automatone.LOWEST_NOTE_CHROMATIC_NUMBER, (int)Math.Min(n.GetStartMeasure() * s.MeasureLength + n.GetStartBeat() * Automatone.SUBBEATS_PER_WHOLE_NOTE, gridWidth - 1)] = CellState.START; for (int i = 1; i < n.GetRemainingDuration() * Automatone.SUBBEATS_PER_WHOLE_NOTE; i++) { if (grid[n.GetOctave() * MusicTheory.OCTAVE_SIZE + n.GetNoteName().ChromaticIndex - Automatone.LOWEST_NOTE_CHROMATIC_NUMBER, (int)Math.Min(n.GetStartMeasure() * s.MeasureLength + n.GetStartBeat() * Automatone.SUBBEATS_PER_WHOLE_NOTE + i, gridWidth - 1)] == CellState.SILENT) { grid[n.GetOctave() * MusicTheory.OCTAVE_SIZE + n.GetNoteName().ChromaticIndex - Automatone.LOWEST_NOTE_CHROMATIC_NUMBER, (int)Math.Min(n.GetStartMeasure() * s.MeasureLength + n.GetStartBeat() * Automatone.SUBBEATS_PER_WHOLE_NOTE + i, gridWidth - 1)] = CellState.HOLD; } } } } automatone.MeasureLength = s.MeasureLength; return grid; }
public Harmony(MusicTheory theory, Random random, NoteName key, MusicTheory.SCALE_MODE mode) { this.random = random; this.key = key; this.mode = mode; this.seventhChordProbability = InputParameters.Instance.SeventhChordProbability; diatonicScale = createDiatonicScale(); }
public List<List<NoteName>> createChordProgression(int phraseLength, MusicTheory.CADENCE_NAMES cadence) { List<int> intervals = new List<int>(); //Get circle progression int[] circle; MusicTheory.CIRCLE_PROGRESSION.TryGetValue(mode, out circle); //Select last chords of progression based on cadence switch (cadence) { case MusicTheory.CADENCE_NAMES.HALF: intervals.Add(circle[random.Next(circle.Length)]); intervals.Add(4); break; case MusicTheory.CADENCE_NAMES.PERFECT_AUTHENTIC: intervals.Add(4); intervals.Add(0); break; case MusicTheory.CADENCE_NAMES.IMPERFECT_AUTHENTIC: intervals.Add(6); intervals.Add(0); break; case MusicTheory.CADENCE_NAMES.PLAGAL: intervals.Add(3); intervals.Add(0); break; case MusicTheory.CADENCE_NAMES.DECEPTIVE: intervals.Add(4); intervals.Add(circle[random.Next(1, circle.Length)]); break; default: intervals.Add(0); break; } //Add chords to progression to fill phrase while (intervals.Count < phraseLength) { intervals.Insert(0, circle[(circle.ToList<int>().IndexOf(intervals.First<int>()) + circle.Length - (random.NextDouble() < 0.1 ? 0 : 1)) % circle.Length]); } //Trim progression to fit phrase while (intervals.Count > phraseLength) { intervals.RemoveAt(0); } //Build chord progression List<List<NoteName>> progression = new List<List<NoteName>>(); foreach (int i in intervals) { progression.Add(createChord(diatonicScale.ElementAt<NoteName>(i), (random.NextDouble() > seventhChordProbability ? new int[] { 2, 4 } : new int[] { 2, 4, 6 }))); } return progression; }
public Part(MusicTheory theory, Random rand, Rhythm rhythm, int rhythmNumber, Melody melody, int melodyNumber, int measureLength, double rhythmCrowdedness, double noteLengthAdjustment, double regularity, int lowerPitchLimit, int octaveRange, bool forceChord, bool forceDiatonic) : this(theory, rand, rhythm, rhythmNumber, melody, melodyNumber, measureLength) { this.rhythmCrowdedness = rhythmCrowdedness; this.noteLengthAdjustment = noteLengthAdjustment; this.regularity = regularity; this.lowerPitchLimit = lowerPitchLimit; this.octaveRange = octaveRange; this.forceChord = forceChord; this.forceDiatonic = forceDiatonic; }
public Part(MusicTheory theory, Random rand, Rhythm rhythm, int rhythmNumber, Melody melody, int melodyNumber, int measureLength) { //Get instance of InputParameters InputParameters inputParameters = InputParameters.Instance; this.theory = theory; this.rand = rand; this.rhythm = rhythm; this.rhythmNumber = rhythmNumber; this.melody = melody; this.melodyNumber = melodyNumber; this.measureLength = measureLength; //Set rhythm crowdedness based on input parameters rhythmCrowdedness = inputParameters.MeanPartRhythmCrowdedness + (inputParameters.MeanPartRhythmCrowdedness * (rand.NextDouble() - 0.5) * inputParameters.PartRhythmCrowdednessVariance); //Set note length adjustment based on input parameters noteLengthAdjustment = 0.5 + (0.5 * (rand.NextDouble() - 0.5) * inputParameters.PartNoteLengthVariance); //Set octave range based on input parameters octaveRange = (int)Math.Round(theory.PART_OCTAVE_RANGE * inputParameters.MeanPartOctaveRange); octaveRange += (int)Math.Round(octaveRange * (rand.NextDouble() - 0.5) * inputParameters.PartOctaveRangeVariance); octaveRange = (int)MathHelper.Clamp(octaveRange, 1, Automatone.PIANO_SIZE / 12); //Set random lower pitch limit lowerPitchLimit = rand.Next(Automatone.PIANO_SIZE - (octaveRange * MusicTheory.OCTAVE_SIZE)) + Automatone.LOWEST_NOTE_CHROMATIC_NUMBER; forceChord = false; forceDiatonic = false; //Set regularity based on input parameters regularity = 0; if (rand.NextDouble() < inputParameters.BeatDefinition) { forceChord = true; regularity = rand.NextDouble(); } }