private Phrase GenratePhraseBasic(int noteCount) { var phrase = new Phrase(); var selectedNotes = (from onoffProbability in _probabilities let noteOn = GetRandomBool(onoffProbability.OnOffChance) where noteOn select onoffProbability).ToList(); while (selectedNotes.Count > noteCount) { var leastPopularNote = selectedNotes.OrderBy(x => x.OnOffChance).FirstOrDefault(); selectedNotes.Remove(leastPopularNote); } while (selectedNotes.Count < noteCount) { var mostPopularNote = _probabilities.Except(selectedNotes) .OrderByDescending(x => x.OnOffChance) .FirstOrDefault(); selectedNotes.Add(mostPopularNote); } selectedNotes = selectedNotes.Where(x => x != null).ToList(); selectedNotes = selectedNotes.OrderBy(x => x.Position).ToList(); foreach (var note in selectedNotes) { var randomNote = GetRandomNote(note.Notes); phrase.Elements.Add(new PhraseElement { Position = note.Position, Duration = 1, Note = randomNote }); } phrase.Elements.RemoveAll(x => x.Position >= _riffLength); PhraseHelper.UpdateDurationsFromPositions(phrase, _riffLength); return(phrase); }
public Phrase GeneratePhrase(string baseRiff = "") { var riffs = _riffs.OrderBy(x => _random.NextDouble()).Take(_numberOfRiffsToMerge).ToList(); if (baseRiff != "") { var riff = _riffs.Where(x => x.Description.ToLower() == baseRiff.ToLower()).ToList(); if (riff.Count == 1) { riffs = riffs.Except(riff).Take(_numberOfRiffsToMerge - 1).ToList(); riffs.InsertRange(0, riff); } } GenerateRiffProbabilities(riffs); var noteCount = GetNumberOfNotes(); var phrase = GenratePhraseBasic(noteCount); var perfectRepeats = GetPerfectRepeats(); var timingRepeats = GetTimingRepeats(perfectRepeats); var repeats = perfectRepeats.Union(timingRepeats) .OrderBy(x => x.WindowSize) .ThenBy(x => x.WindowStart) .ThenBy(x => x.MatchWindowStart) .ToList(); foreach (var repeat in repeats) { var sectionStartPositions = new List <decimal> { repeat.WindowStart, repeat.WindowStart + repeat.WindowSize, repeat.MatchWindowStart, repeat.MatchWindowStart + repeat.WindowSize }; foreach (var position in sectionStartPositions) { var element = phrase.Elements.FirstOrDefault(x => x.Position == position); if (element != null) { continue; } element = GetNewRandomElement(position); if (element != null) { phrase.Elements.Add(element); } } } foreach (var repeat in repeats) { phrase.Elements.RemoveAll(x => x.Position >= repeat.MatchWindowStart && x.Position < repeat.MatchWindowStart + repeat.WindowSize); var repeatingElements = phrase .Elements .Where(x => x.Position >= repeat.WindowStart && x.Position < repeat.WindowStart + repeat.WindowSize) .Select(x => x.Clone()) .ToList(); foreach (var element in repeatingElements) { element.Position = element.Position - repeat.WindowStart + repeat.MatchWindowStart; if (repeat.MatchType != RepeatingElementsFinder.MatchResult.TimingMatch) { continue; } var probability = _probabilities.FirstOrDefault(x => x.Position == element.Position); if (probability != null) { element.Note = GetRandomNote(probability.Notes); } } phrase.Elements.AddRange(repeatingElements); } phrase.Elements = phrase.Elements.OrderBy(x => x.Position).ToList(); phrase.Elements.RemoveAll(x => x.Position >= _riffLength); PhraseHelper.UpdateDurationsFromPositions(phrase, _riffLength); phrase.Bpm = 60; var lowNote = phrase.Elements.Min(x => x.Note); if (lowNote <= NoteHelper.NoteToNumber("C2")) { NoteHelper.ShiftNotesDirect(phrase, 1, Interval.Octave, Direction.Up); } return(phrase); }