Beispiel #1
0
 // Token: 0x0600348C RID: 13452 RVA: 0x00018286 File Offset: 0x00016486
 public static IEnumerable <TrackChunk> Explode(this TrackChunk trackChunk)
 {
     return(TrackChunkUtilities.ConvertTrackChunks(new TrackChunk[]
     {
         trackChunk
     }, MidiFileFormat.MultiTrack));
 }
        public IEnumerable <MidiChunk> Convert(IEnumerable <MidiChunk> chunks)
        {
            if (chunks == null)
            {
                throw new ArgumentNullException(nameof(chunks));
            }

            //

            var trackChunks = chunks.OfType <TrackChunk>().ToArray();

            if (trackChunks.Length == 1)
            {
                return(chunks);
            }

            //

            var eventsDescriptors = trackChunks
                                    .SelectMany(trackChunk =>
            {
                var absoluteTime = 0L;
                var channel      = -1;
                return(trackChunk.Events
                       .Select(midiEvent =>
                {
                    var channelPrefixEvent = midiEvent as ChannelPrefixEvent;
                    if (channelPrefixEvent != null)
                    {
                        channel = channelPrefixEvent.Channel;
                    }

                    if (!(midiEvent is MetaEvent))
                    {
                        channel = -1;
                    }

                    return new EventDescriptor(midiEvent, (absoluteTime += midiEvent.DeltaTime), channel);
                }));
            })
                                    .OrderBy(d => d, new EventDescriptorComparer());

            //

            var resultTrackChunk = new TrackChunk();
            var time             = 0L;

            foreach (var eventDescriptor in eventsDescriptors)
            {
                var midiEvent = (MidiEvent)eventDescriptor.Event.Clone();
                midiEvent.DeltaTime = eventDescriptor.AbsoluteTime - time;
                resultTrackChunk.Events.Add(midiEvent);

                time = eventDescriptor.AbsoluteTime;
            }

            //

            return(new[] { resultTrackChunk }.Concat(chunks.Where(c => !(c is TrackChunk))));
        }
Beispiel #3
0
        private static ushort?GetSequenceNumber(TrackChunk trackChunk)
        {
            ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk);

            return(trackChunk.Events
                   .TakeWhile(m => m.DeltaTime == 0)
                   .OfType <SequenceNumberEvent>()
                   .FirstOrDefault()
                   ?.Number);
        }
        // Token: 0x06003247 RID: 12871 RVA: 0x001474FC File Offset: 0x001456FC
        private static ushort?GetSequenceNumber(TrackChunk trackChunk)
        {
            SequenceNumberEvent sequenceNumberEvent = trackChunk.Events.TakeWhile((MidiEvent m) => m.DeltaTime == 0L).OfType <SequenceNumberEvent>().FirstOrDefault <SequenceNumberEvent>();

            if (sequenceNumberEvent == null)
            {
                return(null);
            }
            return(new ushort?(sequenceNumberEvent.Number));
        }
Beispiel #5
0
        private static ushort?GetSequenceNumber(TrackChunk trackChunk)
        {
            if (trackChunk == null)
            {
                throw new ArgumentNullException(nameof(trackChunk));
            }

            return(trackChunk.Events
                   .TakeWhile(m => m.DeltaTime == 0)
                   .OfType <SequenceNumberEvent>()
                   .FirstOrDefault()
                   ?.Number);
        }
        // Token: 0x06003262 RID: 12898 RVA: 0x0014778C File Offset: 0x0014598C
        public IEnumerable <MidiChunk> Convert(IEnumerable <MidiChunk> chunks)
        {
            TrackChunk[] array = chunks.OfType <TrackChunk>().ToArray <TrackChunk>();
            if (array.Length == 1)
            {
                return(chunks);
            }
            MidiEvent midiEvent;
            IEnumerable <SingleTrackChunksConverter.EventDescriptor> enumerable = array.SelectMany(delegate(TrackChunk trackChunk)
            {
                long absoluteTime = 0L;
                int channel       = -1;
                return(trackChunk.Events.Select(delegate(MidiEvent midiEvent)
                {
                    ChannelPrefixEvent channelPrefixEvent = midiEvent as ChannelPrefixEvent;
                    if (channelPrefixEvent != null)
                    {
                        channel = (int)channelPrefixEvent.Channel;
                    }
                    if (!(midiEvent is MetaEvent))
                    {
                        channel = -1;
                    }
                    return new SingleTrackChunksConverter.EventDescriptor(midiEvent, absoluteTime += midiEvent.DeltaTime, channel);
                }));
            }).OrderBy((SingleTrackChunksConverter.EventDescriptor d) => d, new SingleTrackChunksConverter.EventDescriptorComparer());
            TrackChunk trackChunk2 = new TrackChunk();
            long       num         = 0L;

            foreach (SingleTrackChunksConverter.EventDescriptor eventDescriptor in enumerable)
            {
                midiEvent           = eventDescriptor.Event.Clone();
                midiEvent.DeltaTime = eventDescriptor.AbsoluteTime - num;
                trackChunk2.Events.Add(midiEvent);
                num = eventDescriptor.AbsoluteTime;
            }
            return(new TrackChunk[]
            {
                trackChunk2
            }.Concat(from c in chunks
                     where !(c is TrackChunk)
                     select c));
        }
