Пример #1
0
		public IntervalPattern( IntervalQuality quality, IntervalQuantity quantity = IntervalQuantity.Unison)
		{
			this.quantity = quantity;
			this.semitones = GetSemitones();
			this.quality = quality;

		}
Пример #2
0
        /// <summary>
        /// Gets an instance of the <see cref="Interval"/> by the specified interval quality and number.
        /// </summary>
        /// <param name="intervalQuality">Interval quality.</param>
        /// <param name="intervalNumber">Interval number.</param>
        /// <returns>An instance of the <see cref="Interval"/> which represents <paramref name="intervalNumber"/>
        /// along with <paramref name="intervalQuality"/>.</returns>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="intervalQuality"/> specified an
        /// invalid value.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="intervalNumber"/> is less than 1.</exception>
        /// <exception cref="ArgumentException"><paramref name="intervalQuality"/> is not applicable to
        /// <paramref name="intervalNumber"/>.</exception>
        public static Interval Get(IntervalQuality intervalQuality, int intervalNumber)
        {
            ThrowIfArgument.IsInvalidEnumValue(nameof(intervalQuality), intervalQuality);
            ThrowIfArgument.IsLessThan(nameof(intervalNumber), intervalNumber, 1, "Interval number is less than 1.");

            if (!IsQualityApplicable(intervalQuality, intervalNumber))
            {
                throw new ArgumentException($"{intervalQuality} quality is not applicable to interval number of {intervalNumber}.", nameof(intervalQuality));
            }

            var maxIntervalNumber = 8;

            if (intervalQuality == IntervalQuality.Minor || intervalQuality == IntervalQuality.Major || intervalQuality == IntervalQuality.Augmented)
            {
                maxIntervalNumber = 7;
            }

            var result = intervalNumber > maxIntervalNumber
                ? ((intervalNumber - 1) / 7) * Octave.OctaveSize
                : 0;

            var additionalNumber = intervalNumber;

            if (intervalNumber > maxIntervalNumber)
            {
                additionalNumber = ((intervalNumber - 1) % 7) + 1;
            }

            var halfTones = IntervalsHalfTones[intervalQuality];

            result += halfTones[additionalNumber];

            return(FromHalfSteps(result));
        }
Пример #3
0
        public IntervalMatch CanBeCalled(IntervalQuality quality, int size)
        {
            int targetSemitones       = GetSemitonesInInterval(quality, size);
            int thisIntervalSemitones = Math.Abs(note1 - note2);

            if (targetSemitones == thisIntervalSemitones)
            {
                return(IntervalMatch.ExactMatch);
            }

            // not an exact match; reduce both intervals to less than an octave
            targetSemitones       = targetSemitones % 12;
            thisIntervalSemitones = thisIntervalSemitones % 12;
            if (targetSemitones == thisIntervalSemitones)
            {
                return(IntervalMatch.UninvertedMatch);
            }

            // still not a match; invert one of the intervals as a last try
            thisIntervalSemitones = 12 - thisIntervalSemitones;
            if (targetSemitones == thisIntervalSemitones)
            {
                return(IntervalMatch.InvertedMatch);
            }

            return(IntervalMatch.NoMatch);
        }
Пример #4
0
        public void Test_GetByInterval(Interval interval, IntervalQuality intervalQuality, Key inputKey, Alteration inputAlteration, Key expectedKey, Alteration expectedAlteration)
        {
            var result = _noteService.GetByInterval(new Note(inputKey, inputAlteration), interval, intervalQuality);

            Assert.That(result.Key, Is.EqualTo(expectedKey));
            Assert.That(result.Alteration, Is.EqualTo(expectedAlteration));
        }
Пример #5
0
        public Interval Diminish()
        {
            IntervalQuality quality      = _quality;
            sbyte           multiplicity = _multiplicity;

            if (quality == IntervalQuality.Augmented)
            {
                multiplicity--;
                if (multiplicity == 0)
                {
                    quality = Number.IsPerfect() ? IntervalQuality.Perfect : IntervalQuality.Major;
                }
            }
            else if (quality == IntervalQuality.Perfect || quality == IntervalQuality.Minor)
            {
                multiplicity++;
                quality = IntervalQuality.Diminished;
            }
            else if (quality == IntervalQuality.Major)
            {
                quality = IntervalQuality.Minor;
            }
            else
            {
                multiplicity++;
            }

            return(new Interval(_absoluteNumber, quality, multiplicity));
        }
