public static byte[] WriteToBytes(MidiSequence sequence) { List <byte> listToWrite = new List <byte> (); byte[] MThd = new byte[] { 0x4D, 0x54, 0x68, 0x64, //MThd 0x00, 0x00, 0x00, 0x06, //Length 0x00, 0x01, //Format 0x00, 0x03, //TrackNum 0x00, 0x10 //Division }; byte[] MTrk = new byte[] { 0x4D, 0x54, 0x72, 0x6B }; byte[] TimeSig = new byte[] { 0x00, 0xFF, 0x58, 0x04, 0x02, 0x02, 0x24, 0x08 }; byte[] SetTempo = new byte[] { 0x00, 0xFF, 0x51, 0x03, 0x09, 0x89, 0x68 }; byte[] MetaFooter = new byte[] { 0x83, 0x00, 0xFF, 0x2F, 0x00 }; byte[] NormalFooter = new byte[] { 0x00, 0xFF, 0x2F, 0x00 }; MThd [9] = (byte)sequence.GetFormat(); MThd [11] = (byte)(sequence.GetTrackNum() + 1); AddArrayToList(listToWrite, MThd); int firstEventLength = 0; for (int i = 0; i < sequence.GetList() [0].GetEventList().Count; i++) { firstEventLength += sequence.GetList() [0].GetEventList() [i].GetListSize() * 4; } firstEventLength += 3; firstEventLength += NormalFooter.Length; if (sequence.GetFormat() == 0) { AddArrayToList(listToWrite, MTrk); int SingleTrackLength = firstEventLength + TimeSig.Length + SetTempo.Length; int high = SingleTrackLength / 256; int low = SingleTrackLength - (high * 256); listToWrite.Add((byte)0); listToWrite.Add((byte)0); listToWrite.Add((byte)high); listToWrite.Add((byte)low); TimeSig [4] = (byte)sequence.GetNominator(); TimeSig [5] = (byte)sequence.GetDenominator(); AddArrayToList(listToWrite, TimeSig); int bpm = 60000000 / sequence.GetBpm(); int bpmHigh = bpm / 65536; int bpmMiddle = (625000 - (bpmHigh * 65536)) / 256; int bpmLow = (625000 - (bpmHigh * 65536)) - (bpmMiddle * 256); SetTempo [4] = (byte)bpmHigh; SetTempo [5] = (byte)bpmMiddle; SetTempo [6] = (byte)bpmLow; AddArrayToList(listToWrite, SetTempo); AddArrayToList(listToWrite, NormalFooter); //TODO: End here, make listToWrite to byte[], then return it } else { AddArrayToList(listToWrite, MTrk); int MetaLength = TimeSig.Length + SetTempo.Length + MetaFooter.Length; int high = MetaLength / 256; int low = MetaLength - (high * 256); listToWrite.Add((byte)0); listToWrite.Add((byte)0); listToWrite.Add((byte)high); listToWrite.Add((byte)low); TimeSig [4] = (byte)sequence.GetNominator(); TimeSig [5] = (byte)sequence.GetDenominator(); AddArrayToList(listToWrite, TimeSig); int bpm = 60000000 / sequence.GetBpm(); int bpmHigh = bpm / 65536; int bpmMiddle = (bpm - (bpmHigh * 65536)) / 256; int bpmLow = (bpm - (bpmHigh * 65536)) - (bpmMiddle * 256); SetTempo [4] = (byte)bpmHigh; SetTempo [5] = (byte)bpmMiddle; SetTempo [6] = (byte)bpmLow; AddArrayToList(listToWrite, SetTempo); AddArrayToList(listToWrite, MetaFooter); AddArrayToList(listToWrite, MTrk); int firstHigh = firstEventLength / 256; int firstLow = firstEventLength - (firstHigh * 256); listToWrite.Add((byte)0); listToWrite.Add((byte)0); listToWrite.Add((byte)firstHigh); listToWrite.Add((byte)firstLow); WriteEventsToList(listToWrite, sequence.GetList() [0]); for (int i = 1; i < sequence.GetList().Count; i++) { AddArrayToList(listToWrite, MTrk); int tmpTrackLength = 0; for (int j = 0; j < sequence.GetList() [i].GetEventList().Count; j++) { tmpTrackLength += sequence.GetList() [i].GetEventList() [j].GetListSize() * 4; } tmpTrackLength += 3; tmpTrackLength += NormalFooter.Length; int tmpTrackHigh = tmpTrackLength / 256; int tmpTrackLow = tmpTrackLength - (tmpTrackHigh * 256); listToWrite.Add((byte)0); listToWrite.Add((byte)0); listToWrite.Add((byte)tmpTrackHigh); listToWrite.Add((byte)tmpTrackLow); WriteEventsToList(listToWrite, sequence.GetList() [i]); } } byte[] result = new byte[listToWrite.Count]; for (int i = 0; i < listToWrite.Count; i++) { result [i] = listToWrite [i]; } return(result); }
public static MidiSequence Load(string name, byte[] data) { MidiSequence sequence = new MidiSequence(); DataStreamReader reader = new DataStreamReader(data); sequence.SetName(name); int length = data.Length; reader.ResetPosition(); if (new string (reader.ReadChars(4)) != "MThd") { return(null); } reader.Advance(4); int format = reader.ReadByteToInt2(); int trackNum = reader.ReadByteToInt2(); int division = reader.ReadByteToInt2(); int bpm = 0, nominator = 0, denominator = 0; if (new string(reader.ReadChars(4)) != "MTrk") { return(null); } reader.Advance(4); ReadMetaEvent(data, reader, format, ref bpm, ref nominator, ref denominator, length); sequence.SetHeader(format, trackNum, division, bpm); sequence.SetTempo(nominator, denominator); byte eventCode; if (format == 0) { while (true) { eventCode = (byte)(reader.PeekByte(1) & 0xF0); if (eventCode == (byte)0x80 || eventCode == (byte)0x90 || eventCode == (byte)0xC0) { break; } else { reader.Advance(1); } } } else { if (new string(reader.ReadChars(4)) != "MTrk") { return(null); } reader.Advance(4); } int readCount; if (format == 0) { readCount = 1; } else { readCount = trackNum - 1; } for (int i = 0; i < readCount; i++) { sequence.AddTrack(ReadTrack(data, reader, readCount, i, length)); } return(sequence); }