Beispiel #7
0
        // Token: 0x06003410 RID: 13328 RVA: 0x00148C28 File Offset: 0x00146E28
        private static MidiChunk ReadChunk(MidiReader reader, ReadingSettings settings, int actualTrackChunksCount, int?expectedTrackChunksCount)
        {
            MidiChunk midiChunk = null;

            try
            {
                string text = reader.ReadString(4);
                if (text.Length < 4)
                {
                    NotEnoughBytesPolicy notEnoughBytesPolicy = settings.NotEnoughBytesPolicy;
                    if (notEnoughBytesPolicy == NotEnoughBytesPolicy.Abort)
                    {
                        throw new NotEnoughBytesException("Chunk ID cannot be read since the reader's underlying stream doesn't have enough bytes.", 4L, (long)text.Length);
                    }
                    if (notEnoughBytesPolicy == NotEnoughBytesPolicy.Ignore)
                    {
                        return(null);
                    }
                }
                if (!(text == "MThd"))
                {
                    if (!(text == "MTrk"))
                    {
                        midiChunk = MidiFile.TryCreateChunk(text, settings.CustomChunkTypes);
                    }
                    else
                    {
                        midiChunk = new TrackChunk();
                    }
                }
                else
                {
                    midiChunk = new HeaderChunk();
                }
                if (midiChunk == null)
                {
                    switch (settings.UnknownChunkIdPolicy)
                    {
                    case UnknownChunkIdPolicy.ReadAsUnknownChunk:
                        midiChunk = new UnknownChunk(text);
                        break;

                    case UnknownChunkIdPolicy.Skip:
                    {
                        uint num = reader.ReadDword();
                        reader.Position += (long)((ulong)num);
                        return(null);
                    }

                    case UnknownChunkIdPolicy.Abort:
                        throw new UnknownChunkException("'" + text + "' chunk ID is unknown.", text);
                    }
                }
                if (midiChunk is TrackChunk && expectedTrackChunksCount != null)
                {
                    int?num2 = expectedTrackChunksCount;
                    if (actualTrackChunksCount >= num2.GetValueOrDefault() & num2 != null)
                    {
                        MidiFile.ReactOnUnexpectedTrackChunksCount(settings.UnexpectedTrackChunksCountPolicy, actualTrackChunksCount, expectedTrackChunksCount.Value);
                        ExtraTrackChunkPolicy extraTrackChunkPolicy = settings.ExtraTrackChunkPolicy;
                        if (extraTrackChunkPolicy != ExtraTrackChunkPolicy.Read && extraTrackChunkPolicy == ExtraTrackChunkPolicy.Skip)
                        {
                            uint num3 = reader.ReadDword();
                            reader.Position += (long)((ulong)num3);
                            return(null);
                        }
                    }
                }
                midiChunk.Read(reader, settings);
            }
            catch (NotEnoughBytesException exception)
            {
                MidiFile.ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, exception);
            }
            catch (EndOfStreamException exception2)
            {
                MidiFile.ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, exception2);
            }
            return(midiChunk);
        }
