Edit File by line
/home/zeestwma/richards.../wp-inclu.../ID3
File: module.audio.mp3.php
[500] Fix | Delete
if ($MPEGaudioHeaderValidCache[$head4_key]) {
[501] Fix | Delete
$thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray;
[502] Fix | Delete
} else {
[503] Fix | Delete
$this->warning('Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset);
[504] Fix | Delete
return false;
[505] Fix | Delete
}
[506] Fix | Delete
[507] Fix | Delete
if (!$FastMPEGheaderScan) {
[508] Fix | Delete
$thisfile_mpeg_audio['version'] = $MPEGaudioVersionLookup[$thisfile_mpeg_audio['raw']['version']];
[509] Fix | Delete
$thisfile_mpeg_audio['layer'] = $MPEGaudioLayerLookup[$thisfile_mpeg_audio['raw']['layer']];
[510] Fix | Delete
[511] Fix | Delete
$thisfile_mpeg_audio['channelmode'] = $MPEGaudioChannelModeLookup[$thisfile_mpeg_audio['raw']['channelmode']];
[512] Fix | Delete
$thisfile_mpeg_audio['channels'] = (($thisfile_mpeg_audio['channelmode'] == 'mono') ? 1 : 2);
[513] Fix | Delete
$thisfile_mpeg_audio['sample_rate'] = $MPEGaudioFrequencyLookup[$thisfile_mpeg_audio['version']][$thisfile_mpeg_audio['raw']['sample_rate']];
[514] Fix | Delete
$thisfile_mpeg_audio['protection'] = !$thisfile_mpeg_audio['raw']['protection'];
[515] Fix | Delete
$thisfile_mpeg_audio['private'] = (bool) $thisfile_mpeg_audio['raw']['private'];
[516] Fix | Delete
$thisfile_mpeg_audio['modeextension'] = $MPEGaudioModeExtensionLookup[$thisfile_mpeg_audio['layer']][$thisfile_mpeg_audio['raw']['modeextension']];
[517] Fix | Delete
$thisfile_mpeg_audio['copyright'] = (bool) $thisfile_mpeg_audio['raw']['copyright'];
[518] Fix | Delete
$thisfile_mpeg_audio['original'] = (bool) $thisfile_mpeg_audio['raw']['original'];
[519] Fix | Delete
$thisfile_mpeg_audio['emphasis'] = $MPEGaudioEmphasisLookup[$thisfile_mpeg_audio['raw']['emphasis']];
[520] Fix | Delete
[521] Fix | Delete
$info['audio']['channels'] = $thisfile_mpeg_audio['channels'];
[522] Fix | Delete
$info['audio']['sample_rate'] = $thisfile_mpeg_audio['sample_rate'];
[523] Fix | Delete
[524] Fix | Delete
if ($thisfile_mpeg_audio['protection']) {
[525] Fix | Delete
$thisfile_mpeg_audio['crc'] = getid3_lib::BigEndian2Int(substr($headerstring, 4, 2));
[526] Fix | Delete
}
[527] Fix | Delete
}
[528] Fix | Delete
[529] Fix | Delete
if ($thisfile_mpeg_audio['raw']['bitrate'] == 15) {
[530] Fix | Delete
// http://www.hydrogenaudio.org/?act=ST&f=16&t=9682&st=0
[531] Fix | Delete
$this->warning('Invalid bitrate index (15), this is a known bug in free-format MP3s encoded by LAME v3.90 - 3.93.1');
[532] Fix | Delete
$thisfile_mpeg_audio['raw']['bitrate'] = 0;
[533] Fix | Delete
}
[534] Fix | Delete
$thisfile_mpeg_audio['padding'] = (bool) $thisfile_mpeg_audio['raw']['padding'];
[535] Fix | Delete
$thisfile_mpeg_audio['bitrate'] = $MPEGaudioBitrateLookup[$thisfile_mpeg_audio['version']][$thisfile_mpeg_audio['layer']][$thisfile_mpeg_audio['raw']['bitrate']];
[536] Fix | Delete
[537] Fix | Delete
if (($thisfile_mpeg_audio['bitrate'] == 'free') && ($offset == $info['avdataoffset'])) {
[538] Fix | Delete
// only skip multiple frame check if free-format bitstream found at beginning of file
[539] Fix | Delete
// otherwise is quite possibly simply corrupted data
[540] Fix | Delete
$recursivesearch = false;
[541] Fix | Delete
}
[542] Fix | Delete
[543] Fix | Delete
// For Layer 2 there are some combinations of bitrate and mode which are not allowed.
[544] Fix | Delete
if (!$FastMPEGheaderScan && ($thisfile_mpeg_audio['layer'] == '2')) {
[545] Fix | Delete
[546] Fix | Delete
$info['audio']['dataformat'] = 'mp2';
[547] Fix | Delete
switch ($thisfile_mpeg_audio['channelmode']) {
[548] Fix | Delete
[549] Fix | Delete
case 'mono':
[550] Fix | Delete
if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] <= 192000)) {
[551] Fix | Delete
// these are ok
[552] Fix | Delete
} else {
[553] Fix | Delete
$this->error($thisfile_mpeg_audio['bitrate'].'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.');
[554] Fix | Delete
return false;
[555] Fix | Delete
}
[556] Fix | Delete
break;
[557] Fix | Delete
[558] Fix | Delete
case 'stereo':
[559] Fix | Delete
case 'joint stereo':
[560] Fix | Delete
case 'dual channel':
[561] Fix | Delete
if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] == 64000) || ($thisfile_mpeg_audio['bitrate'] >= 96000)) {
[562] Fix | Delete
// these are ok
[563] Fix | Delete
} else {
[564] Fix | Delete
$this->error(intval(round($thisfile_mpeg_audio['bitrate'] / 1000)).'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.');
[565] Fix | Delete
return false;
[566] Fix | Delete
}
[567] Fix | Delete
break;
[568] Fix | Delete
[569] Fix | Delete
}
[570] Fix | Delete
[571] Fix | Delete
}
[572] Fix | Delete
[573] Fix | Delete
[574] Fix | Delete
if ($info['audio']['sample_rate'] > 0) {
[575] Fix | Delete
$thisfile_mpeg_audio['framelength'] = self::MPEGaudioFrameLength($thisfile_mpeg_audio['bitrate'], $thisfile_mpeg_audio['version'], $thisfile_mpeg_audio['layer'], (int) $thisfile_mpeg_audio['padding'], $info['audio']['sample_rate']);
[576] Fix | Delete
}
[577] Fix | Delete
[578] Fix | Delete
$nextframetestoffset = $offset + 1;
[579] Fix | Delete
if ($thisfile_mpeg_audio['bitrate'] != 'free') {
[580] Fix | Delete
[581] Fix | Delete
$info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
[582] Fix | Delete
[583] Fix | Delete
if (isset($thisfile_mpeg_audio['framelength'])) {
[584] Fix | Delete
$nextframetestoffset = $offset + $thisfile_mpeg_audio['framelength'];
[585] Fix | Delete
} else {
[586] Fix | Delete
$this->error('Frame at offset('.$offset.') is has an invalid frame length.');
[587] Fix | Delete
return false;
[588] Fix | Delete
}
[589] Fix | Delete
[590] Fix | Delete
}
[591] Fix | Delete
[592] Fix | Delete
$ExpectedNumberOfAudioBytes = 0;
[593] Fix | Delete
[594] Fix | Delete
////////////////////////////////////////////////////////////////////////////////////
[595] Fix | Delete
// Variable-bitrate headers
[596] Fix | Delete
[597] Fix | Delete
if (substr($headerstring, 4 + 32, 4) == 'VBRI') {
[598] Fix | Delete
// Fraunhofer VBR header is hardcoded 'VBRI' at offset 0x24 (36)
[599] Fix | Delete
// specs taken from http://minnie.tuhs.org/pipermail/mp3encoder/2001-January/001800.html
[600] Fix | Delete
[601] Fix | Delete
$thisfile_mpeg_audio['bitrate_mode'] = 'vbr';
[602] Fix | Delete
$thisfile_mpeg_audio['VBR_method'] = 'Fraunhofer';
[603] Fix | Delete
$info['audio']['codec'] = 'Fraunhofer';
[604] Fix | Delete
[605] Fix | Delete
$SideInfoData = substr($headerstring, 4 + 2, 32);
[606] Fix | Delete
[607] Fix | Delete
$FraunhoferVBROffset = 36;
[608] Fix | Delete
[609] Fix | Delete
$thisfile_mpeg_audio['VBR_encoder_version'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 4, 2)); // VbriVersion
[610] Fix | Delete
$thisfile_mpeg_audio['VBR_encoder_delay'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 6, 2)); // VbriDelay
[611] Fix | Delete
$thisfile_mpeg_audio['VBR_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 8, 2)); // VbriQuality
[612] Fix | Delete
$thisfile_mpeg_audio['VBR_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 10, 4)); // VbriStreamBytes
[613] Fix | Delete
$thisfile_mpeg_audio['VBR_frames'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 14, 4)); // VbriStreamFrames
[614] Fix | Delete
$thisfile_mpeg_audio['VBR_seek_offsets'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 18, 2)); // VbriTableSize
[615] Fix | Delete
$thisfile_mpeg_audio['VBR_seek_scale'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 20, 2)); // VbriTableScale
[616] Fix | Delete
$thisfile_mpeg_audio['VBR_entry_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 22, 2)); // VbriEntryBytes
[617] Fix | Delete
$thisfile_mpeg_audio['VBR_entry_frames'] = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 24, 2)); // VbriEntryFrames
[618] Fix | Delete
[619] Fix | Delete
$ExpectedNumberOfAudioBytes = $thisfile_mpeg_audio['VBR_bytes'];
[620] Fix | Delete
[621] Fix | Delete
$previousbyteoffset = $offset;
[622] Fix | Delete
for ($i = 0; $i < $thisfile_mpeg_audio['VBR_seek_offsets']; $i++) {
[623] Fix | Delete
$Fraunhofer_OffsetN = getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset, $thisfile_mpeg_audio['VBR_entry_bytes']));
[624] Fix | Delete
$FraunhoferVBROffset += $thisfile_mpeg_audio['VBR_entry_bytes'];
[625] Fix | Delete
$thisfile_mpeg_audio['VBR_offsets_relative'][$i] = ($Fraunhofer_OffsetN * $thisfile_mpeg_audio['VBR_seek_scale']);
[626] Fix | Delete
$thisfile_mpeg_audio['VBR_offsets_absolute'][$i] = ($Fraunhofer_OffsetN * $thisfile_mpeg_audio['VBR_seek_scale']) + $previousbyteoffset;
[627] Fix | Delete
$previousbyteoffset += $Fraunhofer_OffsetN;
[628] Fix | Delete
}
[629] Fix | Delete
[630] Fix | Delete
[631] Fix | Delete
} else {
[632] Fix | Delete
[633] Fix | Delete
// Xing VBR header is hardcoded 'Xing' at a offset 0x0D (13), 0x15 (21) or 0x24 (36)
[634] Fix | Delete
// depending on MPEG layer and number of channels
[635] Fix | Delete
[636] Fix | Delete
$VBRidOffset = self::XingVBRidOffset($thisfile_mpeg_audio['version'], $thisfile_mpeg_audio['channelmode']);
[637] Fix | Delete
$SideInfoData = substr($headerstring, 4 + 2, $VBRidOffset - 4);
[638] Fix | Delete
[639] Fix | Delete
if ((substr($headerstring, $VBRidOffset, strlen('Xing')) == 'Xing') || (substr($headerstring, $VBRidOffset, strlen('Info')) == 'Info')) {
[640] Fix | Delete
// 'Xing' is traditional Xing VBR frame
[641] Fix | Delete
// 'Info' is LAME-encoded CBR (This was done to avoid CBR files to be recognized as traditional Xing VBR files by some decoders.)
[642] Fix | Delete
// 'Info' *can* legally be used to specify a VBR file as well, however.
[643] Fix | Delete
[644] Fix | Delete
// http://www.multiweb.cz/twoinches/MP3inside.htm
[645] Fix | Delete
//00..03 = "Xing" or "Info"
[646] Fix | Delete
//04..07 = Flags:
[647] Fix | Delete
// 0x01 Frames Flag set if value for number of frames in file is stored
[648] Fix | Delete
// 0x02 Bytes Flag set if value for filesize in bytes is stored
[649] Fix | Delete
// 0x04 TOC Flag set if values for TOC are stored
[650] Fix | Delete
// 0x08 VBR Scale Flag set if values for VBR scale is stored
[651] Fix | Delete
//08..11 Frames: Number of frames in file (including the first Xing/Info one)
[652] Fix | Delete
//12..15 Bytes: File length in Bytes
[653] Fix | Delete
//16..115 TOC (Table of Contents):
[654] Fix | Delete
// Contains of 100 indexes (one Byte length) for easier lookup in file. Approximately solves problem with moving inside file.
[655] Fix | Delete
// Each Byte has a value according this formula:
[656] Fix | Delete
// (TOC[i] / 256) * fileLenInBytes
[657] Fix | Delete
// So if song lasts eg. 240 sec. and you want to jump to 60. sec. (and file is 5 000 000 Bytes length) you can use:
[658] Fix | Delete
// TOC[(60/240)*100] = TOC[25]
[659] Fix | Delete
// and corresponding Byte in file is then approximately at:
[660] Fix | Delete
// (TOC[25]/256) * 5000000
[661] Fix | Delete
//116..119 VBR Scale
[662] Fix | Delete
[663] Fix | Delete
[664] Fix | Delete
// should be safe to leave this at 'vbr' and let it be overriden to 'cbr' if a CBR preset/mode is used by LAME
[665] Fix | Delete
// if (substr($headerstring, $VBRidOffset, strlen('Info')) == 'Xing') {
[666] Fix | Delete
$thisfile_mpeg_audio['bitrate_mode'] = 'vbr';
[667] Fix | Delete
$thisfile_mpeg_audio['VBR_method'] = 'Xing';
[668] Fix | Delete
// } else {
[669] Fix | Delete
// $ScanAsCBR = true;
[670] Fix | Delete
// $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
[671] Fix | Delete
// }
[672] Fix | Delete
[673] Fix | Delete
$thisfile_mpeg_audio['xing_flags_raw'] = getid3_lib::BigEndian2Int(substr($headerstring, $VBRidOffset + 4, 4));
[674] Fix | Delete
[675] Fix | Delete
$thisfile_mpeg_audio['xing_flags']['frames'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000001);
[676] Fix | Delete
$thisfile_mpeg_audio['xing_flags']['bytes'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000002);
[677] Fix | Delete
$thisfile_mpeg_audio['xing_flags']['toc'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000004);
[678] Fix | Delete
$thisfile_mpeg_audio['xing_flags']['vbr_scale'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000008);
[679] Fix | Delete
[680] Fix | Delete
if ($thisfile_mpeg_audio['xing_flags']['frames']) {
[681] Fix | Delete
$thisfile_mpeg_audio['VBR_frames'] = getid3_lib::BigEndian2Int(substr($headerstring, $VBRidOffset + 8, 4));
[682] Fix | Delete
//$thisfile_mpeg_audio['VBR_frames']--; // don't count header Xing/Info frame
[683] Fix | Delete
}
[684] Fix | Delete
if ($thisfile_mpeg_audio['xing_flags']['bytes']) {
[685] Fix | Delete
$thisfile_mpeg_audio['VBR_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $VBRidOffset + 12, 4));
[686] Fix | Delete
}
[687] Fix | Delete
[688] Fix | Delete
//if (($thisfile_mpeg_audio['bitrate'] == 'free') && !empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) {
[689] Fix | Delete
//if (!empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) {
[690] Fix | Delete
if (!empty($thisfile_mpeg_audio['VBR_frames'])) {
[691] Fix | Delete
$used_filesize = 0;
[692] Fix | Delete
if (!empty($thisfile_mpeg_audio['VBR_bytes'])) {
[693] Fix | Delete
$used_filesize = $thisfile_mpeg_audio['VBR_bytes'];
[694] Fix | Delete
} elseif (!empty($info['filesize'])) {
[695] Fix | Delete
$used_filesize = $info['filesize'];
[696] Fix | Delete
$used_filesize -= (isset($info['id3v2']['headerlength']) ? intval($info['id3v2']['headerlength']) : 0);
[697] Fix | Delete
$used_filesize -= (isset($info['id3v1']) ? 128 : 0);
[698] Fix | Delete
$used_filesize -= (isset($info['tag_offset_end']) ? $info['tag_offset_end'] - $info['tag_offset_start'] : 0);
[699] Fix | Delete
$this->warning('MP3.Xing header missing VBR_bytes, assuming MPEG audio portion of file is '.number_format($used_filesize).' bytes');
[700] Fix | Delete
}
[701] Fix | Delete
[702] Fix | Delete
$framelengthfloat = $used_filesize / $thisfile_mpeg_audio['VBR_frames'];
[703] Fix | Delete
[704] Fix | Delete
if ($thisfile_mpeg_audio['layer'] == '1') {
[705] Fix | Delete
// BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12
[706] Fix | Delete
//$info['audio']['bitrate'] = ((($framelengthfloat / 4) - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 12;
[707] Fix | Delete
$info['audio']['bitrate'] = ($framelengthfloat / 4) * $thisfile_mpeg_audio['sample_rate'] * (2 / $info['audio']['channels']) / 12;
[708] Fix | Delete
} else {
[709] Fix | Delete
// Bitrate = ((FrameLengthInBytes - Padding) * SampleRate) / 144
[710] Fix | Delete
//$info['audio']['bitrate'] = (($framelengthfloat - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 144;
[711] Fix | Delete
$info['audio']['bitrate'] = $framelengthfloat * $thisfile_mpeg_audio['sample_rate'] * (2 / $info['audio']['channels']) / 144;
[712] Fix | Delete
}
[713] Fix | Delete
$thisfile_mpeg_audio['framelength'] = floor($framelengthfloat);
[714] Fix | Delete
}
[715] Fix | Delete
[716] Fix | Delete
if ($thisfile_mpeg_audio['xing_flags']['toc']) {
[717] Fix | Delete
$LAMEtocData = substr($headerstring, $VBRidOffset + 16, 100);
[718] Fix | Delete
for ($i = 0; $i < 100; $i++) {
[719] Fix | Delete
$thisfile_mpeg_audio['toc'][$i] = ord($LAMEtocData[$i]);
[720] Fix | Delete
}
[721] Fix | Delete
}
[722] Fix | Delete
if ($thisfile_mpeg_audio['xing_flags']['vbr_scale']) {
[723] Fix | Delete
$thisfile_mpeg_audio['VBR_scale'] = getid3_lib::BigEndian2Int(substr($headerstring, $VBRidOffset + 116, 4));
[724] Fix | Delete
}
[725] Fix | Delete
[726] Fix | Delete
[727] Fix | Delete
// http://gabriel.mp3-tech.org/mp3infotag.html
[728] Fix | Delete
if (substr($headerstring, $VBRidOffset + 120, 4) == 'LAME') {
[729] Fix | Delete
[730] Fix | Delete
// shortcut
[731] Fix | Delete
$thisfile_mpeg_audio['LAME'] = array();
[732] Fix | Delete
$thisfile_mpeg_audio_lame = &$thisfile_mpeg_audio['LAME'];
[733] Fix | Delete
[734] Fix | Delete
[735] Fix | Delete
$thisfile_mpeg_audio_lame['long_version'] = substr($headerstring, $VBRidOffset + 120, 20);
[736] Fix | Delete
$thisfile_mpeg_audio_lame['short_version'] = substr($thisfile_mpeg_audio_lame['long_version'], 0, 9);
[737] Fix | Delete
[738] Fix | Delete
//$thisfile_mpeg_audio_lame['numeric_version'] = str_replace('LAME', '', $thisfile_mpeg_audio_lame['short_version']);
[739] Fix | Delete
$thisfile_mpeg_audio_lame['numeric_version'] = '';
[740] Fix | Delete
if (preg_match('#^LAME([0-9\\.a-z]*)#', $thisfile_mpeg_audio_lame['long_version'], $matches)) {
[741] Fix | Delete
$thisfile_mpeg_audio_lame['short_version'] = $matches[0];
[742] Fix | Delete
$thisfile_mpeg_audio_lame['numeric_version'] = $matches[1];
[743] Fix | Delete
}
[744] Fix | Delete
if (strlen($thisfile_mpeg_audio_lame['numeric_version']) > 0) {
[745] Fix | Delete
foreach (explode('.', $thisfile_mpeg_audio_lame['numeric_version']) as $key => $number) {
[746] Fix | Delete
$thisfile_mpeg_audio_lame['integer_version'][$key] = intval($number);
[747] Fix | Delete
}
[748] Fix | Delete
//if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') {
[749] Fix | Delete
if ((($thisfile_mpeg_audio_lame['integer_version'][0] * 1000) + $thisfile_mpeg_audio_lame['integer_version'][1]) >= 3090) { // cannot use string version compare, may have "LAME3.90" or "LAME3.100" -- see https://github.com/JamesHeinrich/getID3/issues/207
[750] Fix | Delete
[751] Fix | Delete
// extra 11 chars are not part of version string when LAMEtag present
[752] Fix | Delete
unset($thisfile_mpeg_audio_lame['long_version']);
[753] Fix | Delete
[754] Fix | Delete
// It the LAME tag was only introduced in LAME v3.90
[755] Fix | Delete
// https://wiki.hydrogenaud.io/index.php/LAME#VBR_header_and_LAME_tag
[756] Fix | Delete
// https://hydrogenaud.io/index.php?topic=9933
[757] Fix | Delete
[758] Fix | Delete
// Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html
[759] Fix | Delete
// are assuming a 'Xing' identifier offset of 0x24, which is the case for
[760] Fix | Delete
// MPEG-1 non-mono, but not for other combinations
[761] Fix | Delete
$LAMEtagOffsetContant = $VBRidOffset - 0x24;
[762] Fix | Delete
[763] Fix | Delete
// shortcuts
[764] Fix | Delete
$thisfile_mpeg_audio_lame['RGAD'] = array('track'=>array(), 'album'=>array());
[765] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD = &$thisfile_mpeg_audio_lame['RGAD'];
[766] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track'];
[767] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album'];
[768] Fix | Delete
$thisfile_mpeg_audio_lame['raw'] = array();
[769] Fix | Delete
$thisfile_mpeg_audio_lame_raw = &$thisfile_mpeg_audio_lame['raw'];
[770] Fix | Delete
[771] Fix | Delete
// byte $9B VBR Quality
[772] Fix | Delete
// This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications.
[773] Fix | Delete
// Actually overwrites original Xing bytes
[774] Fix | Delete
unset($thisfile_mpeg_audio['VBR_scale']);
[775] Fix | Delete
$thisfile_mpeg_audio_lame['vbr_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1));
[776] Fix | Delete
[777] Fix | Delete
// bytes $9C-$A4 Encoder short VersionString
[778] Fix | Delete
$thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9);
[779] Fix | Delete
[780] Fix | Delete
// byte $A5 Info Tag revision + VBR method
[781] Fix | Delete
$LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1));
[782] Fix | Delete
[783] Fix | Delete
$thisfile_mpeg_audio_lame['tag_revision'] = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
[784] Fix | Delete
$thisfile_mpeg_audio_lame_raw['vbr_method'] = $LAMEtagRevisionVBRmethod & 0x0F;
[785] Fix | Delete
$thisfile_mpeg_audio_lame['vbr_method'] = self::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']);
[786] Fix | Delete
$thisfile_mpeg_audio['bitrate_mode'] = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3); // usually either 'cbr' or 'vbr', but truncates 'vbr-old / vbr-rh' to 'vbr'
[787] Fix | Delete
[788] Fix | Delete
// byte $A6 Lowpass filter value
[789] Fix | Delete
$thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
[790] Fix | Delete
[791] Fix | Delete
// bytes $A7-$AE Replay Gain
[792] Fix | Delete
// https://web.archive.org/web/20021015212753/http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html
[793] Fix | Delete
// bytes $A7-$AA : 32 bit floating point "Peak signal amplitude"
[794] Fix | Delete
if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
[795] Fix | Delete
// LAME 3.94a16 and later - 9.23 fixed point
[796] Fix | Delete
// ie 0x0059E2EE / (2^23) = 5890798 / 8388608 = 0.7022378444671630859375
[797] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = (float) ((getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608);
[798] Fix | Delete
} else {
[799] Fix | Delete
// LAME 3.94a15 and earlier - 32-bit floating point
[800] Fix | Delete
// Actually 3.94a16 will fall in here too and be WRONG, but is hard to detect 3.94a16 vs 3.94a15
[801] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = getid3_lib::LittleEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4));
[802] Fix | Delete
}
[803] Fix | Delete
if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) {
[804] Fix | Delete
unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
[805] Fix | Delete
} else {
[806] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD['peak_db'] = getid3_lib::RGADamplitude2dB($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
[807] Fix | Delete
}
[808] Fix | Delete
[809] Fix | Delete
$thisfile_mpeg_audio_lame_raw['RGAD_track'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2));
[810] Fix | Delete
$thisfile_mpeg_audio_lame_raw['RGAD_album'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2));
[811] Fix | Delete
[812] Fix | Delete
[813] Fix | Delete
if ($thisfile_mpeg_audio_lame_raw['RGAD_track'] != 0) {
[814] Fix | Delete
[815] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_track['raw']['name'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13;
[816] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_track['raw']['originator'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10;
[817] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9;
[818] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF;
[819] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_track['name'] = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['name']);
[820] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_track['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']);
[821] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_track['gain_db'] = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']);
[822] Fix | Delete
[823] Fix | Delete
if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
[824] Fix | Delete
$info['replay_gain']['track']['peak'] = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
[825] Fix | Delete
}
[826] Fix | Delete
$info['replay_gain']['track']['originator'] = $thisfile_mpeg_audio_lame_RGAD_track['originator'];
[827] Fix | Delete
$info['replay_gain']['track']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track['gain_db'];
[828] Fix | Delete
} else {
[829] Fix | Delete
unset($thisfile_mpeg_audio_lame_RGAD['track']);
[830] Fix | Delete
}
[831] Fix | Delete
if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 0) {
[832] Fix | Delete
[833] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_album['raw']['name'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13;
[834] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_album['raw']['originator'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10;
[835] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9;
[836] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF;
[837] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_album['name'] = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['name']);
[838] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_album['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']);
[839] Fix | Delete
$thisfile_mpeg_audio_lame_RGAD_album['gain_db'] = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']);
[840] Fix | Delete
[841] Fix | Delete
if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
[842] Fix | Delete
$info['replay_gain']['album']['peak'] = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
[843] Fix | Delete
}
[844] Fix | Delete
$info['replay_gain']['album']['originator'] = $thisfile_mpeg_audio_lame_RGAD_album['originator'];
[845] Fix | Delete
$info['replay_gain']['album']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album['gain_db'];
[846] Fix | Delete
} else {
[847] Fix | Delete
unset($thisfile_mpeg_audio_lame_RGAD['album']);
[848] Fix | Delete
}
[849] Fix | Delete
if (empty($thisfile_mpeg_audio_lame_RGAD)) {
[850] Fix | Delete
unset($thisfile_mpeg_audio_lame['RGAD']);
[851] Fix | Delete
}
[852] Fix | Delete
[853] Fix | Delete
[854] Fix | Delete
// byte $AF Encoding flags + ATH Type
[855] Fix | Delete
$EncodingFlagsATHtype = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1));
[856] Fix | Delete
$thisfile_mpeg_audio_lame['encoding_flags']['nspsytune'] = (bool) ($EncodingFlagsATHtype & 0x10);
[857] Fix | Delete
$thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20);
[858] Fix | Delete
$thisfile_mpeg_audio_lame['encoding_flags']['nogap_next'] = (bool) ($EncodingFlagsATHtype & 0x40);
[859] Fix | Delete
$thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev'] = (bool) ($EncodingFlagsATHtype & 0x80);
[860] Fix | Delete
$thisfile_mpeg_audio_lame['ath_type'] = $EncodingFlagsATHtype & 0x0F;
[861] Fix | Delete
[862] Fix | Delete
// byte $B0 if ABR {specified bitrate} else {minimal bitrate}
[863] Fix | Delete
$thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1));
[864] Fix | Delete
if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) { // Average BitRate (ABR)
[865] Fix | Delete
$thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
[866] Fix | Delete
} elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) { // Constant BitRate (CBR)
[867] Fix | Delete
// ignore
[868] Fix | Delete
} elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) { // Variable BitRate (VBR) - minimum bitrate
[869] Fix | Delete
$thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
[870] Fix | Delete
}
[871] Fix | Delete
[872] Fix | Delete
// bytes $B1-$B3 Encoder delays
[873] Fix | Delete
$EncoderDelays = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3));
[874] Fix | Delete
$thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12;
[875] Fix | Delete
$thisfile_mpeg_audio_lame['end_padding'] = $EncoderDelays & 0x000FFF;
[876] Fix | Delete
[877] Fix | Delete
// byte $B4 Misc
[878] Fix | Delete
$MiscByte = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1));
[879] Fix | Delete
$thisfile_mpeg_audio_lame_raw['noise_shaping'] = ($MiscByte & 0x03);
[880] Fix | Delete
$thisfile_mpeg_audio_lame_raw['stereo_mode'] = ($MiscByte & 0x1C) >> 2;
[881] Fix | Delete
$thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5;
[882] Fix | Delete
$thisfile_mpeg_audio_lame_raw['source_sample_freq'] = ($MiscByte & 0xC0) >> 6;
[883] Fix | Delete
$thisfile_mpeg_audio_lame['noise_shaping'] = $thisfile_mpeg_audio_lame_raw['noise_shaping'];
[884] Fix | Delete
$thisfile_mpeg_audio_lame['stereo_mode'] = self::LAMEmiscStereoModeLookup($thisfile_mpeg_audio_lame_raw['stereo_mode']);
[885] Fix | Delete
$thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality'];
[886] Fix | Delete
$thisfile_mpeg_audio_lame['source_sample_freq'] = self::LAMEmiscSourceSampleFrequencyLookup($thisfile_mpeg_audio_lame_raw['source_sample_freq']);
[887] Fix | Delete
[888] Fix | Delete
// byte $B5 MP3 Gain
[889] Fix | Delete
$thisfile_mpeg_audio_lame_raw['mp3_gain'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true);
[890] Fix | Delete
$thisfile_mpeg_audio_lame['mp3_gain_db'] = (getid3_lib::RGADamplitude2dB(2) / 4) * $thisfile_mpeg_audio_lame_raw['mp3_gain'];
[891] Fix | Delete
$thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6));
[892] Fix | Delete
[893] Fix | Delete
// bytes $B6-$B7 Preset and surround info
[894] Fix | Delete
$PresetSurroundBytes = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2));
[895] Fix | Delete
// Reserved = ($PresetSurroundBytes & 0xC000);
[896] Fix | Delete
$thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800);
[897] Fix | Delete
$thisfile_mpeg_audio_lame['surround_info'] = self::LAMEsurroundInfoLookup($thisfile_mpeg_audio_lame_raw['surround_info']);
[898] Fix | Delete
$thisfile_mpeg_audio_lame['preset_used_id'] = ($PresetSurroundBytes & 0x07FF);
[899] Fix | Delete
$thisfile_mpeg_audio_lame['preset_used'] = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame);
[900] Fix | Delete
if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
[901] Fix | Delete
$this->warning('Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org');
[902] Fix | Delete
}
[903] Fix | Delete
if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
[904] Fix | Delete
// this may change if 3.90.4 ever comes out
[905] Fix | Delete
$thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.3';
[906] Fix | Delete
}
[907] Fix | Delete
[908] Fix | Delete
// bytes $B8-$BB MusicLength
[909] Fix | Delete
$thisfile_mpeg_audio_lame['audio_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4));
[910] Fix | Delete
$ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_bytes']);
[911] Fix | Delete
[912] Fix | Delete
// bytes $BC-$BD MusicCRC
[913] Fix | Delete
$thisfile_mpeg_audio_lame['music_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2));
[914] Fix | Delete
[915] Fix | Delete
// bytes $BE-$BF CRC-16 of Info Tag
[916] Fix | Delete
$thisfile_mpeg_audio_lame['lame_tag_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2));
[917] Fix | Delete
[918] Fix | Delete
[919] Fix | Delete
// LAME CBR
[920] Fix | Delete
if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1 && $thisfile_mpeg_audio['bitrate'] !== 'free') {
[921] Fix | Delete
[922] Fix | Delete
$thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
[923] Fix | Delete
$thisfile_mpeg_audio['bitrate'] = self::ClosestStandardMP3Bitrate($thisfile_mpeg_audio['bitrate']);
[924] Fix | Delete
$info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
[925] Fix | Delete
//if (empty($thisfile_mpeg_audio['bitrate']) || (!empty($thisfile_mpeg_audio_lame['bitrate_min']) && ($thisfile_mpeg_audio_lame['bitrate_min'] != 255))) {
[926] Fix | Delete
// $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio_lame['bitrate_min'];
[927] Fix | Delete
//}
[928] Fix | Delete
[929] Fix | Delete
}
[930] Fix | Delete
[931] Fix | Delete
}
[932] Fix | Delete
}
[933] Fix | Delete
}
[934] Fix | Delete
[935] Fix | Delete
} else {
[936] Fix | Delete
[937] Fix | Delete
// not Fraunhofer or Xing VBR methods, most likely CBR (but could be VBR with no header)
[938] Fix | Delete
$thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
[939] Fix | Delete
if ($recursivesearch) {
[940] Fix | Delete
$thisfile_mpeg_audio['bitrate_mode'] = 'vbr';
[941] Fix | Delete
if ($this->RecursiveFrameScanning($offset, $nextframetestoffset, true)) {
[942] Fix | Delete
$recursivesearch = false;
[943] Fix | Delete
$thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
[944] Fix | Delete
}
[945] Fix | Delete
if ($thisfile_mpeg_audio['bitrate_mode'] == 'vbr') {
[946] Fix | Delete
$this->warning('VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.');
[947] Fix | Delete
}
[948] Fix | Delete
}
[949] Fix | Delete
[950] Fix | Delete
}
[951] Fix | Delete
[952] Fix | Delete
}
[953] Fix | Delete
[954] Fix | Delete
if (($ExpectedNumberOfAudioBytes > 0) && ($ExpectedNumberOfAudioBytes != ($info['avdataend'] - $info['avdataoffset']))) {
[955] Fix | Delete
if ($ExpectedNumberOfAudioBytes > ($info['avdataend'] - $info['avdataoffset'])) {
[956] Fix | Delete
if ($this->isDependencyFor('matroska') || $this->isDependencyFor('riff')) {
[957] Fix | Delete
// ignore, audio data is broken into chunks so will always be data "missing"
[958] Fix | Delete
}
[959] Fix | Delete
elseif (($ExpectedNumberOfAudioBytes - ($info['avdataend'] - $info['avdataoffset'])) == 1) {
[960] Fix | Delete
$this->warning('Last byte of data truncated (this is a known bug in Meracl ID3 Tag Writer before v1.3.5)');
[961] Fix | Delete
}
[962] Fix | Delete
else {
[963] Fix | Delete
$this->warning('Probable truncated file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, only found '.($info['avdataend'] - $info['avdataoffset']).' (short by '.($ExpectedNumberOfAudioBytes - ($info['avdataend'] - $info['avdataoffset'])).' bytes)');
[964] Fix | Delete
}
[965] Fix | Delete
} else {
[966] Fix | Delete
if ((($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes) == 1) {
[967] Fix | Delete
// $prenullbytefileoffset = $this->ftell();
[968] Fix | Delete
// $this->fseek($info['avdataend']);
[969] Fix | Delete
// $PossibleNullByte = $this->fread(1);
[970] Fix | Delete
// $this->fseek($prenullbytefileoffset);
[971] Fix | Delete
// if ($PossibleNullByte === "\x00") {
[972] Fix | Delete
$info['avdataend']--;
[973] Fix | Delete
// $this->warning('Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored');
[974] Fix | Delete
// } else {
[975] Fix | Delete
// $this->warning('Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($info['avdataend'] - $info['avdataoffset']).' ('.(($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)');
[976] Fix | Delete
// }
[977] Fix | Delete
} else {
[978] Fix | Delete
$this->warning('Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($info['avdataend'] - $info['avdataoffset']).' ('.(($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)');
[979] Fix | Delete
}
[980] Fix | Delete
}
[981] Fix | Delete
}
[982] Fix | Delete
[983] Fix | Delete
if (($thisfile_mpeg_audio['bitrate'] == 'free') && empty($info['audio']['bitrate'])) {
[984] Fix | Delete
if (($offset == $info['avdataoffset']) && empty($thisfile_mpeg_audio['VBR_frames'])) {
[985] Fix | Delete
$framebytelength = $this->FreeFormatFrameLength($offset, true);
[986] Fix | Delete
if ($framebytelength > 0) {
[987] Fix | Delete
$thisfile_mpeg_audio['framelength'] = $framebytelength;
[988] Fix | Delete
if ($thisfile_mpeg_audio['layer'] == '1') {
[989] Fix | Delete
// BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12
[990] Fix | Delete
$info['audio']['bitrate'] = ((($framebytelength / 4) - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 12;
[991] Fix | Delete
} else {
[992] Fix | Delete
// Bitrate = ((FrameLengthInBytes - Padding) * SampleRate) / 144
[993] Fix | Delete
$info['audio']['bitrate'] = (($framebytelength - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 144;
[994] Fix | Delete
}
[995] Fix | Delete
} else {
[996] Fix | Delete
$this->error('Error calculating frame length of free-format MP3 without Xing/LAME header');
[997] Fix | Delete
}
[998] Fix | Delete
}
[999] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function