Пример #1
0
        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);
        }
Пример #2
0
        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);
        }