Ejemplo n.º 1
0
 /// <summary>
 /// Writes content of a MIDI meta event.
 /// </summary>
 /// <param name="writer">Writer to write the content with.</param>
 /// <param name="settings">Settings according to which the event's content must be written.</param>
 protected override void WriteContent(MidiWriter writer, WritingSettings settings)
 {
     writer.WriteByte(Numerator);
     writer.WriteByte((byte)Math.Log(Denominator, 2));
     writer.WriteByte(ClocksPerClick);
     writer.WriteByte(ThirtySecondNotesPerBeat);
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Writes content of a MIDI event.
 /// </summary>
 /// <param name="writer">Writer to write the content with.</param>
 /// <param name="settings">Settings according to which the event's content must be written.</param>
 internal sealed override void Write(MidiWriter writer, WritingSettings settings)
 {
     foreach (var parameter in _parameters)
     {
         writer.WriteByte(parameter);
     }
 }
Ejemplo n.º 3
0
        public void Write(MidiEvent midiEvent, MidiWriter writer, WritingSettings settings, bool writeStatusByte)
        {
            if (writeStatusByte)
            {
                writer.WriteByte(EventStatusBytes.Global.Meta);
            }

            //

            byte statusByte;

            var unknownMetaEvent = midiEvent as UnknownMetaEvent;

            if (unknownMetaEvent != null)
            {
                statusByte = unknownMetaEvent.StatusByte;
            }
            else
            {
                var eventType = midiEvent.GetType();
                if (!StandardEventTypes.Meta.TryGetStatusByte(eventType, out statusByte) && settings.CustomMetaEventTypes?.TryGetStatusByte(eventType, out statusByte) != true)
                {
                    Debug.Fail($"Unable to write the {eventType} event.");
                }
            }

            writer.WriteByte(statusByte);

            //

            var contentSize = midiEvent.GetSize(settings);

            writer.WriteVlqNumber(contentSize);
            midiEvent.Write(writer, settings);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MidiEventToBytesConverter"/> with the specified
        /// initial capacity of internal buffer.
        /// </summary>
        /// <param name="capacity">Initial capacity of the internal buffer.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is negative.</exception>
        public MidiEventToBytesConverter(int capacity)
        {
            ThrowIfArgument.IsNegative(nameof(capacity), capacity, "Capacity is negative.");

            _dataBytesStream = new MemoryStream(capacity);
            _midiWriter      = new MidiWriter(_dataBytesStream);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Writes current <see cref="MidiFile"/> to the stream.
        /// </summary>
        /// <param name="stream">Stream to write file's data to.</param>
        /// <param name="format">Format of the file to be written.</param>
        /// <param name="settings">Settings according to which the file must be written. Specify <c>null</c> to use
        /// default settings.</param>
        /// <exception cref="ArgumentNullException"><paramref name="stream"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException"><paramref name="stream"/> doesn't support writing.</exception>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="format"/> specified an invalid value.</exception>
        /// <exception cref="InvalidOperationException">Time division is <c>null</c>.</exception>
        /// <exception cref="IOException">An I/O error occurred while writing to the stream.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="stream"/> is disposed.</exception>
        /// <exception cref="TooManyTrackChunksException">Count of track chunks presented in the file
        /// exceeds maximum value allowed for MIDI file.</exception>
        public void Write(Stream stream, MidiFileFormat format = MidiFileFormat.MultiTrack, WritingSettings settings = null)
        {
            ThrowIfArgument.IsNull(nameof(stream), stream);
            ThrowIfArgument.IsInvalidEnumValue(nameof(format), format);

            if (TimeDivision == null)
            {
                throw new InvalidOperationException("Time division is null.");
            }

            if (!stream.CanWrite)
            {
                throw new ArgumentException("Stream doesn't support writing.", nameof(stream));
            }

            //

            if (settings == null)
            {
                settings = new WritingSettings();
            }

            if (settings.WriterSettings == null)
            {
                settings.WriterSettings = new WriterSettings();
            }

            using (var writer = new MidiWriter(stream, settings.WriterSettings))
            {
                var chunksConverter = ChunksConverterFactory.GetConverter(format);
                var chunks          = chunksConverter.Convert(Chunks);

                if (settings.WriteHeaderChunk)
                {
                    var trackChunksCount = chunks.Count(c => c is TrackChunk);
                    if (trackChunksCount > ushort.MaxValue)
                    {
                        throw new TooManyTrackChunksException(trackChunksCount);
                    }

                    var headerChunk = new HeaderChunk
                    {
                        FileFormat   = (ushort)format,
                        TimeDivision = TimeDivision,
                        TracksNumber = (ushort)trackChunksCount
                    };
                    headerChunk.Write(writer, settings);
                }

                foreach (var chunk in chunks)
                {
                    if (chunk is UnknownChunk && settings.DeleteUnknownChunks)
                    {
                        continue;
                    }

                    chunk.Write(writer, settings);
                }
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Writes content of a <see cref="TrackChunk"/>.
 /// </summary>
 /// <remarks>
 /// Content of a <see cref="TrackChunk"/> is collection of MIDI events.
 /// </remarks>
 /// <param name="writer">Writer to write the chunk's content with.</param>
 /// <param name="settings">Settings according to which the chunk's content must be written.</param>
 /// <exception cref="ObjectDisposedException">Method was called after the writer's underlying stream was disposed.</exception>
 /// <exception cref="IOException">An I/O error occurred on the writer's underlying stream.</exception>
 protected override void WriteContent(MidiWriter writer, WritingSettings settings)
 {
     ProcessEvents(settings, (eventWriter, midiEvent, writeStatusByte) =>
     {
         writer.WriteVlqNumber(midiEvent.DeltaTime);
         eventWriter.Write(midiEvent, writer, settings, writeStatusByte);
     });
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Writes content of a MIDI event.
        /// </summary>
        /// <param name="writer">Writer to write the content with.</param>
        /// <param name="settings">Settings according to which the event's content must be written.</param>
        internal sealed override void Write(MidiWriter writer, WritingSettings settings)
        {
            var data = Data;

            if (data != null)
            {
                writer.WriteBytes(data);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="MidiEventToBytesConverter"/> with the specified
        /// initial capacity of internal buffer.
        /// </summary>
        /// <param name="capacity">Initial capacity of the internal buffer.</param>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is negative.</exception>
        public MidiEventToBytesConverter(int capacity)
        {
            ThrowIfArgument.IsNegative(nameof(capacity), capacity, "Capacity is negative.");

            _dataBytesStream = new MemoryStream(capacity);
            _midiWriter      = new MidiWriter(_dataBytesStream, new WriterSettings {
                UseBuffering = false
            });
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Writes content of a MIDI meta event.
        /// </summary>
        /// <param name="writer">Writer to write the content with.</param>
        /// <param name="settings">Settings according to which the event's content must be written.</param>
        protected override void WriteContent(MidiWriter writer, WritingSettings settings)
        {
            var data = Data;

            if (data != null)
            {
                writer.WriteBytes(data);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Writes current <see cref="MidiFile"/> to the stream.
        /// </summary>
        /// <param name="stream">Stream to write file's data to.</param>
        /// <param name="format">Format of the file to be written.</param>
        /// <param name="settings">Settings according to which the file must be written.</param>
        /// <exception cref="ArgumentNullException"><paramref name="stream"/> is null.</exception>
        /// <exception cref="ArgumentException"><paramref name="stream"/> doesn't support writing.</exception>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="format"/> specified an invalid value.</exception>
        /// <exception cref="InvalidOperationException">Time division is null.</exception>
        /// <exception cref="IOException">An I/O error occurred while writing to the stream.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="stream"/> is disposed. -or-
        /// Underlying stream writer is disposed.</exception>
        /// <exception cref="TooManyTrackChunksException">Count of track chunks presented in the file
        /// exceeds maximum value allowed for MIDI file.</exception>
        public void Write(Stream stream, MidiFileFormat format = MidiFileFormat.MultiTrack, WritingSettings settings = null)
        {
            ThrowIfArgument.IsNull(nameof(stream), stream);
            ThrowIfArgument.IsInvalidEnumValue(nameof(format), format);

            if (TimeDivision == null)
            {
                throw new InvalidOperationException("Time division is null.");
            }

            if (!stream.CanWrite)
            {
                throw new ArgumentException("Stream doesn't support writing.", nameof(stream));
            }

            //

            if (settings == null)
            {
                settings = new WritingSettings();
            }

            ValidateCustomMetaEventsStatusBytes(settings.CustomMetaEventTypes);
            ValidateCustomChunksIds(Chunks.Where(c => !(c is TrackChunk) && !(c is HeaderChunk)));

            using (var writer = new MidiWriter(stream))
            {
                var chunksConverter = ChunksConverterFactory.GetConverter(format);
                var chunks          = chunksConverter.Convert(Chunks);

                var trackChunksCount = chunks.Count(c => c is TrackChunk);
                if (trackChunksCount > ushort.MaxValue)
                {
                    throw new TooManyTrackChunksException(
                              $"Count of track chunks to be written ({trackChunksCount}) is greater than the valid maximum ({ushort.MaxValue}).",
                              trackChunksCount);
                }

                var headerChunk = new HeaderChunk
                {
                    FileFormat   = (ushort)format,
                    TimeDivision = TimeDivision,
                    TracksNumber = (ushort)trackChunksCount
                };
                headerChunk.Write(writer, settings);

                foreach (var chunk in chunks)
                {
                    if (settings.CompressionPolicy.HasFlag(CompressionPolicy.DeleteUnknownChunks) && chunk is UnknownChunk)
                    {
                        continue;
                    }

                    chunk.Write(writer, settings);
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Writes chunk to the <see cref="MidiWriter"/>'s underlying stream according to
        /// specified <see cref="WritingSettings"/>.
        /// </summary>
        /// <param name="writer">Writer to write the chunk's data with.</param>
        /// <param name="settings">Settings according to which the chunk's data must be written.</param>
        /// <exception cref="ObjectDisposedException">
        /// Method was called after <paramref name="writer"/> was disposed.
        /// </exception>
        /// <exception cref="IOException">
        /// An I/O error occurred on the <paramref name="writer"/>'s underlying stream.
        /// </exception>
        internal void Write(MidiWriter writer, WritingSettings settings)
        {
            writer.WriteString(ChunkId);

            var size = GetContentSize(settings);

            writer.WriteDword(size);

            WriteContent(writer, settings);
        }
Ejemplo n.º 12
0
        internal override void Write(MidiWriter writer, WritingSettings settings)
        {
            var component = Component;

            var componentValueMask = ComponentValueMasks[component];
            var componentValue     = ComponentValue & componentValueMask;

            var data = DataTypesUtilities.CombineAsFourBitNumbers((byte)component, (byte)componentValue);

            writer.WriteByte(data);
        }
Ejemplo n.º 13
0
        public void Write(MidiEvent midiEvent, MidiWriter writer, WritingSettings settings, bool writeStatusByte)
        {
            if (writeStatusByte)
            {
                var statusByte = GetStatusByte(midiEvent);
                writer.WriteByte(statusByte);
            }

            //

            midiEvent.Write(writer, settings);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Writes content of a MIDI meta event.
        /// </summary>
        /// <param name="writer">Writer to write the content with.</param>
        /// <param name="settings">Settings according to which the event's content must be written.</param>
        protected sealed override void WriteContent(MidiWriter writer, WritingSettings settings)
        {
            var text = Text;

            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            var encoding = settings.TextEncoding ?? SmfConstants.DefaultTextEncoding;
            var bytes    = encoding.GetBytes(text);

            writer.WriteBytes(bytes);
        }
        public void Write(MidiEvent midiEvent, MidiWriter writer, WritingSettings settings, bool writeStatusByte)
        {
            if (writeStatusByte)
            {
                var statusByte = GetStatusByte(midiEvent);
                writer.WriteByte(statusByte);
            }

            //

            var contentSize = midiEvent.GetSize(settings);

            writer.WriteVlqNumber(contentSize);
            midiEvent.Write(writer, settings);
        }
Ejemplo n.º 16
0
        public void Write(MidiEvent midiEvent, MidiWriter writer, WritingSettings settings, bool writeStatusByte)
        {
            if (writeStatusByte)
            {
                var eventType = midiEvent.GetType();

                byte statusByte;
                if (!StandardEventTypes.SystemCommon.TryGetStatusByte(eventType, out statusByte))
                {
                    Debug.Fail($"Unable to write the {eventType} event.");
                }

                writer.WriteByte(statusByte);
            }

            midiEvent.Write(writer, settings);
        }
Ejemplo n.º 17
0
        public void Write(MidiEvent midiEvent, MidiWriter writer, WritingSettings settings, bool writeStatusByte)
        {
            if (writeStatusByte)
            {
                var eventType = midiEvent.GetType();

                byte statusByte;
                if (!StandardEventTypes.SysEx.TryGetStatusByte(eventType, out statusByte))
                {
                    Debug.Fail($"Unable to write the {eventType} event.");
                }

                writer.WriteByte(statusByte);
            }

            //

            var contentSize = midiEvent.GetSize(settings);

            writer.WriteVlqNumber(contentSize);
            midiEvent.Write(writer, settings);
        }
Ejemplo n.º 18
0
        public void Write(MidiEvent midiEvent, MidiWriter writer, WritingSettings settings, bool writeStatusByte)
        {
            if (writeStatusByte)
            {
                var eventType = midiEvent.GetType();

                byte statusByte;
                if (!StandardEventTypes.Channel.TryGetStatusByte(eventType, out statusByte))
                {
                    Debug.Fail($"Unable to write the {eventType} event.");
                }

                var channel = ((ChannelEvent)midiEvent).Channel;

                var totalStatusByte = DataTypesUtilities.Combine((FourBitNumber)statusByte, channel);
                writer.WriteByte(totalStatusByte);
            }

            //

            midiEvent.Write(writer, settings);
        }
Ejemplo n.º 19
0
 /// <summary>
 /// Writes content of a MIDI meta event.
 /// </summary>
 /// <param name="writer">Writer to write the content with.</param>
 /// <param name="settings">Settings according to which the event's content must be written.</param>
 protected override void WriteContent(MidiWriter writer, WritingSettings settings)
 {
     writer.Write3ByteDword((uint)MicrosecondsPerQuarterNote);
 }
Ejemplo n.º 20
0
        public void Write(MidiEvent midiEvent, MidiWriter writer, WritingSettings settings, bool writeStatusByte)
        {
            if (writeStatusByte)
            {
                writer.WriteByte(EventStatusBytes.Global.Meta);
            }

            //

            byte statusByte = 0;

            switch (midiEvent.EventType)
            {
            case MidiEventType.Lyric:
                statusByte = EventStatusBytes.Meta.Lyric;
                break;

            case MidiEventType.SetTempo:
                statusByte = EventStatusBytes.Meta.SetTempo;
                break;

            case MidiEventType.Text:
                statusByte = EventStatusBytes.Meta.Text;
                break;

            case MidiEventType.SequenceTrackName:
                statusByte = EventStatusBytes.Meta.SequenceTrackName;
                break;

            case MidiEventType.PortPrefix:
                statusByte = EventStatusBytes.Meta.PortPrefix;
                break;

            case MidiEventType.TimeSignature:
                statusByte = EventStatusBytes.Meta.TimeSignature;
                break;

            case MidiEventType.SequencerSpecific:
                statusByte = EventStatusBytes.Meta.SequencerSpecific;
                break;

            case MidiEventType.KeySignature:
                statusByte = EventStatusBytes.Meta.KeySignature;
                break;

            case MidiEventType.Marker:
                statusByte = EventStatusBytes.Meta.Marker;
                break;

            case MidiEventType.ChannelPrefix:
                statusByte = EventStatusBytes.Meta.ChannelPrefix;
                break;

            case MidiEventType.InstrumentName:
                statusByte = EventStatusBytes.Meta.InstrumentName;
                break;

            case MidiEventType.CopyrightNotice:
                statusByte = EventStatusBytes.Meta.CopyrightNotice;
                break;

            case MidiEventType.SmpteOffset:
                statusByte = EventStatusBytes.Meta.SmpteOffset;
                break;

            case MidiEventType.DeviceName:
                statusByte = EventStatusBytes.Meta.DeviceName;
                break;

            case MidiEventType.CuePoint:
                statusByte = EventStatusBytes.Meta.CuePoint;
                break;

            case MidiEventType.ProgramName:
                statusByte = EventStatusBytes.Meta.ProgramName;
                break;

            case MidiEventType.SequenceNumber:
                statusByte = EventStatusBytes.Meta.SequenceNumber;
                break;

            case MidiEventType.EndOfTrack:
                statusByte = EventStatusBytes.Meta.EndOfTrack;
                break;

            case MidiEventType.UnknownMeta:
                statusByte = ((UnknownMetaEvent)midiEvent).StatusByte;
                break;

            default:
            {
                var eventType = midiEvent.GetType();
                if (settings.CustomMetaEventTypes?.TryGetStatusByte(eventType, out statusByte) != true)
                {
                    Debug.Fail($"Unable to write the {eventType} event.");
                }
            }
            break;
            }

            writer.WriteByte(statusByte);

            //

            var contentSize = midiEvent.GetSize(settings);

            writer.WriteVlqNumber(contentSize);
            midiEvent.Write(writer, settings);
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Writes content of a MIDI event.
 /// </summary>
 /// <param name="writer">Writer to write the content with.</param>
 /// <param name="settings">Settings according to which the event's content must be written.</param>
 internal abstract void Write(MidiWriter writer, WritingSettings settings);
Ejemplo n.º 22
0
 /// <summary>
 /// Writes content of a MIDI event.
 /// </summary>
 /// <param name="writer">Writer to write the content with.</param>
 /// <param name="settings">Settings according to which the event's content must be written.</param>
 internal sealed override void Write(MidiWriter writer, WritingSettings settings)
 {
     writer.WriteBytes(_parameters);
 }
Ejemplo n.º 23
0
 internal override void Write(MidiWriter writer, WritingSettings settings)
 {
     writer.WriteByte(_lsb);
     writer.WriteByte(_msb);
 }
Ejemplo n.º 24
0
 internal override sealed void Write(MidiWriter writer, WritingSettings settings)
 {
 }
Ejemplo n.º 25
0
 internal override void Write(MidiWriter writer, WritingSettings settings)
 {
     writer.WriteByte(Number);
 }
Ejemplo n.º 26
0
 /// <summary>
 /// Writes content of a MIDI meta event.
 /// </summary>
 /// <param name="writer">Writer to write the content with.</param>
 /// <param name="settings">Settings according to which the event's content must be written.</param>
 protected override void WriteContent(MidiWriter writer, WritingSettings settings)
 {
     _smpteData.Write(writer.WriteByte);
 }
 internal override void Write(MidiWriter writer, WritingSettings settings)
 {
     writer.WriteByte(_dataByte1);
 }
 /// <summary>
 /// Writes content of a <see cref="HeaderChunk"/>.
 /// </summary>
 /// <remarks>
 /// Content of a <see cref="HeaderChunk"/> is format of the file, number of track chunks and time division.
 /// Six bytes required to write all of this information.
 /// </remarks>
 /// <param name="writer">Writer to write the chunk's content with.</param>
 /// <param name="settings">Settings according to which the chunk's content must be written.</param>
 /// <exception cref="ObjectDisposedException">Method was called after the writer's underlying stream was disposed.</exception>
 /// <exception cref="IOException">An I/O error occurred on the writer's underlying stream.</exception>
 protected override void WriteContent(MidiWriter writer, WritingSettings settings)
 {
     writer.WriteWord(FileFormat);
     writer.WriteWord(TracksNumber);
     writer.WriteInt16(TimeDivision.ToInt16());
 }
Ejemplo n.º 29
0
 /// <summary>
 /// Writes content of a MIDI meta event.
 /// </summary>
 /// <param name="writer">Writer to write the content with.</param>
 /// <param name="settings">Settings according to which the event's content must be written.</param>
 protected override void WriteContent(MidiWriter writer, WritingSettings settings)
 {
     writer.WriteSByte(Key);
     writer.WriteByte(Scale);
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Writes content of a chunk. Content is a part of chunk's data without its header (ID and size).
 /// </summary>
 /// <param name="writer">Writer to write the chunk's content with.</param>
 /// <param name="settings">Settings according to which the chunk's content must be written.</param>
 protected abstract void WriteContent(MidiWriter writer, WritingSettings settings);