Пример #1
0
        /// <summary>
        /// Reverses the order of a sequence of notes for a randomly selected
        /// chord in the given bar, or in a randomly selected bar if <paramref name="barIndex"/> is null.
        /// <para> The revese operation is made in place locally to the selected chord.
        /// The chord notes are determined by the logic in
        /// <see cref="Bar.GetOverlappingNotesForChord(IChord, out IList{int})"/>.</para>
        /// </summary>
        /// <param name="melody"> The candidate melody to operate on.</param>
        /// <param name="barIndex"> Index of the bar to do the reverse in. If no bar index supplied, then a random bar would be selected. </param>
        private protected virtual void ReverseChordNotesMutation(MelodyCandidate melody, int?barIndex = null)
        {
            // initialize random generator
            Random randomizer = new Random();

            // if no specific bar has been requested then set it randomly
            int  selectedBarIndex = barIndex ?? randomizer.Next(melody.Bars.Count);
            IBar selectedBar      = melody.Bars[selectedBarIndex];

            // select a random chord from within the selected bar
            int    randomChordIndex = randomizer.Next(selectedBar.Chords.Count);
            IChord selectedChord    = selectedBar.Chords[randomChordIndex];

            // create a single chord element sequence
            IChord[] chordsToReverse = new[] { selectedChord };

            // delegate reverse operation to superclass
            PermutateNotes(selectedBar, chordsToReverse, Permutation.Reversed);
        }
        private IChord ModifyChord(IChord chord, params string[] modifications)
        {
            bool prevArgModifiedChord = false;
            int  index = 0;

            do
            {
                var argument = modifications[index].ToLowerInvariant();
                if (argument.StartsWith("sus"))
                {
                    chord.Suspend(Int32.Parse(argument.Substring(3)));
                    prevArgModifiedChord = true;
                }
                if (argument.StartsWith("add"))
                {
                    chord.Add(Int32.Parse(argument.Substring(3)));
                    prevArgModifiedChord = true;
                }
                index++;
            } while (prevArgModifiedChord && index < modifications.Length);
            return(chord);
        }
Пример #3
0
 public bool Equals(IChord other) => ChordDefinition.Equals(other.ChordDefinition) && Key.Equals(other.Key);
Пример #4
0
 public void UpdateChord(IChord chord)
 {
     _chordsRegistry.Update(chord, Owner.FromPrincipal(User));
 }
Пример #5
0
 public IUniqueItem AddChord(IChord chord)
 {
     return(_chordsRegistry.Add(chord, Owner.FromPrincipal(User)));
 }
Пример #6
0
        private (List <IStringInstrumentNotePosition> notePositions, bool isValidChord) IsChord(IChord chord, IList <IStringInstrumentNotePosition> notesPerString)
        {
            var notePositions = new List <IStringInstrumentNotePosition>();

            foreach (var nps in notesPerString)
            {
                if (nps == null)
                {
                    notePositions.Clear();
                }
                else
                {
                    notePositions.Add(nps);
                }
            }

            var isValid = chord.Notes.All(chordNote => notePositions.Any(t => t.Note.Equals(chordNote)));

            return(notePositions, isValid);
        }
Пример #7
0
        private IStringInstrumentChord GetStringInstrumentChord(IStringInstrument stringInstrument, IChord chord)
        {
            var possibilities = new List <IStringInstrumentChordPossibility>();
            var ret           = new StringInstrumentChord();

            ret.Chord = chord;

            // semi tone index.
            for (var sti = 0; sti < stringInstrument.SemiToneCount; sti++)
            {
                // string note index.
                var stringNotePositions = stringInstrument.Strings
                                          .Select(currentString =>
                {
                    var notePositions = stringNotePositionForString(currentString, chord, sti, _typicalFingerSemiToneStretch);
                    return(notePositions);
                })
                                          .ToList();

                stringNotePositions.ForEach(t => t.Insert(0, null));
                var allCombinations  = Combos(stringNotePositions);
                var combinationCases = allCombinations
                                       .Select(t => IsChord(chord, t))
                                       .ToList();

                var tempPossibilities = combinationCases
                                        .Where(t => t.isValidChord)
                                        .Select(t => new StringInstrumentChordPossibility
                {
                    NotePositions = t.notePositions
                });

                possibilities.AddRange(tempPossibilities);
            }

            ret.ChordPossibilities = possibilities
                                     .Aggregate(new List <IStringInstrumentChordPossibility>(), (prev, current) =>
            {
                if (!prev.Any(t => t.Equals(current)))
                {
                    prev.Add(current);
                }
                return(prev);
            });

            return(ret);
        }