Пример #6
0
        public void Parse_QualityNumber(string input, IntervalQuality expectedIntervalQuality, int expectedIntervalNumber)
        {
            var parsedInterval   = Interval.Parse(input);
            var expectedInterval = Interval.Get(expectedIntervalQuality, expectedIntervalNumber);

            Assert.AreEqual(expectedInterval, parsedInterval, "Parsed interval is invalid.");
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="IntervalDefinition"/> with the specified
        /// interval number and quality.
        /// </summary>
        /// <param name="number">Interval number.</param>
        /// <param name="quality">Interval quality.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="number"/> is less than 1.</exception>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="quality"/> specified an invalid value.</exception>
        public IntervalDefinition(int number, IntervalQuality quality)
        {
            ThrowIfArgument.IsLessThan(nameof(number), number, 1, "Interval number is less than 1.");
            ThrowIfArgument.IsInvalidEnumValue(nameof(quality), quality);

            Number  = number;
            Quality = quality;
        }
Пример #8
0
        private static int QualitySize(IntervalQuality quality, int number)
        {
            switch ((Math.Abs(number) - 1) % 7 + 1)
            {
            case 1:
            case 4:
            case 5:
                switch (quality)
                {
                case IntervalQuality.Diminished:
                    return(-1);

                case IntervalQuality.Minor:
                    throw new InvalidEnumArgumentException("Invalid quality for interval. Quality: " + quality + " Interval: " + number);

                case IntervalQuality.Perfect:
                    return(0);

                case IntervalQuality.Major:
                    throw new InvalidEnumArgumentException("Invalid quality for interval. Quality: " + quality + " Interval: " + number);

                case IntervalQuality.Augmented:
                    return(1);

                default:
                    throw new Exception("Should not be possible");
                }

            case 2:
            case 3:
            case 6:
            case 7:
                switch (quality)
                {
                case IntervalQuality.Diminished:
                    return(-2);

                case IntervalQuality.Minor:
                    return(-1);

                case IntervalQuality.Perfect:
                    throw new InvalidEnumArgumentException("Invalid quality for interval. Quality: " + quality + " Interval: " + number);

                case IntervalQuality.Major:
                    return(0);

                case IntervalQuality.Augmented:
                    return(1);

                default:
                    throw new Exception("Should not be possible");
                }

            default:
                throw new Exception("Should not be possible");
            }
        }
Пример #9
0
        public Note GetByInterval(Note startNote, Interval interval, IntervalQuality intervalQuality)
        {
            var targetKey = _keyService.GetByInterval(startNote.Key, interval);
            var halfStepCountBetweenStartNoteAndTargetKey = (_keyService.GetHalfStepCountBetweenTwoKey(startNote.Key, targetKey) - (int)startNote.Alteration);
            var targetHalfStepCount           = GetHalfStepCountFromInterval(interval, intervalQuality);
            var neededAlterationHalfStepCount = targetHalfStepCount - halfStepCountBetweenStartNoteAndTargetKey;
            var alteration = (Alteration)(neededAlterationHalfStepCount);

            return(new Note(targetKey, alteration));
        }
Пример #10
0
        /// <remarks>interval number is zero based, thus a second interval has a number of 1</remarks>
        public Interval(int number, IntervalQuality quality)
        {
            if (!Interval.IsValid(number, quality))
            {
                throw new ArgumentException("Number and quality mismatch");
            }

            this.Number  = number;
            this.Quality = quality;
        }
Пример #11
0
        public static int GetSemitonesInInterval(IntervalQuality quality, int size)
        {
            int zeroBasedSize    = size - 1;
            int octaveOffset     = (zeroBasedSize / 7) * 12;
            int baseInterval     = zeroBasedSize % 7;
            int baseIntervalSize = intervalTable[baseInterval, (int)quality];

            if (baseIntervalSize == -9)
            {
                throw new InvalidIntervalException();
            }

            return(octaveOffset + baseIntervalSize);
        }
Пример #12
0
        /// <remarks>interval number is zero based, thus a second interval has a number of 1</remarks>
        public static bool IsValid(int number, IntervalQuality quality)
        {
            if (number < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(number));
            }

            var normalizedNumber = number % 7;

            if (normalizedNumber == 0 || normalizedNumber == 3 || normalizedNumber == 4)
            {
                return(quality != IntervalQuality.Major && quality != IntervalQuality.Minor);
            }
            else
            {
                return(quality != IntervalQuality.Perfect);
            }
        }
