/// <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 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); } } }
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> /// 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); } }
/// <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> /// 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); }
/// <summary> /// Gets size of <see cref="TrackChunk"/>'s content as number of bytes required to write it according /// to specified <see cref="WritingSettings"/>. /// </summary> /// <param name="settings">Settings according to which the chunk's content will be written.</param> /// <returns>Number of bytes required to write <see cref="TrackChunk"/>'s content.</returns> protected override uint GetContentSize(WritingSettings settings) { uint result = 0; ProcessEvents(settings, (eventWriter, midiEvent, writeStatusByte) => { result += (uint)(midiEvent.DeltaTime.GetVlqLength() + eventWriter.CalculateSize(midiEvent, settings, writeStatusByte)); }); return(result); }
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> /// Gets the size of the content of a MIDI meta event. /// </summary> /// <param name="settings">Settings according to which the event's content must be written.</param> /// <returns>Size of the event's content.</returns> protected sealed override int GetContentSize(WritingSettings settings) { var text = Text; if (string.IsNullOrEmpty(text)) { return(0); } var encoding = settings.TextEncoding ?? SmfConstants.DefaultTextEncoding; return(encoding.GetByteCount(Text)); }
/// <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> /// Gets the size of the content of a MIDI meta event. /// </summary> /// <param name="settings">Settings according to which the event's content must be written.</param> /// <returns>Size of the event's content.</returns> protected override int GetContentSize(WritingSettings settings) { return(Data?.Length ?? 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);
/// <summary> /// Gets the size of the content of a MIDI event. /// </summary> /// <param name="settings">Settings according to which the event's content must be written.</param> /// <returns>Size of the event's content.</returns> internal abstract int GetSize(WritingSettings settings);
internal override void Write(MidiWriter writer, WritingSettings settings) { writer.WriteByte(_dataByte1); }
public int CalculateSize(MidiEvent midiEvent, WritingSettings settings, bool writeStatusByte) { return((writeStatusByte ? 1 : 0) + midiEvent.GetSize(settings)); }
private void ProcessEvents(WritingSettings settings, Action <IEventWriter, MidiEvent, bool> eventHandler) { byte?runningStatus = null; var skipSetTempo = true; var skipKeySignature = true; var skipTimeSignature = true; foreach (var midiEvent in Events) { var eventToWrite = midiEvent; if (eventToWrite is SystemCommonEvent || eventToWrite is SystemRealTimeEvent) { continue; } if (eventToWrite.EventType == MidiEventType.UnknownMeta && settings.DeleteUnknownMetaEvents) { continue; } // if (settings.NoteOffAsSilentNoteOn) { var noteOffEvent = eventToWrite as NoteOffEvent; if (noteOffEvent != null) { eventToWrite = new NoteOnEvent { DeltaTime = noteOffEvent.DeltaTime, Channel = noteOffEvent.Channel, NoteNumber = noteOffEvent.NoteNumber } } ; } // if (settings.DeleteDefaultSetTempo && TrySkipDefaultSetTempo(eventToWrite, ref skipSetTempo)) { continue; } if (settings.DeleteDefaultKeySignature && TrySkipDefaultKeySignature(eventToWrite, ref skipKeySignature)) { continue; } if (settings.DeleteDefaultTimeSignature && TrySkipDefaultTimeSignature(eventToWrite, ref skipTimeSignature)) { continue; } // IEventWriter eventWriter = EventWriterFactory.GetWriter(eventToWrite); var writeStatusByte = true; if (eventToWrite is ChannelEvent) { var statusByte = eventWriter.GetStatusByte(eventToWrite); writeStatusByte = runningStatus != statusByte || !settings.UseRunningStatus; runningStatus = statusByte; } else { runningStatus = null; } // eventHandler(eventWriter, eventToWrite, writeStatusByte); } var endOfTrackEvent = new EndOfTrackEvent(); var endOfTrackEventWriter = EventWriterFactory.GetWriter(endOfTrackEvent); eventHandler(endOfTrackEventWriter, endOfTrackEvent, true); }
internal override int GetSize(WritingSettings settings) { return(1); }
/// <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 sealed int GetSize(WritingSettings settings) { return(0); }
internal override sealed void Write(MidiWriter writer, WritingSettings settings) { }
/// <summary> /// Gets the size of the content of a MIDI event. /// </summary> /// <param name="settings">Settings according to which the event's content must be written.</param> /// <returns>Size of the event's content.</returns> internal sealed override int GetSize(WritingSettings settings) { return(_parameters.Length); }
/// <summary> /// Gets the size of the content of a MIDI meta event. /// </summary> /// <param name="settings">Settings according to which the event's content must be written.</param> /// <returns>Size of the event's content.</returns> protected override int GetContentSize(WritingSettings settings) { return(5); }