720 $thisfile_mpeg_audio_lame = &$thisfile_mpeg_audio['LAME']; |
730 $thisfile_mpeg_audio_lame = &$thisfile_mpeg_audio['LAME']; |
721 |
731 |
722 |
732 |
723 $thisfile_mpeg_audio_lame['long_version'] = substr($headerstring, $VBRidOffset + 120, 20); |
733 $thisfile_mpeg_audio_lame['long_version'] = substr($headerstring, $VBRidOffset + 120, 20); |
724 $thisfile_mpeg_audio_lame['short_version'] = substr($thisfile_mpeg_audio_lame['long_version'], 0, 9); |
734 $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']); |
735 |
726 if (preg_match('#^LAME([0-9\\.a-z]+)#', $thisfile_mpeg_audio_lame['long_version'], $matches)) { |
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)) { |
727 $thisfile_mpeg_audio_lame['short_version'] = $matches[0]; |
739 $thisfile_mpeg_audio_lame['short_version'] = $matches[0]; |
728 $thisfile_mpeg_audio_lame['numeric_version'] = $matches[1]; |
740 $thisfile_mpeg_audio_lame['numeric_version'] = $matches[1]; |
729 } |
741 } |
730 foreach (explode('.', $thisfile_mpeg_audio_lame['numeric_version']) as $key => $number) { |
742 if (strlen($thisfile_mpeg_audio_lame['numeric_version']) > 0) { |
731 $thisfile_mpeg_audio_lame['integer_version'][$key] = intval($number); |
743 foreach (explode('.', $thisfile_mpeg_audio_lame['numeric_version']) as $key => $number) { |
732 } |
744 $thisfile_mpeg_audio_lame['integer_version'][$key] = intval($number); |
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)); |
|
787 } |
745 } |
788 if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) { |
746 //if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') { |
789 unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']); |
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 |
790 } else { |
748 |
791 $thisfile_mpeg_audio_lame_RGAD['peak_db'] = getid3_lib::RGADamplitude2dB($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']); |
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 |
792 } |
928 } |
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 |
|
916 } |
929 } |
917 } |
930 } |
918 |
931 |
919 } else { |
932 } else { |
920 |
933 |