コード例 #1
0
        /// <summary>
        /// Resizes group of notes to the specified length treating all notes as single object.
        /// </summary>
        /// <param name="notes">Notes to resize.</param>
        /// <param name="length">New length of the notes collection.</param>
        /// <param name="distanceCalculationType">Type of distance calculations.</param>
        /// <param name="tempoMap"></param>
        /// <exception cref="ArgumentNullException"><paramref name="notes"/> is null. -or-
        /// <paramref name="length"/> is null. -or- <paramref name="tempoMap"/> is null.</exception>
        /// <exception cref="ArgumentException"><see cref="TimeSpanType.BarBeat"/> used for <paramref name="distanceCalculationType"/>
        /// with relative resizing.</exception>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="distanceCalculationType"/> specified an
        /// invalid value.</exception>
        public static void ResizeNotes(this IEnumerable <Note> notes,
                                       ITimeSpan length,
                                       TimeSpanType distanceCalculationType,
                                       TempoMap tempoMap)
        {
            ThrowIfArgument.IsNull(nameof(notes), notes);
            ThrowIfArgument.IsNull(nameof(length), length);
            ThrowIfArgument.IsInvalidEnumValue(nameof(distanceCalculationType), distanceCalculationType);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            if (distanceCalculationType == TimeSpanType.BarBeat)
            {
                throw new ArgumentException("BarBeat length type is not supported for relative resizing.", nameof(distanceCalculationType));
            }

            if (!notes.Any())
            {
                return;
            }

            //

            var minStartTime = long.MaxValue;
            var maxEndTime   = 0L;

            foreach (var note in notes.Where(n => n != null))
            {
                var noteStartTime = note.Time;
                var noteEndTime   = noteStartTime + note.Length;

                minStartTime = Math.Min(minStartTime, noteStartTime);
                maxEndTime   = Math.Max(maxEndTime, noteEndTime);
            }

            var totalLength = maxEndTime - minStartTime;

            //

            var oldLength = LengthConverter.ConvertTo(totalLength, distanceCalculationType, minStartTime, tempoMap);
            var newLength = LengthConverter.ConvertTo(length, distanceCalculationType, minStartTime, tempoMap);
            var ratio     = TimeSpanUtilities.Divide(newLength, oldLength);

            var startTime = TimeConverter.ConvertTo(minStartTime, distanceCalculationType, tempoMap);

            foreach (var note in notes.Where(n => n != null))
            {
                var noteLength = note.LengthAs(distanceCalculationType, tempoMap);
                var noteTime   = note.TimeAs(distanceCalculationType, tempoMap);

                var scaledShiftFromStart = noteTime.Subtract(startTime, TimeSpanMode.TimeTime).Multiply(ratio);
                note.Time = TimeConverter.ConvertFrom(startTime.Add(scaledShiftFromStart, TimeSpanMode.TimeLength), tempoMap);

                var scaledLength = noteLength.Multiply(ratio);
                note.Length = LengthConverter.ConvertFrom(scaledLength, note.Time, tempoMap);
            }
        }
