Exemple #1
0
        public long ConvertFrom(ILength length, long time, TempoMap tempoMap)
        {
            ThrowIfArgument.IsNull(nameof(length), length);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            var mathLength = length as MathLength;

            if (mathLength == null)
            {
                throw new ArgumentException($"Length is not an instance of the {nameof(MathLength)}.", nameof(length));
            }

            var convertedLength1 = LengthConverter.ConvertFrom(mathLength.Length1, time, tempoMap);
            var endTime1         = time + convertedLength1;

            switch (mathLength.Operation)
            {
            case MathOperation.Sum:
                return(convertedLength1 + LengthConverter.ConvertFrom(mathLength.Length2, endTime1, tempoMap));

            case MathOperation.Subtract:
                return(convertedLength1 - LengthConverter.ConvertFrom(mathLength.Length2, endTime1, tempoMap.Flip(endTime1)));
            }

            throw new NotImplementedException($"Conversion from the {nameof(MathLength)} with {mathLength.Operation} operation is not implemented.");
        }
Exemple #2
0
        /// <summary>
        /// Sets new time signature that will last from the specified time until next change of
        /// time signature.
        /// </summary>
        /// <param name="time">Time to set the new time signature at.</param>
        /// <param name="timeSignature">New time signature that will last from the specified
        /// time until next change of time signature.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="timeSignature"/> is null.</exception>
        public void SetTimeSignature(long time, TimeSignature timeSignature)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(timeSignature), timeSignature);

            TempoMap.TimeSignature.SetValue(time, timeSignature);
        }
        private static MetricTime ConvertToByTicksPerQuarterNote(long time, short ticksPerQuarterNote, TempoMap tempoMap)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            //

            var tempoLine    = tempoMap.Tempo;
            var tempoChanges = tempoLine.Values.Where(v => v.Time < time);

            if (!tempoChanges.Any())
            {
                return(new MetricTime(RoundMicroseconds(GetMicroseconds(time, Tempo.Default, ticksPerQuarterNote))));
            }

            //

            var accumulatedMicroseconds = 0d;
            var lastTime  = 0L;
            var lastTempo = Tempo.Default;

            foreach (var tempoChange in tempoChanges.Concat(new[] { new ValueChange <Tempo>(time, tempoLine.AtTime(time)) }))
            {
                var tempoChangeTime = tempoChange.Time;

                accumulatedMicroseconds += GetMicroseconds(tempoChangeTime - lastTime, lastTempo, ticksPerQuarterNote);
                lastTempo = tempoChange.Value;
                lastTime  = tempoChangeTime;
            }

            return(new MetricTime(RoundMicroseconds(accumulatedMicroseconds)));
        }
Exemple #4
0
        /// <summary>
        ///     Deletes all parameter's value changes in the specified time range.
        /// </summary>
        /// <param name="startTime">Start time of the time range where value changes should be deleted.</param>
        /// <param name="endTime">End time of the time range where value changes should be deleted.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     <paramref name="startTime" /> is negative. -or-
        ///     <paramref name="endTime" /> is negative.
        /// </exception>
        internal void DeleteValues(long startTime, long endTime)
        {
            ThrowIfTimeArgument.StartIsNegative(nameof(startTime), startTime);
            ThrowIfTimeArgument.EndIsNegative(nameof(endTime), endTime);

            _values.RemoveAll(v => v.Time >= startTime && v.Time <= endTime);
        }
Exemple #5
0
        /// <summary>
        /// Removes all changes of tempo that occured between the specified times.
        /// </summary>
        /// <param name="startTime">Start of time range to remove changes of tempo in.</param>
        /// <param name="endTime">End of time range to remove changes of tempo in.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="startTime"/> is negative. -or-
        /// <paramref name="endTime"/> is negative.</exception>
        public void ClearTempo(long startTime, long endTime)
        {
            ThrowIfTimeArgument.StartIsNegative(nameof(startTime), startTime);
            ThrowIfTimeArgument.EndIsNegative(nameof(endTime), endTime);

            TempoMap.Tempo.DeleteValues(startTime, endTime);
        }
