コード例 #1
0
ファイル: MusicTheoryServices.cs プロジェクト: cwelt/Soloist
        /// <inheritdoc cref="GetNotes(IChord, ChordNoteMappingSource, NotePitch, NotePitch)"/>
        internal static IEnumerable <NotePitch> GetNotes(IChord chord, ChordNoteMappingSource mappingSource, int minOctave = 0, int maxOctave = 9)
        {
            int       basePitch = MusicTheoryServices.SemitonesInOctave;
            NotePitch minPitch  = (NotePitch)(basePitch + (minOctave * MusicTheoryServices.SemitonesInOctave));
            NotePitch maxPitch  = (NotePitch)(basePitch + ((maxOctave + 1) * MusicTheoryServices.SemitonesInOctave) - 1);

            return(MusicTheoryServices.GetNotes(chord, mappingSource, minPitch, maxPitch));
        }
コード例 #2
0
ファイル: MusicTheoryServices.cs プロジェクト: cwelt/Soloist
        /// <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);
        }