408 {
409 static $MPEGaudioVersionLookup;
410 static $MPEGaudioLayerLookup;
411 static $MPEGaudioBitrateLookup;
412 static $MPEGaudioFrequencyLookup;
413 static $MPEGaudioChannelModeLookup;
414 static $MPEGaudioModeExtensionLookup;
415 static $MPEGaudioEmphasisLookup;
416 if (empty($MPEGaudioVersionLookup)) {
424 }
425
426 if ($this->
fseek($offset) != 0) {
427 $this->
error(
'decodeMPEGaudioHeader() failed to seek to next offset at '.$offset);
428 return false;
429 }
430
431 $headerstring = $this->
fread(226);
432
433
434
435
436
437
438
439 $head4 = substr($headerstring, 0, 4);
440 static $MPEGaudioHeaderDecodeCache = array();
441 if (isset($MPEGaudioHeaderDecodeCache[$head4])) {
442 $MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4];
443 } else {
445 $MPEGaudioHeaderDecodeCache[$head4] = $MPEGheaderRawArray;
446 }
447
448 static $MPEGaudioHeaderValidCache = array();
449 if (!isset($MPEGaudioHeaderValidCache[$head4])) {
450
452 }
453
454
455 if (!isset(
$info[
'mpeg'][
'audio'])) {
456 $info[
'mpeg'][
'audio'] = array();
457 }
458 $thisfile_mpeg_audio = &
$info[
'mpeg'][
'audio'];
459
460
461 if ($MPEGaudioHeaderValidCache[$head4]) {
462 $thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray;
463 } else {
465 return false;
466 }
467
468 if (!$FastMPEGheaderScan) {
469 $thisfile_mpeg_audio['version'] = $MPEGaudioVersionLookup[$thisfile_mpeg_audio['raw']['version']];
470 $thisfile_mpeg_audio['layer'] = $MPEGaudioLayerLookup[$thisfile_mpeg_audio['raw']['layer']];
471
472 $thisfile_mpeg_audio['channelmode'] = $MPEGaudioChannelModeLookup[$thisfile_mpeg_audio['raw']['channelmode']];
473 $thisfile_mpeg_audio['channels'] = (($thisfile_mpeg_audio['channelmode'] == 'mono') ? 1 : 2);
474 $thisfile_mpeg_audio['sample_rate'] = $MPEGaudioFrequencyLookup[$thisfile_mpeg_audio['version']][$thisfile_mpeg_audio['raw']['sample_rate']];
475 $thisfile_mpeg_audio['protection'] = !$thisfile_mpeg_audio['raw']['protection'];
476 $thisfile_mpeg_audio['private'] = (bool) $thisfile_mpeg_audio['raw']['private'];
477 $thisfile_mpeg_audio['modeextension'] = $MPEGaudioModeExtensionLookup[$thisfile_mpeg_audio['layer']][$thisfile_mpeg_audio['raw']['modeextension']];
478 $thisfile_mpeg_audio['copyright'] = (bool) $thisfile_mpeg_audio['raw']['copyright'];
479 $thisfile_mpeg_audio['original'] = (bool) $thisfile_mpeg_audio['raw']['original'];
480 $thisfile_mpeg_audio['emphasis'] = $MPEGaudioEmphasisLookup[$thisfile_mpeg_audio['raw']['emphasis']];
481
482 $info[
'audio'][
'channels'] = $thisfile_mpeg_audio[
'channels'];
483 $info[
'audio'][
'sample_rate'] = $thisfile_mpeg_audio[
'sample_rate'];
484
485 if ($thisfile_mpeg_audio['protection']) {
487 }
488 }
489
490 if ($thisfile_mpeg_audio['raw']['bitrate'] == 15) {
491
492 $this->
warning(
'Invalid bitrate index (15), this is a known bug in free-format MP3s encoded by LAME v3.90 - 3.93.1');
493 $thisfile_mpeg_audio['raw']['bitrate'] = 0;
494 }
495 $thisfile_mpeg_audio['padding'] = (bool) $thisfile_mpeg_audio['raw']['padding'];
496 $thisfile_mpeg_audio['bitrate'] = $MPEGaudioBitrateLookup[$thisfile_mpeg_audio['version']][$thisfile_mpeg_audio['layer']][$thisfile_mpeg_audio['raw']['bitrate']];
497
498 if (($thisfile_mpeg_audio[
'bitrate'] ==
'free') && ($offset ==
$info[
'avdataoffset'])) {
499
500
501 $recursivesearch = false;
502 }
503
504
505 if (!$FastMPEGheaderScan && ($thisfile_mpeg_audio['layer'] == '2')) {
506
507 $info[
'audio'][
'dataformat'] =
'mp2';
508 switch ($thisfile_mpeg_audio['channelmode']) {
509
510 case 'mono':
511 if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] <= 192000)) {
512
513 } else {
514 $this->
error($thisfile_mpeg_audio[
'bitrate'].
'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio[
'channelmode'].
'.');
515 return false;
516 }
517 break;
518
519 case 'stereo':
520 case 'joint stereo':
521 case 'dual channel':
522 if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] == 64000) || ($thisfile_mpeg_audio['bitrate'] >= 96000)) {
523
524 } else {
525 $this->
error(intval(round($thisfile_mpeg_audio[
'bitrate'] / 1000)).
'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio[
'channelmode'].
'.');
526 return false;
527 }
528 break;
529
530 }
531
532 }
533
534
535 if (
$info[
'audio'][
'sample_rate'] > 0) {
536 $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']);
537 }
538
539 $nextframetestoffset = $offset + 1;
540 if ($thisfile_mpeg_audio['bitrate'] != 'free') {
541
542 $info[
'audio'][
'bitrate'] = $thisfile_mpeg_audio[
'bitrate'];
543
544 if (isset($thisfile_mpeg_audio['framelength'])) {
545 $nextframetestoffset = $offset + $thisfile_mpeg_audio['framelength'];
546 } else {
547 $this->
error(
'Frame at offset('.$offset.
') is has an invalid frame length.');
548 return false;
549 }
550
551 }
552
553 $ExpectedNumberOfAudioBytes = 0;
554
556
557
558 if (substr($headerstring, 4 + 32, 4) == 'VBRI') {
559
560
561
562 $thisfile_mpeg_audio['bitrate_mode'] = 'vbr';
563 $thisfile_mpeg_audio['VBR_method'] = 'Fraunhofer';
564 $info[
'audio'][
'codec'] =
'Fraunhofer';
565
566 $SideInfoData = substr($headerstring, 4 + 2, 32);
567
568 $FraunhoferVBROffset = 36;
569
570 $thisfile_mpeg_audio[
'VBR_encoder_version'] =
getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 4, 2));
571 $thisfile_mpeg_audio[
'VBR_encoder_delay'] =
getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 6, 2));
575 $thisfile_mpeg_audio[
'VBR_seek_offsets'] =
getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 18, 2));
577 $thisfile_mpeg_audio[
'VBR_entry_bytes'] =
getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 22, 2));
578 $thisfile_mpeg_audio[
'VBR_entry_frames'] =
getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 24, 2));
579
580 $ExpectedNumberOfAudioBytes = $thisfile_mpeg_audio['VBR_bytes'];
581
582 $previousbyteoffset = $offset;
583 for (
$i = 0;
$i < $thisfile_mpeg_audio[
'VBR_seek_offsets'];
$i++) {
584 $Fraunhofer_OffsetN =
getid3_lib::BigEndian2Int(substr($headerstring, $FraunhoferVBROffset, $thisfile_mpeg_audio[
'VBR_entry_bytes']));
585 $FraunhoferVBROffset += $thisfile_mpeg_audio['VBR_entry_bytes'];
586 $thisfile_mpeg_audio[
'VBR_offsets_relative'][
$i] = ($Fraunhofer_OffsetN * $thisfile_mpeg_audio[
'VBR_seek_scale']);
587 $thisfile_mpeg_audio[
'VBR_offsets_absolute'][
$i] = ($Fraunhofer_OffsetN * $thisfile_mpeg_audio[
'VBR_seek_scale']) + $previousbyteoffset;
588 $previousbyteoffset += $Fraunhofer_OffsetN;
589 }
590
591
592 } else {
593
594
595
596
597 $VBRidOffset =
self::XingVBRidOffset($thisfile_mpeg_audio[
'version'], $thisfile_mpeg_audio[
'channelmode']);
598 $SideInfoData = substr($headerstring, 4 + 2, $VBRidOffset - 4);
599
600 if ((substr($headerstring, $VBRidOffset, strlen('Xing')) == 'Xing') || (substr($headerstring, $VBRidOffset, strlen('Info')) == 'Info')) {
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627 $thisfile_mpeg_audio['bitrate_mode'] = 'vbr';
628 $thisfile_mpeg_audio['VBR_method'] = 'Xing';
629
630
631
632
633
635
636 $thisfile_mpeg_audio['xing_flags']['frames'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000001);
637 $thisfile_mpeg_audio['xing_flags']['bytes'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000002);
638 $thisfile_mpeg_audio['xing_flags']['toc'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000004);
639 $thisfile_mpeg_audio['xing_flags']['vbr_scale'] = (bool) ($thisfile_mpeg_audio['xing_flags_raw'] & 0x00000008);
640
641 if ($thisfile_mpeg_audio['xing_flags']['frames']) {
643
644 }
645 if ($thisfile_mpeg_audio['xing_flags']['bytes']) {
647 }
648
649
650
651 if (!empty($thisfile_mpeg_audio['VBR_frames'])) {
652 $used_filesize = 0;
653 if (!empty($thisfile_mpeg_audio['VBR_bytes'])) {
654 $used_filesize = $thisfile_mpeg_audio['VBR_bytes'];
655 } elseif (!empty(
$info[
'filesize'])) {
656 $used_filesize =
$info[
'filesize'];
657 $used_filesize -= intval(@
$info[
'id3v2'][
'headerlength']);
658 $used_filesize -= (isset(
$info[
'id3v1']) ? 128 : 0);
659 $used_filesize -= (isset(
$info[
'tag_offset_end']) ?
$info[
'tag_offset_end'] -
$info[
'tag_offset_start'] : 0);
660 $this->
warning(
'MP3.Xing header missing VBR_bytes, assuming MPEG audio portion of file is '.number_format($used_filesize).
' bytes');
661 }
662
663 $framelengthfloat = $used_filesize / $thisfile_mpeg_audio['VBR_frames'];
664
665 if ($thisfile_mpeg_audio['layer'] == '1') {
666
667
668 $info[
'audio'][
'bitrate'] = ($framelengthfloat / 4) * $thisfile_mpeg_audio[
'sample_rate'] * (2 /
$info[
'audio'][
'channels']) / 12;
669 } else {
670
671
672 $info[
'audio'][
'bitrate'] = $framelengthfloat * $thisfile_mpeg_audio[
'sample_rate'] * (2 /
$info[
'audio'][
'channels']) / 144;
673 }
674 $thisfile_mpeg_audio['framelength'] = floor($framelengthfloat);
675 }
676
677 if ($thisfile_mpeg_audio['xing_flags']['toc']) {
678 $LAMEtocData = substr($headerstring, $VBRidOffset + 16, 100);
679 for (
$i = 0;
$i < 100;
$i++) {
680 $thisfile_mpeg_audio[
'toc'][
$i] = ord($LAMEtocData{
$i});
681 }
682 }
683 if ($thisfile_mpeg_audio['xing_flags']['vbr_scale']) {
685 }
686
687
688
689 if (substr($headerstring, $VBRidOffset + 120, 4) == 'LAME') {
690
691
692 $thisfile_mpeg_audio['LAME'] = array();
693 $thisfile_mpeg_audio_lame = &$thisfile_mpeg_audio['LAME'];
694
695
696 $thisfile_mpeg_audio_lame['long_version'] = substr($headerstring, $VBRidOffset + 120, 20);
697 $thisfile_mpeg_audio_lame['short_version'] = substr($thisfile_mpeg_audio_lame['long_version'], 0, 9);
698
699 if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') {
700
701
702 unset($thisfile_mpeg_audio_lame['long_version']);
703
704
705
706
707
708
709
710 $LAMEtagOffsetContant = $VBRidOffset - 0x24;
711
712
713 $thisfile_mpeg_audio_lame['RGAD'] = array('track'=>array(), 'album'=>array());
714 $thisfile_mpeg_audio_lame_RGAD = &$thisfile_mpeg_audio_lame['RGAD'];
715 $thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track'];
716 $thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album'];
717 $thisfile_mpeg_audio_lame['raw'] = array();
718 $thisfile_mpeg_audio_lame_raw = &$thisfile_mpeg_audio_lame['raw'];
719
720
721
722
723 unset($thisfile_mpeg_audio['VBR_scale']);
724 $thisfile_mpeg_audio_lame[
'vbr_quality'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1));
725
726
727 $thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9);
728
729
731
732 $thisfile_mpeg_audio_lame['tag_revision'] = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
733 $thisfile_mpeg_audio_lame_raw['vbr_method'] = $LAMEtagRevisionVBRmethod & 0x0F;
735 $thisfile_mpeg_audio['bitrate_mode'] = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3);
736
737
738 $thisfile_mpeg_audio_lame[
'lowpass_frequency'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
739
740
741
742
743 if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
744
745
746 $thisfile_mpeg_audio_lame_RGAD[
'peak_amplitude'] = (float) ((
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608);
747 } else {
748
749
751 }
752 if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) {
753 unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
754 } else {
756 }
757
758 $thisfile_mpeg_audio_lame_raw[
'RGAD_track'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2));
759 $thisfile_mpeg_audio_lame_raw[
'RGAD_album'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2));
760
761
762 if ($thisfile_mpeg_audio_lame_raw['RGAD_track'] != 0) {
763
764 $thisfile_mpeg_audio_lame_RGAD_track['raw']['name'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13;
765 $thisfile_mpeg_audio_lame_RGAD_track['raw']['originator'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10;
766 $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9;
767 $thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF;
768 $thisfile_mpeg_audio_lame_RGAD_track[
'name'] =
getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track[
'raw'][
'name']);
770 $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']);
771
772 if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
773 $info[
'replay_gain'][
'track'][
'peak'] = $thisfile_mpeg_audio_lame_RGAD[
'peak_amplitude'];
774 }
775 $info[
'replay_gain'][
'track'][
'originator'] = $thisfile_mpeg_audio_lame_RGAD_track[
'originator'];
776 $info[
'replay_gain'][
'track'][
'adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track[
'gain_db'];
777 } else {
778 unset($thisfile_mpeg_audio_lame_RGAD['track']);
779 }
780 if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 0) {
781
782 $thisfile_mpeg_audio_lame_RGAD_album['raw']['name'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13;
783 $thisfile_mpeg_audio_lame_RGAD_album['raw']['originator'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10;
784 $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9;
785 $thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF;
786 $thisfile_mpeg_audio_lame_RGAD_album[
'name'] =
getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album[
'raw'][
'name']);
788 $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']);
789
790 if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
791 $info[
'replay_gain'][
'album'][
'peak'] = $thisfile_mpeg_audio_lame_RGAD[
'peak_amplitude'];
792 }
793 $info[
'replay_gain'][
'album'][
'originator'] = $thisfile_mpeg_audio_lame_RGAD_album[
'originator'];
794 $info[
'replay_gain'][
'album'][
'adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album[
'gain_db'];
795 } else {
796 unset($thisfile_mpeg_audio_lame_RGAD['album']);
797 }
798 if (empty($thisfile_mpeg_audio_lame_RGAD)) {
799 unset($thisfile_mpeg_audio_lame['RGAD']);
800 }
801
802
803
805 $thisfile_mpeg_audio_lame['encoding_flags']['nspsytune'] = (bool) ($EncodingFlagsATHtype & 0x10);
806 $thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20);
807 $thisfile_mpeg_audio_lame['encoding_flags']['nogap_next'] = (bool) ($EncodingFlagsATHtype & 0x40);
808 $thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev'] = (bool) ($EncodingFlagsATHtype & 0x80);
809 $thisfile_mpeg_audio_lame['ath_type'] = $EncodingFlagsATHtype & 0x0F;
810
811
812 $thisfile_mpeg_audio_lame[
'raw'][
'abrbitrate_minbitrate'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1));
813 if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) {
814 $thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
815 } elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
816
817 } elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) {
818 $thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
819 }
820
821
823 $thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12;
824 $thisfile_mpeg_audio_lame['end_padding'] = $EncoderDelays & 0x000FFF;
825
826
828 $thisfile_mpeg_audio_lame_raw['noise_shaping'] = ($MiscByte & 0x03);
829 $thisfile_mpeg_audio_lame_raw['stereo_mode'] = ($MiscByte & 0x1C) >> 2;
830 $thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5;
831 $thisfile_mpeg_audio_lame_raw['source_sample_freq'] = ($MiscByte & 0xC0) >> 6;
832 $thisfile_mpeg_audio_lame['noise_shaping'] = $thisfile_mpeg_audio_lame_raw['noise_shaping'];
834 $thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality'];
836
837
838 $thisfile_mpeg_audio_lame_raw[
'mp3_gain'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1),
false,
true);
840 $thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6));
841
842
844
845 $thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800);
847 $thisfile_mpeg_audio_lame['preset_used_id'] = ($PresetSurroundBytes & 0x07FF);
849 if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
850 $this->
warning(
'Unknown LAME preset used ('.$thisfile_mpeg_audio_lame[
'preset_used_id'].
') - please report to info@getid3.org');
851 }
852 if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
853
854 $thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.3';
855 }
856
857
858 $thisfile_mpeg_audio_lame[
'audio_bytes'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4));
859 $ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_bytes']);
860
861
862 $thisfile_mpeg_audio_lame[
'music_crc'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2));
863
864
865 $thisfile_mpeg_audio_lame[
'lame_tag_crc'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2));
866
867
868
869 if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
870
871 $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
873 $info[
'audio'][
'bitrate'] = $thisfile_mpeg_audio[
'bitrate'];
874
875
876
877
878 }
879
880 }
881 }
882
883 } else {
884
885
886 $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
887 if ($recursivesearch) {
888 $thisfile_mpeg_audio['bitrate_mode'] = 'vbr';
890 $recursivesearch = false;
891 $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
892 }
893 if ($thisfile_mpeg_audio['bitrate_mode'] == 'vbr') {
894 $this->
warning(
'VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.');
895 }
896 }
897
898 }
899
900 }
901
902 if (($ExpectedNumberOfAudioBytes > 0) && ($ExpectedNumberOfAudioBytes != (
$info[
'avdataend'] -
$info[
'avdataoffset']))) {
903 if ($ExpectedNumberOfAudioBytes > (
$info[
'avdataend'] -
$info[
'avdataoffset'])) {
905
906 }
907 elseif (($ExpectedNumberOfAudioBytes - (
$info[
'avdataend'] -
$info[
'avdataoffset'])) == 1) {
908 $this->
warning(
'Last byte of data truncated (this is a known bug in Meracl ID3 Tag Writer before v1.3.5)');
909 }
910 else {
911 $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)');
912 }
913 } else {
914 if (((
$info[
'avdataend'] -
$info[
'avdataoffset']) - $ExpectedNumberOfAudioBytes) == 1) {
915
916
917
918
919
920 $info[
'avdataend']--;
921
922
923
924
925 } else {
926 $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)');
927 }
928 }
929 }
930
931 if (($thisfile_mpeg_audio[
'bitrate'] ==
'free') && empty(
$info[
'audio'][
'bitrate'])) {
932 if (($offset ==
$info[
'avdataoffset']) && empty($thisfile_mpeg_audio[
'VBR_frames'])) {
934 if ($framebytelength > 0) {
935 $thisfile_mpeg_audio['framelength'] = $framebytelength;
936 if ($thisfile_mpeg_audio['layer'] == '1') {
937
938 $info[
'audio'][
'bitrate'] = ((($framebytelength / 4) - intval($thisfile_mpeg_audio[
'padding'])) * $thisfile_mpeg_audio[
'sample_rate']) / 12;
939 } else {
940
941 $info[
'audio'][
'bitrate'] = (($framebytelength - intval($thisfile_mpeg_audio[
'padding'])) * $thisfile_mpeg_audio[
'sample_rate']) / 144;
942 }
943 } else {
944 $this->
error(
'Error calculating frame length of free-format MP3 without Xing/LAME header');
945 }
946 }
947 }
948
949 if (isset($thisfile_mpeg_audio['VBR_frames']) ? $thisfile_mpeg_audio['VBR_frames'] : '') {
950 switch ($thisfile_mpeg_audio['bitrate_mode']) {
951 case 'vbr':
952 case 'abr':
953 $bytes_per_frame = 1152;
954 if (($thisfile_mpeg_audio['version'] == '1') && ($thisfile_mpeg_audio['layer'] == 1)) {
955 $bytes_per_frame = 384;
956 } elseif ((($thisfile_mpeg_audio['version'] == '2') || ($thisfile_mpeg_audio['version'] == '2.5')) && ($thisfile_mpeg_audio['layer'] == 3)) {
957 $bytes_per_frame = 576;
958 }
959 $thisfile_mpeg_audio[
'VBR_bitrate'] = (isset($thisfile_mpeg_audio[
'VBR_bytes']) ? (($thisfile_mpeg_audio[
'VBR_bytes'] / $thisfile_mpeg_audio[
'VBR_frames']) * 8) * (
$info[
'audio'][
'sample_rate'] / $bytes_per_frame) : 0);
960 if ($thisfile_mpeg_audio['VBR_bitrate'] > 0) {
961 $info[
'audio'][
'bitrate'] = $thisfile_mpeg_audio[
'VBR_bitrate'];
962 $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate'];
963 }
964 break;
965 }
966 }
967
968
970
971 if ($recursivesearch) {
972
974 return false;
975 }
976
977 }
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082 return true;
1083 }
static RGADadjustmentLookup($rawadjustment, $signbit)
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
static RGADamplitude2dB($amplitude)
static RGADoriginatorLookup($originatorcode)
static LittleEndian2Float($byteword)
static RGADnameLookup($namecode)
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
static MPEGaudioFrameLength(&$bitrate, &$version, &$layer, $padding, &$samplerate)
static MPEGaudioFrequencyArray()
static LAMEpresetUsedLookup($LAMEtag)
static MPEGaudioHeaderValid($rawarray, $echoerrors=false, $allowBitrate15=false)
static LAMEmiscStereoModeLookup($StereoModeID)
RecursiveFrameScanning(&$offset, &$nextframetestoffset, $ScanAsCBR)
static MPEGaudioHeaderDecode($Header4Bytes)
static MPEGaudioVersionArray()
static MPEGaudioEmphasisArray()
static XingVBRidOffset($version, $channelmode)
static ClosestStandardMP3Bitrate($bit_rate)
static LAMEvbrMethodLookup($VBRmethodID)
static MPEGaudioModeExtensionArray()
static LAMEmiscSourceSampleFrequencyLookup($SourceSampleFrequencyID)
static MPEGaudioChannelModeArray()
static MPEGaudioLayerArray()
static LAMEsurroundInfoLookup($SurroundInfoID)
FreeFormatFrameLength($offset, $deepscan=false)
static MPEGaudioBitrateArray()