Exemple #6
0
        /// <summary>
        /// Splits the current <see cref="Chord"/> by the specified time.
        /// </summary>
        /// <remarks>
        /// If <paramref name="time"/> is less than time of the chord, the left part will be null.
        /// If <paramref name="time"/> is greater than end time of the chord, the right part
        /// will be null.
        /// </remarks>
        /// <param name="time">Time to split the chord by.</param>
        /// <returns>An object containing left and right parts of the splitted <see cref="Chord"/>.
        /// Both parts are instances of <see cref="Chord"/> too.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        public SplittedLengthedObject <Chord> Split(long time)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);

            //

            var startTime = Time;
            var endTime   = startTime + Length;

            if (time <= startTime)
            {
                return(new SplittedLengthedObject <Chord>(null, Clone()));
            }

            if (time >= endTime)
            {
                return(new SplittedLengthedObject <Chord>(Clone(), null));
            }

            //

            var parts = Notes.Select(n => n.Split(time)).ToArray();

            var leftPart  = new Chord(parts.Select(p => p.LeftPart).Where(p => p != null));
            var rightPart = new Chord(parts.Select(p => p.RightPart).Where(p => p != null));

            return(new SplittedLengthedObject <Chord>(leftPart, rightPart));
        }
Exemple #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MathTime"/> with the specified
        /// time, offset and mathematical operation.
        /// </summary>
        /// <param name="time">The MIDI time to add <paramref name="offset"/> to or
        /// subtract <paramref name="offset"/> from.</param>
        /// <param name="offset"><see cref="ILength"/> that should be added to or subtracted
        /// from <paramref name="time"/>.</param>
        /// <param name="operation">Mathematical operation to perform on <paramref name="time"/>.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="offset"/> is null.</exception>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="operation"/> specified
        /// an invalid value.</exception>
        public MathTime(long time, ILength offset, MathOperation operation = MathOperation.Sum)
            : this(offset, operation)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);

            MidiTime = time;
        }
Exemple #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Chord"/> with the specified
        /// collection of notes and chord time.
        /// </summary>
        /// <param name="notes">Notes to combine into a chord.</param>
        /// <param name="time">Time of the chord which is time of the earliest note of the <paramref name="notes"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="notes"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        public Chord(IEnumerable <Note> notes, long time)
            : this(notes)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);

            Time = time;
        }
Exemple #9
0
        /// <summary>
        /// Splits the current <see cref="Note"/> by the specified time.
        /// </summary>
        /// <remarks>
        /// If <paramref name="time"/> is less than time of the note, the left part will be null.
        /// If <paramref name="time"/> is greater than end time of the note, the right part
        /// will be null.
        /// </remarks>
        /// <param name="time">Time to split the note by.</param>
        /// <returns>An object containing left and right parts of the splitted <see cref="Note"/>.
        /// Both parts are instances of <see cref="Note"/> too.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        public SplittedLengthedObject<Note> Split(long time)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);

            //

            var startTime = Time;
            var endTime = startTime + Length;

            if (time <= startTime)
                return new SplittedLengthedObject<Note>(null, Clone());

            if (time >= endTime)
                return new SplittedLengthedObject<Note>(Clone(), null);

            //

            var leftPart = Clone();
            leftPart.Length = time - startTime;

            var rightPart = Clone();
            rightPart.Time = time;
            rightPart.Length = endTime - time;

            return new SplittedLengthedObject<Note>(leftPart, rightPart);
        }
Exemple #10
0
        /// <summary>
        /// Sets new tempo that will last from the specified time until next change of tempo.
        /// </summary>
        /// <param name="time">Time to set the new tempo at.</param>
        /// <param name="tempo">New tempo that will last from the specified time until next change
        /// of tempo.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="tempo"/> is null.</exception>
        public void SetTempo(long time, Tempo tempo)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempo), tempo);

            TempoMap.Tempo.SetValue(time, tempo);
        }
Exemple #11
0
        /// <summary>
        /// Converts length from the specified length type to <see cref="long"/>.
        /// </summary>
        /// <param name="length">Length to convert.</param>
        /// <param name="time">Start time of an object to convert length of.</param>
        /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param>
        /// <returns>Length as <see cref="long"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="length"/> is null. -or-
        /// <paramref name="tempoMap"/> is null.</exception>
        public static long ConvertFrom(ITimeSpan length, long time, TempoMap tempoMap)
        {
            ThrowIfArgument.IsNull(nameof(length), length);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            return(TimeSpanConverter.ConvertFrom(length, time, tempoMap));
        }
