Ejemplo n.º 1
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));
        }
        /// <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;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets a value indicating whether the specified interval number (1 and greater) is perfect or not.
        /// </summary>
        /// <param name="intervalNumber">Interval number to determine whether it's perfect or not.</param>
        /// <returns>true if <paramref name="intervalNumber"/> is perfect; otherwise, false.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="intervalNumber"/> is less than 1.</exception>
        public static bool IsPerfect(int intervalNumber)
        {
            ThrowIfArgument.IsLessThan(nameof(intervalNumber), intervalNumber, 1, "Interval number is less than 1.");

            var remainder = intervalNumber % 7 - 1;

            return(remainder == 0 || remainder == 3 || remainder == 4);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MidiClock"/> with the specified
        /// value indicating whether first tick should be generated immediately after clock started, and
        /// tick generator.
        /// </summary>
        /// <param name="startImmediately">A value indicating whether first tick should be generated
        /// immediately after clock started.</param>
        /// <param name="tickGenerator">Tick generator used as timer firing at the specified interval. Null for
        /// no tick generator.</param>
        /// <param name="interval">Interval of clock's ticiking.</param>
        public MidiClock(bool startImmediately, TickGenerator tickGenerator, TimeSpan interval)
        {
            ThrowIfArgument.IsLessThan(nameof(interval), interval, TimeSpan.FromMilliseconds(1), "Interval is less than 1 ms.");

            _startImmediately = startImmediately;

            _tickGenerator = tickGenerator;
            if (_tickGenerator != null)
            {
                _tickGenerator.TickGenerated += OnTickGenerated;
            }

            Interval = interval;
        }
Ejemplo n.º 5
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);
        }