diff --git a/src/ID3/Encoding.php b/src/ID3/Encoding.php new file mode 100644 index 0000000..0689069 --- /dev/null +++ b/src/ID3/Encoding.php @@ -0,0 +1,67 @@ +Encoding interface implies that the ID3v2 frame supports + * content encoding. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +interface ID3_Encoding +{ + /** The ISO-8859-1 encoding. */ + const ISO88591 = 0x00; + + /** The UTF-16 Unicode encoding with BOM. */ + const UTF16 = 0x01; + + /** The UTF-16BE Unicode encoding without BOM. */ + const UTF16BE = 0x02; + + /** The UTF-8 Unicode encoding. */ + const UTF8 = 0x03; + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding(); +} diff --git a/src/ID3/Exception.php b/src/ID3/Exception.php new file mode 100644 index 0000000..5628a59 --- /dev/null +++ b/src/ID3/Exception.php @@ -0,0 +1,49 @@ + + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +class ID3_Exception extends Exception +{ +} diff --git a/src/ID3/ExtendedHeader.php b/src/ID3/ExtendedHeader.php new file mode 100644 index 0000000..f70ebf5 --- /dev/null +++ b/src/ID3/ExtendedHeader.php @@ -0,0 +1,190 @@ + + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_ExtendedHeader extends ID3_Object +{ + /** + * A flag to denote that the present tag is an update of a tag found earlier + * in the present file or stream. If frames defined as unique are found in + * the present tag, they are to override any corresponding ones found in the + * earlier tag. This flag has no corresponding data. + */ + const UPDATE = 128; + + /** + * A flag to denote that a CRC-32 data is included in the extended header. + * The CRC is calculated on all the data between the header and footer as + * indicated by the header's tag length field, minus the extended header. Note + * that this includes the padding (if there is any), but excludes the footer. + * The CRC-32 is stored as an 35 bit synchsafe integer, leaving the upper four + * bits always zeroed. + */ + const CRC32 = 64; + + /** A flag to denote whether or not the tag has restrictions applied on it. */ + const RESTRICTED = 32; + + /** @var integer */ + private $_size; + + /** @var integer */ + private $_flags; + + /** @var integer */ + private $_crc; + + /** @var integer */ + private $_restrictions; + + /** + * Constructs the class with given parameters and reads object related data + * from the ID3v2 tag. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $offset = $this->_reader->getOffset(); + $this->_size = $this->decodeSynchsafe32($this->_reader->getUInt32BE()); + $this->_reader->skip(1); + $this->_flags = $this->_reader->getInt8(); + + if ($this->hasFlag(self::UPDATE)) + $this->_reader->skip(1); + if ($this->hasFlag(self::CRC32)) { + $this->_reader->skip(1); + $this->_crc = Transform::getInt32BE + (($this->_reader->read(1) << 4) & + $this->decodeSynchsafe32($this->_reader->read(4))); + } + if ($this->hasFlag(self::RESTRICTED)) { + $this->_reader->skip(1); + $this->_restrictions = $this->_reader->getInt8(1); + } + + $this->_reader->skip($this->_size - $this->_reader->getOffset() - $offset); + } + + /** + * Returns the extended header size in bytes. + * + * @return integer + */ + public function getSize() { return $this->_size; } + + /** + * Checks whether or not the flag is set. Returns true if the flag + * is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } + + /** + * Returns the CRC-32 data. + * + * @return integer + */ + public function getCRC() { return $this->_crc; } + + /** + * Returns the restrictions. For some applications it might be desired to + * restrict a tag in more ways than imposed by the ID3v2 specification. Note + * that the presence of these restrictions does not affect how the tag is + * decoded, merely how it was restricted before encoding. If this flag is set + * the tag is restricted as follows: + * + *
+   * Restrictions %ppqrrstt
+   *
+   * p - Tag size restrictions
+   *
+   *   00   No more than 128 frames and 1 MB total tag size.
+   *   01   No more than 64 frames and 128 KB total tag size.
+   *   10   No more than 32 frames and 40 KB total tag size.
+   *   11   No more than 32 frames and 4 KB total tag size.
+   *
+   * q - Text encoding restrictions
+   *
+   *   0    No restrictions
+   *   1    Strings are only encoded with ISO-8859-1 or UTF-8.
+   *
+   * r - Text fields size restrictions
+   *
+   *   00   No restrictions
+   *   01   No string is longer than 1024 characters.
+   *   10   No string is longer than 128 characters.
+   *   11   No string is longer than 30 characters.
+   *
+   *   Note that nothing is said about how many bytes is used to represent those
+   *   characters, since it is encoding dependent. If a text frame consists of
+   *   more than one string, the sum of the strungs is restricted as stated.
+   *
+   * s - Image encoding restrictions
+   *
+   *   0   No restrictions
+   *   1   Images are encoded only with PNG [PNG] or JPEG [JFIF].
+   *
+   * t - Image size restrictions
+   *
+   *   00  No restrictions
+   *   01  All images are 256x256 pixels or smaller.
+   *   10  All images are 64x64 pixels or smaller.
+   *   11  All images are exactly 64x64 pixels, unless required otherwise.
+   * 
+ * + * @return integer + */ + public function getRestrictions() { return $this->_restrictions; } +} diff --git a/src/ID3/Frame.php b/src/ID3/Frame.php new file mode 100644 index 0000000..81d9994 --- /dev/null +++ b/src/ID3/Frame.php @@ -0,0 +1,170 @@ + + * @copyright 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +class ID3_Frame extends ID3_Object +{ + /** + * This flag tells the tag parser what to do with this frame if it is unknown + * and the tag is altered in any way. This applies to all kinds of + * alterations, including adding more padding and reordering the frames. + */ + const DISCARD_ON_TAGCHANGE = 16384; + + /** + * This flag tells the tag parser what to do with this frame if it is unknown + * and the file, excluding the tag, is altered. This does not apply when the + * audio is completely replaced with other audio data. + */ + const DISCARD_ON_FILECHANGE = 8192; + + /** + * This flag, if set, tells the software that the contents of this frame are + * intended to be read only. Changing the contents might break something, + * e.g. a signature. + */ + const READ_ONLY = 4096; + + /** + * This flag indicates whether or not this frame belongs in a group with + * other frames. If set, a group identifier byte is added to the frame. Every + * frame with the same group identifier belongs to the same group. + */ + const GROUPING_IDENTITY = 32; + + /** + * This flag indicates whether or not the frame is compressed. A Data + * Length Indicator byte is included in the frame. + * + * @see DATA_LENGTH_INDICATOR + */ + const COMPRESSION = 8; + + /** + * This flag indicates whether or not the frame is encrypted. If set, one byte + * indicating with which method it was encrypted will be added to the frame. + * See description of the {@link ID3_Frame_ENCR} frame for more information + * about encryption method registration. Encryption should be done after + * compression. Whether or not setting this flag requires the presence of a + * Data Length Indicator depends on the specific algorithm used. + * + * @see DATA_LENGTH_INDICATOR + */ + const ENCRYPTION = 4; + + /** + * This flag indicates whether or not unsynchronisation was applied to this + * frame. + */ + const UNSYNCHRONISATION = 2; + + /** + * This flag indicates that a data length indicator has been added to the + * frame. + */ + const DATA_LENGTH_INDICATOR = 1; + + /** @var integer */ + private $_identifier; + + /** @var integer */ + private $_size; + + /** @var integer */ + private $_flags; + + /** + * Raw content read from the frame. + * + * @var string + */ + protected $_data; + + /** + * Constructs the class with given parameters and reads object related data + * from the ID3v2 tag. + * + * @todo Only limited subset of flags are processed. + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_identifier = $this->_reader->getString8(4); + $this->_size = $this->decodeSynchsafe32($this->_reader->getUInt32BE()); + $this->_flags = $this->_reader->getUInt16BE(); + $this->_data = $this->_reader->read($this->_size); + } + + /** + * Returns the frame identifier string. + * + * @return string + */ + public function getIdentifier() { return $this->_identifier; } + + /** + * Returns the size of the data in the final frame, after encryption, + * compression and unsynchronisation. The size is excluding the frame header. + * + * @return integer + */ + public function getSize() { return $this->_size; } + + /** + * Checks whether or not the flag is set. Returns true if the flag + * is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } +} diff --git a/src/ID3/Frame/AENC.php b/src/ID3/Frame/AENC.php new file mode 100644 index 0000000..3d7ce76 --- /dev/null +++ b/src/ID3/Frame/AENC.php @@ -0,0 +1,111 @@ +Audio encryption indicates if the actual audio stream is + * encrypted, and by whom. + * + * The identifier is a URL containing an email address, or a link to a location + * where an email address can be found, that belongs to the organisation + * responsible for this specific encrypted audio file. Questions regarding the + * encrypted audio should be sent to the email address specified. There may be + * more than one AENC frame in a tag, but only one with the same owner + * identifier. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_AENC extends ID3_Frame +{ + /** @var string */ + private $_id; + + /** @var integer */ + private $_previewStart; + + /** @var integer */ + private $_previewLength; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); + $this->_previewStart = substr($this->_data, 0, 2); + $this->_previewLength = substr($this->_data, 2, 2); + $this->_data = substr($this->_data, 4); + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getIdentifier() { return $this->_id; } + + /** + * Returns the pointer to an unencrypted part of the audio in frames. + * + * @return integer + */ + public function getPreviewStart() { return $this->_previewStart; } + + /** + * Returns the length of the preview in frames. + * + * @return integer + */ + public function getPreviewLength() { return $this->_previewLength; } + + /** + * Returns the encryption info. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/APIC.php b/src/ID3/Frame/APIC.php new file mode 100644 index 0000000..e17b073 --- /dev/null +++ b/src/ID3/Frame/APIC.php @@ -0,0 +1,169 @@ +Attached picture frame contains a picture directly related to the + * audio file. Image format is the MIME type and subtype for the image. + * + * There may be several pictures attached to one file, each in their individual + * APIC frame, but only one with the same content descriptor. There may only + * be one picture with the same picture type. There is the possibility to put + * only a link to the image file by using the MIME type "-->" and having a + * complete URL instead of picture data. + * + * The use of linked files should however be used sparingly since there is the + * risk of separation of files. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_APIC extends ID3_Frame + implements ID3_Encoding +{ + /** + * The list of image types. + * + * @var Array + */ + public static $types = array + (0x00 => "Other", + 0x01 => "32x32 pixels file icon (PNG only)", + 0x02 => "Other file icon", + 0x03 => "Cover (front)", + 0x04 => "Cover (back)", + 0x05 => "Leaflet page", + 0x06 => "Media (e.g. label side of CD)", + 0x07 => "Lead artist/lead performer/soloist", + 0x08 => "Artist/performer", + 0x09 => "Conductor", + 0x0A => "Band/Orchestra", + 0x0B => "Composer", + 0x0C => "Lyricist/text writer", + 0x0D => "Recording Location", + 0x0E => "During recording", + 0x0F => "During performance", + 0x10 => "Movie/video screen capture", + 0x11 => "A bright coloured fish", + 0x12 => "Illustration", + 0x13 => "Band/artist logotype", + 0x14 => "Publisher/Studio logotype"); + + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_mimeType; + + /** @var integer */ + private $_imageType; + + /** @var string */ + private $_description; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + $this->_mimeType = substr + ($this->_data, 1, ($pos = strpos($this->_data, "\0", 1)) - 1); + $this->_pictureType = substr($this->_data, $pos++, 1); + switch ($this->_encoding) { + case self::UTF16: + list ($this->_description, $this->_data) = + preg_split("/\\x00\\x00/", substr($this->_data, $pos), 2); + $this->_description = Transform::getString16LE($this->_description); + break; + case self::UTF16BE: + list ($this->_description, $this->_data) = + preg_split("/\\x00\\x00/", substr($this->_data, $pos), 2); + $this->_description = Transform::getString16BE($this->_description); + break; + default: + list ($this->_description, $this->_data) = + preg_split("/\\x00/", substr($this->_data, $pos), 2); + $this->_description = Transform::getString8($this->_description); + } + } + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns the MIME type. The MIME type is always encoded with ISO-8859-1. + * + * @return string + */ + public function getMimeType() { return $this->_mimeType; } + + /** + * Returns the image type. + * + * @return integer + */ + public function getImageType() { return $this->_imageType; } + + /** + * Returns the file description. + * + * @return string + */ + public function getDescription() { return $this->_description; } + + /** + * Returns the embedded picture data. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/ASPI.php b/src/ID3/Frame/ASPI.php new file mode 100644 index 0000000..bebed1e --- /dev/null +++ b/src/ID3/Frame/ASPI.php @@ -0,0 +1,125 @@ +Audio seek point index or + * ASPI frame makes seeking easier by providing a list a seek points within the + * audio file. The seek points are a fractional offset within the audio data, + * providing a starting point from which to find an appropriate point to start + * decoding. The presence of an ASPI frame requires the existence of a + * {@link ID3_Frame_TLEN} frame, indicating the duration of the file in + * milliseconds. There may only be one audio seek point index frame in a tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_ASPI extends ID3_Frame +{ + /** @var integer */ + private $_dataStart; + + /** @var integer */ + private $_dataLength; + + /** @var integer */ + private $_size; + + /** @var Array */ + private $_fraction = array(); + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_dataStart = Transform::getInt32BE(substr($this->_data, 0, 4)); + $this->_dataLength = Transform::getInt32BE(substr($this->_data, 4, 4)); + $this->_size = Transform::getInt16BE(substr($this->_data, 8, 2)); + $bitsPerPoint = substr($this->_data, 10, 1); + for ($i = 0, $offset = 11; $i < $this->_size; $i++) { + if ($bitsPerPoint == 16) { + $this->_fraction[$i] = substr($this->_data, $offset, 2); + $offset += 2; + } else { + $this->_fraction[$i] = substr($this->_data, $offset, 1); + $offset ++; + } + } + } + + /** + * Returns the byte offset from the beginning of the file. + * + * @return integer + */ + public function getDataStart() { return $this->_dataStart; } + + /** + * Returns the byte length of the audio data being indexed. + * + * @return integer + */ + public function getDataLength() { return $this->_dataLength; } + + /** + * Returns the number of index points in the frame. + * + * @return integer + */ + public function getSize() { return $this->_size; } + + /** + * Returns the numerator of the fraction representing a relative position in + * the data or false if index not defined. The denominator is 2 + * to the power of b. + * + * @param integer $index The fraction numerator. + * @return integer + */ + public function getFractionAt($index) { return $this->_fraction[$index]; } +} diff --git a/src/ID3/Frame/AbstractLink.php b/src/ID3/Frame/AbstractLink.php new file mode 100644 index 0000000..4096e8a --- /dev/null +++ b/src/ID3/Frame/AbstractLink.php @@ -0,0 +1,72 @@ + + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +abstract class ID3_Frame_AbstractLink extends ID3_Frame +{ + /** @var string */ + protected $_link; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + $this->_link = preg_split("/\\x00/", $this->_data, 1); + } + + /** + * Returns the link associated with the frame. + * + * @return string + */ + public function getLink() { return $this->_link; } +} diff --git a/src/ID3/Frame/AbstractText.php b/src/ID3/Frame/AbstractText.php new file mode 100644 index 0000000..6973596 --- /dev/null +++ b/src/ID3/Frame/AbstractText.php @@ -0,0 +1,98 @@ + + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +abstract class ID3_Frame_AbstractText extends ID3_Frame + implements ID3_Encoding +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_text; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + switch ($this->_encoding) { + case self::UTF16: + $this->_data = Transform::getString16LE(substr($this->_data, 1)); + $this->_text = preg_split("/\\x00\\x00/", $this->_data); + break; + case self::UTF16BE: + $this->_data = Transform::getString16BE(substr($this->_data, 1)); + $this->_text = preg_split("/\\x00\\x00/", $this->_data); + break; + default: + $this->_data = Transform::getString8(substr($this->_data, 1)); + $this->_text = preg_split("/\\x00/", $this->_data); + } + } + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns an array of texts the frame contains. + * + * @return Array + */ + public function getText() { return $this->_text; } +} diff --git a/src/ID3/Frame/COMM.php b/src/ID3/Frame/COMM.php new file mode 100644 index 0000000..2a12eb6 --- /dev/null +++ b/src/ID3/Frame/COMM.php @@ -0,0 +1,134 @@ +Comments frame is intended for any kind of full text information + * that does not fit in any other frame. It consists of a frame header followed + * by encoding, language and content descriptors and is ended with the actual + * comment as a text string. Newline characters are allowed in the comment text + * string. There may be more than one comment frame in each tag, but only one + * with the same language and content descriptor. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_COMM extends ID3_Frame + implements ID3_Encoding, ID3_Language +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_language; + + /** @var string */ + private $_description; + + /** @var string */ + private $_text; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + $this->_language = substr($this->_data, 1, 3); + + switch ($this->_encoding) { + case self::UTF16: + list ($this->_description, $this->_text) = + preg_split("/\\x00\\x00/", substr($this->_data, 4), 2); + $this->_description = Transform::getString16LE($this->_description); + $this->_text = Transform::getString16LE($this->_text); + break; + case self::UTF16BE: + list ($this->_description, $this->_text) = + preg_split("/\\x00\\x00/", substr($this->_data, 4), 2); + $this->_description = Transform::getString16BE($this->_description); + $this->_text = Transform::getString16BE($this->_text); + break; + default: + list ($this->_description, $this->_text) = + preg_split("/\\x00/", substr($this->_data, 4), 2); + $this->_description = Transform::getString8($this->_description); + $this->_text = Transform::getString8($this->_text); + } + } + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns the language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see ID3_Language#ISO_639_2 + * @return string + */ + public function getLanguage() { return $this->_language; } + + /** + * Returns the short content description. + * + * @return string + */ + public function getDescription() { return $this->_description; } + + /** + * Returns the comment text. + * + * @return string + */ + public function getText() { return $this->_text; } +} diff --git a/src/ID3/Frame/COMR.php b/src/ID3/Frame/COMR.php new file mode 100644 index 0000000..4e261e5 --- /dev/null +++ b/src/ID3/Frame/COMR.php @@ -0,0 +1,226 @@ +Commercial frame enables several competing offers in the same tag + * by bundling all needed information. That makes this frame rather complex but + * it's an easier solution than if one tries to achieve the same result with + * several frames. + * + * There may be more than one commercial frame in a tag, but no two may be + * identical. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_COMR extends ID3_Frame + implements ID3_Encoding +{ + /** + * The delivery types. + * + * @var Array + */ + public static $types = array + (0x00 => "Other", + 0x01 => "Standard CD album with other songs", + 0x02 => "Compressed audio on CD", + 0x03 => "File over the Internet", + 0x04 => "Stream over the Internet", + 0x05 => "As note sheets", + 0x06 => "As note sheets in a book with other sheets", + 0x07 => "Music on other media", + 0x08 => "Non-musical merchandise"); + + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_currency; + + /** @var string */ + private $_price; + + /** @var string */ + private $_date; + + /** @var string */ + private $_contact; + + /** @var integer */ + private $_delivery; + + /** @var string */ + private $_seller; + + /** @var string */ + private $_description; + + /** @var string */ + private $_mimeType = false; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + list($pricing, $this->_data) = + preg_split("/\\x00/", substr($this->_data, 1), 2); + $this->_currency = substr($pricing, 0, 3); + $this->_price = substr($pricing, 3); + $this->_date = substr($this->_data, 0, 8); + list($this->_contact, $this->_data) = + preg_split("/\\x00/", substr($this->_data, 8), 2); + $this->_delivery = substr($this->_data, 0, 1); + + switch ($this->_encoding) { + case self::UTF16: + list ($this->_seller, $this->_description, $this->_data) = + preg_split("/\\x00\\x00/", substr($this->_data, 1), 3); + $this->_seller = Transform::getString16LE($this->_seller); + $this->_description = Transform::getString16LE($this->_description); + break; + case self::UTF16BE: + list ($this->_seller, $this->_description, $this->_data) = + preg_split("/\\x00\\x00/", substr($this->_data, 1), 3); + $this->_seller = Transform::getString16BE($this->_seller); + $this->_description = Transform::getString16BE($this->_description); + break; + default: + list ($this->_seller, $this->_description, $this->_data) = + preg_split("/\\x00/", substr($this->_data, 1), 3); + $this->_seller = Transform::getString8($this->_seller); + $this->_description = Transform::getString8($this->_description); + } + + if (strlen($this->_data) == 0) + return; + + list($this->_mimeType, $this->_data) = + preg_split("/\\x00/", $this->_data, 2); + } + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns the currency code, encoded according to + * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm + * ISO 4217} alphabetic currency code. + * + * @return string + */ + public function getCurrency() { return $this->_currency; } + + /** + * Returns the price as a numerical string using "." as the decimal separator. + * + * In the price string several prices may be concatenated, separated by a "/" + * character, but there may only be one currency of each type. + * + * @return string + */ + public function getPrice() { return $this->_price; } + + /** + * Returns the date as an 8 character date string (YYYYMMDD), describing for + * how long the price is valid. + * + * @return string + */ + public function getDate() { return $this->_price; } + + /** + * Returns the contact URL, with which the user can contact the seller. + * + * @return string + */ + public function getContact() { return $this->_contact; } + + /** + * Returns the delivery type with whitch the audio was delivered when bought. + * + * @return integer + */ + public function getDelivery() { return $this->_delivery; } + + /** + * Returns the name of the seller. + * + * @return string + */ + public function getSeller() { return $this->_seller; } + + /** + * Returns the short description of the product. + * + * @return string + */ + public function getDescription() { return $this->_description; } + + /** + * Returns the MIME type of the seller's company logo, if attached, or + * false otherwise. Currently only "image/png" and "image/jpeg" + * are allowed. + * + * @return string + */ + public function getMimeType() { return $this->_mimeType; } + + /** + * Returns the embedded image binary data. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/ENCR.php b/src/ID3/Frame/ENCR.php new file mode 100644 index 0000000..0f273cb --- /dev/null +++ b/src/ID3/Frame/ENCR.php @@ -0,0 +1,109 @@ +Encryption method + * registration frame. + * + * The owner identifier a URL containing an email address, or a link to a + * location where an email address can be found, that belongs to the + * organisation responsible for this specific encryption method. Questions + * regarding the encryption method should be sent to the indicated email + * address. + * + * The method symbol contains a value that is associated with this method + * throughout the whole tag, in the range $80-F0. All other values are reserved. + * The method symbol may optionally be followed by encryption specific data. + * + * There may be several ENCR frames in a tag but only one containing the same + * symbol and only one containing the same owner identifier. The method must be + * used somewhere in the tag. See {@link ID3_Frame#ENCRYPTION} for more + * information. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_ENCR extends ID3_Frame +{ + /** @var string */ + private $_id; + + /** @var integer */ + private $_method; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); + $this->_method = substr($this->_data, 0, 1); + $this->_data = substr($this->_data, 1); + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getIdentifier() { return $this->_id; } + + /** + * Returns the method symbol. + * + * @return integer + */ + public function getMethod() { return $this->_method; } + + /** + * Returns the encryption data. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/EQU2.php b/src/ID3/Frame/EQU2.php new file mode 100644 index 0000000..677d359 --- /dev/null +++ b/src/ID3/Frame/EQU2.php @@ -0,0 +1,130 @@ +Equalisation (2) is another subjective, alignment frame. It allows + * the user to predefine an equalisation curve within the audio file. There may + * be more than one EQU2 frame in each tag, but only one with the same + * identification string. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_EQU2 extends ID3_Frame +{ + /** + * Interpolation type that defines that no interpolation is made. A jump from + * one adjustment level to another occurs in the middle between two adjustment + * points. + */ + const BAND = 0x00; + + /** + * Interpolation type that defines that interpolation between adjustment + * points is linear. + */ + const LINEAR = 0x01; + + /** @var integer */ + private $_interpolation; + + /** @var string */ + private $_device; + + /** @var Array */ + private $_adjustments; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_interpolation = substr($this->_data, 0, 1); + list ($this->_device, $this->_data) = + preg_split("/\\x00/", substr($this->_data, 1), 2); + + for ($i = 0; $i < strlen($this->_data); $i += 8) + $this->_adjustments[Transform::getInt16BE(substr($this->_data, $j, 2))] = + Transform::getInt16BE(substr($this->_data, $j + 2, 2)); + sort($this->_adjustments); + } + + /** + * Returns the interpolation method. The interpolation method describes which + * method is preferred when an interpolation between the adjustment point that + * follows. + * + * @return integer + */ + public function getInterpolation() { return $this->_interpolation; } + + /** + * Returns the device where the adjustments should apply. + * + * @return string + */ + public function getDevice() { return $this->_device; } + + /** + * Returns the array containing adjustments having fequencies as keys and + * their corresponding adjustments as values. + * + * The frequency is stored in units of 1/2 Hz, giving it a range from 0 to + * 32767 Hz. + * + * The volume adjustment is encoded as a fixed point decibel value, 16 bit + * signed integer representing (adjustment*512), giving +/- 64 dB with a + * precision of 0.001953125 dB. E.g. +2 dB is stored as $04 00 and -2 dB is + * $FC 00. + * + * Adjustment points are ordered by frequency and one frequency is described + * once in the frame. + * + * @return Array + */ + public function getAdjustments() { return $this->_adjustments; } +} diff --git a/src/ID3/Frame/ETCO.php b/src/ID3/Frame/ETCO.php new file mode 100644 index 0000000..1dac451 --- /dev/null +++ b/src/ID3/Frame/ETCO.php @@ -0,0 +1,152 @@ +Event timing codes allows synchronisation with key events in the + * audio. + * + * The events are an array of timestamp and type pairs. The time stamp is set to + * zero if directly at the beginning of the sound or after the previous event. + * All events are sorted in chronological order. + * + * The events $E0-EF are for user events. You might want to synchronise your + * music to something, like setting off an explosion on-stage, activating a + * screensaver etc. + * + * There may only be one ETCO frame in each tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_ETCO extends ID3_Frame + implements ID3_Timing +{ + /** + * The list of event types. + * + * @var Array + */ + public static $types = array + (0x00 => "Padding", + 0x01 => "End of initial silence", + 0x02 => "Intro start", + 0x03 => "Main part start", + 0x04 => "Outro start", + 0x05 => "Outro end", + 0x06 => "Verse start", + 0x07 => "Refrain start", + 0x08 => "Interlude start", + 0x09 => "Theme start", + 0x0a => "Variation start", + 0x0b => "Key change", + 0x0c => "Time change", + 0x0d => "Momentary unwanted noise", + 0x0e => "Sustained noise", + 0x0f => "Sustained noise end", + 0x10 => "Intro end", + 0x11 => "Main part end", + 0x12 => "Verse end", + 0x13 => "Refrain end", + 0x14 => "Theme end", + 0x15 => "Profanity", + 0x16 => "Profanity end", + 0xe0 => "User event", + 0xe1 => "User event", + 0xe2 => "User event", + 0xe3 => "User event", + 0xe4 => "User event", + 0xe5 => "User event", + 0xe6 => "User event", + 0xe7 => "User event", + 0xea => "User event", + 0xeb => "User event", + 0xec => "User event", + 0xed => "User event", + 0xee => "User event", + 0xef => "User event", + 0xfd => "Audio end (start of silence)", + 0xfe => "Audio file ends", + 0xff => "One more byte of events follows"); + + /** @var integer */ + private $_format; + + /** @var Array */ + private $_events = array(); + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_format = substr($this->_data, 0, 1); + + for ($i = 1; $i < $this->getSize(); $i += 5) { + $this->_events[Transform::getInt32BE(substr($this->_data, $i + 1, 4))] = + $data = substr($this->_data, $i, 1); + if ($data == 0xff) + break; + } + sort($this->_events); + } + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat() { return $this->_format; } + + /** + * Returns the events as an associated array having the timestamps as keys and + * the event types as values. + * + * @return string + */ + public function getEvents() { return $this->_events; } +} diff --git a/src/ID3/Frame/GEOB.php b/src/ID3/Frame/GEOB.php new file mode 100644 index 0000000..6d701c5 --- /dev/null +++ b/src/ID3/Frame/GEOB.php @@ -0,0 +1,134 @@ +General encapsulated object frame any type of file can be + * encapsulated. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_GEOB extends ID3_Frame + implements ID3_Encoding +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_mimeType; + + /** @var string */ + private $_filename; + + /** @var string */ + private $_description; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + $this->_mimeType = substr + ($this->_data, 1, ($pos = strpos($this->_data, "\0", 1)) - 1); + switch ($this->_encoding) { + case self::UTF16: + list ($this->_filename, $this->_description, $this->_data) = + preg_split("/\\x00\\x00/", substr($this->_data, $pos), 3); + $this->_filename = Transform::getString16LE($this->_filename); + $this->_description = Transform::getString16LE($this->_description); + break; + case self::UTF16BE: + list ($this->_filename, $this->_description, $this->_data) = + preg_split("/\\x00\\x00/", substr($this->_data, $pos), 3); + $this->_filename = Transform::getString16BE($this->_filename); + $this->_description = Transform::getString16BE($this->_description); + break; + default: + list ($this->_filename, $this->_description, $this->_data) = + preg_split("/\\x00/", substr($this->_data, $pos), 3); + $this->_filename = Transform::getString8($this->_filename); + $this->_description = Transform::getString8($this->_description); + } + } + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns the MIME type. The MIME type is always encoded with ISO-8859-1. + * + * @return string + */ + public function getMimeType() { return $this->_mimeType; } + + /** + * Returns the file name. + * + * @return string + */ + public function getFilename() { return $this->_filename; } + + /** + * Returns the file description. + * + * @return string + */ + public function getDescription() { return $this->_description; } + + /** + * Returns the embedded object binary data. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/GRID.php b/src/ID3/Frame/GRID.php new file mode 100644 index 0000000..345b5cc --- /dev/null +++ b/src/ID3/Frame/GRID.php @@ -0,0 +1,108 @@ +Group identification registration frame enables grouping of + * otherwise unrelated frames. This can be used when some frames are to be + * signed. To identify which frames belongs to a set of frames a group + * identifier must be registered in the tag with this frame. + * + * The owner identifier is a URL containing an email address, or a link to a + * location where an email address can be found, that belongs to the + * organisation responsible for this grouping. Questions regarding the grouping + * should be sent to the indicated email address. + * + * The group symbol contains a value that associates the frame with this group + * throughout the whole tag, in the range $80-F0. All other values are reserved. + * The group symbol may optionally be followed by some group specific data, e.g. + * a digital signature. There may be several "GRID" frames in a tag but only one + * containing the same symbol and only one containing the same owner identifier. + * The group symbol must be used somewhere in the tag. See + * {@link ID3_Frame#GROUPING_IDENTITY} for more information. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_GRID extends ID3_Frame +{ + /** @var string */ + private $_id; + + /** @var integer */ + private $_group; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); + $this->_group = substr($this->_data, 0, 1); + $this->_data = substr($this->_data, 1); + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getIdentifier() { return $this->_id; } + + /** + * Returns the group symbol. + * + * @return integer + */ + public function getGroup() { return $this->_group; } + + /** + * Returns the group dependent data. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/LINK.php b/src/ID3/Frame/LINK.php new file mode 100644 index 0000000..1783325 --- /dev/null +++ b/src/ID3/Frame/LINK.php @@ -0,0 +1,126 @@ +Linked information frame is used to keep information duplication + * as low as possible by linking information from another ID3v2 tag that might + * reside in another audio file or alone in a binary file. It is recommended + * that this method is only used when the files are stored on a CD-ROM or other + * circumstances when the risk of file separation is low. + * + * Data should be retrieved from the first tag found in the file to which this + * link points. There may be more than one LINK frame in a tag, but only one + * with the same contents. + * + * A linked frame is to be considered as part of the tag and has the same + * restrictions as if it was a physical part of the tag (i.e. only one + * {@link ID3_Frame_RVRB} frame allowed, whether it's linked or not). + * + * Frames that may be linked and need no additional data are + * {@link ID3_Frame_ASPI}, {@link ID3_Frame_ETCO}, {@link ID3_Frame_EQU2}, + * {@link ID3_Frame_MCDI}, {@link ID3_Frame_MLLT}, {@link ID3_Frame_OWNE}, + * {@link ID3_Frame_RVA2}, {@link ID3_Frame_RVRB}, {@link ID3_Frame_SYTC}, the + * text information frames (ie frames descendats of + * {@link ID3_Frame_AbstractText}) and the URL link frames (ie frames descendants + * of {@link ID3_Frame_AbstractLink}). + * + * The {@link ID3_Frame_AENC}, {@link ID3_Frame_APIC}, {@link ID3_Frame_GEOB} + * and {@link ID3_Frame_TXXX} frames may be linked with the content descriptor + * as additional ID data. + * + * The {@link ID3_Frame_USER} frame may be linked with the language field as + * additional ID data. + * + * The {@link ID3_Frame_PRIV} frame may be linked with the owner identifier as + * additional ID data. + * + * The {@link ID3_Frame_COMM}, {@link ID3_Frame_SYLT} and {@link ID3_Frame_USLT} + * frames may be linked with three bytes of language descriptor directly + * followed by a content descriptor as additional ID data. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_LINK extends ID3_Frame +{ + /** @var string */ + private $_target; + + /** @var string */ + private $_url; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_target = substr($this->_data, 0, 4); + list($this->_url, $this->_data) = + preg_split("/\\x00/", substr($this->_data, 4), 2); + } + + /** + * Returns the target tag identifier. + * + * @return string + */ + public function getTarget() { return $this->_target; } + + /** + * Returns the target tag URL. + * + * @return string + */ + public function getURL() { return $this->_url; } + + /** + * Returns the additional ID data. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/MCDI.php b/src/ID3/Frame/MCDI.php new file mode 100644 index 0000000..58289cc --- /dev/null +++ b/src/ID3/Frame/MCDI.php @@ -0,0 +1,69 @@ + + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_MCDI extends ID3_Frame +{ + /** + * Returns the CD TOC binary dump. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/MLLT.php b/src/ID3/Frame/MLLT.php new file mode 100644 index 0000000..d3c77c0 --- /dev/null +++ b/src/ID3/Frame/MLLT.php @@ -0,0 +1,132 @@ +MPEG location lookup table frame includes references that the + * software can use to calculate positions in the file. + * + * The MPEG frames between reference describes how much the frame counter should + * be increased for every reference. If this value is two then the first + * reference points out the second frame, the 2nd reference the 4th frame, the + * 3rd reference the 6th frame etc. In a similar way the bytes between reference + * and milliseconds between reference points out bytes and milliseconds + * respectively. + * + * Each reference consists of two parts; a certain number of bits that describes + * the difference between what is said in bytes between reference and the + * reality and a certain number of bits that describes the difference between + * what is said in milliseconds between reference and the reality. + * + * There may only be one MLLT frame in each tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_MLLT extends ID3_Frame +{ + /** @var integer */ + private $_frames; + + /** @var integer */ + private $_bytes; + + /** @var integer */ + private $_milliseconds; + + /** @var Array */ + private $_deviation = array(); + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_frames = Transform::getInt16BE(substr($this->_data, 0, 2)); + $this->_bytes = Transform::getInt32BE(substr($this->_data, 2, 3)); + $this->_milliseconds = Transform::getInt32BE(substr($this->_data, 5, 3)); + + $byteDevBits = ord(substr($this->_data, 8, 1)); + $millisDevBits = ord(substr($this->_data, 9, 1)); + + $this->_data = substr($this->_data, 10); // FIXME: Better parsing of data + } + + /** + * Returns the number of MPEG frames between reference. + * + * @return integer + */ + public function getFrames() { return $this->_frames; } + + /** + * Returns the number of bytes between reference. + * + * @return integer + */ + public function getBytes() { return $this->_bytes; } + + /** + * Returns the number of milliseconds between references. + * + * @return integer + */ + public function getMilliseconds() { return $this->_milliseconds; } + + /** + * Returns the deviations as an array. Each value is an array containing two + * values, ie the deviation in bytes, and the deviation in milliseconds, + * respectively. + * + * @return Array + */ + public function getDeviation() { return $this->_deviation; } +} diff --git a/src/ID3/Frame/OWNE.php b/src/ID3/Frame/OWNE.php new file mode 100644 index 0000000..d086250 --- /dev/null +++ b/src/ID3/Frame/OWNE.php @@ -0,0 +1,136 @@ +Ownership frame might be used as a reminder of a made transaction + * or, if signed, as proof. Note that the {@link ID3_Frame_USER} and + * {@link ID3_Frame_TOWN} frames are good to use in conjunction with this one. + * + * There may only be one OWNE frame in a tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_OWNE extends ID3_Frame + implements ID3_Encoding +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_currency; + + /** @var string */ + private $_price; + + /** @var string */ + private $_date; + + /** @var string */ + private $_seller; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + list($tmp1, $tmp2) = preg_split("/\\x00/", substr($this->_data, 1), 2); + $this->_currency = substr($tmp1, 0, 3); + $this->_price = substr($tmp1, 3); + $this->_date = substr($tmp2, 0, 8); + + switch ($this->_encoding) { + case self::UTF16: + $this->_seller = Transform::getString16LE(substr($tmp2, 8)); + break; + case self::UTF16BE: + $this->_seller = Transform::getString16BE(substr($tmp2, 8)); + break; + default: + $this->_seller = Transform::getString8(substr($tmp2, 8)); + } + } + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns the currency used in transaction, encoded according to + * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm + * ISO 4217} alphabetic currency code. + * + * @return string + */ + public function getCurrency() { return $this->_currency; } + + /** + * Returns the price as a numerical string using "." as the decimal separator. + * + * @return string + */ + public function getPrice() { return $this->_price; } + + /** + * Returns the date of purchase as an 8 character date string (YYYYMMDD). + * + * @return string + */ + public function getDate() { return $this->_price; } + + /** + * Returns the name of the seller. + * + * @return string + */ + public function getSeller() { return $this->_seller; } +} diff --git a/src/ID3/Frame/PCNT.php b/src/ID3/Frame/PCNT.php new file mode 100644 index 0000000..caad931 --- /dev/null +++ b/src/ID3/Frame/PCNT.php @@ -0,0 +1,82 @@ +Play counter is simply a counter of the number of times a file has + * been played. The value is increased by one every time the file begins to + * play. There may only be one PCNT frame in each tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_PCNT extends ID3_Frame +{ + /** @var integer */ + private $_counter; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + switch (strlen($this->_data)) { + case 8: + $this->_counter = Transform::getInt64BE($this->_data); + break; + case 4: + $this->_counter = Transform::getInt32BE($this->_data); + break; + } + } + + /** + * Returns the counter. + * + * @return integer + */ + public function getCounter() { return $this->_counter; } +} diff --git a/src/ID3/Frame/POPM.php b/src/ID3/Frame/POPM.php new file mode 100644 index 0000000..e0fa977 --- /dev/null +++ b/src/ID3/Frame/POPM.php @@ -0,0 +1,118 @@ +Popularimeter frame is to specify how good an audio + * file is. Many interesting applications could be found to this frame such as a + * playlist that features better audio files more often than others or it could + * be used to profile a person's taste and find other good files by comparing + * people's profiles. The frame contains the email address to the user, one + * rating byte and a four byte play counter, intended to be increased with one + * for every time the file is played. + * + * The rating is 1-255 where 1 is worst and 255 is best. 0 is unknown. If no + * personal counter is wanted it may be omitted. When the counter reaches all + * one's, one byte is inserted in front of the counter thus making the counter + * eight bits bigger in the same away as the play counter + * {@link ID3_Frame_PCNT}. There may be more than one POPM frame in each tag, + * but only one with the same email address. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_POPM extends ID3_Frame +{ + /** @var string */ + private $_id; + + /** @var integer */ + private $_rating; + + /** @var integer */ + private $_counter; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); + $this->_rating = substr($this->_data, 0, 1); + $this->_data = substr($this->_data, 1); + + switch (strlen($this->_data)) { + case 8: + $this->_counter = Transform::getInt64BE($this->_data); + break; + case 4: + $this->_counter = Transform::getInt32BE($this->_data); + break; + } + } + + /** + * Returns the user identifier string. + * + * @return string + */ + public function getIdentifier() { return $this->_id; } + + + /** + * Returns the user rating. + * + * @return integer + */ + public function getRating() { return $this->_rating; } + + /** + * Returns the counter. + * + * @return integer + */ + public function getCounter() { return $this->_counter; } +} diff --git a/src/ID3/Frame/POSS.php b/src/ID3/Frame/POSS.php new file mode 100644 index 0000000..d714fc7 --- /dev/null +++ b/src/ID3/Frame/POSS.php @@ -0,0 +1,90 @@ +Position synchronisation frame delivers information to the + * listener of how far into the audio stream he picked up; in effect, it states + * the time offset from the first frame in the stream. There may only be one + * POSS frame in each tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_POSS extends ID3_Frame + implements ID3_Timing +{ + /** @var integer */ + private $_format; + + /** @var string */ + private $_position; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_format = substr($this->_data, 0, 1); + $this->_position = Transform::getInt32BE(substr($this->_data, 1, 4)); + } + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat() { return $this->_format; } + + /** + * Returns the position where in the audio the listener starts to receive, + * i.e. the beginning of the next frame. + * + * @return integer + */ + public function getPosition() { return $this->_position; } +} diff --git a/src/ID3/Frame/PRIV.php b/src/ID3/Frame/PRIV.php new file mode 100644 index 0000000..89333d2 --- /dev/null +++ b/src/ID3/Frame/PRIV.php @@ -0,0 +1,87 @@ +Private frame is used to contain information from a software + * producer that its program uses and does not fit into the other frames. The + * frame consists of an owner identifier string and the binary data. The owner + * identifier is URL containing an email address, or a link to a location where + * an email address can be found, that belongs to the organisation responsible + * for the frame. Questions regarding the frame should be sent to the indicated + * email address. The tag may contain more than one PRIV frame but only with + * different contents. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_PRIV extends ID3_Frame +{ + /** @var string */ + private $_id; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + list($this->_id, $this->_data) = preg_split("/\\x00/", $this->_data, 2); + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getIdentifier() { return $this->_id; } + + /** + * Returns the private binary data associated with the frame. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/RBUF.php b/src/ID3/Frame/RBUF.php new file mode 100644 index 0000000..3d6f68e --- /dev/null +++ b/src/ID3/Frame/RBUF.php @@ -0,0 +1,124 @@ +Recommended buffer size frame. If the embedded info + * flag is set then this indicates that an ID3 tag with the maximum size + * described in buffer size may occur in the audio stream. In such case the tag + * should reside between two MPEG frames, if the audio is MPEG encoded. If the + * position of the next tag is known, offset to next tag may be used. The offset + * is calculated from the end of tag in which this frame resides to the first + * byte of the header in the next. This field may be omitted. Embedded tags are + * generally not recommended since this could render unpredictable behaviour + * from present software/hardware. + * + * For applications like streaming audio it might be an idea to embed tags into + * the audio stream though. If the clients connects to individual connections + * like HTTP and there is a possibility to begin every transmission with a tag, + * then this tag should include a recommended buffer size frame. If the client + * is connected to a arbitrary point in the stream, such as radio or multicast, + * then the recommended buffer size frame should be included in every tag. + * + * The buffer size should be kept to a minimum. There may only be one "RBUF" + * frame in each tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_RBUF extends ID3_Frame +{ + /** + * A flag to denote that an ID3 tag with the maximum size described in buffer + * size may occur in the audio stream. + */ + const EMBEDDED = 0x1; + + /** @var integer */ + private $_size; + + /** @var integer */ + private $_flags; + + /** @var integer */ + private $_offset; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_size = Transform::getInt32BE(substr($this->_data, 0, 3)); + $this->_flags = substr($this->_data, 3, 1); + $this->_offset = Transform::getInt32BE(substr($this->_data, 4, 4)); + } + + /** + * Returns the buffer size. + * + * @return integer + */ + public function getSize() { return $this->_size; } + + /** + * Checks whether or not the flag is set. Returns true if the flag + * is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } + + /** + * Returns the offset to next tag. + * + * @return integer + */ + public function getOffset() { return $this->_size; } +} diff --git a/src/ID3/Frame/RVA2.php b/src/ID3/Frame/RVA2.php new file mode 100644 index 0000000..2655907 --- /dev/null +++ b/src/ID3/Frame/RVA2.php @@ -0,0 +1,139 @@ +Relative volume adjustment (2) frame is a more subjective frame than + * the previous ones. It allows the user to say how much he wants to + * increase/decrease the volume on each channel when the file is played. The + * purpose is to be able to align all files to a reference volume, so that you + * don't have to change the volume constantly. This frame may also be used to + * balance adjust the audio. The volume adjustment is encoded as a fixed point + * decibel value, 16 bit signed integer representing (adjustment*512), giving + * +/- 64 dB with a precision of 0.001953125 dB. E.g. +2 dB is stored as $04 00 + * and -2 dB is $FC 00. + * + * There may be more than one RVA2 frame in each tag, but only one with the same + * identification string. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_RVA2 extends ID3_Frame +{ + /** + * The list of channel types. + * + * @var Array + */ + public static $types = array + (0x00 => "Other", + 0x01 => "Master volume", + 0x02 => "Front right", + 0x03 => "Front left", + 0x04 => "Back right", + 0x05 => "Back left", + 0x06 => "Front centre", + 0x07 => "Back centre", + 0x08 => "Subwoofer"); + + /** @var string */ + private $_device; + + /** @var Array */ + private $_adjustments; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + list ($this->_device, $this->_data) = + preg_split("/\\x00/", $this->_data, 2); + + for ($i = $j = 0; $i < 9; $i++) { + $this->_adjustments[$i] = array + ("channelType" => substr($this->_data, $j++, 1), + "volumeAdjustment" => + Transform::getInt16BE(substr($this->_data, $j++, 2))); + $bitsInPeak = ord(substr($this->_data, (++$j)++, 1)); + $bytesInPeak = $bitsInPeak > 0 ? ceil($bitsInPeak / 8) : 0; + switch ($bytesInPeak) { + case 32: + case 24: + $this->_adjustments[$i]["peakVolume"] = + Transform::getInt32BE(substr($this->_data, $j, $bytesInPeak)); + $j += $bytesInPeak; + break; + case 16: + $this->_adjustments[$i]["peakVolume"] = + Transform::getInt16BE(substr($this->_data, $j, $bytesInPeak)); + $j += $bytesInPeak; + break; + case 8: + $this->_adjustments[$i]["peakVolume"] = + Transform::getInt8(substr($this->_data, $j, $bytesInPeak)); + $j += $bytesInPeak; + } + } + } + + /** + * Returns the device where the adjustments should apply. + * + * @return string + */ + public function getDevice() { return $this->_device; } + + /** + * Returns the array containing volume adjustments for each channel. Volume + * adjustments are arrays themselves containing the following keys: + * channelType, volumeAdjustment, peakVolume. + * + * @return Array + */ + public function getAdjustments() { return $this->_adjustments; } +} diff --git a/src/ID3/Frame/RVRB.php b/src/ID3/Frame/RVRB.php new file mode 100644 index 0000000..14ec764 --- /dev/null +++ b/src/ID3/Frame/RVRB.php @@ -0,0 +1,204 @@ +Reverb is yet another subjective frame, with which you can adjust + * echoes of different kinds. Reverb left/right is the delay between every + * bounce in milliseconds. Reverb bounces left/right is the number of bounces + * that should be made. $FF equals an infinite number of bounces. Feedback is + * the amount of volume that should be returned to the next echo bounce. $00 is + * 0%, $FF is 100%. If this value were $7F, there would be 50% volume reduction + * on the first bounce, 50% of that on the second and so on. Left to left means + * the sound from the left bounce to be played in the left speaker, while left + * to right means sound from the left bounce to be played in the right speaker. + * + * Premix left to right is the amount of left sound to be mixed in the right + * before any reverb is applied, where $00 id 0% and $FF is 100%. Premix right + * to left does the same thing, but right to left. Setting both premix to $FF + * would result in a mono output (if the reverb is applied symmetric). There may + * only be one RVRB frame in each tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_RVRB extends ID3_Frame +{ + /** @var integer */ + private $_reverbLeft; + + /** @var integer */ + private $_reverbRight; + + /** @var integer */ + private $_reverbBouncesLeft; + + /** @var integer */ + private $_reverbBouncesRight; + + /** @var integer */ + private $_reverbFeedbackLtoL; + + /** @var integer */ + private $_reverbFeedbackLtoR; + + /** @var integer */ + private $_reverbFeedbackRtoR; + + /** @var integer */ + private $_reverbFeedbackRtoL; + + /** @var integer */ + private $_premixLtoR; + + /** @var integer */ + private $_premixRtoL; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_reverbLeft = substr($this->_data, 0, 2); + $this->_reverbRight = substr($this->_data, 2, 2); + $this->_reverbBouncesLeft = substr($this->_data, 4, 1); + $this->_reverbBouncesRight = substr($this->_data, 5, 1); + $this->_reverbFeedbackLtoL = substr($this->_data, 6, 1); + $this->_reverbFeedbackLtoR = substr($this->_data, 7, 1); + $this->_reverbFeedbackRtoR = substr($this->_data, 8, 1); + $this->_reverbFeedbackRtoL = substr($this->_data, 9, 1); + $this->_premixLtoR = substr($this->_data, 10, 1); + $this->_premixRtoL = substr($this->_data, 11, 1); + } + + /** + * Returns the left reverb. + * + * @return integer + */ + public function getReverbLeft() { return $this->_reverbLeft; } + + /** + * Returns the right reverb. + * + * @return integer + */ + public function getReverbRight() { return $this->_reverbRight; } + + /** + * Returns the left reverb bounces. + * + * @return integer + */ + public function getReverbBouncesLeft() { return $this->_reverbBouncesLeft; } + + /** + * Returns the right reverb bounces. + * + * @return integer + */ + public function getReverbBouncesRight() { return $this->_reverbBouncesRight; } + + /** + * Returns the left-to-left reverb feedback. + * + * @return integer + */ + public function getReverbFeedbackLtoL() + { + return $this->_reverbFeedbackLtoL; + } + + /** + * Returns the left-to-right reverb feedback. + * + * @return integer + */ + public function getReverbFeedbackLtoR() + { + return $this->_reverbFeedbackLtoR; + } + + /** + * Returns the right-to-right reverb feedback. + * + * @return integer + */ + public function getReverbFeedbackRtoR() + { + return $this->_reverbFeedbackRtoR; + } + + /** + * Returns the right-to-left reverb feedback. + * + * @return integer + */ + public function getReverbFeedbackRtoL() + { + return $this->_reverbFeedbackRtoL; + } + + /** + * Returns the left-to-right premix. + * + * @return integer + */ + public function getPremixLtoR() + { + return $this->_premixLtoR; + } + + /** + * Returns the right-to-left premix. + * + * @return integer + */ + public function getPremixRtoL() + { + return $this->_premixRtoL; + } +} diff --git a/src/ID3/Frame/SEEK.php b/src/ID3/Frame/SEEK.php new file mode 100644 index 0000000..757f17a --- /dev/null +++ b/src/ID3/Frame/SEEK.php @@ -0,0 +1,75 @@ +Seek frame indicates where other tags in a file/stream can be + * found. The minimum offset to next tag is calculated from the end of this tag + * to the beginning of the next. There may only be one seek frame in a tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_SEEK extends ID3_Frame +{ + /** @var integer */ + private $_minOffset; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_minOffset = Transform::getInt32BE($this->_data); + } + + /** + * Returns the minimum offset to next tag in bytes. + * + * @return integer + */ + public function getMinimumOffset() { return $this->_minOffset; } +} diff --git a/src/ID3/Frame/SIGN.php b/src/ID3/Frame/SIGN.php new file mode 100644 index 0000000..fd164f1 --- /dev/null +++ b/src/ID3/Frame/SIGN.php @@ -0,0 +1,88 @@ +Group identification registration, to be signed. Although signatures + * can reside inside the registration frame, it might be desired to store the + * signature elsewhere, e.g. in watermarks. There may be more than one signature + * frame in a tag, but no two may be identical. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_SIGN extends ID3_Frame +{ + /** @var integer */ + private $_group; + + /** @var string */ + private $_signature; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_group = substr($this->_data, 0, 1); + $this->_signature = substr($this->_data, 1); + } + + /** + * Returns the group symbol. + * + * @return integer + */ + public function getGroup() { return $this->_group; } + + /** + * Returns the signature binary data. + * + * @return string + */ + public function getSignature() { return $this->_signature; } +} diff --git a/src/ID3/Frame/SYLT.php b/src/ID3/Frame/SYLT.php new file mode 100644 index 0000000..0405d99 --- /dev/null +++ b/src/ID3/Frame/SYLT.php @@ -0,0 +1,173 @@ +Synchronised lyrics/text frame is another way of incorporating the + * words, said or sung lyrics, in the audio file as text, this time, however, + * in sync with the audio. It might also be used to describing events e.g. + * occurring on a stage or on the screen in sync with the audio. + * + * There may be more than one SYLT frame in each tag, but only one with the + * same language and content descriptor. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_USER extends ID3_Frame + implements ID3_Encoding, ID3_Language, ID3_Timing +{ + /** + * The list of content types. + * + * @var Array + */ + public static $types = array + (0x00 => "Other", + 0x01 => "Lyrics", + 0x02 => "Text transcription", + 0x03 => "Movement/Part name", + 0x04 => "Eevents", + 0x05 => "Chord", + 0x06 => "Trivia", + 0x07 => "URLs to webpages", + 0x08 => "URLs to images"); + + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_language; + + /** @var integer */ + private $_format; + + /** @var integer */ + private $_type; + + /** @var string */ + private $_description; + + /** @var Array */ + private $_text = array(); + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + $this->_language = substr($this->_data, 1, 3); + $this->_format = substr($this->_data, 3, 1); + $this->_type = substr($this->_data, 4, 1); + + switch ($this->_encoding) { + case self::UTF16: + list($this->_description, $this->_data) = + preg_split("/\\x00\\x00/", substr($this->_data, 5), 2); + $this->_description = Transform::getString16LE($this->_description); + break; + case self::UTF16BE: + list($this->_description, $this->_data) = + preg_split("/\\x00\\x00/", substr($this->_data, 5), 2); + $this->_description = Transform::getString16BE($this->_description); + break; + default: + list($this->_description, $this->_data) = + preg_split("/\\x00/", substr($this->_data, 5), 2); + $this->_description = Transform::getString8($this->_description); + } + + $this->_text = $this->_data; // FIXME: Better parsing of data + } + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns the language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see ID3_Language#ISO_639_2 + * @return string + */ + public function getLanguage() { return $this->_language; } + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat() { return $this->_format; } + + /** + * Returns the content type code. + * + * @return integer + */ + public function getType() { return $this->_type; } + + /** + * Returns the content description. + * + * @return string + */ + public function getDescription() { return $this->_description; } + + /** + * Returns the texts with their timestamps. + * + * @return Array + */ + public function getText() { return $this->_text; } +} diff --git a/src/ID3/Frame/SYTC.php b/src/ID3/Frame/SYTC.php new file mode 100644 index 0000000..5730a23 --- /dev/null +++ b/src/ID3/Frame/SYTC.php @@ -0,0 +1,99 @@ +Synchronised tempo codes frame might be used. + * + * The tempo data consists of one or more tempo codes. Each tempo code consists + * of one tempo part and one time part. The tempo is in BPM described with one + * or two bytes. If the first byte has the value $FF, one more byte follows, + * which is added to the first giving a range from 2 - 510 BPM, since $00 and + * $01 is reserved. $00 is used to describe a beat-free time period, which is + * not the same as a music-free time period. $01 is used to indicate one single + * beat-stroke followed by a beat-free period. + * + * The tempo descriptor is followed by a time stamp. Every time the tempo in the + * music changes, a tempo descriptor may indicate this for the player. All tempo + * descriptors must be sorted in chronological order. The first beat-stroke in + * a time-period is at the same time as the beat description occurs. There may + * only be one "SYTC" frame in each tag. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_SYTC extends ID3_Frame + implements ID3_Timing +{ + /** @var integer */ + private $_format; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_format = substr($this->_data, 0, 1); + + $this->_data = substr($this->_data, 1); // FIXME: Better parsing of data + } + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat() { return $this->_format; } + + /** + * Returns the tempo data. + * + * @return string + */ + public function getData() { return $this->_data; } +} diff --git a/src/ID3/Frame/TALB.php b/src/ID3/Frame/TALB.php new file mode 100644 index 0000000..2e646ac --- /dev/null +++ b/src/ID3/Frame/TALB.php @@ -0,0 +1,51 @@ +Album/Movie/Show title frame is intended for the title of the + * recording (or source of sound) from which the audio in the file is taken. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TALB extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TBPM.php b/src/ID3/Frame/TBPM.php new file mode 100644 index 0000000..2ff48c8 --- /dev/null +++ b/src/ID3/Frame/TBPM.php @@ -0,0 +1,51 @@ +BPM frame contains the number of beats per minute in the main part + * of the audio. The BPM is an integer and represented as a numerical string. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TBPM extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TCOM.php b/src/ID3/Frame/TCOM.php new file mode 100644 index 0000000..0e0581e --- /dev/null +++ b/src/ID3/Frame/TCOM.php @@ -0,0 +1,50 @@ +Composer frame is intended for the name of the composer. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TCOM extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TCON.php b/src/ID3/Frame/TCON.php new file mode 100644 index 0000000..e01c847 --- /dev/null +++ b/src/ID3/Frame/TCON.php @@ -0,0 +1,60 @@ +Content type, which ID3v1 was stored as a one byte numeric value + * only, is now a string. You may use one or several of the ID3v1 types as + * numerical strings, or, since the category list would be impossible to + * maintain with accurate and up to date categories, define your own. + * + * You may also use any of the following keywords: + * + *
+ *  RX  Remix
+ *  CR  Cover
+ * 
+ * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TCON extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TCOP.php b/src/ID3/Frame/TCOP.php new file mode 100644 index 0000000..21b504d --- /dev/null +++ b/src/ID3/Frame/TCOP.php @@ -0,0 +1,57 @@ +Copyright message frame, in which the string must begin with a + * year and a space character (making five characters), is intended for the + * copyright holder of the original sound, not the audio file itself. The + * absence of this frame means only that the copyright information is + * unavailable or has been removed, and must not be interpreted to mean that the + * audio is public domain. Every time this field is displayed the field must be + * preceded with "Copyright " (C) " ", where (C) is one character showing a C in + * a circle. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TCOP extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDEN.php b/src/ID3/Frame/TDEN.php new file mode 100644 index 0000000..69e1b87 --- /dev/null +++ b/src/ID3/Frame/TDEN.php @@ -0,0 +1,52 @@ +Encoding time frame contains a timestamp describing when the audio + * was encoded. Timestamp format is described in the + * {@link http://www.id3.org/id3v2.4.0-structure ID3v2 structure document}. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TDEN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDLY.php b/src/ID3/Frame/TDLY.php new file mode 100644 index 0000000..e815c57 --- /dev/null +++ b/src/ID3/Frame/TDLY.php @@ -0,0 +1,52 @@ +Playlist delay defines the numbers of milliseconds of silence that + * should be inserted before this audio. The value zero indicates that this is a + * part of a multifile audio track that should be played continuously. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TDLY extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDOR.php b/src/ID3/Frame/TDOR.php new file mode 100644 index 0000000..812f0bb --- /dev/null +++ b/src/ID3/Frame/TDOR.php @@ -0,0 +1,53 @@ +Original release time frame contains a timestamp describing when + * the original recording of the audio was released. Timestamp format is + * described in the {@link http://www.id3.org/id3v2.4.0-structure ID3v2 + * structure document}. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TDOR extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDRC.php b/src/ID3/Frame/TDRC.php new file mode 100644 index 0000000..0573bf5 --- /dev/null +++ b/src/ID3/Frame/TDRC.php @@ -0,0 +1,52 @@ +Recording time frame contains a timestamp describing when the + * audio was recorded. Timestamp format is described in the + * {@link http://www.id3.org/id3v2.4.0-structure ID3v2 structure document}. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TDRC extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDRL.php b/src/ID3/Frame/TDRL.php new file mode 100644 index 0000000..45129f5 --- /dev/null +++ b/src/ID3/Frame/TDRL.php @@ -0,0 +1,52 @@ +Release time frame contains a timestamp describing when the audio + * was first released. Timestamp format is described in the + * {@link http://www.id3.org/id3v2.4.0-structure ID3v2 structure document}. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TDRL extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDTG.php b/src/ID3/Frame/TDTG.php new file mode 100644 index 0000000..4ee842b --- /dev/null +++ b/src/ID3/Frame/TDTG.php @@ -0,0 +1,52 @@ +Tagging time frame contains a timestamp describing then the audio + * was tagged. Timestamp format is described in the + * {@link http://www.id3.org/id3v2.4.0-structure ID3v2 structure document}. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TDTG extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TENC.php b/src/ID3/Frame/TENC.php new file mode 100644 index 0000000..08ef695 --- /dev/null +++ b/src/ID3/Frame/TENC.php @@ -0,0 +1,52 @@ +Encoded by frame contains the name of the person or organisation + * that encoded the audio file. This field may contain a copyright message, if + * the audio file also is copyrighted by the encoder. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TENC extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TEXT.php b/src/ID3/Frame/TEXT.php new file mode 100644 index 0000000..3f5c631 --- /dev/null +++ b/src/ID3/Frame/TEXT.php @@ -0,0 +1,51 @@ +Lyricist/Text writer frame is intended for the writer of the text + * or lyrics in the recording. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TEXT extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TFLT.php b/src/ID3/Frame/TFLT.php new file mode 100644 index 0000000..98b9370 --- /dev/null +++ b/src/ID3/Frame/TFLT.php @@ -0,0 +1,67 @@ +File type frame indicates which type of audio this tag defines. + * The following types and refinements are defined: + * + *
+ * MIME   MIME type follows
+ *  MPG    MPEG Audio
+ *    /1     MPEG 1/2 layer I
+ *    /2     MPEG 1/2 layer II
+ *    /3     MPEG 1/2 layer III
+ *    /2.5   MPEG 2.5
+ *    /AAC   Advanced audio compression
+ *  VQF    Transform-domain Weighted Interleave Vector Quantisation
+ *  PCM    Pulse Code Modulated audio
+ * 
+ * + * but other types may be used, but not for these types though. This is used in + * a similar way to the predefined types in the {@link ID3_Frame_TMED} + * frame. If this frame is not present audio type is assumed to be MPG. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TFLT extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TIPL.php b/src/ID3/Frame/TIPL.php new file mode 100644 index 0000000..d83b278 --- /dev/null +++ b/src/ID3/Frame/TIPL.php @@ -0,0 +1,51 @@ +Involved people list is very similar to the musician credits list, + * but maps between functions, like producer, and names. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TIPL extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TIT1.php b/src/ID3/Frame/TIT1.php new file mode 100644 index 0000000..bc31ca8 --- /dev/null +++ b/src/ID3/Frame/TIT1.php @@ -0,0 +1,52 @@ +Content group description frame is used if the sound belongs to a + * larger category of sounds/music. For example, classical music is often sorted + * in different musical sections (e.g. "Piano Concerto", "Weather - Hurricane"). + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TIT1 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TIT2.php b/src/ID3/Frame/TIT2.php new file mode 100644 index 0000000..4bd2140 --- /dev/null +++ b/src/ID3/Frame/TIT2.php @@ -0,0 +1,51 @@ +Title/Songname/Content description frame is the actual name of the + * piece (e.g. "Adagio", "Hurricane Donna"). + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TIT2 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TIT3.php b/src/ID3/Frame/TIT3.php new file mode 100644 index 0000000..4203739 --- /dev/null +++ b/src/ID3/Frame/TIT3.php @@ -0,0 +1,52 @@ +Subtitle/Description refinement frame is used for information + * directly related to the contents title (e.g. "Op. 16" or "Performed live at + * Wembley"). + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TIT3 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TKEY.php b/src/ID3/Frame/TKEY.php new file mode 100644 index 0000000..66aa838 --- /dev/null +++ b/src/ID3/Frame/TKEY.php @@ -0,0 +1,54 @@ +Initial key frame contains the musical key in which the sound + * starts. It is represented as a string with a maximum length of three + * characters. The ground keys are represented with "A", "B", "C", "D", "E", "F" + * and "G" and halfkeys represented with "b" and "#". Minor is represented as + * "m", e.g. "Dbm" $00. Off key is represented with an "o" only. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TKEY extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TLAN.php b/src/ID3/Frame/TLAN.php new file mode 100644 index 0000000..8bff396 --- /dev/null +++ b/src/ID3/Frame/TLAN.php @@ -0,0 +1,55 @@ +Language frame should contain the languages of the text or lyrics + * spoken or sung in the audio. The language is represented with three + * characters according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO-639-2}. If more than one language is used in the text their language + * codes should follow according to the amount of their usage, e.g. + * "eng" $00 "sve" $00. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TLAN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TLEN.php b/src/ID3/Frame/TLEN.php new file mode 100644 index 0000000..750eb24 --- /dev/null +++ b/src/ID3/Frame/TLEN.php @@ -0,0 +1,51 @@ +Length frame contains the length of the audio file in + * milliseconds, represented as a numeric string. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TLEN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TMCL.php b/src/ID3/Frame/TMCL.php new file mode 100644 index 0000000..badfbdc --- /dev/null +++ b/src/ID3/Frame/TMCL.php @@ -0,0 +1,52 @@ +Musician credits list is intended as a mapping between instruments + * and the musician that played it. Every odd field is an instrument and every + * even is an artist or a comma delimited list of artists. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TMCL extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TMED.php b/src/ID3/Frame/TMED.php new file mode 100644 index 0000000..7e3c94a --- /dev/null +++ b/src/ID3/Frame/TMED.php @@ -0,0 +1,135 @@ +Media type frame describes from which media the sound originated. + * This may be a text string or a reference to the predefined media types found + * in the list below. Example: "VID/PAL/VHS" $00. + * + *
+ *  DIG    Other digital media
+ *    /A    Analogue transfer from media
+ *
+ *  ANA    Other analogue media
+ *    /WAC  Wax cylinder
+ *    /8CA  8-track tape cassette
+ *
+ *  CD     CD
+ *    /A    Analogue transfer from media
+ *    /DD   DDD
+ *    /AD   ADD
+ *    /AA   AAD
+ *
+ *  LD     Laserdisc
+ *
+ *  TT     Turntable records
+ *    /33    33.33 rpm
+ *    /45    45 rpm
+ *    /71    71.29 rpm
+ *    /76    76.59 rpm
+ *    /78    78.26 rpm
+ *    /80    80 rpm
+ *
+ *  MD     MiniDisc
+ *    /A    Analogue transfer from media
+ *
+ *  DAT    DAT
+ *    /A    Analogue transfer from media
+ *    /1    standard, 48 kHz/16 bits, linear
+ *    /2    mode 2, 32 kHz/16 bits, linear
+ *    /3    mode 3, 32 kHz/12 bits, non-linear, low speed
+ *    /4    mode 4, 32 kHz/12 bits, 4 channels
+ *    /5    mode 5, 44.1 kHz/16 bits, linear
+ *    /6    mode 6, 44.1 kHz/16 bits, 'wide track' play
+ *
+ *  DCC    DCC
+ *    /A    Analogue transfer from media
+ *
+ *  DVD    DVD
+ *    /A    Analogue transfer from media
+ *
+ *  TV     Television
+ *    /PAL    PAL
+ *    /NTSC   NTSC
+ *    /SECAM  SECAM
+ *
+ *  VID    Video
+ *    /PAL    PAL
+ *    /NTSC   NTSC
+ *    /SECAM  SECAM
+ *    /VHS    VHS
+ *    /SVHS   S-VHS
+ *    /BETA   BETAMAX
+ *
+ *  RAD    Radio
+ *    /FM   FM
+ *    /AM   AM
+ *    /LW   LW
+ *    /MW   MW
+ *
+ *  TEL    Telephone
+ *    /I    ISDN
+ *
+ *  MC     MC (normal cassette)
+ *    /4    4.75 cm/s (normal speed for a two sided cassette)
+ *    /9    9.5 cm/s
+ *    /I    Type I cassette (ferric/normal)
+ *    /II   Type II cassette (chrome)
+ *    /III  Type III cassette (ferric chrome)
+ *    /IV   Type IV cassette (metal)
+ *
+ *  REE    Reel
+ *    /9    9.5 cm/s
+ *    /19   19 cm/s
+ *    /38   38 cm/s
+ *    /76   76 cm/s
+ *    /I    Type I cassette (ferric/normal)
+ *    /II   Type II cassette (chrome)
+ *    /III  Type III cassette (ferric chrome)
+ *    /IV   Type IV cassette (metal)
+ * 
+ * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TMED extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TMOO.php b/src/ID3/Frame/TMOO.php new file mode 100644 index 0000000..89975ac --- /dev/null +++ b/src/ID3/Frame/TMOO.php @@ -0,0 +1,51 @@ +Mood frame is intended to reflect the mood of the audio with a few + * keywords, e.g. "Romantic" or "Sad". + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TMOO extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOAL.php b/src/ID3/Frame/TOAL.php new file mode 100644 index 0000000..fd1e940 --- /dev/null +++ b/src/ID3/Frame/TOAL.php @@ -0,0 +1,52 @@ +Original album/movie/show title frame is intended for the title of + * the original recording (or source of sound), if for example the music in the + * file should be a cover of a previously released song. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TOAL extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOFN.php b/src/ID3/Frame/TOFN.php new file mode 100644 index 0000000..5b5ae3f --- /dev/null +++ b/src/ID3/Frame/TOFN.php @@ -0,0 +1,52 @@ +Original filename frame contains the preferred filename for the + * file, since some media doesn't allow the desired length of the filename. The + * filename is case sensitive and includes its suffix. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TOFN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOLY.php b/src/ID3/Frame/TOLY.php new file mode 100644 index 0000000..75dbe30 --- /dev/null +++ b/src/ID3/Frame/TOLY.php @@ -0,0 +1,52 @@ +Original lyricist/text writer frame is intended for the text + * writer of the original recording, if for example the music in the file should + * be a cover of a previously released song. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TOLY extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOPE.php b/src/ID3/Frame/TOPE.php new file mode 100644 index 0000000..26ba5cf --- /dev/null +++ b/src/ID3/Frame/TOPE.php @@ -0,0 +1,52 @@ +Original artist/performer frame is intended for the performer of + * the original recording, if for example the music in the file should be a + * cover of a previously released song. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TOPE extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOWN.php b/src/ID3/Frame/TOWN.php new file mode 100644 index 0000000..0eff873 --- /dev/null +++ b/src/ID3/Frame/TOWN.php @@ -0,0 +1,51 @@ +File owner/licensee frame contains the name of the owner or + * licensee of the file and it's contents. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TOWN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPE1.php b/src/ID3/Frame/TPE1.php new file mode 100644 index 0000000..60be012 --- /dev/null +++ b/src/ID3/Frame/TPE1.php @@ -0,0 +1,51 @@ +Lead artist/Lead performer/Soloist/Performing group is used for + * the main artist. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TPE1 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPE2.php b/src/ID3/Frame/TPE2.php new file mode 100644 index 0000000..287a6c1 --- /dev/null +++ b/src/ID3/Frame/TPE2.php @@ -0,0 +1,51 @@ +Band/Orchestra/Accompaniment frame is used for additional + * information about the performers in the recording. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TPE2 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPE3.php b/src/ID3/Frame/TPE3.php new file mode 100644 index 0000000..59a5ee5 --- /dev/null +++ b/src/ID3/Frame/TPE3.php @@ -0,0 +1,50 @@ +Conductor frame is used for the name of the conductor. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TPE3 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPE4.php b/src/ID3/Frame/TPE4.php new file mode 100644 index 0000000..db46f61 --- /dev/null +++ b/src/ID3/Frame/TPE4.php @@ -0,0 +1,52 @@ +Interpreted, remixed, or otherwise modified by frame contains more + * information about the people behind a remix and similar interpretations of + * another existing piece. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TPE4 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPOS.php b/src/ID3/Frame/TPOS.php new file mode 100644 index 0000000..60c0d07 --- /dev/null +++ b/src/ID3/Frame/TPOS.php @@ -0,0 +1,54 @@ +Part of a set frame is a numeric string that describes which part + * of a set the audio came from. This frame is used if the source described in + * the {@link ID3_Frame_TALB} frame is divided into several mediums, e.g. + * a double CD. The value may be extended with a "/" character and a numeric + * string containing the total number of parts in the set. E.g. "1/2". + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TPOS extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPRO.php b/src/ID3/Frame/TPRO.php new file mode 100644 index 0000000..f727934 --- /dev/null +++ b/src/ID3/Frame/TPRO.php @@ -0,0 +1,57 @@ +Produced notice frame, in which the string must begin with a year + * and a space character (making five characters), is intended for the + * production copyright holder of the original sound, not the audio file itself. + * The absence of this frame means only that the production copyright + * information is unavailable or has been removed, and must not be interpreted + * to mean that the audio is public domain. Every time this field is displayed + * the field must be preceded with "Produced " (P) " ", where (P) is one + * character showing a P in a circle. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TPRO extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPUB.php b/src/ID3/Frame/TPUB.php new file mode 100644 index 0000000..782a672 --- /dev/null +++ b/src/ID3/Frame/TPUB.php @@ -0,0 +1,51 @@ +Publisher frame simply contains the name of the label or + * publisher. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TPUB extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TRCK.php b/src/ID3/Frame/TRCK.php new file mode 100644 index 0000000..bed052a --- /dev/null +++ b/src/ID3/Frame/TRCK.php @@ -0,0 +1,53 @@ +Track number/Position in set frame is a numeric string containing + * the order number of the audio-file on its original recording. This may be + * extended with a "/" character and a numeric string containing the total + * number of tracks/elements on the original recording. E.g. "4/9". + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TRCK extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TRSN.php b/src/ID3/Frame/TRSN.php new file mode 100644 index 0000000..52b7b35 --- /dev/null +++ b/src/ID3/Frame/TRSN.php @@ -0,0 +1,51 @@ +Internet radio station name frame contains the name of the + * internet radio station from which the audio is streamed. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TRSN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TRSO.php b/src/ID3/Frame/TRSO.php new file mode 100644 index 0000000..41ecabb --- /dev/null +++ b/src/ID3/Frame/TRSO.php @@ -0,0 +1,51 @@ +Internet radio station owner frame contains the name of the owner + * of the internet radio station from which the audio is streamed. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TRSO extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSOA.php b/src/ID3/Frame/TSOA.php new file mode 100644 index 0000000..9714ec8 --- /dev/null +++ b/src/ID3/Frame/TSOA.php @@ -0,0 +1,51 @@ +Album sort order frame defines a string which should be used + * instead of the {@link ID3_Frame_TALB} album name frame for sorting purposes. +* + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TSOA extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSOP.php b/src/ID3/Frame/TSOP.php new file mode 100644 index 0000000..3f61b44 --- /dev/null +++ b/src/ID3/Frame/TSOP.php @@ -0,0 +1,51 @@ +Performer sort order frame defines a string which should be used + * instead of the {@link ID3_Frame_TPE2} performer frame for sorting purposes. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TSOP extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSOT.php b/src/ID3/Frame/TSOT.php new file mode 100644 index 0000000..edacb59 --- /dev/null +++ b/src/ID3/Frame/TSOT.php @@ -0,0 +1,51 @@ +Title sort order frame defines a string which should be used + * instead of the {@link ID3_Frame_TIT2} title frame for sorting purposes. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TSOT extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSRC.php b/src/ID3/Frame/TSRC.php new file mode 100644 index 0000000..dbbb74d --- /dev/null +++ b/src/ID3/Frame/TSRC.php @@ -0,0 +1,51 @@ +ISRC frame should contain the International Standard Recording + * Code (12 characters). + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_ISRC extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSSE.php b/src/ID3/Frame/TSSE.php new file mode 100644 index 0000000..ca60444 --- /dev/null +++ b/src/ID3/Frame/TSSE.php @@ -0,0 +1,52 @@ +Software/Hardware and settings used for encoding frame includes + * the used audio encoder and its settings when the file was encoded. Hardware + * refers to hardware encoders, not the computer on which a program was run. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TSSE extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSST.php b/src/ID3/Frame/TSST.php new file mode 100644 index 0000000..96027c6 --- /dev/null +++ b/src/ID3/Frame/TSST.php @@ -0,0 +1,51 @@ +Set subtitle frame is intended for the subtitle of the part of a + * set this track belongs to. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TSST extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TXXX.php b/src/ID3/Frame/TXXX.php new file mode 100644 index 0000000..68b55ee --- /dev/null +++ b/src/ID3/Frame/TXXX.php @@ -0,0 +1,57 @@ + + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_TXXX extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/USER.php b/src/ID3/Frame/USER.php new file mode 100644 index 0000000..a68c030 --- /dev/null +++ b/src/ID3/Frame/USER.php @@ -0,0 +1,114 @@ +Terms of use frame contains a brief description of the terms of + * use and ownership of the file. More detailed information concerning the legal + * terms might be available through the {@link ID3_Frame_WCOP} frame. Newlines + * are allowed in the text. There may be more than one Terms of use frames in a + * tag, but only one with the same language. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_USER extends ID3_Frame + implements ID3_Encoding, ID3_Language +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_language; + + /** @var string */ + private $_text; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + $this->_language = substr($this->_data, 1, 3); + + switch ($this->_encoding) { + case self::UTF16: + $this->_text = Transform::getString16LE(substr($this->_data, 4)); + break; + case self::UTF16BE: + $this->_text = Transform::getString16BE(substr($this->_data, 4)); + break; + default: + $this->_text = Transform::getString8(substr($this->_data, 4)); + } + } + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns the language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see ID3_Language#ISO_639_2 + * @return string + */ + public function getLanguage() { return $this->_language; } + + /** + * Returns the text. + * + * @return string + */ + public function getText() { return $this->_text; } +} diff --git a/src/ID3/Frame/USLT.php b/src/ID3/Frame/USLT.php new file mode 100644 index 0000000..e729414 --- /dev/null +++ b/src/ID3/Frame/USLT.php @@ -0,0 +1,132 @@ +Unsynchronised lyrics/text transcription frame contains the lyrics + * of the song or a text transcription of other vocal activities. There may be + * more than one unsynchronised lyrics/text transcription frame in each tag, but + * only one with the same language and content descriptor. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_USLT extends ID3_Frame + implements ID3_Encoding, ID3_Language +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_language; + + /** @var string */ + private $_description; + + /** @var string */ + private $_text; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + $this->_language = substr($this->_data, 1, 3); + + switch ($this->_encoding) { + case self::UTF16: + list ($this->_description, $this->_text) = + preg_split("/\\x00\\x00/", substr($this->_data, 4), 2); + $this->_description = Transform::getString16LE($this->_description); + $this->_text = Transform::getString16LE($this->_text); + break; + case self::UTF16BE: + list ($this->_description, $this->_text) = + preg_split("/\\x00\\x00/", substr($this->_data, 4), 2); + $this->_description = Transform::getString16BE($this->_description); + $this->_text = Transform::getString16BE($this->_text); + break; + default: + list ($this->_description, $this->_text) = + preg_split("/\\x00/", substr($this->_data, 4), 2); + $this->_description = Transform::getString8($this->_description); + $this->_text = Transform::getString8($this->_text); + } + } + + /** + * Returns the text encoding. + * + * @return integer + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns the language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see ID3_Language#ISO_639_2 + * @return string + */ + public function getLanguage() { return $this->_language; } + + /** + * Returns the short content description. + * + * @return string + */ + public function getDescription() { return $this->_description; } + + /** + * Returns the lyrics/text. + * + * @return string + */ + public function getText() { return $this->_text; } +} diff --git a/src/ID3/Frame/WCOM.php b/src/ID3/Frame/WCOM.php new file mode 100644 index 0000000..0c494c6 --- /dev/null +++ b/src/ID3/Frame/WCOM.php @@ -0,0 +1,52 @@ +Commercial information frame is a URL pointing at a webpage with + * information such as where the album can be bought. There may be more than one + * WCOM frame in a tag, but not with the same content. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_WCOM extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WCOP.php b/src/ID3/Frame/WCOP.php new file mode 100644 index 0000000..4eb9da1 --- /dev/null +++ b/src/ID3/Frame/WCOP.php @@ -0,0 +1,51 @@ +Copyright/Legal information frame is a URL pointing at a webpage + * where the terms of use and ownership of the file is described. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_WCOP extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WOAF.php b/src/ID3/Frame/WOAF.php new file mode 100644 index 0000000..c78941d --- /dev/null +++ b/src/ID3/Frame/WOAF.php @@ -0,0 +1,51 @@ +Official audio file webpage frame is a URL pointing at a file + * specific webpage. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_WOAF extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WOAR.php b/src/ID3/Frame/WOAR.php new file mode 100644 index 0000000..c6e9a1b --- /dev/null +++ b/src/ID3/Frame/WOAR.php @@ -0,0 +1,52 @@ +Official artist/performer webpage frame is a URL pointing at the + * artists official webpage. There may be more than one WOAR frame in a tag if + * the audio contains more than one performer, but not with the same content. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_WOAR extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WOAS.php b/src/ID3/Frame/WOAS.php new file mode 100644 index 0000000..ddc7f96 --- /dev/null +++ b/src/ID3/Frame/WOAS.php @@ -0,0 +1,51 @@ +Official audio source webpage frame is a URL pointing at the + * official webpage for the source of the audio file, e.g. a movie. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_WOAS extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WORS.php b/src/ID3/Frame/WORS.php new file mode 100644 index 0000000..e92e719 --- /dev/null +++ b/src/ID3/Frame/WORS.php @@ -0,0 +1,51 @@ +Official Internet radio station homepage contains a URL pointing + * at the homepage of the internet radio station. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_WORS extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WPAY.php b/src/ID3/Frame/WPAY.php new file mode 100644 index 0000000..bfb52de --- /dev/null +++ b/src/ID3/Frame/WPAY.php @@ -0,0 +1,51 @@ +Payment frame is a URL pointing at a webpage that will handle the + * process of paying for this file. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_WPAY extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WPUB.php b/src/ID3/Frame/WPUB.php new file mode 100644 index 0000000..5cc05ad --- /dev/null +++ b/src/ID3/Frame/WPUB.php @@ -0,0 +1,51 @@ +Publishers official webpage frame is a URL pointing at the + * official webpage for the publisher. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_WPUB extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WXXX.php b/src/ID3/Frame/WXXX.php new file mode 100644 index 0000000..0ffc12a --- /dev/null +++ b/src/ID3/Frame/WXXX.php @@ -0,0 +1,114 @@ + + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Frame_WXXX extends ID3_Frame_AbstractLink + implements ID3_Encoding +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_description; + + /** + * Constructs the class with given parameters and parses object related data. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_encoding = substr($this->_data, 0, 1); + switch ($this->_encoding) { + case self::UTF16: + $chunks = preg_split("/\\x00\\x00/", substr($this->_data, 1)); + $this->_description = Transform::getString16LE($chunks[0]); + $this->_link = $chunks[1]; + break; + case self::UTF16BE: + $chunks = preg_split("/\\x00\\x00/", substr($this->_data, 1)); + $this->_description = Transform::getString16BE($chunks[0]); + $this->_link = $chunks[1]; + break; + case self::UTF8: + case self::ISO88591: + default: + list($this->_description, $this->_link) = + preg_split("/\\x00/", substr($this->_data, 1)); + break; + } + } + + /** + * Returns the text encoding. + * + * @return integer The encoding. + */ + public function getEncoding() { return $this->_encoding; } + + /** + * Returns the link description. + * + * @return string + */ + public function getDescription() { return $this->_description; } + + /** + * Returns the link. + * + * @return string + */ + public function getLink() { return $this->_link; } +} diff --git a/src/ID3/Header.php b/src/ID3/Header.php new file mode 100644 index 0000000..fcad4ab --- /dev/null +++ b/src/ID3/Header.php @@ -0,0 +1,129 @@ + + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3_Header extends ID3_Object +{ + /** A flag to denote whether or not unsynchronisation is applied on all + frames */ + const UNSYNCHRONISATION = 256; + + /** A flag to denote whether or not the header is followed by an extended + header */ + const EXTENDEDHEADER = 128; + + /** A flag used as an experimental indicator. This flag shall always be set + when the tag is in an experimental stage. */ + const EXPERIMENTAL = 64; + + /** A flag to denote whether a footer is present at the very end of the tag */ + const FOOTER = 32; + + /** @var integer */ + private $_version; + + /** @var integer */ + private $_revision; + + /** @var integer */ + private $_flags; + + /** @var integer */ + private $_size; + + /** + * Constructs the class with given parameters and reads object related data + * from the ID3v2 tag. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_version = ord($this->_reader->getInt8()); + $this->_revision = ord($this->_reader->getInt8()); + $this->_flags = $this->_reader->getInt8(); + $this->_size = $this->decodeSynchsafe32($this->_reader->getUInt32BE()); + } + + /** + * Returns the tag major version number. + * + * @return integer + */ + public function getVersion() { return $this->_version; } + + /** + * Returns the tag revision number. + * + * @return integer + */ + public function getRevision() { return $this->_revision; } + + /** + * Checks whether or not the flag is set. Returns true if the flag + * is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } + + /** + * Returns the tag size, excluding the header and the footer. + * + * @return integer + */ + public function getSize() { return $this->_size; } +} diff --git a/src/ID3/Language.php b/src/ID3/Language.php new file mode 100644 index 0000000..8d2e2eb --- /dev/null +++ b/src/ID3/Language.php @@ -0,0 +1,60 @@ +Language interface implies that the ID3v2 frame supports + * its content to be given in multiple languages. + * + * The three byte language code is used to describe the language of the frame's + * content, according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO-639-2}. The language should be represented in lower case. If the language + * is not known the string "xxx" should be used. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +interface ID3_Language +{ + /** + * Returns the text language code. + * + * @return string + */ + public function getLanguage(); +} diff --git a/src/ID3/Object.php b/src/ID3/Object.php new file mode 100644 index 0000000..8b14761 --- /dev/null +++ b/src/ID3/Object.php @@ -0,0 +1,91 @@ + + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +abstract class ID3_Object +{ + /** + * The reader object. + * + * @var Reader + */ + protected $_reader; + + /** + * Constructs the class with given parameters and reads object related data + * from the ID3v2 tag. + * + * @param Reader $reader The reader object. + */ + public function __construct($reader) + { + $this->_reader = $reader; + } + + /** + * Encodes the given 32-bit integer to 28-bit synchsafe integer, where the + * most significant bit of each byte is zero, making seven bits out of eight + * available. + * + * @param integer $val The integer to encode. + * @return integer + */ + protected function encodeSynchsafe32($val) { + for ($i = 0, $mask = 0xffffff00; $i < 4; $i++, $mask <<= 8) + $val = ($val << 1 & $mask) | ($val << 1 & ~$mask) >> 1; + return $val & 0x7fffffff; + } + + /** + * Decodes the given 28-bit synchsafe integer to regular 32-bit integer. + * + * @param integer $val The integer to decode + * @return integer + */ + protected function decodeSynchsafe32($val) { + for ($i = 0, $mask = 0xff000000; $i < 3; $i++, $mask >>= 8) + $val = ($val & $mask) >> 1 | ($val & ~$mask); + return $val; + } +} diff --git a/src/ID3/Timing.php b/src/ID3/Timing.php new file mode 100644 index 0000000..66da687 --- /dev/null +++ b/src/ID3/Timing.php @@ -0,0 +1,64 @@ +Timing interface implies that the ID3v2 frame contains + * one or more 32-bit timestamps. + * + * The timestamps are absolute times, meaning that every stamp contains the time + * from the beginning of the file. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +interface ID3_Timing +{ + /** The timestamp is an absolute time, using MPEG frames as unit. */ + const MPEG_FRAMES = 0x01; + + /** The timestamp is an absolute time, using milliseconds as unit. */ + const MILLISECONDS = 0x02; + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat(); +} diff --git a/src/ID3v2.php b/src/ID3v2.php new file mode 100644 index 0000000..2c8b588 --- /dev/null +++ b/src/ID3v2.php @@ -0,0 +1,230 @@ + + * +-----------------------------+ + * | Header (10 bytes) | + * +-----------------------------+ + * | Extended Header | + * | (variable length, OPTIONAL) | + * +-----------------------------+ + * | Frames (variable length) | + * +-----------------------------+ + * | Padding | + * | (variable length, OPTIONAL) | + * +-----------------------------+ + * | Footer (10 bytes, OPTIONAL) | + * +-----------------------------+ + * + * + * In general, padding and footer are mutually exclusive. + * + * @package php-reader + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ID3v2 +{ + /** @var Reader */ + private $_reader; + + /** @var ID3_Header */ + private $_header; + + /** @var ID3_ExtendedHeader */ + private $_extendedHeader; + + /** @var ID3_Header */ + private $_footer; + + /** + * Constructs the ID3v2 class with given file. + * + * @todo Only limited subset of flags are processed. + * @param string $filename The path to the file. + */ + public function __construct($filename) + { + $this->_reader = new Reader($filename); + + if ($this->_reader->getString8(3) != "ID3") + throw new ID3_Exception("File does not contain ID3v2 tag: " . $filename); + + $this->_header = new ID3_Header($this->_reader); + if ($this->_header->getVersion() > 4) + throw new ID3_Exception + ("File does not contain ID3v2 tag of supported version: " . $filename); + if ($this->_header->hasFlag(ID3_Header::EXTENDEDHEADER)) + $this->_extendedHeader = new ID3_ExtendedHeader($this->_reader); + if ($this->_header->hasFlag(ID3_Header::FOOTER)) { + $offset = $this->_reader->getOffset(); + $this->_reader->setOffset($this->_header->getSize() + 10); + $this->_footer = new ID3_Header($this->_reader); + $this->_reader->setOffset($offset); + } + } + + /** + * Returns the header object. + * + * @return ID3_Header + */ + public function getHeader() { return $this->_header; } + + /** + * Checks whether there is an extended header present in the tag. Returns + * true if the header is present, false otherwise. + * + * @return boolean + */ + public function hasExtendedHeader() + { + return $this->_header->hasFlag(ID3_Header::EXTENDEDHEADER); + } + + /** + * Returns the extended header object if present, or false + * otherwise. + * + * @return ID3_ExtendedHeader|false + */ + public function getExtendedHeader() + { + if ($this->hasExtendedHeader()) + return $this->_extendedHeader; + return false; + } + + /** + * Checks whether there are frames left in the tag. Returns true if + * there are frames left in the tag, false otherwise. + * + * @return boolean + */ + public function hasFrames() + { + $offset = $this->_reader->getOffset(); + + // Return false if we reached the end of the tag + if ($offset >= $this->_header->getSize() - 10 - + ($this->hasFooter() ? 10 : 0)) + return false; + + // Return false if we reached the last frame, true otherwise + $res = $this->_reader->getUInt32() != 0; + $this->_reader->setOffset($offset); + return $res; + } + + /** + * Returns the next ID3 frame or false if end of tag has been + * reached. Returned objects are of the type ID3_Frame or of any of its child + * types. + * + * @return ID3_Frame|false + */ + public function nextFrame() + { + $frame = false; + if ($this->hasFrames()) { + $offset = $this->_reader->getOffset(); + $identifier = $this->_reader->getString8(4); + $this->_reader->setOffset($offset); + + if (file_exists($filename = "ID3/Frame/" . $identifier . ".php")) + require_once($filename); + if (class_exists($classname = "ID3_Frame_" . $identifier)) + $frame = new $classname($this->_reader); + else + $frame = new ID3_Frame($this->_reader); + } + return $frame; + } + + /** + * Checks whether there is a footer present in the tag. Returns + * true if the footer is present, false otherwise. + * + * @return boolean + */ + public function hasFooter() + { + return $this->_header->hasFlag(ID3_Header::FOOTER); + } + + /** + * Returns the footer object if present, or false otherwise. + * + * @return ID3_Header|false + */ + public function getFooter() + { + if ($this->hasFooter()) + return $this->_footer; + return false; + } +}