Exemple #12
0
        /// <summary>
        /// Converts time from <see cref="long"/> to the specified time type.
        /// </summary>
        /// <param name="time">Time to convert.</param>
        /// <param name="timeType">Type that will represent the time of an object.</param>
        /// <param name="tempoMap">Tempo map used to convert <paramref name="time"/>.</param>
        /// <returns>Time as an instance of time span defined by <paramref name="timeType"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="tempoMap"/> is null.</exception>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="timeType"/> specified an invalid value.</exception>
        public static ITimeSpan ConvertTo(long time, TimeSpanType timeType, TempoMap tempoMap)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsInvalidEnumValue(nameof(timeType), timeType);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            return(TimeSpanConverter.ConvertTo(time, timeType, 0, tempoMap));
        }
        /// <summary>
        /// Filters collection of <see cref="ITimedObject"/> to return objects at the specified time.
        /// </summary>
        /// <typeparam name="TObject">The type of the elements of <paramref name="objects"/>.</typeparam>
        /// <param name="objects">A collection to filter.</param>
        /// <param name="time">Time to filter objects by.</param>
        /// <returns>A collection that contains objects from the input sequence that are at the specified time.</returns>
        /// <remarks>
        /// Note that changes made on the objects returned by this method will not be saved to an underlying
        /// data source (events collection, track chunk, file). To change properties of timed objects and
        /// save them you need to use a manager appropriate for an object's type.
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="objects"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        public static IEnumerable <TObject> AtTime <TObject>(this IEnumerable <TObject> objects, long time)
            where TObject : ITimedObject
        {
            ThrowIfArgument.IsNull(nameof(objects), objects);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);

            return(objects.Where(o => o.Time == time));
        }
Exemple #14
0
        /// <summary>
        /// Converts time from <see cref="long"/> to the specified time type.
        /// </summary>
        /// <typeparam name="TTimeSpan">Type that will represent the time of an object.</typeparam>
        /// <param name="time">Time to convert.</param>
        /// <param name="tempoMap">Tempo map used to convert <paramref name="time"/>.</param>
        /// <returns>Time as an instance of <typeparamref name="TTimeSpan"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="tempoMap"/> is null.</exception>
        /// <exception cref="NotSupportedException"><typeparamref name="TTimeSpan"/> is not supported.</exception>
        public static TTimeSpan ConvertTo <TTimeSpan>(long time, TempoMap tempoMap)
            where TTimeSpan : ITimeSpan
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            return(TimeSpanConverter.ConvertTo <TTimeSpan>(time, 0, tempoMap));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ValueChange{T}"/> with the specified
        /// time of change and new value.
        /// </summary>
        /// <param name="time">MIDI time when value is changed.</param>
        /// <param name="value">New value that will last until next value change.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
        internal ValueChange(long time, TValue value)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(value), value);

            Time  = time;
            Value = value;
        }
        /// <summary>
        /// Adds a <see cref="MidiEvent"/> into a <see cref="TimedEventsCollection"/> with the specified
        /// absolute time.
        /// </summary>
        /// <param name="eventsCollection"><see cref="TimedEventsCollection"/> to add an event into.</param>
        /// <param name="midiEvent">Event to add into the <paramref name="eventsCollection"/>.</param>
        /// <param name="time">Absolute time that will be assigned to the <paramref name="midiEvent"/>
        /// when it will be placed into the <paramref name="eventsCollection"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="eventsCollection"/> is null. -or-
        /// <paramref name="midiEvent"/> is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        public static void AddEvent(this TimedEventsCollection eventsCollection, MidiEvent midiEvent, long time)
        {
            ThrowIfArgument.IsNull(nameof(eventsCollection), eventsCollection);
            ThrowIfArgument.IsNull(nameof(midiEvent), midiEvent);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);

            eventsCollection.Add(new TimedEvent(midiEvent, time));
        }
Exemple #17
0
        /// <summary>
        /// Converts time from <see cref="long"/> to the specified time type.
        /// </summary>
        /// <typeparam name="TTime">Type that will represent the time of an object.</typeparam>
        /// <param name="time">Time to convert.</param>
        /// <param name="tempoMap">Tempo map used to convert <paramref name="time"/>.</param>
        /// <returns>Time as an instance of <typeparamref name="TTime"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="tempoMap"/> is null.</exception>
        /// <exception cref="NotSupportedException"><typeparamref name="TTime"/> is not supported.</exception>
        public static TTime ConvertTo <TTime>(long time, TempoMap tempoMap)
            where TTime : ITime
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            return((TTime)GetConverter <TTime>().ConvertTo(time, tempoMap));
        }
Exemple #18
0
        /// <summary>
        /// Gets value at specified time.
        /// </summary>
        /// <param name="time">Time to get a value at.</param>
        /// <returns>Parameter's value at the <paramref name="time"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        public TValue AtTime(long time)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);

            return(this.TakeWhile(p => p.Time <= time)
                   .LastOrDefault()
                   ?.Value
                   ?? _defaultValue);
        }
