コード例 #1
0
 /// <summary>
 /// Add an interval to this representation.
 /// </summary>
 /// <param name="interval">The interval to add.</param>
 /// <param name="direction">Which direction to go - up or down.</param>
 /// <returns>Null if there is no supported enharmonically correct representation of the requested interval.  For example,
 /// adding a minor second to a Bb should return a Cb, but this is not supported so the result will be null.  If there is
 /// a valid representation (for example, A# plus a minor second correctly yields B) it will be returned.</returns>
 public NoteRepresentation AddInterval(Interval interval, IntervalDirection direction = IntervalDirection.Up)
 {
     var coefficient = direction == IntervalDirection.Up ? 1 : -1;
     var newNoteNumber = this.Note.Number + (interval.NumberOfSemitones() * coefficient);
     var newNoteName = this.Name.AddNoteNames(interval.NumberOfNoteNames() * coefficient);
     var result = new Note(newNoteNumber).GetRepresentations().SingleOrDefault(r => r.Name == newNoteName);
     return result;
 }
コード例 #2
0
        public Interval(int pitch, bool isInTonality)
        {
            Interval i = Interval.fromPitch(pitch, isInTonality);

            this.distance  = i.distance;
            this.mode      = i.mode;
            this.direction = i.direction;
        }
コード例 #3
0
        public Interval(int pitch)
        {
            Interval i = Interval.fromPitch(pitch, true);

            this.distance  = i.distance;
            this.mode      = i.mode;
            this.direction = i.direction;
        }
コード例 #4
0
        /// <summary>
        /// Returns an <see cref="IntervalDefinition"/> by the specified half steps number and
        /// interval's direction.
        /// </summary>
        /// <param name="interval">The interval as a number of half steps away.</param>
        /// <param name="direction">The direction of an interval (up or down).</param>
        /// <returns>An <see cref="IntervalDefinition"/> with the specified interval and direction.</returns>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="direction"/> specified an
        /// invalid value.</exception>
        public static IntervalDefinition Get(SevenBitNumber interval, IntervalDirection direction)
        {
            ThrowIfArgument.IsInvalidEnumValue(nameof(direction), direction);

            if (!_cache.TryGetValue(interval, out Dictionary <IntervalDirection, IntervalDefinition> intervalDefinitions))
            {
                _cache.Add(interval, intervalDefinitions = new Dictionary <IntervalDirection, IntervalDefinition>());
            }

            if (!intervalDefinitions.TryGetValue(direction, out IntervalDefinition intervalDefinition))
            {
                intervalDefinitions.Add(direction, intervalDefinition = new IntervalDefinition(interval, direction));
            }

            return(intervalDefinition);
        }
コード例 #5
0
        /// <summary>
        /// Returns an <see cref="Interval"/> by the specified half steps number and
        /// interval's direction.
        /// </summary>
        /// <param name="intervalSize">The size of an interval as a number of half steps away.</param>
        /// <param name="direction">The direction of an interval (up or down).</param>
        /// <returns>An <see cref="Interval"/> with the specified interval and direction.</returns>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="direction"/> specified an
        /// invalid value.</exception>
        public static Interval Get(SevenBitNumber intervalSize, IntervalDirection direction)
        {
            ThrowIfArgument.IsInvalidEnumValue(nameof(direction), direction);

            Dictionary <IntervalDirection, Interval> intervals;

            if (!_cache.TryGetValue(intervalSize, out intervals))
            {
                _cache.Add(intervalSize, intervals = new Dictionary <IntervalDirection, Interval>());
            }

            Interval cachedInterval;

            if (!intervals.TryGetValue(direction, out cachedInterval))
            {
                intervals.Add(direction, cachedInterval = new Interval(intervalSize, direction));
            }

            return(cachedInterval);
        }
コード例 #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Interval"/> with the
 /// specified interval and its direction.
 /// </summary>
 /// <param name="size">The size of interval as a number of half steps away.</param>
 /// <param name="direction">The direction of an interval (up or down).</param>
 private Interval(SevenBitNumber size, IntervalDirection direction)
 {
     Size      = size;
     Direction = direction;
 }
コード例 #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="IntervalDefinition"/> with the
 /// specified interval and its direction.
 /// </summary>
 /// <param name="interval">The interval as a number of half steps away.</param>
 /// <param name="direction">The direction of an interval (up or down).</param>
 private IntervalDefinition(SevenBitNumber interval, IntervalDirection direction)
 {
     Interval  = interval;
     Direction = direction;
 }
