function Float2String($floatvalue, $bits) { // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html switch ($bits) { case 32: $exponentbits = 8; $fractionbits = 23; break; case 64: $exponentbits = 11; $fractionbits = 52; break; default: return false; break; } if ($floatvalue >= 0) { $signbit = '0'; } else { $signbit = '1'; } $normalizedbinary = NormalizeBinaryPoint(Float2BinaryDecimal($floatvalue), $fractionbits); $biasedexponent = pow(2, $exponentbits - 1) - 1 + $normalizedbinary['exponent']; // (127 or 1023) +/- exponent $exponentbitstring = str_pad(decbin($biasedexponent), $exponentbits, '0', STR_PAD_LEFT); $fractionbitstring = str_pad(substr($normalizedbinary['normalized'], 2), $fractionbits, '0', STR_PAD_RIGHT); return BigEndian2String(Bin2Dec($signbit . $exponentbitstring . $fractionbitstring), $bits % 8, false); }
function Float2String($floatvalue, $bits) { // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html if ($bits != 32 && $bits != 64) { return FALSE; } else { if ($bits == 32) { $exponentbits = 8; $fractionbits = 23; } else { if ($bits == 64) { $exponentbits = 11; $fractionbits = 52; } } } if ($floatvalue >= 0) { $signbit = '0'; } else { $signbit = '1'; } $normalizedbinary = NormalizeBinaryPoint(Float2BinaryDecimal($floatvalue), $fractionbits); $biasedexponent = pow(2, $exponentbits - 1) - 1 + $normalizedbinary['exponent']; // (127 or 1023) +/- exponent $exponentbitstring = str_pad(decbin($biasedexponent), $exponentbits, '0', STR_PAD_LEFT); $fractionbitstring = str_pad(substr($normalizedbinary['normalized'], 2), $fractionbits, '0', STR_PAD_RIGHT); return BigEndian2String(Bin2Dec($signbit . $exponentbitstring . $fractionbitstring), $bits % 8, FALSE); }
function GenerateID3v2Tag($data, $majorversion = 4, $minorversion = 0, $paddedlength = 0, $extendedheader = '', $footer = FALSE, $showerrors = TRUE, $noerrorsonly = TRUE) { ID3v2FrameIsAllowed(NULL, '', ''); // clear static array in case this isn't the first call to GenerateID3v2Tag() if (is_array($data)) { if (is_array($extendedheader)) { // not supported yet } foreach ($data as $frame_name => $frame_rawinputdata) { if (!is_array($frame_rawinputdata[0])) { // force everything to be arrayed so only one processing loop $frame_rawinputdata = array($frame_rawinputdata); } foreach ($frame_rawinputdata as $irrelevantindex => $frame_inputdata) { if (IsValidID3v2FrameName($frame_name, $majorversion)) { unset($frame_length); unset($frame_flags); $frame_data = FALSE; if (ID3v2FrameIsAllowed($frame_name, $frame_inputdata, $majorversion, $showerrors)) { if ($frame_data = GenerateID3v2FrameData($frame_name, $frame_inputdata, $majorversion, $showerrors)) { if ($majorversion >= 4) { // frame-level unsynchronization $FrameUnsynchronisation = FALSE; $unsynchdata = Unsynchronise($frame_data); if (strlen($unsynchdata) != strlen($frame_data)) { // unsynchronization needed $FrameUnsynchronisation = TRUE; $frame_data = $unsynchdata; if (isset($TagUnsynchronisation) && $TagUnsynchronisation === FALSE) { // only set to true if ALL frames are unsynchronised } else { $TagUnsynchronisation = TRUE; } } else { if (isset($TagUnsynchronisation)) { $TagUnsynchronisation = FALSE; } } unset($unsynchdata); $frame_length = BigEndian2String(strlen($frame_data), 4, TRUE); } else { $frame_length = BigEndian2String(strlen($frame_data), 4, FALSE); } $frame_flags = GenerateID3v2FrameFlags($majorversion, ID3v2FrameFlagsLookupTagAlter($frame_name, $majorversion), ID3v2FrameFlagsLookupFileAlter($frame_name, $majorversion), FALSE, FALSE, FALSE, FALSE, $FrameUnsynchronisation, FALSE); } } else { if ($showerrors) { echo 'Frame "' . $frame_name . '" is NOT allowed<BR>'; } } if ($frame_data === FALSE) { if ($showerrors) { echo 'GenerateID3v2FrameData() failed for "' . $frame_name . '"<BR>'; echo 'Error generated in getID3() v' . GETID3VERSION . '<BR>'; } if ($noerrorsonly) { return FALSE; } else { unset($frame_name); } } } else { // ignore any invalid frame names, including 'title', 'header', etc unset($frame_name); unset($frame_length); unset($frame_flags); unset($frame_data); } $tagstring .= $frame_name . $frame_length . $frame_flags . $frame_data; } } if ($footer) { if ($showerrors) { echo 'Footer not supported (yet)<BR>'; } return FALSE; } //echo number_format(strlen($tagstring)); if ($majorversion <= 3) { // tag-level unsynchronization $unsynchdata = Unsynchronise($tagstring); if (strlen($unsynchdata) != strlen($tagstring)) { // unsynchronization needed $TagUnsynchronisation = TRUE; $tagstring = $unsynchdata; } } //echo ' - '.number_format(strlen($tagstring)).'<BR>'; if (!$footer && $paddedlength > strlen($tagstring) + ID3v2HeaderLength($id3info['majorversion'])) { // pad up to $paddedlength bytes if unpadded tag is shorter than $paddedlength // "Furthermore it MUST NOT have any padding when a tag footer is added to the tag." $tagstring .= @str_repeat(chr(0), $paddedlength - strlen($tagstring)); } if (substr($tagstring, strlen($tagstring) - 1, 1) == chr(255)) { // special unsynchronization case: // if last byte == $FF then appended a $00 $TagUnsynchronisation = TRUE; $tagstring .= chr(0); } $tagheader = 'ID3'; $tagheader .= chr($majorversion); $tagheader .= chr($minorversion); $tagheader .= GenerateID3v2TagFlags($majorversion, $TagUnsynchronisation, FALSE, (bool) $extendedheader, FALSE, $footer); $tagheader .= BigEndian2String(strlen($tagstring), 4, TRUE); return $tagheader . $tagstring; } else { return FALSE; } }
function GenerateRealTag() { $RealCONT = ""; // object version $RealCONT .= BigEndian2String(strlen(@$this->tag_data['title']), 4); $RealCONT .= @$this->tag_data['title']; $RealCONT .= BigEndian2String(strlen(@$this->tag_data['artist']), 4); $RealCONT .= @$this->tag_data['artist']; $RealCONT .= BigEndian2String(strlen(@$this->tag_data['copyright']), 4); $RealCONT .= @$this->tag_data['copyright']; $RealCONT .= BigEndian2String(strlen(@$this->tag_data['comment']), 4); $RealCONT .= @$this->tag_data['comment']; if ($this->paddedlength > strlen($RealCONT) + 8) { $RealCONT .= str_repeat("", $this->paddedlength - strlen($RealCONT) - 8); } $RealCONT = 'CONT' . BigEndian2String(strlen($RealCONT) + 8, 4) . $RealCONT; // CONT chunk identifier + chunk length return $RealCONT; }