private static bool _TryReadChunk(Stream stream, out KeyValuePair <string, byte[]> chunk) { chunk = default(KeyValuePair <string, byte[]>); var buf = new byte[4]; if (4 != stream.Read(buf, 0, 4)) { return(false); } var name = Encoding.ASCII.GetString(buf); if (4 != stream.Read(buf, 0, 4)) { throw new EndOfStreamException(); } var len = BitConverter.ToInt32(buf, 0); if (BitConverter.IsLittleEndian) { len = MidiUtility.Swap(len); } buf = new byte[len]; if (len != stream.Read(buf, 0, len)) { throw new EndOfStreamException(); } chunk = new KeyValuePair <string, byte[]>(name, buf); return(true); }
/// <summary> /// Reads a MIDI file from the specified stream /// </summary> /// <param name="stream">The stream to read from</param> /// <returns>A MIDI file object representing the MIDI data in the stream</returns> public static MidiFile ReadFrom(Stream stream) { KeyValuePair <string, byte[]> chunk; if (!_TryReadChunk(stream, out chunk) || "MThd" != chunk.Key || 6 > chunk.Value.Length) { throw new InvalidDataException("The stream is not a MIDI file format."); } var type = BitConverter.ToInt16(chunk.Value, 0); var trackCount = BitConverter.ToInt16(chunk.Value, 2); var timeBase = BitConverter.ToInt16(chunk.Value, 4); if (BitConverter.IsLittleEndian) { type = MidiUtility.Swap(type); trackCount = MidiUtility.Swap(trackCount); timeBase = MidiUtility.Swap(timeBase); } var result = new MidiFile(type, timeBase); while (_TryReadChunk(stream, out chunk)) { if ("MTrk" == chunk.Key) { var tstm = new MemoryStream(chunk.Value, false); var trk = MidiSequence.ReadFrom(tstm); result.Tracks.Add(trk); } } return(result); }
/// <summary> /// Writes the MIDI file to the specified stream /// </summary> /// <param name="stream">The stream to write to</param> public void WriteTo(Stream stream) { var fileStream = stream as FileStream; if (null != fileStream) { FilePath = fileStream.Name; } try { stream.SetLength(0); } catch { } var buf = new byte[4]; buf[0] = (byte)'M'; buf[1] = (byte)'T'; buf[2] = (byte)'h'; buf[3] = (byte)'d'; stream.Write(buf, 0, 4); var len = 6; if (BitConverter.IsLittleEndian) { len = MidiUtility.Swap(len); } stream.Write(BitConverter.GetBytes(len), 0, 4); var type = Type; var trackCount = (short)Tracks.Count; var timeBase = TimeBase; if (BitConverter.IsLittleEndian) { type = MidiUtility.Swap(type); trackCount = MidiUtility.Swap(trackCount); timeBase = MidiUtility.Swap(timeBase); } stream.Write(BitConverter.GetBytes(type), 0, 2); stream.Write(BitConverter.GetBytes(trackCount), 0, 2); stream.Write(BitConverter.GetBytes(timeBase), 0, 2); foreach (var trk in Tracks) { buf[0] = (byte)'M'; buf[1] = (byte)'T'; buf[2] = (byte)'r'; buf[3] = (byte)'k'; stream.Write(buf, 0, 4); var tstm = new MemoryStream(); trk.WriteTo(tstm); tstm.Position = 0; len = (int)tstm.Length; if (BitConverter.IsLittleEndian) { len = MidiUtility.Swap(len); } stream.Write(BitConverter.GetBytes(len), 0, 4); tstm.CopyTo(stream); tstm.Close(); } }
/// <summary> /// Creates a new MIDI channel pitch message /// </summary> /// <param name="pitch">The MIDI pressure (0-16383)</param> /// <param name="channel">The MIDI channel (0-15)</param> public MidiMessageChannelPitch(short pitch, byte channel) : base(unchecked ((byte)(0xE0 | channel)), BitConverter.IsLittleEndian?MidiUtility.Swap(pitch):pitch) { }