MidiEvent MidiEvent::ReadFromStream(istream &stream, unsigned char last_status, bool contains_delta_pulses) { MidiEvent ev; if (contains_delta_pulses) ev.m_delta_pulses = parse_variable_length(stream); else ev.m_delta_pulses = 0; // MIDI uses a compression mechanism called "running status". // Anytime you read a status byte that doesn't have the highest- // order bit set, what you actually read is the 1st data byte // of a message with the status of the previous message. ev.m_status = static_cast<unsigned char>(stream.peek()); if ((ev.m_status & 0x80) == 0) ev.m_status = last_status; else // It was a status byte after all, just read past it // in the stream stream.read(reinterpret_cast<char*>(&ev.m_status), sizeof(unsigned char)); switch (ev.Type()) { case MidiEventType_Meta: ev.ReadMeta(stream); break; case MidiEventType_SysEx: ev.ReadSysEx(stream); break; default: ev.ReadStandard(stream); break; } return ev; }