Exemple #19
0
        /// <summary>
        /// Filters collection of <see cref="ILengthedObject"/> to return objects at the specified time.
        /// </summary>
        /// <typeparam name="TObject">The type of the elements of <paramref name="objects"/>.</typeparam>
        /// <param name="objects">A collection to filter.</param>
        /// <param name="time">Time to filter objects by.</param>
        /// <param name="matchBy">Part of an object which have to be at <paramref name="time"/>.</param>
        /// <returns>A collection that contains objects from the input sequence that are at the specified time.</returns>
        /// <remarks>
        /// Note that changes made on the objects returned by this method will not be saved to an underlying
        /// data source (events collection, track chunk, file). To change properties of lengthed objects and
        /// save them you need to use a manager appropriate for an object's type.
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="objects"/> is null. -or- One of the objects is null.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="matchBy"/> specified an invalid value.</exception>
        public static IEnumerable <TObject> AtTime <TObject>(this IEnumerable <TObject> objects, long time, LengthedObjectPart matchBy)
            where TObject : ILengthedObject
        {
            ThrowIfArgument.IsNull(nameof(objects), objects);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsInvalidEnumValue(nameof(matchBy), matchBy);

            return(objects.Where(o => o != null && IsObjectAtTime(o, time, matchBy)));
        }
Exemple #20
0
        /// <summary>
        /// Converts length from the specified length type to <see cref="long"/>.
        /// </summary>
        /// <param name="length">Length to convert.</param>
        /// <param name="time">Start time of an object to convert length of.</param>
        /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param>
        /// <returns>Length as <see cref="long"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="length"/> is null. -or-
        /// <paramref name="tempoMap"/> is null.</exception>
        public static long ConvertFrom(ILength length, long time, TempoMap tempoMap)
        {
            ThrowIfArgument.IsNull(nameof(length), length);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            return(LengthConverterFactory.GetConverter(length.GetType())
                   .ConvertFrom(length, time, tempoMap));
        }
Exemple #21
0
        /// <summary>
        /// Converts length from <see cref="long"/> to the specified length type.
        /// </summary>
        /// <typeparam name="TLength">Type that will represent the length of an object.</typeparam>
        /// <param name="length">Length to convert.</param>
        /// <param name="time">Start time of an object to convert length of.</param>
        /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param>
        /// <returns>Length as an instance of <typeparamref name="TLength"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is negative. -or-
        /// <paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="tempoMap"/> is null.</exception>
        /// <exception cref="NotSupportedException"><typeparamref name="TLength"/> is not supported.</exception>
        public static TLength ConvertTo <TLength>(long length, long time, TempoMap tempoMap)
            where TLength : ILength
        {
            ThrowIfLengthArgument.IsNegative(nameof(length), length);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            return((TLength)GetConverter <TLength>().ConvertTo(length, time, tempoMap));
        }
Exemple #22
0
        /// <summary>
        /// Converts length from one length type to another one.
        /// </summary>
        /// <typeparam name="TLength">Type that will represent the length of an object.</typeparam>
        /// <param name="length">Length to convert.</param>
        /// <param name="time">Start time of an object to convert length of.</param>
        /// <param name="tempoMap">Tempo map used to convert <paramref name="length"/>.</param>
        /// <returns>Length as an instance of <typeparamref name="TLength"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time"/> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="length"/> is null. -or-
        /// <paramref name="tempoMap"/> is null.</exception>
        /// <exception cref="NotSupportedException"><typeparamref name="TLength"/> is not supported.</exception>
        public static TLength ConvertTo <TLength>(ILength length, long time, TempoMap tempoMap)
            where TLength : ILength
        {
            ThrowIfArgument.IsNull(nameof(length), length);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            return(ConvertTo <TLength>(ConvertFrom(length, time, tempoMap), time, tempoMap));
        }
Exemple #23
0
        /// <summary>
        ///     Gets value at specified time.
        /// </summary>
        /// <param name="time">Time to get a value at.</param>
        /// <returns>Parameter's value at the <paramref name="time" />.</returns>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time" /> is negative.</exception>
        public TValue AtTime(long time)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);

            return(_values.Where(p => p.Time <= time)
                   .OrderBy(p => p.Time)
                   .LastOrDefault()
                   ?.Value
                   ?? _defaultValue);
        }
        public ILength ConvertTo(long length, long time, TempoMap tempoMap)
        {
            ThrowIfLengthArgument.IsNegative(nameof(length), length);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            //

            var startTime = TimeConverter.ConvertTo <MetricTime>(time, tempoMap);
            var endTime   = TimeConverter.ConvertTo <MetricTime>(time + length, tempoMap);

            return(new MetricLength(endTime - startTime));
        }
        public ITime ConvertTo(long time, TempoMap tempoMap)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            var ticksPerQuarterNoteTimeDivision = tempoMap.TimeDivision as TicksPerQuarterNoteTimeDivision;

            if (ticksPerQuarterNoteTimeDivision != null)
            {
                return(ConvertToByTicksPerQuarterNote(time, ticksPerQuarterNoteTimeDivision.TicksPerQuarterNote, tempoMap));
            }

            ThrowIfTimeDivision.IsNotSupportedForTimeConversion(tempoMap.TimeDivision);
            return(null);
        }