コード例 #2
0
        /// <summary>
        /// Resizes group of notes to the specified length treating all notes as single object.
        /// </summary>
        /// <param name="notes">Notes to resize.</param>
        /// <param name="length">New length of the notes collection.</param>
        /// <param name="distanceCalculationType">Type of distance calculations.</param>
        /// <param name="tempoMap"></param>
        /// <exception cref="ArgumentNullException"><paramref name="notes"/> is null. -or-
        /// <paramref name="length"/> is null. -or- <paramref name="tempoMap"/> is null.</exception>
        /// <exception cref="ArgumentException"><see cref="TimeSpanType.BarBeatTicks"/> or <see cref="TimeSpanType.BarBeatFraction"/>
        /// is used for <paramref name="distanceCalculationType"/> which is unsupported.</exception>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="distanceCalculationType"/> specified an
        /// invalid value.</exception>
        public static void ResizeNotes(this IEnumerable <Note> notes,
                                       ITimeSpan length,
                                       TimeSpanType distanceCalculationType,
                                       TempoMap tempoMap)
        {
            ThrowIfArgument.IsNull(nameof(notes), notes);
            ThrowIfArgument.IsNull(nameof(length), length);
            ThrowIfArgument.IsInvalidEnumValue(nameof(distanceCalculationType), distanceCalculationType);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            // Unable to calculate ratio between two bar/beat time spans
            if (distanceCalculationType == TimeSpanType.BarBeatTicks || distanceCalculationType == TimeSpanType.BarBeatFraction)
            {
                throw new ArgumentException("Bar/beat distance calculation type is not supported.", nameof(distanceCalculationType));
            }

            var notNullNotes = notes.Where(n => n != null);

            if (!notNullNotes.Any())
            {
                return;
            }

            //

            var minStartTime = long.MaxValue;
            var maxEndTime   = 0L;

            foreach (var note in notNullNotes)
            {
                var noteStartTime = note.Time;
                var noteEndTime   = noteStartTime + note.Length;

                minStartTime = Math.Min(minStartTime, noteStartTime);
                maxEndTime   = Math.Max(maxEndTime, noteEndTime);
            }

            var totalLength = maxEndTime - minStartTime;

            //

            var oldLength = LengthConverter.ConvertTo(totalLength, distanceCalculationType, minStartTime, tempoMap);
            var newLength = LengthConverter.ConvertTo(length, distanceCalculationType, minStartTime, tempoMap);
            var ratio     = TimeSpanUtilities.Divide(newLength, oldLength);

            var startTime = TimeConverter.ConvertTo(minStartTime, distanceCalculationType, tempoMap);

            ResizeNotesByRatio(notNullNotes, ratio, distanceCalculationType, tempoMap, startTime);
        }
コード例 #3
0
        /// <summary>
        /// Resizes <see cref="MidiFile"/> to the specified length.
        /// </summary>
        /// <param name="midiFile"><see cref="MidiFile"/> to resize.</param>
        /// <param name="length">New length of the <paramref name="midiFile"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="midiFile"/> is null. -or-
        /// <paramref name="length"/> is null.</exception>
        public static void Resize(this MidiFile midiFile, ITimeSpan length)
        {
            ThrowIfArgument.IsNull(nameof(midiFile), midiFile);
            ThrowIfArgument.IsNull(nameof(length), length);

            if (midiFile.IsEmpty())
            {
                return;
            }

            var tempoMap = midiFile.GetTempoMap();
            var duration = midiFile.GetDuration <MidiTimeSpan>();

            var oldLength = TimeConverter.ConvertTo(duration, length.GetType(), tempoMap);
            var ratio     = TimeSpanUtilities.Divide(length, oldLength);

            ResizeByRatio(midiFile, ratio);
        }
コード例 #4
0
        /// <summary>
        /// Resizes <see cref="MidiFile"/> to the specified length.
        /// </summary>
        /// <param name="midiFile"><see cref="MidiFile"/> to resize.</param>
        /// <param name="length">New length of the <paramref name="midiFile"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="midiFile"/> is null. -or-
        /// <paramref name="length"/> is null.</exception>
        public static void Resize(this MidiFile midiFile, ITimeSpan length)
        {
            ThrowIfArgument.IsNull(nameof(midiFile), midiFile);
            ThrowIfArgument.IsNull(nameof(length), length);

            var lastTime = midiFile.GetTimedEvents().LastOrDefault()?.Time ?? 0;

            if (lastTime == 0)
            {
                return;
            }

            var tempoMap = midiFile.GetTempoMap();

            var oldLength = TimeConverter.ConvertTo((MidiTimeSpan)lastTime, length.GetType(), tempoMap);
            var ratio     = TimeSpanUtilities.Divide(length, oldLength);

            ResizeByRatio(midiFile, ratio);
        }
コード例 #5
0
        public static void Resize(this MidiFile midiFile, ITimeSpan length)
        {
            ThrowIfArgument.IsNull(nameof(midiFile), midiFile);
            ThrowIfArgument.IsNull(nameof(length), length);

            // TODO: create method to get absolute time (or last time...)
            var lastTime = midiFile.GetTimedEvents().LastOrDefault()?.Time;

            if (lastTime.GetValueOrDefault() == 0)
            {
                return;
            }

            var tempoMap = midiFile.GetTempoMap();

            var oldLength = TimeConverter.ConvertTo((MidiTimeSpan)lastTime.Value, length.GetType(), tempoMap);
            var ratio     = TimeSpanUtilities.Divide(length, oldLength);

            ResizeByRatio(midiFile, ratio);
        }