/// <summary> /// Converts the specified bytes to an instance of the <see cref="MidiEvent"/>. First byte is /// the status byte of MIDI event. /// </summary> /// <param name="bytes">Bytes representing a MIDI event.</param> /// <returns><see cref="MidiEvent"/> read from <paramref name="bytes"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="bytes"/> is an empty array.</exception> public MidiEvent Convert(byte[] bytes) { ThrowIfArgument.IsNull(nameof(bytes), bytes); ThrowIfArgument.IsEmptyCollection(nameof(bytes), bytes, "Bytes is empty array."); return(Convert(bytes, 0, bytes.Length)); }
/// <summary> /// Initializes a new instance of the <see cref="Chord"/> with the specified notes names (for example, C E G). /// </summary> /// <param name="notesNames">The set of notes names.</param> /// <exception cref="ArgumentNullException"><paramref name="notesNames"/> is <c>null</c>.</exception> /// <exception cref="InvalidEnumArgumentException"><paramref name="notesNames"/> contains an invalid value.</exception> /// <exception cref="ArgumentException"><paramref name="notesNames"/> is empty collection.</exception> public Chord(ICollection <NoteName> notesNames) { ThrowIfArgument.IsNull(nameof(notesNames), notesNames); ThrowIfArgument.ContainsInvalidEnumValue(nameof(notesNames), notesNames); ThrowIfArgument.IsEmptyCollection(nameof(notesNames), notesNames, "Notes names collection is empty."); NotesNames = notesNames; }
/// <summary> /// Replaces tempo map contained in the specified collection of the <see cref="TrackChunk" /> with /// another one. /// </summary> /// <param name="trackChunks">Collection of the <see cref="TrackChunk" /> holding a tempo map to replace.</param> /// <param name="tempoMap">Tempo map to replace the one contained in the <paramref name="trackChunks" />.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="trackChunks" /> is null. -or- /// <paramref name="tempoMap" /> is null. /// </exception> /// <exception cref="ArgumentException"><paramref name="trackChunks" /> is empty.</exception> public static void ReplaceTempoMap(this IEnumerable <TrackChunk> trackChunks, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); ThrowIfArgument.IsEmptyCollection(nameof(trackChunks), trackChunks, $"Collection of {nameof(TrackChunk)} is empty."); trackChunks.Select(c => c.Events).ReplaceTempoMap(tempoMap); }
/// <summary> /// Replaces tempo map contained in the specified collection of the <see cref="EventsCollection" /> with /// another one. /// </summary> /// <param name="eventsCollections">Collection of the <see cref="EventsCollection" /> holding a tempo map to replace.</param> /// <param name="tempoMap">Tempo map to replace the one contained in the <paramref name="eventsCollections" />.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="eventsCollections" /> is null. -or- /// <paramref name="tempoMap" /> is null. /// </exception> /// <exception cref="ArgumentException"><paramref name="eventsCollections" /> is empty.</exception> public static void ReplaceTempoMap(this IEnumerable <EventsCollection> eventsCollections, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(eventsCollections), eventsCollections); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); ThrowIfArgument.IsEmptyCollection(nameof(eventsCollections), eventsCollections, $"Collection of {nameof(EventsCollection)} is empty."); using (var tempoMapManager = eventsCollections.ManageTempoMap(tempoMap.TimeDivision)) { tempoMapManager.ReplaceTempoMap(tempoMap); } }
/// <summary> /// Converts sub-array of the specified bytes to an instance of the <see cref="MidiEvent"/>. /// </summary> /// <param name="bytes">Bytes to take sub-array from.</param> /// <param name="offset">Offset of sub-array to read MIDI event from.</param> /// <param name="length">Length of sub-array to read MIDI event from.</param> /// <returns><see cref="MidiEvent"/> read from <paramref name="bytes"/> starting from /// <paramref name="offset"/> and taking <paramref name="length"/> of bytes.</returns> /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="bytes"/> is an empty array.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is out of range. -or- /// <paramref name="length"/> is out of range.</exception> public MidiEvent Convert(byte[] bytes, int offset, int length) { ThrowIfArgument.IsNull(nameof(bytes), bytes); ThrowIfArgument.IsEmptyCollection(nameof(bytes), bytes, "Bytes is empty array."); ThrowIfArgument.IsOutOfRange(nameof(offset), offset, 0, bytes.Length - 1, "Offset is out of range."); ThrowIfArgument.IsOutOfRange(nameof(length), length, 0, bytes.Length - offset, "Length is out of range."); var dataBytes = new byte[bytes.Length - 1 - offset]; Array.Copy(bytes, offset + 1, dataBytes, 0, dataBytes.Length); return(Convert(bytes[offset], dataBytes)); }
/// <summary> /// Replaces tempo map contained in the specified <see cref="MidiFile" /> with another one. /// </summary> /// <param name="file"><see cref="MidiFile" /> holding a tempo map to replace.</param> /// <param name="tempoMap">Tempo map to replace the one contained in the <paramref name="file" />.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="file" /> is null. -or- /// <paramref name="tempoMap" /> is null. /// </exception> /// <exception cref="ArgumentException"><paramref name="file" /> is empty.</exception> public static void ReplaceTempoMap(this MidiFile file, TempoMap tempoMap) { ThrowIfArgument.IsNull(nameof(file), file); ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap); var trackChunks = file.GetTrackChunks(); ThrowIfArgument.IsEmptyCollection(nameof(trackChunks), trackChunks, $"Collection of {nameof(TrackChunk)} of the file is empty."); trackChunks.ReplaceTempoMap(tempoMap); file.TimeDivision = tempoMap.TimeDivision.Clone(); }
/// <summary> /// Initializes a new instance of the <see cref="TempoMapManager"/> with the specified time division /// and events collections. /// </summary> /// <param name="timeDivision">MIDI file time division which specifies the meaning of the time /// used by events of the file.</param> /// <param name="eventsCollections">Collection of <see cref="EventsCollection"/> which hold events that /// represent tempo map of a MIDI file.</param> /// <exception cref="ArgumentNullException"> /// <para>One of the following errors occured:</para> /// <list type="bullet"> /// <item> /// <description><paramref name="timeDivision"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="eventsCollections"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> /// <exception cref="ArgumentException"><paramref name="eventsCollections"/> is empty.</exception> public TempoMapManager(TimeDivision timeDivision, IEnumerable <EventsCollection> eventsCollections) { ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); ThrowIfArgument.IsNull(nameof(eventsCollections), eventsCollections); ThrowIfArgument.IsEmptyCollection(nameof(eventsCollections), eventsCollections, $"Collection of {nameof(EventsCollection)} is empty."); _timedEventsManagers = eventsCollections.Where(events => events != null) .Select(events => events.ManageTimedEvents()) .ToList(); // TempoMap = new TempoMap(timeDivision); CollectTimeSignatureChanges(); CollectTempoChanges(); }