Exemple #26
0
        /// <summary>
        ///     Sets new value at specified time that will last until next value change.
        /// </summary>
        /// <param name="time">Time parameter's value should be changed at.</param>
        /// <param name="value">New parameter's value that will last until next value change.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="time" /> is negative.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception>
        internal void SetValue(long time, TValue value)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(value), value);

            var currentValue = AtTime(time);

            if (currentValue.Equals(value))
            {
                return;
            }

            _values.RemoveAll(v => v.Time == time);
            _values.Add(new ValueChange <TValue>(time, value));
        }
Exemple #27
0
        public ILength ConvertTo(long length, long time, TempoMap tempoMap)
        {
            ThrowIfLengthArgument.IsNegative(nameof(length), length);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            var ticksPerQuarterNoteTimeDivision = tempoMap.TimeDivision as TicksPerQuarterNoteTimeDivision;

            if (ticksPerQuarterNoteTimeDivision != null)
            {
                return(new MusicalLength(FractionUtilities.FromTicks(length, ticksPerQuarterNoteTimeDivision.TicksPerQuarterNote)));
            }

            ThrowIfTimeDivision.IsNotSupportedForLengthConversion(tempoMap.TimeDivision);
            return(null);
        }
        public long ConvertFrom(ILength length, long time, TempoMap tempoMap)
        {
            ThrowIfArgument.IsNull(nameof(length), length);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            var metricLength = length as MetricLength;

            if (metricLength == null)
            {
                throw new ArgumentException($"Length is not an instance of the {nameof(MetricLength)}.", nameof(length));
            }

            var startTime = TimeConverter.ConvertTo <MetricTime>(time, tempoMap);
            var endTime   = new MetricTime(startTime.TotalMicroseconds + metricLength.TotalMicroseconds);

            return(TimeConverter.ConvertFrom(endTime, tempoMap) - time);
        }
Exemple #29
0
        private static MusicalTime ConvertToByTicksPerQuarterNote(long time, short ticksPerQuarterNote, TempoMap tempoMap)
        {
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            //

            var bars              = 0;
            var lastTime          = 0L;
            var lastTimeSignature = TimeSignature.Default;

            foreach (var timeSignatureChange in tempoMap.TimeSignature.Values.Where(v => v.Time <= time))
            {
                var timeSignatureChangeTime = timeSignatureChange.Time;

                bars += GetBarsCount(timeSignatureChangeTime - lastTime, lastTimeSignature, ticksPerQuarterNote);
                lastTimeSignature = timeSignatureChange.Value;
                lastTime          = timeSignatureChangeTime;
            }

            //

            var deltaTime = time - lastTime;
            var lastBars  = GetBarsCount(deltaTime, lastTimeSignature, ticksPerQuarterNote);

            bars += lastBars;

            //

            deltaTime = deltaTime % GetBarLength(lastTimeSignature, ticksPerQuarterNote);
            var beatLength = GetBeatLength(lastTimeSignature, ticksPerQuarterNote);
            var beats      = deltaTime / beatLength;

            //

            var fraction = FractionUtilities.FromTicks(deltaTime % beatLength, ticksPerQuarterNote);

            //

            return(new MusicalTime(bars, (int)beats, fraction));
        }
Exemple #30
0
        public long ConvertFrom(ILength length, long time, TempoMap tempoMap)
        {
            ThrowIfArgument.IsNull(nameof(length), length);
            ThrowIfTimeArgument.IsNegative(nameof(time), time);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            var musicalLength = length as MusicalLength;

            if (musicalLength == null)
            {
                throw new ArgumentException($"Length is not an instance of the {nameof(MusicalLength)}.", nameof(length));
            }

            var ticksPerQuarterNoteTimeDivision = tempoMap.TimeDivision as TicksPerQuarterNoteTimeDivision;

            if (ticksPerQuarterNoteTimeDivision != null)
            {
                return(musicalLength.Fraction.ToTicks(ticksPerQuarterNoteTimeDivision.TicksPerQuarterNote));
            }

            ThrowIfTimeDivision.IsNotSupportedForLengthConversion(tempoMap.TimeDivision);
            return(0);
        }