/// <summary> /// Gets length of an <see cref="ILengthedObject"/> as an instance of type that /// implements the <see cref="ILength"/> interface. /// </summary> /// <typeparam name="TLength">Type that will represent the length of the <paramref name="obj"/>.</typeparam> /// <param name="obj">Object to get length of.</param> /// <param name="tempoMap">Tempo map to calculate length of the <paramref name="obj"/>.</param> /// <returns>Length of the specified object as an instance of <typeparamref name="TLength"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="obj"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="NotSupportedException"><typeparamref name="TLength"/> is not supported.</exception> public static TLength LengthAs <TLength>(this ILengthedObject obj, TempoMap tempoMap) where TLength : ILength { ThrowIfArgument.IsNull(nameof(obj), obj); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(LengthConverter.ConvertTo <TLength>(obj.Length, obj.Time, tempoMap)); }
/// <summary> /// Gets end time of an <see cref="ITimedObject"/> as an instance of time span defined by the /// specified time span type. /// </summary> /// <param name="obj">Object to get end time of.</param> /// <param name="timeType">The type of time span to convert the end time of <paramref name="obj"/> to.</param> /// <param name="tempoMap">Tempo map to calculate end time of the <paramref name="obj"/>.</param> /// <returns>End time of the specified object as an instance of time span defined by the /// <paramref name="timeType"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="obj"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="timeType"/> specified an invalid value.</exception> public static ITimeSpan EndTimeAs(this ILengthedObject obj, TimeSpanType timeType, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(obj), obj); ThrowIfArgument.IsInvalidEnumValue(nameof(timeType), timeType); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(TimeConverter.ConvertTo(obj.Time + obj.Length, timeType, tempoMap)); }
/// <summary> /// Gets end time of an <see cref="ITimedObject"/> as an instance of type that implements the /// <see cref="ITimeSpan"/> interface. /// </summary> /// <typeparam name="TTime">Type that will represent the end time of the <paramref name="obj"/>.</typeparam> /// <param name="obj">Object to get end time of.</param> /// <param name="tempoMap">Tempo map to calculate end time of the <paramref name="obj"/>.</param> /// <returns>End time of the specified object as an instance of <typeparamref name="TTime"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="obj"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="NotSupportedException"><typeparamref name="TTime"/> is not supported.</exception> public static TTime EndTimeAs <TTime>(this ILengthedObject obj, TempoMap tempoMap) where TTime : ITimeSpan { ThrowIfArgument.IsNull(nameof(obj), obj); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(TimeConverter.ConvertTo <TTime>(obj.Time + obj.Length, tempoMap)); }
/// <summary> /// Gets length of an <see cref="ILengthedObject"/> as an instance of type defined by the /// specified time span type. /// </summary> /// <param name="obj">Object to get length of.</param> /// <param name="lengthType">The type of time span to convert the length of <paramref name="obj"/> to.</param> /// <param name="tempoMap">Tempo map to calculate length of the <paramref name="obj"/>.</param> /// <returns>Time of the specified object as an instance of time span defined by the /// <paramref name="lengthType"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="obj"/> is null. -or- /// <paramref name="tempoMap"/> is null.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="lengthType"/> specified an invalid value.</exception> public static ITimeSpan LengthAs(this ILengthedObject obj, TimeSpanType lengthType, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(obj), obj); ThrowIfArgument.IsInvalidEnumValue(nameof(lengthType), lengthType); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); return(LengthConverter.ConvertTo(obj.Length, lengthType, obj.Time, tempoMap)); }
private Event LengthedToEvent(ILengthedObject lengthed, int order) { if (lengthed is Melanchall.DryWetMidi.Smf.Interaction.Note note) { return(new Genetic.Note(note.ToString(), note.NoteNumber, order)); } return(new Genetic.Rest((int)RestOrTie.Rest, order)); }
public void GetNotesAndRests_SeparateByNoteNumber_DifferentNoteNumbers( byte channel1, byte channel2) { var noteNumber1 = (SevenBitNumber)10; var noteNumber2 = (SevenBitNumber)100; var notes = new[] { new Note(noteNumber1, 100, 0) { Channel = (FourBitNumber)channel2 }, new Note(noteNumber2, 100, 30) { Channel = (FourBitNumber)channel1 }, new Note(noteNumber1, 50, 300) { Channel = (FourBitNumber)channel2 }, new Note(noteNumber2, 500, 1000) { Channel = (FourBitNumber)channel1 }, }; var expectedObjects = new ILengthedObject[] { new Note(noteNumber1, 100, 0) { Channel = (FourBitNumber)channel2 }, new Rest(0, 30, null, noteNumber2), new Note(noteNumber2, 100, 30) { Channel = (FourBitNumber)channel1 }, new Rest(100, 200, null, noteNumber1), new Rest(130, 870, null, noteNumber2), new Note(noteNumber1, 50, 300) { Channel = (FourBitNumber)channel2 }, new Note(noteNumber2, 500, 1000) { Channel = (FourBitNumber)channel1 }, }; TestGetNotesAndRests(notes, RestSeparationPolicy.SeparateByNoteNumber, expectedObjects); }
private Measure MidiToMeasure(MidiFile midiMeasure, int measureOrder, int ticksPerEvent, int sizeOfMeasure) { var notesAndRests = midiMeasure.GetTrackChunks().Last().GetNotes().GetNotesAndRests(RestSeparationPolicy.NoSeparation).ToList(); var measureTotalTicks = ticksPerEvent * sizeOfMeasure; var ticks = 0; var events = new List <Event>(); ILengthedObject previous = null; while (ticks < measureTotalTicks) { Event measureEvent = null; var notesEndRestsOfTime = notesAndRests.PlayingAtTime(ticks); if (notesEndRestsOfTime.Any()) { var lengthed = notesEndRestsOfTime.First(); if (lengthed is Melanchall.DryWetMidi.Smf.Interaction.Rest || !lengthed.Equal(previous)) { measureEvent = LengthedToEvent(lengthed, events.Count); previous = lengthed; } else { measureEvent = new Tie((int)RestOrTie.Tie, events.Count); } } else { measureEvent = new Genetic.Rest((int)RestOrTie.Rest, events.Count); } events.Add(measureEvent); ticks += ticksPerEvent; } return(new Measure(events, measureOrder)); }
public static bool Equal(this ILengthedObject obj, ILengthedObject objB) { return(obj.Time == objB?.Time && obj.Length == objB?.Length && obj.GetType() == objB?.GetType()); }
public void GetNotesAndRests_SeparateByChannelAndNoteNumber() { var noteNumber1 = (SevenBitNumber)10; var noteNumber2 = (SevenBitNumber)100; var channel1 = (FourBitNumber)10; var channel2 = (FourBitNumber)2; var notes = new[] { new Note(noteNumber1, 100, 10) { Channel = channel1 }, new Note(noteNumber2, 100, 30) { Channel = channel1 }, new Note(noteNumber1, 50, 300) { Channel = channel2 }, new Note(noteNumber2, 500, 1000) { Channel = channel2 }, new Note(noteNumber1, 150, 1200) { Channel = channel1 }, new Note(noteNumber2, 1000, 1300) { Channel = channel1 }, }; var expectedObjects = new ILengthedObject[] { new Rest(0, 10, channel1, noteNumber1), new Rest(0, 30, channel1, noteNumber2), new Rest(0, 300, channel2, noteNumber1), new Rest(0, 1000, channel2, noteNumber2), new Note(noteNumber1, 100, 10) { Channel = channel1 }, new Note(noteNumber2, 100, 30) { Channel = channel1 }, new Rest(110, 1090, channel1, noteNumber1), new Rest(130, 1170, channel1, noteNumber2), new Note(noteNumber1, 50, 300) { Channel = channel2 }, new Note(noteNumber2, 500, 1000) { Channel = channel2 }, new Note(noteNumber1, 150, 1200) { Channel = channel1 }, new Note(noteNumber2, 1000, 1300) { Channel = channel1 }, }; TestGetNotesAndRests(notes, RestSeparationPolicy.SeparateByChannelAndNoteNumber, expectedObjects); }
public void GetNotesAndRests_SeparateByNoteNumber_SingleNoteNumber( byte channel1, byte channel2) { var noteNumber = (SevenBitNumber)10; var notes = new[] { new Note(noteNumber, 100, 10) { Channel = (FourBitNumber)channel2 }, new Note(noteNumber, 100, 30) { Channel = (FourBitNumber)channel1 }, new Note(noteNumber, 50, 300) { Channel = (FourBitNumber)channel2 }, new Note(noteNumber, 500, 1000) { Channel = (FourBitNumber)channel1 }, new Note(noteNumber, 150, 1200) { Channel = (FourBitNumber)channel2 }, new Note(noteNumber, 1000, 1300) { Channel = (FourBitNumber)channel1 }, }; var expectedObjects = new ILengthedObject[] { new Rest(0, 10, null, noteNumber), new Note(noteNumber, 100, 10) { Channel = (FourBitNumber)channel2 }, new Note(noteNumber, 100, 30) { Channel = (FourBitNumber)channel1 }, new Rest(130, 170, null, noteNumber), new Note(noteNumber, 50, 300) { Channel = (FourBitNumber)channel2 }, new Rest(350, 650, null, noteNumber), new Note(noteNumber, 500, 1000) { Channel = (FourBitNumber)channel1 }, new Note(noteNumber, 150, 1200) { Channel = (FourBitNumber)channel2 }, new Note(noteNumber, 1000, 1300) { Channel = (FourBitNumber)channel1 }, }; TestGetNotesAndRests(notes, RestSeparationPolicy.SeparateByNoteNumber, expectedObjects); }
public void GetNotesAndRests_NoSeparation( byte channel1, byte channel2, byte noteNumber1, byte noteNumber2) { var notes = new[] { new Note((SevenBitNumber)noteNumber1, 100, 10) { Channel = (FourBitNumber)channel2 }, new Note((SevenBitNumber)noteNumber1, 100, 30) { Channel = (FourBitNumber)channel1 }, new Note((SevenBitNumber)noteNumber2, 50, 300) { Channel = (FourBitNumber)channel2 }, new Note((SevenBitNumber)noteNumber1, 500, 1000) { Channel = (FourBitNumber)channel1 }, new Note((SevenBitNumber)noteNumber2, 150, 1200) { Channel = (FourBitNumber)channel2 }, new Note((SevenBitNumber)noteNumber1, 1000, 1300) { Channel = (FourBitNumber)channel1 }, new Note((SevenBitNumber)noteNumber2, 1000, 10000) { Channel = (FourBitNumber)channel2 }, new Note((SevenBitNumber)noteNumber1, 1000, 100000) { Channel = (FourBitNumber)channel1 }, new Note((SevenBitNumber)noteNumber2, 10, 100100) { Channel = (FourBitNumber)channel2 }, new Note((SevenBitNumber)noteNumber1, 10, 110000) { Channel = (FourBitNumber)channel1 }, }; var expectedObjects = new ILengthedObject[] { new Rest(0, 10, null, null), new Note((SevenBitNumber)noteNumber1, 100, 10) { Channel = (FourBitNumber)channel2 }, new Note((SevenBitNumber)noteNumber1, 100, 30) { Channel = (FourBitNumber)channel1 }, new Rest(130, 170, null, null), new Note((SevenBitNumber)noteNumber2, 50, 300) { Channel = (FourBitNumber)channel2 }, new Rest(350, 650, null, null), new Note((SevenBitNumber)noteNumber1, 500, 1000) { Channel = (FourBitNumber)channel1 }, new Note((SevenBitNumber)noteNumber2, 150, 1200) { Channel = (FourBitNumber)channel2 }, new Note((SevenBitNumber)noteNumber1, 1000, 1300) { Channel = (FourBitNumber)channel1 }, new Rest(2300, 7700, null, null), new Note((SevenBitNumber)noteNumber2, 1000, 10000) { Channel = (FourBitNumber)channel2 }, new Rest(11000, 89000, null, null), new Note((SevenBitNumber)noteNumber1, 1000, 100000) { Channel = (FourBitNumber)channel1 }, new Note((SevenBitNumber)noteNumber2, 10, 100100) { Channel = (FourBitNumber)channel2 }, new Rest(101000, 9000, null, null), new Note((SevenBitNumber)noteNumber1, 10, 110000) { Channel = (FourBitNumber)channel1 }, }; TestGetNotesAndRests(notes, RestSeparationPolicy.NoSeparation, expectedObjects); }
public void GetNotesAndRests_SeparateByChannel_DifferentChannels( byte noteNumber1, byte noteNumber2) { var channel1 = (FourBitNumber)10; var channel2 = (FourBitNumber)2; var notes = new[] { new Note((SevenBitNumber)noteNumber1, 100, 10) { Channel = channel1 }, new Note((SevenBitNumber)noteNumber1, 100, 30) { Channel = channel2 }, new Note((SevenBitNumber)noteNumber2, 50, 300) { Channel = channel1 }, new Note((SevenBitNumber)noteNumber1, 500, 1000) { Channel = channel2 }, new Note((SevenBitNumber)noteNumber2, 150, 1200) { Channel = channel1 }, new Note((SevenBitNumber)noteNumber1, 1000, 1300) { Channel = channel2 }, }; var expectedObjects = new ILengthedObject[] { new Rest(0, 10, channel1, null), new Rest(0, 30, channel2, null), new Note((SevenBitNumber)noteNumber1, 100, 10) { Channel = channel1 }, new Note((SevenBitNumber)noteNumber1, 100, 30) { Channel = channel2 }, new Rest(110, 190, channel1, null), new Rest(130, 870, channel2, null), new Note((SevenBitNumber)noteNumber2, 50, 300) { Channel = channel1 }, new Rest(350, 850, channel1, null), new Note((SevenBitNumber)noteNumber1, 500, 1000) { Channel = channel2 }, new Note((SevenBitNumber)noteNumber2, 150, 1200) { Channel = channel1 }, new Note((SevenBitNumber)noteNumber1, 1000, 1300) { Channel = channel2 }, }; TestGetNotesAndRests(notes, RestSeparationPolicy.SeparateByChannel, expectedObjects); }
public void GetNotesAndRests_SeparateByChannel_SingleChannel( byte noteNumber1, byte noteNumber2) { var channel = (FourBitNumber)10; var notes = new[] { new Note((SevenBitNumber)noteNumber1, 100, 10) { Channel = channel }, new Note((SevenBitNumber)noteNumber1, 100, 30) { Channel = channel }, new Note((SevenBitNumber)noteNumber2, 50, 300) { Channel = channel }, new Note((SevenBitNumber)noteNumber1, 500, 1000) { Channel = channel }, new Note((SevenBitNumber)noteNumber2, 150, 1200) { Channel = channel }, new Note((SevenBitNumber)noteNumber1, 1000, 1300) { Channel = channel }, new Note((SevenBitNumber)noteNumber2, 1000, 10000) { Channel = channel }, }; var expectedObjects = new ILengthedObject[] { new Rest(0, 10, channel, null), new Note((SevenBitNumber)noteNumber1, 100, 10) { Channel = channel }, new Note((SevenBitNumber)noteNumber1, 100, 30) { Channel = channel }, new Rest(130, 170, channel, null), new Note((SevenBitNumber)noteNumber2, 50, 300) { Channel = channel }, new Rest(350, 650, channel, null), new Note((SevenBitNumber)noteNumber1, 500, 1000) { Channel = channel }, new Note((SevenBitNumber)noteNumber2, 150, 1200) { Channel = channel }, new Note((SevenBitNumber)noteNumber1, 1000, 1300) { Channel = channel }, new Rest(2300, 7700, channel, null), new Note((SevenBitNumber)noteNumber2, 1000, 10000) { Channel = channel }, }; TestGetNotesAndRests(notes, RestSeparationPolicy.SeparateByChannel, expectedObjects); }