//Create TrackChunk Object from Array of Bytes public void TrackChunkFromBytes(byte[] TrackBytes) { //MidiEvent int Delta = 0; sbyte EventType; sbyte MidiChannel; byte Param1; byte Param2; //TempoEvent int MicroSecondsPerQuarterNote = 1; //InstrumentEvent byte InstrumentNumber = 1; MidiEvent[] OpenedEvents = new MidiEvent[1]; Boolean DeltaRetrieved = false; int NextEventIndex = 0; byte NextByteValue; for (int ByteIndex = TRACKHEADERLENGTH; ByteIndex < TrackBytes.Length - 1; ByteIndex++) { Delta = 0; while (!(DeltaRetrieved)) { NextByteValue = TrackBytes[ByteIndex]; if ((NextByteValue) >= 128) { Delta = NextByteValue & 127; Delta = Delta << SHIFT; } else { Delta = Delta | NextByteValue; DeltaRetrieved = true; } ByteIndex++; } DeltaRetrieved = false; NextByteValue = TrackBytes[ByteIndex]; //If its a Meta Event if (NextByteValue == 0xff) { ByteIndex++; NextByteValue = TrackBytes[ByteIndex]; if ((NextByteValue == 0x2F)) { //EOT found break; } ByteIndex++; NextByteValue = TrackBytes[ByteIndex]; ByteIndex++; MicroSecondsPerQuarterNote = TrackBytes[ByteIndex] << 8; ByteIndex++; MicroSecondsPerQuarterNote = (MicroSecondsPerQuarterNote | TrackBytes[ByteIndex]) << 8; ByteIndex++; MicroSecondsPerQuarterNote = (MicroSecondsPerQuarterNote | TrackBytes[ByteIndex]); if (OpenedEvents[0] == null) { } else { Array.Resize(ref OpenedEvents, OpenedEvents.Length + 1); } OpenedEvents[NextEventIndex] = new TempoMidiEvent(Delta, MicroSecondsPerQuarterNote); NextEventIndex++; } //if its an instrument change event else if (NextByteValue == 0xC0) { MidiChannel = Convert.ToSByte(0x0f & NextByteValue << 4); ByteIndex++; NextByteValue = TrackBytes[ByteIndex]; InstrumentNumber = NextByteValue; if (OpenedEvents[0] == null) { //Do Nothing. Opened events are empty and the first element is free } else //Resize the array for the extra event { Array.Resize(ref OpenedEvents, OpenedEvents.Length + 1); } OpenedEvents[NextEventIndex] = new InstrumentMidiEvent(Delta, 0, MidiChannel, InstrumentNumber); NextEventIndex++; } //Other Midi Event else { EventType = Convert.ToSByte(NextByteValue >> 4); //No ByteIndex++ because EventType& MidiChannel are stored in same byte MidiChannel = Convert.ToSByte(NextByteValue & 0xf); ByteIndex++; NextByteValue = TrackBytes[ByteIndex]; Param1 = NextByteValue; ByteIndex++; NextByteValue = TrackBytes[ByteIndex]; Param2 = NextByteValue; if (OpenedEvents[0] == null) { } else { Array.Resize(ref OpenedEvents, OpenedEvents.Length + 1); } OpenedEvents[NextEventIndex] = new MidiEvent(0, 0, Delta, EventType, MidiChannel, Param1, Param2); NextEventIndex++; } } CalculateScorePositionFromDeltaTimes(OpenedEvents, MidiHeaderChunk.Ticks); CalculateNoteDownLengths(OpenedEvents); MidiTrackChunk = new TrackChunk(OpenedEvents); }
public StandardMidi() { MidiHeaderChunk = new HeaderChunk(); MidiTrackChunk = new TrackChunk(); }