コード例 #8
0
        private static Interval fromPitch(int pitch, bool isInTonality)
        {
            //Calculate direction

            IntervalDirection direction = IntervalDirection.INCREASING;

            if (pitch < 0)
            {
                pitch     = -pitch;
                direction = IntervalDirection.DECREASING;
            }

            //Reduce pitch change to 1 octave

            int octave = 0;

            while (pitch >= Note.PITCH_OCTAVE)
            {
                pitch -= Note.PITCH_OCTAVE;
                octave++;
            }

            switch (pitch)
            {
            case 0: return(new Interval(
                               1 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.PERFECT,
                               direction
                               ));

            case 1: return(new Interval(
                               2 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.MINOR,
                               direction
                               ));

            case 2: return(new Interval(
                               2 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.MAJOR,
                               direction
                               ));

            case 3: if (isInTonality)
                {
                    return(new Interval(
                               3 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.MINOR,
                               direction
                               ));
                }
                else
                {
                    return(new Interval(
                               2 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.AUGMENTED,
                               direction
                               ));
                }

            case 4: if (isInTonality)
                {
                    return(new Interval(
                               3 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.MAJOR,
                               direction
                               ));
                }
                else
                {
                    return(new Interval(
                               4 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.DIMINISHED,
                               direction
                               ));
                }

            case 5: return(new Interval(
                               4 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.PERFECT,
                               direction
                               ));

            case 6: return(new Interval(
                               5 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.DIMINISHED,
                               direction
                               ));

            case 7: return(new Interval(
                               5 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.PERFECT,
                               direction
                               ));

            case 8: if (isInTonality)
                {
                    return(new Interval(
                               6 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.MINOR,
                               direction
                               ));
                }
                else
                {
                    return(new Interval(
                               5 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.AUGMENTED,
                               direction
                               ));
                }

            case 9: if (isInTonality)
                {
                    return(new Interval(
                               6 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.MAJOR,
                               direction
                               ));
                }
                else
                {
                    return(new Interval(
                               7 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.DIMINISHED,
                               direction
                               ));
                }

            case 10: if (isInTonality)
                {
                    return(new Interval(
                               7 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.MINOR,
                               direction
                               ));
                }
                else
                {
                    return(new Interval(
                               6 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.AUGMENTED,
                               direction
                               ));
                }

            case 11: if (isInTonality)
                {
                    return(new Interval(
                               7 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.MAJOR,
                               direction
                               ));
                }
                else
                {
                    return(new Interval(
                               7 + octave * Interval.INTERVAL_OCTAVE,
                               IntervalMode.MAJOR,
                               direction
                               ));
                }

            default: return(null);
            }
        }
コード例 #9
0
 public Interval(int distance, IntervalMode mode, IntervalDirection direction)
 {
     this.distance  = distance;
     this.mode      = mode;
     this.direction = direction;
 }
コード例 #10
0
        public void invert(bool invertDistance, bool invertMode, bool invertDirection)
        {
            if (invertDistance)
            {
                int octave  = 0;
                int newDist = this.distance;

                //Reduce to 1 octave
                while (newDist > Interval.INTERVAL_OCTAVE + 1)
                {
                    newDist -= Interval.INTERVAL_OCTAVE;
                    octave++;
                }

                //Inversion:
                // - newDist : 1-7
                // - if 1: inverted interval is 1
                // - if 2-7: inverted is 7-2 (9-newDist)
                if (newDist > 1)
                {
                    newDist = 9 - newDist;
                }

                // Recover octave
                newDist += Interval.INTERVAL_OCTAVE * octave;

                this.distance = newDist;
            }

            if (invertMode)
            {
                switch (this.mode)
                {
                case IntervalMode.DIMINISHED:
                    this.mode = IntervalMode.AUGMENTED;
                    break;

                case IntervalMode.AUGMENTED:
                    this.mode = IntervalMode.DIMINISHED;
                    break;

                case IntervalMode.MAJOR:
                    this.mode = IntervalMode.MINOR;
                    break;

                case IntervalMode.MINOR:
                    this.mode = IntervalMode.MAJOR;
                    break;

                case IntervalMode.PERFECT:     //do nothing
                    break;
                }
            }

            if (invertDirection)
            {
                if (this.direction == IntervalDirection.DECREASING)
                {
                    this.direction = IntervalDirection.INCREASING;
                }
                else
                {
                    this.direction = IntervalDirection.DECREASING;
                }
            }
        }