Beispiel #1
0
        /// <summary>
        /// Writes the chunk object <paramref name="instance"/> to the stream.
        /// </summary>
        /// <param name="context">Must not be null.</param>
        /// <param name="instance">Must not be null.</param>
        public override void Write(ChunkFileContext context, object instance)
        {
            Check.IfArgumentNull(context, nameof(context));
            Check.IfArgumentNull(instance, nameof(instance));
            Check.IfArgumentNotOfType <MTrkChunk>(instance, nameof(instance));

            var trackChunk = (MTrkChunk)instance;
            var writer     = context.Services.GetService <FileChunkWriter>();
            var stream     = writer.CurrentStream;
            var midiWriter = new MidiFileStreamWriter(stream);

            foreach (var message in trackChunk.Events)
            {
                if (message.Message is MidiShortMessage shortMessage)
                {
                    midiWriter.WriteMidiEvent(message.DeltaTime, shortMessage.Data);
                }
                else
                {
                    if (message.Message is MidiMetaMessage metaMsg)
                    {
                        midiWriter.WriteMetaEvent(message.DeltaTime, metaMsg.MetaType, metaMsg.GetData());
                    }
                    if (message.Message is MidiSysExMessage sysexMsg)
                    {
                        midiWriter.WriteSysExEvent(message.DeltaTime, sysexMsg.GetData(), sysexMsg.IsContinuation);
                    }
                }
            }
        }
Beispiel #2
0
        public override void Write(ChunkFileContext context, object instance)
        {
            Check.IfArgumentNull(context, "context");
            Check.IfArgumentNull(instance, "instance");
            Check.IfArgumentNotOfType <MTrkChunk>(instance, "instance");

            var trackChunk = (MTrkChunk)instance;
            var writer     = context.CompositionContainer.GetService <FileChunkWriter>();
            var stream     = writer.CurrentStream;
            var midiWriter = new MidiFileStreamWriter(stream);

            foreach (var message in trackChunk.Events)
            {
                if (message.Message is MidiShortMessage)
                {
                    midiWriter.WriteMidiEvent(message.DeltaTime, ((MidiShortMessage)message.Message).Data);
                }
                else
                {
                    var metaMsg  = message.Message as MidiMetaMessage;
                    var sysexMsg = message.Message as MidiSysExMessage;

                    if (metaMsg != null)
                    {
                        midiWriter.WriteMetaEvent(message.DeltaTime, metaMsg.MetaType, metaMsg.GetData());
                    }
                    if (sysexMsg != null)
                    {
                        midiWriter.WriteSysExEvent(message.DeltaTime, sysexMsg.GetData(), sysexMsg.IsContinuation);
                    }
                }
            }
        }
Beispiel #3
0
        public override void Write(ChunkFileContext context, object instance)
        {
            Check.IfArgumentNull(context, "context");
            Check.IfArgumentNull(instance, "instance");
            Check.IfArgumentNotOfType <ListChunk>(instance, "instance");

            var listChunk = (ListChunk)instance;

            if (listChunk.InnerChunks == null)
            {
                throw new ArgumentException("No LIST content found.", "instance");
            }

            listChunk.ItemType = new FourCharacterCode(GetCollectionItemChunkId(listChunk.InnerChunks));

            // write out LIST chunk
            base.Write(context, instance);

            var writer = context.CompositionContainer.GetService <FileChunkWriter>();

            foreach (var item in listChunk.InnerChunks)
            {
                writer.WriteRuntimeChunkType(item);
            }
        }