Пример #13
0
        public Interval(int absoluteNumber, IntervalQuality quality, sbyte multiplicity = 0)
        {
            var number = GetNumber(absoluteNumber);

            if (number.IsPerfect())
            {
                if (quality == IntervalQuality.Minor || quality == IntervalQuality.Major)
                {
                    throw new ArgumentException(null, nameof(quality));
                }
            }
            else
            {
                if (quality == IntervalQuality.Perfect)
                {
                    throw new ArgumentException(null, nameof(quality));
                }
            }

            if (quality < IntervalQuality.Diminished || quality > IntervalQuality.Augmented)
            {
                throw new ArgumentOutOfRangeException(nameof(quality));
            }

            if (quality == IntervalQuality.Diminished || quality == IntervalQuality.Augmented)
            {
                if (multiplicity <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(multiplicity));
                }
            }
            else
            {
                if (multiplicity != 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(multiplicity));
                }
            }

            _absoluteNumber = absoluteNumber;
            _quality        = quality;
            _multiplicity   = multiplicity;
        }
Пример #14
0
        public Interval(int number, IntervalQuality quality)
        {
            Direction = number >= 0;
            Number    = number;

            Quality            = quality;
            noteNumQualitySize = QualitySize(quality, number);
            HalfTones          = 0;

            number = Math.Abs(number);
            while (number > 7)
            {
                HalfTones += 12;
                number    -= 7;
            }
            HalfTones += INTERVAL_LENGTHS[number - 1];
            HalfTones += noteNumQualitySize;
            if (!Direction)
            {
                HalfTones *= -1;
            }
        }
Пример #15
0
        private static int GetSemitones(IntervalNumber number, IntervalQuality quality, sbyte multiplicity)
        {
            int semitones = s_numberToSemitones[number - IntervalNumber.Unison];

            if (quality == IntervalQuality.Minor || quality == IntervalQuality.Diminished && !number.IsPerfect())
            {
                semitones--;
            }

            if (multiplicity > 0)
            {
                if (quality == IntervalQuality.Augmented)
                {
                    semitones += multiplicity;
                }
                else
                {
                    semitones -= multiplicity;
                }
            }

            return(semitones);
        }
Пример #16
0
        private static string QualityToString(IntervalQuality quality)
        {
            switch (quality)
            {
            case IntervalQuality.Diminished:
                return("d");

            case IntervalQuality.Minor:
                return("m");

            case IntervalQuality.Perfect:
                return("P");

            case IntervalQuality.Major:
                return("M");

            case IntervalQuality.Augmented:
                return("A");

            default:
                throw new Exception("Should not be possible.");
            }
        }
Пример #17
0
        /// <summary>
        /// Gets a value indicating whether quality is applicable to the specified interval number (1 and greater) or not.
        /// </summary>
        /// <param name="intervalQuality">Interval quality to check whether it's applicable to
        /// <paramref name="intervalNumber"/> or not.</param>
        /// <param name="intervalNumber">Interval number to check whether <paramref name="intervalQuality"/> is
        /// applicable to it or not.</param>
        /// <returns>true if <paramref name="intervalQuality"/> is applicable to <paramref name="intervalNumber"/>;
        /// otherwise, false.</returns>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="intervalQuality"/> specified an
        /// invalid value.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="intervalNumber"/> is less than 1.</exception>
        public static bool IsQualityApplicable(IntervalQuality intervalQuality, int intervalNumber)
        {
            ThrowIfArgument.IsInvalidEnumValue(nameof(intervalQuality), intervalQuality);
            ThrowIfArgument.IsLessThan(nameof(intervalNumber), intervalNumber, 1, "Interval number is less than 1.");

            switch (intervalQuality)
            {
            case IntervalQuality.Perfect:
                return(IsPerfect(intervalNumber));

            case IntervalQuality.Minor:
            case IntervalQuality.Major:
                return(!IsPerfect(intervalNumber));

            case IntervalQuality.Diminished:
                return(intervalNumber >= 2);

            case IntervalQuality.Augmented:
                return(true);
            }

            return(false);
        }
Пример #18
0
 internal IntervalTableItem(int chromaticDegree, int scaleDegree, IntervalQuality intervalType)
 {
     ChromaticDegree = chromaticDegree;
     ScaleDegree     = scaleDegree;
     IntervalQuality = intervalType;
 }
Пример #19
0
 public Interval(IntervalNumber number, IntervalQuality quality, sbyte multiplicity = 0)
     : this(IntervalNumber.Unison <= number && number <= IntervalNumber.Octave ? number - IntervalNumber.Unison : throw new ArgumentOutOfRangeException(nameof(number)),
            quality, multiplicity)
 {
 }
Пример #20
0
 public static string GetSign(this IntervalQuality quality, int multiciplity = 0)
 {
     return(new string(s_qualitySigns[quality - IntervalQuality.Diminished], Math.Max(multiciplity, 1)));
 }
