/** * Parses the buffer stream for a meta event * * @since 1.0 * @uses read() * @uses Util::unpack() * @uses getDelta() * @uses getMetaEvent() * * @return MetaEvent */ protected function parseMetaEvent() { $metaEventType = Util::unpack($this->read(1, true)); $metaEventType = $metaEventType[0]; $length = $this->getDelta(); $data = $this->read($length, true); return $this->getMetaEvent($metaEventType, $data); }
/** * Parses the given track header * * @since 1.0 * @uses TrackHeader::LENGTH * @uses Util::unpack() * * @param binary $header * @throws InvalidArgumentException * @throws {@link ParseException} if the header is invalid * @return TrackHeader */ public function parseTrackHeader($header) { /*if (strlen($header) !== TrackHeader::LENGTH) { throw new \InvalidArgumentException('Track header must be ' . \Midi\TrackHeader::LENGTH . ' bytes'); }*/ $id = Util::unpack(substr($header, 0, 4)); $size = array_reverse(Util::unpack(substr($header, 4))); if ($id !== array(0x4d, 0x54, 0x72, 0x6b)) { throw new ParseException('Invalid track header, expected [4D 54 72 6B]'); } $shift = 0; $trackSize = 0; foreach ($size as $byte) { $trackSize |= $byte << $shift; $shift += 8; } return new TrackHeader($trackSize); }
/** * Reads a delta time from the buffer stream * * @since 1.0 * @uses read() * @uses Util::unpack() * @uses Util::getTicksFromDeltaByteSequence() * * @return int The number of clock ticks in the delta time */ protected function getDelta() { $byte = $this->read(1, true); $value = Util::unpack($byte); $delta = ''; while ($this->file->valid() && $value[0] > 0x7f) { $delta .= $byte; $byte = $this->read(1); $value = Util::unpack($byte); } if ($byte !== null) { $delta .= $byte; } return Util::getTicksFromDeltaByteSequence($delta); }
/** * Parses the given file header * * @since 1.0 * @uses FileHeader::LENGTH * @uses Util::unpack() * * @param binary $header * @throws InvalidArgumentException * @throws {@link ParseException} if the file header is not a valid MIDI file header * @return FileHeader */ public function parseFileHeader($header) { if (strlen($header) !== FileHeader::LENGTH) { throw new \InvalidArgumentException('MIDI file header must be ' . FileHeader::LENGTH . ' bytes'); } $id = Util::unpack(substr($header, 0, 4)); $chunkSize = Util::unpack(substr($header, 4, 4)); $format = Util::unpack(substr($header, 8, 2)); $tracks = Util::unpack(substr($header, 10, 2)); $timeDivision = Util::unpack(substr($header, 12, 2)); if ($id !== array(0x4d, 0x54, 0x68, 0x64)) { throw new ParseException('Invalid file header, expected byte sequence [4D 54 68 64]'); } if ($chunkSize !== array(0x0, 0x0, 0x0, 0x6)) { throw new ParseException('File header chunk size must be [00 00 00 06]'); } $format = $format[0] << 8 | $format[1]; $timeDivision = $timeDivision[0] << 8 | $timeDivision[1]; $tracks = $tracks[0] << 8 | $tracks[1]; if ($format !== 0 && $format !== 1 && $format !== 2) { throw new ParseException('MIDI file format must be 0, 1 or 2 (got ' . $format . ')'); } return new FileHeader($format, $tracks, $timeDivision); }