/// <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); }
/// <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); } }
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); }
/// <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); }
/// <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); } } }
/// <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); }); }
/// <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 }); }
/// <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); } }
/// <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); } } }
/// <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); }
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); }
public void Write(MidiEvent midiEvent, MidiWriter writer, WritingSettings settings, bool writeStatusByte) { if (writeStatusByte) { var statusByte = GetStatusByte(midiEvent); writer.WriteByte(statusByte); } // midiEvent.Write(writer, settings); }
/// <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); }
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); }
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); }
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); }
/// <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); }
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); }
/// <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);
/// <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); }
internal override void Write(MidiWriter writer, WritingSettings settings) { writer.WriteByte(_lsb); writer.WriteByte(_msb); }
internal override sealed void Write(MidiWriter writer, WritingSettings settings) { }
internal override void Write(MidiWriter writer, WritingSettings settings) { writer.WriteByte(Number); }
/// <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()); }
/// <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); }
/// <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);