Пример #21
0
        private int GetHalfStepCountFromInterval(Interval interval, IntervalQuality intervalQuality)
        {
            switch (interval)
            {
            case Interval.Second:
                switch (intervalQuality)
                {
                case IntervalQuality.Major:
                    return(2);

                case IntervalQuality.Minor:
                    return(1);

                case IntervalQuality.Augmented:
                    return(3);

                case IntervalQuality.Diminished:
                    return(0);

                case IntervalQuality.Perfect:
                    throw new NotExistingIntervalException($"Interval {interval} {intervalQuality} does not exist");

                default:
                    throw new ArgumentOutOfRangeException(nameof(intervalQuality), intervalQuality, null);
                }

            case Interval.Third:
                switch (intervalQuality)
                {
                case IntervalQuality.Major:
                    return(4);

                case IntervalQuality.Minor:
                    return(3);

                case IntervalQuality.Augmented:
                    return(5);

                case IntervalQuality.Diminished:
                    return(2);

                case IntervalQuality.Perfect:
                    throw new NotExistingIntervalException($"Interval {interval} {intervalQuality} does not exist");

                default:
                    throw new ArgumentOutOfRangeException(nameof(intervalQuality), intervalQuality, null);
                }

            case Interval.Fourth:
                switch (intervalQuality)
                {
                case IntervalQuality.Perfect:
                    return(5);

                case IntervalQuality.Augmented:
                    return(6);

                case IntervalQuality.Diminished:
                    return(4);

                case IntervalQuality.Major:
                case IntervalQuality.Minor:
                    throw new NotExistingIntervalException($"Interval {interval} {intervalQuality} does not exist");

                default:
                    throw new ArgumentOutOfRangeException(nameof(intervalQuality), intervalQuality, null);
                }

            case Interval.Fifth:
                switch (intervalQuality)
                {
                case IntervalQuality.Perfect:
                    return(7);

                case IntervalQuality.Augmented:
                    return(8);

                case IntervalQuality.Diminished:
                    return(6);

                case IntervalQuality.Major:
                case IntervalQuality.Minor:
                    throw new NotExistingIntervalException($"Interval {interval} {intervalQuality} does not exist");

                default:
                    throw new ArgumentOutOfRangeException(nameof(intervalQuality), intervalQuality, null);
                }

            case Interval.Sixth:
                switch (intervalQuality)
                {
                case IntervalQuality.Major:
                    return(9);

                case IntervalQuality.Minor:
                    return(8);

                case IntervalQuality.Augmented:
                    return(10);

                case IntervalQuality.Diminished:
                    return(7);

                case IntervalQuality.Perfect:
                    throw new NotExistingIntervalException($"Interval {interval} {intervalQuality} does not exist");

                default:
                    throw new ArgumentOutOfRangeException(nameof(intervalQuality), intervalQuality, null);
                }

            case Interval.Seventh:
                switch (intervalQuality)
                {
                case IntervalQuality.Major:
                    return(11);

                case IntervalQuality.Minor:
                    return(10);

                case IntervalQuality.Augmented:
                    return(12);

                case IntervalQuality.Diminished:
                    return(9);

                case IntervalQuality.Perfect:
                    throw new NotExistingIntervalException($"Interval {interval} {intervalQuality} does not exist");

                default:
                    throw new ArgumentOutOfRangeException(nameof(intervalQuality), intervalQuality, null);
                }

            default:
                throw new ArgumentOutOfRangeException(nameof(interval), interval, null);
            }
        }