Beispiel #8
0
        /// <summary>
        /// Reads a chunk from a MIDI-file.
        /// </summary>
        /// <param name="reader">Reader to read a chunk with.</param>
        /// <param name="settings">Settings according to which a chunk must be read.</param>
        /// <param name="actualTrackChunksCount">Actual count of track chunks at the moment.</param>
        /// <param name="expectedTrackChunksCount">Expected count of track chunks.</param>
        /// <returns>A MIDI-file chunk.</returns>
        /// <exception cref="ObjectDisposedException">Method was called after the reader was disposed.</exception>
        /// <exception cref="IOException">An I/O error occurred on the underlying stream.</exception>
        /// <exception cref="UnknownChunkException">Chunk to be read has unknown ID and that
        /// should be treated as error accordng to the specified <paramref name="settings"/>.</exception>
        /// <exception cref="UnexpectedTrackChunksCountException">Actual track chunks
        /// count is greater than expected one and that should be treated as error according to
        /// the specified <paramref name="settings"/>.</exception>
        /// <exception cref="InvalidChunkSizeException">Actual chunk's size differs from the one declared
        /// in its header and that should be treated as error according to the specified
        /// <paramref name="settings"/>.</exception>
        /// <exception cref="UnknownChannelEventException">Reader has encountered an unknown channel event.</exception>
        /// <exception cref="NotEnoughBytesException">Value cannot be read since the reader's underlying stream
        /// doesn't have enough bytes.</exception>
        /// <exception cref="UnexpectedRunningStatusException">Unexpected running status is encountered.</exception>
        /// <exception cref="MissedEndOfTrackEventException">Track chunk doesn't end with End Of Track event and that
        /// should be treated as error accordng to the specified <paramref name="settings"/>.</exception>
        /// <exception cref="InvalidChannelEventParameterValueException">Value of a channel event's parameter
        /// just read is invalid.</exception>
        /// <exception cref="InvalidMetaEventParameterValueException">Value of a meta event's parameter
        /// just read is invalid.</exception>
        private static MidiChunk ReadChunk(MidiReader reader, ReadingSettings settings, int actualTrackChunksCount, int?expectedTrackChunksCount)
        {
            MidiChunk chunk = null;

            try
            {
                var chunkId = reader.ReadString(MidiChunk.IdLength);
                if (chunkId.Length < MidiChunk.IdLength)
                {
                    switch (settings.NotEnoughBytesPolicy)
                    {
                    case NotEnoughBytesPolicy.Abort:
                        throw new NotEnoughBytesException("Chunk ID cannot be read since the reader's underlying stream doesn't have enough bytes.",
                                                          MidiChunk.IdLength,
                                                          chunkId.Length);

                    case NotEnoughBytesPolicy.Ignore:
                        return(null);
                    }
                }

                //

                switch (chunkId)
                {
                case HeaderChunk.Id:
                    chunk = new HeaderChunk();
                    break;

                case TrackChunk.Id:
                    chunk = new TrackChunk();
                    break;

                default:
                    chunk = TryCreateChunk(chunkId, settings.CustomChunkTypes);
                    break;
                }

                //

                if (chunk == null)
                {
                    switch (settings.UnknownChunkIdPolicy)
                    {
                    case UnknownChunkIdPolicy.ReadAsUnknownChunk:
                        chunk = new UnknownChunk(chunkId);
                        break;

                    case UnknownChunkIdPolicy.Skip:
                        var size = reader.ReadDword();
                        reader.Position += size;
                        return(null);

                    case UnknownChunkIdPolicy.Abort:
                        throw new UnknownChunkException($"'{chunkId}' chunk ID is unknown.", chunkId);
                    }
                }

                //

                if (chunk is TrackChunk && expectedTrackChunksCount != null && actualTrackChunksCount >= expectedTrackChunksCount)
                {
                    ReactOnUnexpectedTrackChunksCount(settings.UnexpectedTrackChunksCountPolicy, actualTrackChunksCount, expectedTrackChunksCount.Value);

                    switch (settings.ExtraTrackChunkPolicy)
                    {
                    case ExtraTrackChunkPolicy.Read:
                        break;

                    case ExtraTrackChunkPolicy.Skip:
                        var size = reader.ReadDword();
                        reader.Position += size;
                        return(null);
                    }
                }

                //

                chunk.Read(reader, settings);
            }
            catch (NotEnoughBytesException ex)
            {
                ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, ex);
            }
            catch (EndOfStreamException ex)
            {
                ReactOnNotEnoughBytes(settings.NotEnoughBytesPolicy, ex);
            }

            return(chunk);
        }
        /// <summary>
        /// Splits a track chunk into multiple ones that correspond to <see cref="MidiFileFormat.MultiTrack"/>.
        /// </summary>
        /// <param name="trackChunk">Track chunk to split into multiple ones.</param>
        /// <returns>Multiple track chunks that represent <paramref name="trackChunk"/>.</returns>
        /// <remarks>
        /// Note that events will be cloned so events in the result track chunks will not be equal
        /// by reference to events in the <paramref name="trackChunk"/>.
        /// </remarks>
        /// <exception cref="ArgumentNullException"><paramref name="trackChunk"/> is null.</exception>
        public static IEnumerable <TrackChunk> Explode(this TrackChunk trackChunk)
        {
            ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk);

            return(ConvertTrackChunks(new[] { trackChunk }, MidiFileFormat.MultiTrack));
        }