Пример #8
0
        /// <summary>
        /// Returns notes that sound "good" under the given chord and pitch range restriction.
        /// </summary>
        /// <param name="chord"> he requested chrod to map the notes against. </param>
        /// <param name="mappingSource"> The mapping source - either scale notes or the chord's arpeggio notes. </param>
        /// <param name="minPitch"> Lower bound pitch range constraint for the mapped notes. </param>
        /// <param name="maxPitch"> Upper bound pitch range constraint for the mapped notes. </param>
        /// <returns> Notes that sound "good" under the given chord, mapping source, and pitch range restriction. </returns>
        internal static IEnumerable <NotePitch> GetNotes(IChord chord, ChordNoteMappingSource mappingSource, NotePitch minPitch, NotePitch maxPitch)
        {
            // build the scale (sequence of intervals from the chord's root note)
            var   rootNote = ConvertToExternalNoteName(chord.ChordRoot);
            Scale scale    = null;

            switch (chord.ChordType)
            {
            case ChordType.Diminished:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Three, Interval.Three, Interval.Six }, rootNote);
                }
                else     // diminished arppeigo with added 9th
                {
                    scale = new Scale(new Interval[] { Interval.One, Interval.Two, Interval.Three, Interval.Six }, rootNote);
                }
                break;

            case ChordType.Dominant7:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Four, Interval.Three, Interval.Three, Interval.Two }, rootNote);
                }
                else     // mixolydian scale with omitted 4th
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.Two, Interval.Three, Interval.Two, Interval.One, Interval.Two }, rootNote);
                }
                break;

            case ChordType.Dominant7b9:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Four, Interval.Three, Interval.Three, Interval.Three, Interval.FromHalfSteps(-1) }, rootNote);
                }
                else     // harmonic minor v scale with 6th omitted
                {
                    scale = new Scale(new Interval[] { Interval.One, Interval.Three, Interval.One, Interval.Two, Interval.Three, Interval.Two }, rootNote);
                }
                break;

            case ChordType.Dominant7Suspended4:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Five, Interval.Two, Interval.Three, Interval.Two }, rootNote);
                }
                else     // mixolydian scale
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.Two, Interval.One, Interval.Two, Interval.Two, Interval.One, Interval.Two }, rootNote);
                }
                break;

            case ChordType.Dominant7Augmented5:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Four, Interval.Four, Interval.Two, Interval.Two }, rootNote);
                }
                else     // whole tone scale
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.Two, Interval.Two, Interval.Two, Interval.Two, Interval.Two }, rootNote);
                }
                break;

            case ChordType.Dominant7Sharped9:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Four, Interval.Three, Interval.Three, Interval.Four, Interval.FromHalfSteps(-3) }, rootNote);
                }
                else     // mixolydian #2 scale with omitted 4th
                {
                    scale = new Scale(new Interval[] { Interval.Three, Interval.One, Interval.Three, Interval.Two, Interval.One, Interval.Two }, rootNote);
                }
                break;

            case ChordType.HalfDiminished:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Three, Interval.Three, Interval.Four, Interval.Two }, rootNote);
                }
                else     // locrian mode scale with ommited 2nd
                {
                    scale = new Scale(new Interval[] { Interval.Three, Interval.Two, Interval.One, Interval.Two, Interval.Two, Interval.Two }, rootNote);
                }
                break;

            case ChordType.Major:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Four, Interval.Three, Interval.Five }, rootNote);
                }
                else     // dorian major scale with omitted 4th and 7th
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.Two, Interval.Three, Interval.Two, Interval.Three }, rootNote);
                }
                break;

            case ChordType.Major7:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Four, Interval.Three, Interval.Four, Interval.One }, rootNote);
                }
                else     // dorian major scale with omitted 4th
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.Two, Interval.Three, Interval.Two, Interval.Two, Interval.One }, rootNote);
                }
                break;

            case ChordType.MajorAugmented5:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Four, Interval.Four, Interval.Four }, rootNote);
                }
                else     // lydian augmented scale
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.Two, Interval.Two, Interval.Two, Interval.One, Interval.Two, Interval.One }, rootNote);
                }
                break;

            case ChordType.MajorSuspended4:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Five, Interval.Two, Interval.Five }, rootNote);
                }
                else     // mixolydian scale
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.Two, Interval.One, Interval.Two, Interval.Two, Interval.One, Interval.Two }, rootNote);
                }
                break;

            case ChordType.Minor:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Three, Interval.Four, Interval.Five }, rootNote);
                }
                else     // aeolian minor scale with omitted 2nd and 6th
                {
                    scale = new Scale(new Interval[] { Interval.Three, Interval.Two, Interval.Two, Interval.Three, Interval.Two }, rootNote);
                }
                break;

            case ChordType.Minor6:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Three, Interval.Four, Interval.Two, Interval.Three }, rootNote);
                }
                else     // dorian minor scale with omitted 7th
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.One, Interval.Two, Interval.Two, Interval.Two, Interval.Three }, rootNote);
                }
                break;

            case ChordType.Minor7:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Three, Interval.Four, Interval.Three, Interval.Two }, rootNote);
                }
                else     // aeolian minor scale with omitted 6th
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.One, Interval.Two, Interval.Two, Interval.Three, Interval.Two }, rootNote);
                }
                break;

            case ChordType.MinorMajor7:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Three, Interval.Four, Interval.Four, Interval.One }, rootNote);
                }
                else     // harmonic minor scale
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.One, Interval.Two, Interval.Two, Interval.One, Interval.Three, Interval.One }, rootNote);
                }
                break;

            case ChordType.Major13:
                if (mappingSource == ChordNoteMappingSource.Chord)
                {
                    scale = new Scale(new Interval[] { Interval.Four, Interval.Three, Interval.Two, Interval.Three }, rootNote);
                }
                else     // dorian major scale with omitted 4th and 7th
                {
                    scale = new Scale(new Interval[] { Interval.Two, Interval.Two, Interval.Three, Interval.Two, Interval.Three }, rootNote);
                }
                break;

            default:
                break;
            }

            // get actual notes and filter out results according to range constraints
            var result = from note in scale.GetNotes()
                         where (int)note.NoteNumber >= (byte)minPitch && (int)note.NoteNumber <= (byte) maxPitch
                         select(NotePitch)(int) note.NoteNumber;

            return(result);
        }
Пример #9
0
 public IUniqueItem Add(IChord item, IUser owner)
 {
     throw new NotImplementedException();
 }
Пример #10
0
 public void Update(IChord item, IUser owner)
 {
     throw new NotImplementedException();
 }
Пример #11
0
 public IReadOnlyList <IChordTarget> GetItemsByChord(IChord chord)
 {
     throw new ArgumentException("Unable to find requested items: fake registry is always empty!", nameof(chord));
 }