Beispiel #4
0
        public override object Read(ChunkFileContext context)
        {
            // create instance and read type
            var riffChunk = base.Read(context) as RiffChunk;

            if (riffChunk == null)
            {
                throw new InvalidOperationException();
            }

            // read child chunk of 'type'
            var reader = context.CompositionContainer.GetService <FileChunkReader>();
            var stream = reader.CurrentStream;

            riffChunk.InnerChunk = reader.ReadRuntimeContainerChunkType(stream, riffChunk.FileType);

            // the 4CC FileType was not found as a runtime chunk type.
            if (riffChunk.InnerChunk == null)
            {
                // normally we'd skip an unknown chunk but at the root its no use.
                var msg = String.Format(
                    CultureInfo.InvariantCulture,
                    "The Four Character Code '{0}' specified in the RIFF (root) chunk could not be mapped to a CLR Type.",
                    riffChunk.FileType);

                throw new ChunkFileException(msg);
            }

            return(riffChunk);
        }
        public virtual ChunkFileContext Detach()
        {
            Context.Services.RemoveService(GetType());

            var context = Context;

            Context = null;
            return(context);
        }
        public static ChunkFileContext CreateFileContextForReading(string filePath)
        {
            var context = new ChunkFileContext();

            context.ChunkFile = ChunkFileInfo.OpenRead(filePath);

            context.CompositionContainer = CreateCompositionContextForReading();

            return(context);
        }
Beispiel #7
0
        public override object Read(ChunkFileContext context)
        {
            Contract.Requires(context.CompositionContainer != null);
            Check.IfArgumentNull(context, "context");
            Check.IfArgumentNull(context.ChunkStack, "context.ChunkStack");
            Check.IfArgumentNull(context.ChunkStack.CurrentChunk, "context.ChunkStack.CurrentChunk");
            Check.IfArgumentNull(context.CompositionContainer, "context.CompositionContainer");

            // create instance and read type
            var listChunk = base.Read(context) as ListChunk;

            if (listChunk == null)
            {
                throw new InvalidOperationException();
            }

            // read child chunk of 'type'
            var reader = context.CompositionContainer.GetService <FileChunkReader>();
            var chunk  = context.ChunkStack.CurrentChunk;

            var   stream   = chunk.DataStream;
            var   itemType = LookupItemType(context, listChunk.ItemType);
            IList children = null;

            if (itemType != null)
            {
                // create a generic list with the correct item type.
                var listType = typeof(List <>).MakeGenericType(new[] { itemType });
                children = (IList)Activator.CreateInstance(listType);
            }

            // while there is still data in the stream
            while (stream.Position < stream.Length)
            {
                var runtimeObj = reader.ReadRuntimeContainerChunkType(stream, listChunk.ItemType);

                // check if CLR type could be found for 'ItemType'.
                if (runtimeObj != null && children != null)
                {
                    children.Add(runtimeObj);
                }
            }

            if (children != null)
            {
                listChunk.InnerChunks = children.Cast <object>();
            }

            return(children);
        }
