WordPress.org

Make WordPress Core


Ignore:
Timestamp:
10/10/2021 12:12:03 AM (7 weeks ago)
Author:
SergeyBiryukov
Message:

External Libraries: Update getID3 to version 1.9.21.

The latest version includes preliminary PHP 8.1 support, as well as a variety of bug fixes.

Release notes: https://github.com/JamesHeinrich/getID3/releases/tag/v1.9.21

A full list of changes in this update can be found on GitHub:
https://github.com/JamesHeinrich/getID3/compare/v1.9.20...v1.9.21

This commit also includes PHPCS adjustments previously made for a passing PHP Compatibility scan.

Follow-up to [47601], [47737], [47902], [48278], [49621], [50714].

Props jrf, SergeyBiryukov.
Fixes #54162.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/ID3/module.audio.mp3.php

    r48278 r51900  
    1919}
    2020
    21 // number of frames to scan to determine if MPEG-audio sequence is valid
    22 // Lower this number to 5-20 for faster scanning
    23 // Increase this number to 50+ for most accurate detection of valid VBR/CBR
    24 // mpeg-audio streams
    25 define('GETID3_MP3_VALID_CHECK_FRAMES', 35);
    26 
    2721
    2822class getid3_mp3 extends getid3_handler
     
    3731
    3832    /**
     33     * number of frames to scan to determine if MPEG-audio sequence is valid
     34     * Lower this number to 5-20 for faster scanning
     35     * Increase this number to 50+ for most accurate detection of valid VBR/CBR mpeg-audio streams
     36     *
     37     * @var int
     38     */
     39    public $mp3_valid_check_frames = 50;
     40
     41    /**
    3942     * @return bool
    4043     */
     
    5659        }
    5760
     61        $CurrentDataLAMEversionString = null;
    5862        if (((isset($info['id3v2']['headerlength']) && ($info['avdataoffset'] > $info['id3v2']['headerlength'])) || (!isset($info['id3v2']) && ($info['avdataoffset'] > 0) && ($info['avdataoffset'] != $initialOffset)))) {
    5963
     
    122126                    $PossiblyLongerLAMEversion_NewString = substr($PossiblyLongerLAMEversion_String, 0, strspn($PossiblyLongerLAMEversion_String, 'LAME0123456789., (abcdefghijklmnopqrstuvwxyzJFSOND)')); //"LAME3.90.3"  "LAME3.87 (beta 1, Sep 27 2000)" "LAME3.88 (beta)"
    123127                    if (empty($info['audio']['encoder']) || (strlen($PossiblyLongerLAMEversion_NewString) > strlen($info['audio']['encoder']))) {
     128                        if (!empty($info['audio']['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version']) && ($info['audio']['encoder'] == $info['mpeg']['audio']['LAME']['short_version'])) {
     129                            if (preg_match('#^LAME[0-9\\.]+#', $PossiblyLongerLAMEversion_NewString, $matches)) {
     130                                // "LAME3.100" -> "LAME3.100.1", but avoid including "(alpha)" and similar
     131                                $info['mpeg']['audio']['LAME']['short_version'] = $matches[0];
     132                            }
     133                        }
    124134                        $info['audio']['encoder'] = $PossiblyLongerLAMEversion_NewString;
    125135                    }
     
    296306
    297307            if ($info['audio']['bitrate_mode'] == 'cbr') {
    298                 $encoder_options = strtoupper($info['audio']['bitrate_mode']).ceil($info['audio']['bitrate'] / 1000);
     308                $encoder_options = strtoupper($info['audio']['bitrate_mode']).round($info['audio']['bitrate'] / 1000);
    299309            } else {
    300310                $encoder_options = strtoupper($info['audio']['bitrate_mode']);
     
    489499            $thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray;
    490500        } else {
    491             $this->error('Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset);
     501            $this->warning('Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset);
    492502            return false;
    493503        }
     
    723733                    $thisfile_mpeg_audio_lame['long_version']  = substr($headerstring, $VBRidOffset + 120, 20);
    724734                    $thisfile_mpeg_audio_lame['short_version'] = substr($thisfile_mpeg_audio_lame['long_version'], 0, 9);
    725                     $thisfile_mpeg_audio_lame['numeric_version'] = str_replace('LAME', '', $thisfile_mpeg_audio_lame['short_version']);
    726                     if (preg_match('#^LAME([0-9\\.a-z]+)#', $thisfile_mpeg_audio_lame['long_version'], $matches)) {
     735
     736                    //$thisfile_mpeg_audio_lame['numeric_version'] = str_replace('LAME', '', $thisfile_mpeg_audio_lame['short_version']);
     737                    $thisfile_mpeg_audio_lame['numeric_version'] = '';
     738                    if (preg_match('#^LAME([0-9\\.a-z]*)#', $thisfile_mpeg_audio_lame['long_version'], $matches)) {
    727739                        $thisfile_mpeg_audio_lame['short_version']   = $matches[0];
    728740                        $thisfile_mpeg_audio_lame['numeric_version'] = $matches[1];
    729741                    }
    730                     foreach (explode('.', $thisfile_mpeg_audio_lame['numeric_version']) as $key => $number) {
    731                         $thisfile_mpeg_audio_lame['integer_version'][$key] = intval($number);
    732                     }
    733 
    734                     //if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') {
    735                     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
    736 
    737                         // extra 11 chars are not part of version string when LAMEtag present
    738                         unset($thisfile_mpeg_audio_lame['long_version']);
    739 
    740                         // It the LAME tag was only introduced in LAME v3.90
    741                         // http://www.hydrogenaudio.org/?act=ST&f=15&t=9933
    742 
    743                         // Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html
    744                         // are assuming a 'Xing' identifier offset of 0x24, which is the case for
    745                         // MPEG-1 non-mono, but not for other combinations
    746                         $LAMEtagOffsetContant = $VBRidOffset - 0x24;
    747 
    748                         // shortcuts
    749                         $thisfile_mpeg_audio_lame['RGAD']    = array('track'=>array(), 'album'=>array());
    750                         $thisfile_mpeg_audio_lame_RGAD       = &$thisfile_mpeg_audio_lame['RGAD'];
    751                         $thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track'];
    752                         $thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album'];
    753                         $thisfile_mpeg_audio_lame['raw'] = array();
    754                         $thisfile_mpeg_audio_lame_raw    = &$thisfile_mpeg_audio_lame['raw'];
    755 
    756                         // byte $9B  VBR Quality
    757                         // This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications.
    758                         // Actually overwrites original Xing bytes
    759                         unset($thisfile_mpeg_audio['VBR_scale']);
    760                         $thisfile_mpeg_audio_lame['vbr_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1));
    761 
    762                         // bytes $9C-$A4  Encoder short VersionString
    763                         $thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9);
    764 
    765                         // byte $A5  Info Tag revision + VBR method
    766                         $LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1));
    767 
    768                         $thisfile_mpeg_audio_lame['tag_revision']   = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
    769                         $thisfile_mpeg_audio_lame_raw['vbr_method'] =  $LAMEtagRevisionVBRmethod & 0x0F;
    770                         $thisfile_mpeg_audio_lame['vbr_method']     = self::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']);
    771                         $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'
    772 
    773                         // byte $A6  Lowpass filter value
    774                         $thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
    775 
    776                         // bytes $A7-$AE  Replay Gain
    777                         // http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html
    778                         // bytes $A7-$AA : 32 bit floating point "Peak signal amplitude"
    779                         if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
    780                             // LAME 3.94a16 and later - 9.23 fixed point
    781                             // ie 0x0059E2EE / (2^23) = 5890798 / 8388608 = 0.7022378444671630859375
    782                             $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = (float) ((getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608);
    783                         } else {
    784                             // LAME 3.94a15 and earlier - 32-bit floating point
    785                             // Actually 3.94a16 will fall in here too and be WRONG, but is hard to detect 3.94a16 vs 3.94a15
    786                             $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = getid3_lib::LittleEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4));
     742                    if (strlen($thisfile_mpeg_audio_lame['numeric_version']) > 0) {
     743                        foreach (explode('.', $thisfile_mpeg_audio_lame['numeric_version']) as $key => $number) {
     744                            $thisfile_mpeg_audio_lame['integer_version'][$key] = intval($number);
    787745                        }
    788                         if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) {
    789                             unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
    790                         } else {
    791                             $thisfile_mpeg_audio_lame_RGAD['peak_db'] = getid3_lib::RGADamplitude2dB($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
     746                        //if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') {
     747                        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
     748
     749                            // extra 11 chars are not part of version string when LAMEtag present
     750                            unset($thisfile_mpeg_audio_lame['long_version']);
     751
     752                            // It the LAME tag was only introduced in LAME v3.90
     753                            // http://www.hydrogenaudio.org/?act=ST&f=15&t=9933
     754
     755                            // Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html
     756                            // are assuming a 'Xing' identifier offset of 0x24, which is the case for
     757                            // MPEG-1 non-mono, but not for other combinations
     758                            $LAMEtagOffsetContant = $VBRidOffset - 0x24;
     759
     760                            // shortcuts
     761                            $thisfile_mpeg_audio_lame['RGAD']    = array('track'=>array(), 'album'=>array());
     762                            $thisfile_mpeg_audio_lame_RGAD       = &$thisfile_mpeg_audio_lame['RGAD'];
     763                            $thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track'];
     764                            $thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album'];
     765                            $thisfile_mpeg_audio_lame['raw'] = array();
     766                            $thisfile_mpeg_audio_lame_raw    = &$thisfile_mpeg_audio_lame['raw'];
     767
     768                            // byte $9B  VBR Quality
     769                            // This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications.
     770                            // Actually overwrites original Xing bytes
     771                            unset($thisfile_mpeg_audio['VBR_scale']);
     772                            $thisfile_mpeg_audio_lame['vbr_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1));
     773
     774                            // bytes $9C-$A4  Encoder short VersionString
     775                            $thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9);
     776
     777                            // byte $A5  Info Tag revision + VBR method
     778                            $LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1));
     779
     780                            $thisfile_mpeg_audio_lame['tag_revision']   = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
     781                            $thisfile_mpeg_audio_lame_raw['vbr_method'] =  $LAMEtagRevisionVBRmethod & 0x0F;
     782                            $thisfile_mpeg_audio_lame['vbr_method']     = self::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']);
     783                            $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'
     784
     785                            // byte $A6  Lowpass filter value
     786                            $thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
     787
     788                            // bytes $A7-$AE  Replay Gain
     789                            // http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html
     790                            // bytes $A7-$AA : 32 bit floating point "Peak signal amplitude"
     791                            if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
     792                                // LAME 3.94a16 and later - 9.23 fixed point
     793                                // ie 0x0059E2EE / (2^23) = 5890798 / 8388608 = 0.7022378444671630859375
     794                                $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = (float) ((getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608);
     795                            } else {
     796                                // LAME 3.94a15 and earlier - 32-bit floating point
     797                                // Actually 3.94a16 will fall in here too and be WRONG, but is hard to detect 3.94a16 vs 3.94a15
     798                                $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = getid3_lib::LittleEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4));
     799                            }
     800                            if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) {
     801                                unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
     802                            } else {
     803                                $thisfile_mpeg_audio_lame_RGAD['peak_db'] = getid3_lib::RGADamplitude2dB($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
     804                            }
     805
     806                            $thisfile_mpeg_audio_lame_raw['RGAD_track']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2));
     807                            $thisfile_mpeg_audio_lame_raw['RGAD_album']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2));
     808
     809
     810                            if ($thisfile_mpeg_audio_lame_raw['RGAD_track'] != 0) {
     811
     812                                $thisfile_mpeg_audio_lame_RGAD_track['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13;
     813                                $thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10;
     814                                $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9;
     815                                $thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] =  $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF;
     816                                $thisfile_mpeg_audio_lame_RGAD_track['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['name']);
     817                                $thisfile_mpeg_audio_lame_RGAD_track['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']);
     818                                $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']);
     819
     820                                if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
     821                                    $info['replay_gain']['track']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
     822                                }
     823                                $info['replay_gain']['track']['originator'] = $thisfile_mpeg_audio_lame_RGAD_track['originator'];
     824                                $info['replay_gain']['track']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track['gain_db'];
     825                            } else {
     826                                unset($thisfile_mpeg_audio_lame_RGAD['track']);
     827                            }
     828                            if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 0) {
     829
     830                                $thisfile_mpeg_audio_lame_RGAD_album['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13;
     831                                $thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10;
     832                                $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9;
     833                                $thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF;
     834                                $thisfile_mpeg_audio_lame_RGAD_album['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['name']);
     835                                $thisfile_mpeg_audio_lame_RGAD_album['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']);
     836                                $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']);
     837
     838                                if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
     839                                    $info['replay_gain']['album']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
     840                                }
     841                                $info['replay_gain']['album']['originator'] = $thisfile_mpeg_audio_lame_RGAD_album['originator'];
     842                                $info['replay_gain']['album']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album['gain_db'];
     843                            } else {
     844                                unset($thisfile_mpeg_audio_lame_RGAD['album']);
     845                            }
     846                            if (empty($thisfile_mpeg_audio_lame_RGAD)) {
     847                                unset($thisfile_mpeg_audio_lame['RGAD']);
     848                            }
     849
     850
     851                            // byte $AF  Encoding flags + ATH Type
     852                            $EncodingFlagsATHtype = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1));
     853                            $thisfile_mpeg_audio_lame['encoding_flags']['nspsytune']   = (bool) ($EncodingFlagsATHtype & 0x10);
     854                            $thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20);
     855                            $thisfile_mpeg_audio_lame['encoding_flags']['nogap_next']  = (bool) ($EncodingFlagsATHtype & 0x40);
     856                            $thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev']  = (bool) ($EncodingFlagsATHtype & 0x80);
     857                            $thisfile_mpeg_audio_lame['ath_type']                      =         $EncodingFlagsATHtype & 0x0F;
     858
     859                            // byte $B0  if ABR {specified bitrate} else {minimal bitrate}
     860                            $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1));
     861                            if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) { // Average BitRate (ABR)
     862                                $thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
     863                            } elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) { // Constant BitRate (CBR)
     864                                // ignore
     865                            } elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) { // Variable BitRate (VBR) - minimum bitrate
     866                                $thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
     867                            }
     868
     869                            // bytes $B1-$B3  Encoder delays
     870                            $EncoderDelays = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3));
     871                            $thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12;
     872                            $thisfile_mpeg_audio_lame['end_padding']   =  $EncoderDelays & 0x000FFF;
     873
     874                            // byte $B4  Misc
     875                            $MiscByte = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1));
     876                            $thisfile_mpeg_audio_lame_raw['noise_shaping']       = ($MiscByte & 0x03);
     877                            $thisfile_mpeg_audio_lame_raw['stereo_mode']         = ($MiscByte & 0x1C) >> 2;
     878                            $thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5;
     879                            $thisfile_mpeg_audio_lame_raw['source_sample_freq']  = ($MiscByte & 0xC0) >> 6;
     880                            $thisfile_mpeg_audio_lame['noise_shaping']       = $thisfile_mpeg_audio_lame_raw['noise_shaping'];
     881                            $thisfile_mpeg_audio_lame['stereo_mode']         = self::LAMEmiscStereoModeLookup($thisfile_mpeg_audio_lame_raw['stereo_mode']);
     882                            $thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality'];
     883                            $thisfile_mpeg_audio_lame['source_sample_freq']  = self::LAMEmiscSourceSampleFrequencyLookup($thisfile_mpeg_audio_lame_raw['source_sample_freq']);
     884
     885                            // byte $B5  MP3 Gain
     886                            $thisfile_mpeg_audio_lame_raw['mp3_gain'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true);
     887                            $thisfile_mpeg_audio_lame['mp3_gain_db']     = (getid3_lib::RGADamplitude2dB(2) / 4) * $thisfile_mpeg_audio_lame_raw['mp3_gain'];
     888                            $thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6));
     889
     890                            // bytes $B6-$B7  Preset and surround info
     891                            $PresetSurroundBytes = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2));
     892                            // Reserved                                                    = ($PresetSurroundBytes & 0xC000);
     893                            $thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800);
     894                            $thisfile_mpeg_audio_lame['surround_info']     = self::LAMEsurroundInfoLookup($thisfile_mpeg_audio_lame_raw['surround_info']);
     895                            $thisfile_mpeg_audio_lame['preset_used_id']    = ($PresetSurroundBytes & 0x07FF);
     896                            $thisfile_mpeg_audio_lame['preset_used']       = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame);
     897                            if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
     898                                $this->warning('Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org');
     899                            }
     900                            if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
     901                                // this may change if 3.90.4 ever comes out
     902                                $thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.3';
     903                            }
     904
     905                            // bytes $B8-$BB  MusicLength
     906                            $thisfile_mpeg_audio_lame['audio_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4));
     907                            $ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_bytes']);
     908
     909                            // bytes $BC-$BD  MusicCRC
     910                            $thisfile_mpeg_audio_lame['music_crc']    = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2));
     911
     912                            // bytes $BE-$BF  CRC-16 of Info Tag
     913                            $thisfile_mpeg_audio_lame['lame_tag_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2));
     914
     915
     916                            // LAME CBR
     917                            if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
     918
     919                                $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
     920                                $thisfile_mpeg_audio['bitrate'] = self::ClosestStandardMP3Bitrate($thisfile_mpeg_audio['bitrate']);
     921                                $info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
     922                                //if (empty($thisfile_mpeg_audio['bitrate']) || (!empty($thisfile_mpeg_audio_lame['bitrate_min']) && ($thisfile_mpeg_audio_lame['bitrate_min'] != 255))) {
     923                                //  $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio_lame['bitrate_min'];
     924                                //}
     925
     926                            }
     927
    792928                        }
    793 
    794                         $thisfile_mpeg_audio_lame_raw['RGAD_track']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2));
    795                         $thisfile_mpeg_audio_lame_raw['RGAD_album']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2));
    796 
    797 
    798                         if ($thisfile_mpeg_audio_lame_raw['RGAD_track'] != 0) {
    799 
    800                             $thisfile_mpeg_audio_lame_RGAD_track['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13;
    801                             $thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10;
    802                             $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9;
    803                             $thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] =  $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF;
    804                             $thisfile_mpeg_audio_lame_RGAD_track['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['name']);
    805                             $thisfile_mpeg_audio_lame_RGAD_track['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']);
    806                             $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']);
    807 
    808                             if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
    809                                 $info['replay_gain']['track']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
    810                             }
    811                             $info['replay_gain']['track']['originator'] = $thisfile_mpeg_audio_lame_RGAD_track['originator'];
    812                             $info['replay_gain']['track']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track['gain_db'];
    813                         } else {
    814                             unset($thisfile_mpeg_audio_lame_RGAD['track']);
    815                         }
    816                         if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 0) {
    817 
    818                             $thisfile_mpeg_audio_lame_RGAD_album['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13;
    819                             $thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10;
    820                             $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9;
    821                             $thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF;
    822                             $thisfile_mpeg_audio_lame_RGAD_album['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['name']);
    823                             $thisfile_mpeg_audio_lame_RGAD_album['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']);
    824                             $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']);
    825 
    826                             if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
    827                                 $info['replay_gain']['album']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
    828                             }
    829                             $info['replay_gain']['album']['originator'] = $thisfile_mpeg_audio_lame_RGAD_album['originator'];
    830                             $info['replay_gain']['album']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album['gain_db'];
    831                         } else {
    832                             unset($thisfile_mpeg_audio_lame_RGAD['album']);
    833                         }
    834                         if (empty($thisfile_mpeg_audio_lame_RGAD)) {
    835                             unset($thisfile_mpeg_audio_lame['RGAD']);
    836                         }
    837 
    838 
    839                         // byte $AF  Encoding flags + ATH Type
    840                         $EncodingFlagsATHtype = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1));
    841                         $thisfile_mpeg_audio_lame['encoding_flags']['nspsytune']   = (bool) ($EncodingFlagsATHtype & 0x10);
    842                         $thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20);
    843                         $thisfile_mpeg_audio_lame['encoding_flags']['nogap_next']  = (bool) ($EncodingFlagsATHtype & 0x40);
    844                         $thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev']  = (bool) ($EncodingFlagsATHtype & 0x80);
    845                         $thisfile_mpeg_audio_lame['ath_type']                      =         $EncodingFlagsATHtype & 0x0F;
    846 
    847                         // byte $B0  if ABR {specified bitrate} else {minimal bitrate}
    848                         $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1));
    849                         if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) { // Average BitRate (ABR)
    850                             $thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
    851                         } elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) { // Constant BitRate (CBR)
    852                             // ignore
    853                         } elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) { // Variable BitRate (VBR) - minimum bitrate
    854                             $thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
    855                         }
    856 
    857                         // bytes $B1-$B3  Encoder delays
    858                         $EncoderDelays = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3));
    859                         $thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12;
    860                         $thisfile_mpeg_audio_lame['end_padding']   =  $EncoderDelays & 0x000FFF;
    861 
    862                         // byte $B4  Misc
    863                         $MiscByte = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1));
    864                         $thisfile_mpeg_audio_lame_raw['noise_shaping']       = ($MiscByte & 0x03);
    865                         $thisfile_mpeg_audio_lame_raw['stereo_mode']         = ($MiscByte & 0x1C) >> 2;
    866                         $thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5;
    867                         $thisfile_mpeg_audio_lame_raw['source_sample_freq']  = ($MiscByte & 0xC0) >> 6;
    868                         $thisfile_mpeg_audio_lame['noise_shaping']       = $thisfile_mpeg_audio_lame_raw['noise_shaping'];
    869                         $thisfile_mpeg_audio_lame['stereo_mode']         = self::LAMEmiscStereoModeLookup($thisfile_mpeg_audio_lame_raw['stereo_mode']);
    870                         $thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality'];
    871                         $thisfile_mpeg_audio_lame['source_sample_freq']  = self::LAMEmiscSourceSampleFrequencyLookup($thisfile_mpeg_audio_lame_raw['source_sample_freq']);
    872 
    873                         // byte $B5  MP3 Gain
    874                         $thisfile_mpeg_audio_lame_raw['mp3_gain'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true);
    875                         $thisfile_mpeg_audio_lame['mp3_gain_db']     = (getid3_lib::RGADamplitude2dB(2) / 4) * $thisfile_mpeg_audio_lame_raw['mp3_gain'];
    876                         $thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6));
    877 
    878                         // bytes $B6-$B7  Preset and surround info
    879                         $PresetSurroundBytes = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2));
    880                         // Reserved                                                    = ($PresetSurroundBytes & 0xC000);
    881                         $thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800);
    882                         $thisfile_mpeg_audio_lame['surround_info']     = self::LAMEsurroundInfoLookup($thisfile_mpeg_audio_lame_raw['surround_info']);
    883                         $thisfile_mpeg_audio_lame['preset_used_id']    = ($PresetSurroundBytes & 0x07FF);
    884                         $thisfile_mpeg_audio_lame['preset_used']       = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame);
    885                         if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
    886                             $this->warning('Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org');
    887                         }
    888                         if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
    889                             // this may change if 3.90.4 ever comes out
    890                             $thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.3';
    891                         }
    892 
    893                         // bytes $B8-$BB  MusicLength
    894                         $thisfile_mpeg_audio_lame['audio_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4));
    895                         $ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_bytes']);
    896 
    897                         // bytes $BC-$BD  MusicCRC
    898                         $thisfile_mpeg_audio_lame['music_crc']    = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2));
    899 
    900                         // bytes $BE-$BF  CRC-16 of Info Tag
    901                         $thisfile_mpeg_audio_lame['lame_tag_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2));
    902 
    903 
    904                         // LAME CBR
    905                         if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
    906 
    907                             $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
    908                             $thisfile_mpeg_audio['bitrate'] = self::ClosestStandardMP3Bitrate($thisfile_mpeg_audio['bitrate']);
    909                             $info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
    910                             //if (empty($thisfile_mpeg_audio['bitrate']) || (!empty($thisfile_mpeg_audio_lame['bitrate_min']) && ($thisfile_mpeg_audio_lame['bitrate_min'] != 255))) {
    911                             //  $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio_lame['bitrate_min'];
    912                             //}
    913 
    914                         }
    915 
    916929                    }
    917930                }
     
    10091022            if (!$this->RecursiveFrameScanning($offset, $nextframetestoffset, $ScanAsCBR)) {
    10101023                return false;
     1024            }
     1025            if (!empty($this->getid3->info['mp3_validity_check_bitrates']) && !empty($thisfile_mpeg_audio['bitrate_mode']) && ($thisfile_mpeg_audio['bitrate_mode'] == 'vbr') && !empty($thisfile_mpeg_audio['VBR_bitrate'])) {
     1026                // https://github.com/JamesHeinrich/getID3/issues/287
     1027                if (count(array_keys($this->getid3->info['mp3_validity_check_bitrates'])) == 1) {
     1028                    list($cbr_bitrate_in_short_scan) = array_keys($this->getid3->info['mp3_validity_check_bitrates']);
     1029                    $deviation_cbr_from_header_bitrate = abs($thisfile_mpeg_audio['VBR_bitrate'] - $cbr_bitrate_in_short_scan) / $cbr_bitrate_in_short_scan;
     1030                    if ($deviation_cbr_from_header_bitrate < 0.01) {
     1031                        // VBR header bitrate may differ slightly from true bitrate of frames, perhaps accounting for overhead of VBR header frame itself?
     1032                        // If measured CBR bitrate is within 1% of specified bitrate in VBR header then assume that file is truly CBR
     1033                        $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
     1034                        //$this->warning('VBR header ignored, assuming CBR '.round($cbr_bitrate_in_short_scan / 1000).'kbps based on scan of '.$this->mp3_valid_check_frames.' frames');
     1035                    }
     1036                }
     1037            }
     1038            if (isset($this->getid3->info['mp3_validity_check_bitrates'])) {
     1039                unset($this->getid3->info['mp3_validity_check_bitrates']);
    10111040            }
    10121041
     
    11311160        $this->decodeMPEGaudioHeader($offset, $firstframetestarray, false);
    11321161
    1133         for ($i = 0; $i < GETID3_MP3_VALID_CHECK_FRAMES; $i++) {
    1134             // check next GETID3_MP3_VALID_CHECK_FRAMES frames for validity, to make sure we haven't run across a false synch
     1162        $info['mp3_validity_check_bitrates'] = array();
     1163        for ($i = 0; $i < $this->mp3_valid_check_frames; $i++) {
     1164            // check next (default: 50) frames for validity, to make sure we haven't run across a false synch
    11351165            if (($nextframetestoffset + 4) >= $info['avdataend']) {
    11361166                // end of file
     
    11401170            $nextframetestarray = array('error' => array(), 'warning' => array(), 'avdataend' => $info['avdataend'], 'avdataoffset'=>$info['avdataoffset']);
    11411171            if ($this->decodeMPEGaudioHeader($nextframetestoffset, $nextframetestarray, false)) {
     1172                getid3_lib::safe_inc($info['mp3_validity_check_bitrates'][$nextframetestarray['mpeg']['audio']['bitrate']]);
    11421173                if ($ScanAsCBR) {
    11431174                    // force CBR mode, used for trying to pick out invalid audio streams with valid(?) VBR headers, or VBR streams with no VBR header
     
    12741305        $LongMPEGpaddingLookup        = array();
    12751306        $LongMPEGfrequencyLookup      = array();
     1307        $Distribution                 = array();
    12761308        $Distribution['bitrate']      = array();
    12771309        $Distribution['frequency']    = array();
     
    14341466        $sync_seek_buffer_size = strlen($header);
    14351467        $SynchSeekOffset = 0;
     1468        $SyncSeekAttempts = 0;
     1469        $SyncSeekAttemptsMax = 1000;
     1470        $FirstFrameThisfileInfo = null;
    14361471        while ($SynchSeekOffset < $sync_seek_buffer_size) {
    14371472            if ((($avdataoffset + $SynchSeekOffset)  < $info['avdataend']) && !feof($this->getid3->fp)) {
     
    14721507            }
    14731508
    1474             if (($header[$SynchSeekOffset] == "\xFF") && ($header[($SynchSeekOffset + 1)] > "\xE0")) { // synch detected
     1509            if (($header[$SynchSeekOffset] == "\xFF") && ($header[($SynchSeekOffset + 1)] > "\xE0")) { // possible synch detected
     1510                if (++$SyncSeekAttempts >= $SyncSeekAttemptsMax) {
     1511                    // https://github.com/JamesHeinrich/getID3/issues/286
     1512                    // corrupt files claiming to be MP3, with a large number of 0xFF bytes near the beginning, can cause this loop to take a very long time
     1513                    // should have escape condition to avoid spending too much time scanning a corrupt file
     1514                    // if a synch's not found within the first 128k bytes, then give up
     1515                    $this->error('Could not find valid MPEG audio synch after scanning '.$SyncSeekAttempts.' candidate offsets');
     1516                    if (isset($info['audio']['bitrate'])) {
     1517                        unset($info['audio']['bitrate']);
     1518                    }
     1519                    if (isset($info['mpeg']['audio'])) {
     1520                        unset($info['mpeg']['audio']);
     1521                    }
     1522                    if (empty($info['mpeg'])) {
     1523                        unset($info['mpeg']);
     1524                    }
     1525                    return false;
     1526                }
    14751527                $FirstFrameAVDataOffset = null;
    14761528                if (!isset($FirstFrameThisfileInfo) && !isset($info['mpeg']['audio'])) {
     
    15121564                                $info = $dummy;
    15131565                                $info['avdataoffset'] = $GarbageOffsetEnd;
    1514                                 $this->warning('apparently-valid VBR header not used because could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.'), but did find valid CBR stream starting at '.$GarbageOffsetEnd);
     1566                                $this->warning('apparently-valid VBR header not used because could not find '.$this->mp3_valid_check_frames.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.'), but did find valid CBR stream starting at '.$GarbageOffsetEnd);
    15151567                            } else {
    1516                                 $this->warning('using data from VBR header even though could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.')');
     1568                                $this->warning('using data from VBR header even though could not find '.$this->mp3_valid_check_frames.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.')');
    15171569                            }
    15181570                        }
     
    15591611                        for ($current_segment = 0; $current_segment < $max_scan_segments; $current_segment++) {
    15601612                            $frames_scanned_this_segment = 0;
     1613                            $scan_start_offset = array();
    15611614                            if ($this->ftell() >= $info['avdataend']) {
    15621615                                break;
     
    18881941        }
    18891942
     1943        $MPEGrawHeader = array();
    18901944        $MPEGrawHeader['synch']         = (getid3_lib::BigEndian2Int(substr($Header4Bytes, 0, 2)) & 0xFFE0) >> 4;
    18911945        $MPEGrawHeader['version']       = (ord($Header4Bytes[1]) & 0x18) >> 3; //    BB
Note: See TracChangeset for help on using the changeset viewer.