Пример #22
0
        public static Interval GetC4BasedInterval(IntervalQuality quality, IntervalQuantity quantity)
        {
            var C4 = new Pitch(new Step(StepLetter.C));
            switch (quantity)
            {
                case IntervalQuantity.Unison:
                    if (quality == IntervalQuality.Perfect) return new Interval(C4, C4);
                    else throw new ArgumentException(string.Format(exceptionFormatString, quantity, quality));
                    break;
                case IntervalQuantity.Second:
                    if (quality == IntervalQuality.Minor) return new Interval(C4, new Pitch(new Step(StepLetter.D), accidental: Accidentals.Flat));
                    if (quality == IntervalQuality.Major) return new Interval(C4, new Pitch(new Step(StepLetter.D)));
                    if (quality == IntervalQuality.Augmented) return new Interval(C4, new Pitch(new Step(StepLetter.D), accidental: Accidentals.Sharp));
                    if (quality == IntervalQuality.Diminished) return new Interval(C4, new Pitch(new Step(StepLetter.D), accidental: Accidentals.DoubleFlat));
                    else throw new ArgumentException(string.Format(exceptionFormatString, quantity, quality));
                    break;
                case IntervalQuantity.Third:
                    if (quality == IntervalQuality.Minor) return new Interval(C4, new Pitch(new Step(StepLetter.E), accidental: Accidentals.Flat));
                    if (quality == IntervalQuality.Major) return new Interval(C4, new Pitch(new Step(StepLetter.E)));
                    if (quality == IntervalQuality.Augmented) return new Interval(C4, new Pitch(new Step(StepLetter.E), accidental: Accidentals.Sharp));
                    if (quality == IntervalQuality.Diminished) return new Interval(C4, new Pitch(new Step(StepLetter.E), accidental: Accidentals.DoubleFlat));
                    else throw new ArgumentException(string.Format(exceptionFormatString, quantity, quality));
                    break;
                case IntervalQuantity.Fourth:
                    if (quality == IntervalQuality.Perfect) return new Interval(C4, new Pitch(new Step(StepLetter.F)));
                    if (quality == IntervalQuality.Augmented) return new Interval(C4, new Pitch(new Step(StepLetter.F), accidental: Accidentals.Sharp));
                    if (quality == IntervalQuality.Diminished) return new Interval(C4, new Pitch(new Step(StepLetter.F), accidental: Accidentals.Flat));
                    else throw new ArgumentException(string.Format(exceptionFormatString, quantity, quality));
                    break;
                case IntervalQuantity.Fifth:
                    if (quality == IntervalQuality.Perfect) return new Interval(C4, new Pitch(new Step(StepLetter.G)));
                    if (quality == IntervalQuality.Augmented) return new Interval(C4, new Pitch(new Step(StepLetter.G), accidental: Accidentals.Sharp));
                    if (quality == IntervalQuality.Diminished) return new Interval(C4, new Pitch(new Step(StepLetter.G), accidental: Accidentals.Flat));
                    else throw new ArgumentException(string.Format(exceptionFormatString, quantity, quality));
                    break;
                case IntervalQuantity.Sixth:
                    if (quality == IntervalQuality.Minor) return new Interval(C4, new Pitch(new Step(StepLetter.A), accidental: Accidentals.Flat));
                    if (quality == IntervalQuality.Major) return new Interval(C4, new Pitch(new Step(StepLetter.A)));
                    if (quality == IntervalQuality.Augmented) return new Interval(C4, new Pitch(new Step(StepLetter.A), accidental: Accidentals.Sharp));
                    if (quality == IntervalQuality.Diminished) return new Interval(C4, new Pitch(new Step(StepLetter.A), accidental: Accidentals.DoubleFlat));
                    else throw new ArgumentException(string.Format(exceptionFormatString, quantity, quality));
                    break;
                case IntervalQuantity.Seventh:
                    if (quality == IntervalQuality.Minor) return new Interval(C4, new Pitch(new Step(StepLetter.B), accidental: Accidentals.Flat));
                    if (quality == IntervalQuality.Major) return new Interval(C4, new Pitch(new Step(StepLetter.B)));
                    if (quality == IntervalQuality.Augmented) return new Interval(C4, new Pitch(new Step(StepLetter.A), accidental: Accidentals.Sharp));
                    if (quality == IntervalQuality.Diminished) return new Interval(C4, new Pitch(new Step(StepLetter.A), accidental: Accidentals.DoubleFlat));
                    else throw new ArgumentException(string.Format(exceptionFormatString, quantity, quality));
                    break;
                case IntervalQuantity.Octave:
					var tempInterval = GetC4BasedInterval(quality, IntervalQuantity.Unison);
		            if (quality == IntervalQuality.Perfect) return new Interval(tempInterval.Root, tempInterval.Top.TransposeOctaves(1));
                    if (quality == IntervalQuality.Augmented) return new Interval(C4, new Pitch(new Step(StepLetter.A), accidental: Accidentals.Sharp));
                    if (quality == IntervalQuality.Diminished) return new Interval(C4, new Pitch(new Step(StepLetter.A), accidental: Accidentals.DoubleFlat));
                    else throw new ArgumentException(string.Format(exceptionFormatString, quantity, quality));
		            
		            break;
                case IntervalQuantity.Ninth:
                    break;
                case IntervalQuantity.Tenth: break;
                case IntervalQuantity.Eleventh: break;
                case IntervalQuantity.Twelfth: break;
                case IntervalQuantity.Thirteenth: break;
                case IntervalQuantity.Fourteenth: break;
                case IntervalQuantity.Fifteenth: break;
                default: break;
            }
            return default(Interval);
        }