Beispiel #10
0
        /// <summary>
        /// Gets all channel numbers presented in the specified <see cref="TrackChunk"/>.
        /// </summary>
        /// <param name="trackChunk"><see cref="TrackChunk"/> to get channels of.</param>
        /// <returns>Collection of channel numbers presented in the <paramref name="trackChunk"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="trackChunk"/> is null.</exception>
        public static IEnumerable <FourBitNumber> GetChannels(this TrackChunk trackChunk)
        {
            ThrowIfArgument.IsNull(nameof(trackChunk), trackChunk);

            return(trackChunk.Events.OfType <ChannelEvent>().Select(e => e.Channel).Distinct().ToArray());
        }
Beispiel #11
0
        // Token: 0x06003234 RID: 12852 RVA: 0x001470DC File Offset: 0x001452DC
        private void ProcessEvents(WritingSettings settings, Action <IEventWriter, MidiEvent, bool> eventHandler)
        {
            byte?b     = null;
            bool flag  = true;
            bool flag2 = true;
            bool flag3 = true;

            foreach (MidiEvent midiEvent in this.Events.Concat(new EndOfTrackEvent[]
            {
                new EndOfTrackEvent()
            }))
            {
                if (!(midiEvent is UnknownMetaEvent) || !settings.CompressionPolicy.HasFlag(CompressionPolicy.DeleteUnknownMetaEvents))
                {
                    if (settings.CompressionPolicy.HasFlag(CompressionPolicy.NoteOffAsSilentNoteOn))
                    {
                        NoteOffEvent noteOffEvent = midiEvent as NoteOffEvent;
                        if (noteOffEvent != null)
                        {
                            midiEvent = new NoteOnEvent
                            {
                                DeltaTime  = noteOffEvent.DeltaTime,
                                Channel    = noteOffEvent.Channel,
                                NoteNumber = noteOffEvent.NoteNumber
                            };
                        }
                    }
                    if ((!settings.CompressionPolicy.HasFlag(CompressionPolicy.DeleteDefaultSetTempo) || !TrackChunk.TrySkipDefaultSetTempo(midiEvent, ref flag)) && (!settings.CompressionPolicy.HasFlag(CompressionPolicy.DeleteDefaultKeySignature) || !TrackChunk.TrySkipDefaultKeySignature(midiEvent, ref flag2)) && (!settings.CompressionPolicy.HasFlag(CompressionPolicy.DeleteDefaultTimeSignature) || !TrackChunk.TrySkipDefaultTimeSignature(midiEvent, ref flag3)))
                    {
                        IEventWriter writer = EventWriterFactory.GetWriter(midiEvent);
                        bool         arg;
                        if (midiEvent is ChannelEvent)
                        {
                            byte statusByte = writer.GetStatusByte(midiEvent);
                            byte?b2         = b;
                            int? num        = (b2 != null) ? new int?((int)b2.GetValueOrDefault()) : null;
                            int  num2       = (int)statusByte;
                            arg = (!(num.GetValueOrDefault() == num2 & num != null) || !settings.CompressionPolicy.HasFlag(CompressionPolicy.UseRunningStatus));
                            b   = new byte?(statusByte);
                        }
                        else
                        {
                            b   = null;
                            arg = true;
                        }
                        eventHandler(writer, midiEvent, arg);
                    }
                }
            }
        }