Beispiel #8
0
        /// <summary>
        /// Write event data to a Midi file using a prepared chunk-file context.
        /// </summary>
        /// <param name="midiFile">The Midi file data to write. Must not be null.</param>
        /// <param name="context">Must not be null or empty.</param>
        /// <remarks>May throw exceptions.</remarks>
        public static void Write(MidiFile midiFile, ChunkFileContext context)
        {
            Check.IfArgumentNull(midiFile, nameof(midiFile));
            Check.IfArgumentNull(context, nameof(context));

            var writer = new FileChunkWriter(context);

            writer.WriteNextChunk(midiFile.Header);

            foreach (var track in midiFile.Tracks)
            {
                writer.WriteNextChunk(track);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Reads the midi track from the midi file.
        /// </summary>
        /// <param name="context">File context of the midi file being read. Must not be null.</param>
        /// <returns>Returns the custom chunk object containing the data that was read.</returns>
        public override object Read(ChunkFileContext context)
        {
            Check.IfArgumentNull(context, nameof(context));

            var reader = context.Services.GetService <FileChunkReader>();
            var stream = reader.CurrentStream;
            var chunk  = new MTrkChunk();
            var events = new List <MidiFileEvent>();

            chunk.Events = events;

            var midiReader = new MidiFileStreamReader(stream);

            // use the indication to copy buffers.
            _midiMessageFactory.CopyData = context.CopyStreams;

            while (midiReader.ReadNextEvent())
            {
                MidiFileEvent midiEvent = null;

                switch (midiReader.EventType)
                {
                case MidiFileEventType.Event:
                    midiEvent = CreateMidiEvent(midiReader.AbsoluteTime, midiReader.DeltaTime, midiReader.MidiEvent);
                    break;

                case MidiFileEventType.SystemExclusive:
                    midiEvent = CreateSysExEvent(midiReader.AbsoluteTime, midiReader.DeltaTime, midiReader.Data, false);
                    break;

                case MidiFileEventType.SystemExclusiveContinuation:
                    midiEvent = CreateSysExEvent(midiReader.AbsoluteTime, midiReader.DeltaTime, midiReader.Data, true);
                    break;

                case MidiFileEventType.Meta:
                    midiEvent = CreateMetaEvent(midiReader.AbsoluteTime, midiReader.DeltaTime, midiReader.MetaEvent, midiReader.Data);
                    break;
                }

                if (midiEvent != null)
                {
                    events.Add(midiEvent);
                }
            }

            return(chunk);
        }
Beispiel #10
0
        public static ChunkFileContext CreateFileContextForWriting(string filePath, bool littleEndian)
        {
            Assert.IsNotNull(filePath);
            Assert.IsTrue(Directory.Exists(Path.GetDirectoryName(filePath)));

            var context = new ChunkFileContext();

            context.ChunkFile = ChunkFileInfo.OpenWrite(filePath);

            Assert.IsNotNull(context.ChunkFile);
            Assert.IsNotNull(context.ChunkFile.BaseStream);

            context.CompositionContainer = CreateCompositionContext(littleEndian);

            Assert.IsNotNull(context.CompositionContainer);

            return(context);
        }
Beispiel #11
0
        public static ChunkFileContext CreateFileContextForReading(string filePath, bool littleEndian)
        {
            Assert.IsNotNull(filePath);
            Assert.IsTrue(File.Exists(filePath));

            var context = new ChunkFileContext();

            context.ChunkFile = ChunkFileInfo.OpenRead(filePath);

            Assert.IsNotNull(context.ChunkFile);
            Assert.IsNotNull(context.ChunkFile.BaseStream);

            context.CompositionContainer = CreateCompositionContext(littleEndian);

            Assert.IsNotNull(context.CompositionContainer);

            return(context);
        }
Beispiel #12
0
        /// <summary>
        /// Read event data of a Midi file prepared chunk-file context.
        /// </summary>
        /// <param name="context">Must not be null.</param>
        /// <returns>Never returns null.</returns>
        /// <remarks>May throw exceptions.</remarks>
        public static MidiFile Read(ChunkFileContext context)
        {
            Check.IfArgumentNull(context, nameof(context));

            var reader = new FileChunkReader(context);
            var file   = new MidiFile
            {
                Header = reader.ReadNextChunk() as MThdChunk
            };

            var tracks = new List <MTrkChunk>();

            for (int i = 0; i < file.Header.NumberOfTracks; i++)
            {
                var track = reader.ReadNextChunk() as MTrkChunk;
                tracks.Add(track);
            }

            file.Tracks = tracks;
            return(file);
        }
Beispiel #13
0
        public override void Write(ChunkFileContext context, object instance)
        {
            Check.IfArgumentNull(context, "context");
            Check.IfArgumentNull(instance, "instance");
            Check.IfArgumentNotOfType <RiffChunk>(instance, "instance");

            var chunk = (RiffChunk)instance;

            if (chunk.InnerChunk == null)
            {
                throw new ArgumentException("No RIFF chunk content found.", "instance");
            }

            // make sure the correct file type is set.
            chunk.FileType = new FourCharacterCode(ChunkAttribute.GetChunkId(chunk.InnerChunk));

            // write out RIFF file type
            base.Write(context, instance);

            var writer = context.CompositionContainer.GetService <FileChunkWriter>();

            writer.WriteRuntimeChunkType(chunk.InnerChunk);
        }
Beispiel #14
0
        /// <summary>
        /// Helper to find the runtime Type for a chunk.
        /// </summary>
        /// <param name="context">Must not be null.</param>
        /// <param name="chunkId">Must not be null.</param>
        /// <returns>Returns null when not found.</returns>
        private static Type LookupItemType(ChunkFileContext context, FourCharacterCode chunkId)
        {
            var factory = context.CompositionContainer.GetService <IChunkTypeFactory>();

            return(factory.LookupChunkObjectType(chunkId));
        }
 protected ChunkFileContextOwner(ChunkFileContext context)
 {
     Check.IfArgumentNull(context, nameof(context));
     Context = context;
 }