401 {
402
403 static $MPEGaudioVersionLookup;
404 static $MPEGaudioLayerLookup;
405 static $MPEGaudioBitrateLookup;
406 static $MPEGaudioFrequencyLookup;
407 static $MPEGaudioChannelModeLookup;
408 static $MPEGaudioModeExtensionLookup;
409 static $MPEGaudioEmphasisLookup;
410 if (empty($MPEGaudioVersionLookup)) {
418 }
419
420 if ($offset >= $ThisFileInfo['avdataend']) {
421 $ThisFileInfo['error'][] = 'end of file encounter looking for MPEG synch';
422 return false;
423 }
424 fseek($fd, $offset, SEEK_SET);
425
426 $headerstring = fread($fd, 226);
427
428
429
430
431
432
433
434 $head4 = substr($headerstring, 0, 4);
435
436 static $MPEGaudioHeaderDecodeCache = array();
437 if (isset($MPEGaudioHeaderDecodeCache[$head4])) {
438 $MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4];
439 } else {
441 $MPEGaudioHeaderDecodeCache[$head4] = $MPEGheaderRawArray;
442 }
443
444 static $MPEGaudioHeaderValidCache = array();
445
446
447 if (!isset($MPEGaudioHeaderValidCache[$head4])) {
448
450 }
451
452
453 if (!isset($ThisFileInfo['mpeg']['audio'])) {
454 $ThisFileInfo['mpeg']['audio'] = array();
455 }
456 $thisfile_mpeg_audio = &$ThisFileInfo['mpeg']['audio'];
457
458
459 if ($MPEGaudioHeaderValidCache[$head4]) {
460 $thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray;
461 } else {
462 $ThisFileInfo['error'][] = 'Invalid MPEG audio header at offset '.$offset;
463 return false;
464 }
465
466 if (!$FastMPEGheaderScan) {
467
468 $thisfile_mpeg_audio['version'] = $MPEGaudioVersionLookup[$thisfile_mpeg_audio['raw']['version']];
469 $thisfile_mpeg_audio['layer'] = $MPEGaudioLayerLookup[$thisfile_mpeg_audio['raw']['layer']];
470
471 $thisfile_mpeg_audio['channelmode'] = $MPEGaudioChannelModeLookup[$thisfile_mpeg_audio['raw']['channelmode']];
472 $thisfile_mpeg_audio['channels'] = (($thisfile_mpeg_audio['channelmode'] == 'mono') ? 1 : 2);
473 $thisfile_mpeg_audio['sample_rate'] = $MPEGaudioFrequencyLookup[$thisfile_mpeg_audio['version']][$thisfile_mpeg_audio['raw']['sample_rate']];
474 $thisfile_mpeg_audio['protection'] = !$thisfile_mpeg_audio['raw']['protection'];
475 $thisfile_mpeg_audio['private'] = (bool) $thisfile_mpeg_audio['raw']['private'];
476 $thisfile_mpeg_audio['modeextension'] = $MPEGaudioModeExtensionLookup[$thisfile_mpeg_audio['layer']][$thisfile_mpeg_audio['raw']['modeextension']];
477 $thisfile_mpeg_audio['copyright'] = (bool) $thisfile_mpeg_audio['raw']['copyright'];
478 $thisfile_mpeg_audio['original'] = (bool) $thisfile_mpeg_audio['raw']['original'];
479 $thisfile_mpeg_audio['emphasis'] = $MPEGaudioEmphasisLookup[$thisfile_mpeg_audio['raw']['emphasis']];
480
481 $ThisFileInfo['audio']['channels'] = $thisfile_mpeg_audio['channels'];
482 $ThisFileInfo['audio']['sample_rate'] = $thisfile_mpeg_audio['sample_rate'];
483
484 if ($thisfile_mpeg_audio['protection']) {
486 }
487
488 }
489
490 if ($thisfile_mpeg_audio['raw']['bitrate'] == 15) {
491
492 $ThisFileInfo['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 == $ThisFileInfo['avdataoffset'])) {
499
500
501 $recursivesearch = false;
502 }
503
504
505 if (!$FastMPEGheaderScan && ($thisfile_mpeg_audio['layer'] == '2')) {
506
507 $ThisFileInfo['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 $ThisFileInfo['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 $ThisFileInfo['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 ($ThisFileInfo['audio']['sample_rate'] > 0) {
536 $thisfile_mpeg_audio[
'framelength'] =
getid3_mp3::MPEGaudioFrameLength($thisfile_mpeg_audio[
'bitrate'], $thisfile_mpeg_audio[
'version'], $thisfile_mpeg_audio[
'layer'], (
int) $thisfile_mpeg_audio[
'padding'], $ThisFileInfo[
'audio'][
'sample_rate']);
537 }
538
539 $nextframetestoffset = $offset + 1;
540 if ($thisfile_mpeg_audio['bitrate'] != 'free') {
541
542 $ThisFileInfo['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
543
544 if (isset($thisfile_mpeg_audio['framelength'])) {
545 $nextframetestoffset = $offset + $thisfile_mpeg_audio['framelength'];
546 } else {
547 $ThisFileInfo['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 $ThisFileInfo['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
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 if (!empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) {
651
652 $framelengthfloat = $thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames'];
653
654 if ($thisfile_mpeg_audio['layer'] == '1') {
655
656
657 $ThisFileInfo['audio']['bitrate'] = ($framelengthfloat / 4) * $thisfile_mpeg_audio['sample_rate'] * (2 / $ThisFileInfo['audio']['channels']) / 12;
658 } else {
659
660
661 $ThisFileInfo['audio']['bitrate'] = $framelengthfloat * $thisfile_mpeg_audio['sample_rate'] * (2 / $ThisFileInfo['audio']['channels']) / 144;
662 }
663 $thisfile_mpeg_audio['framelength'] = floor($framelengthfloat);
664 }
665
666 if ($thisfile_mpeg_audio['xing_flags']['toc']) {
667 $LAMEtocData = substr($headerstring, $VBRidOffset + 16, 100);
668 for ($i = 0; $i < 100; $i++) {
669 $thisfile_mpeg_audio['toc'][$i] = ord($LAMEtocData{$i});
670 }
671 }
672 if ($thisfile_mpeg_audio['xing_flags']['vbr_scale']) {
674 }
675
676
677
678 if (substr($headerstring, $VBRidOffset + 120, 4) == 'LAME') {
679
680
681 $thisfile_mpeg_audio['LAME'] = array();
682 $thisfile_mpeg_audio_lame = &$thisfile_mpeg_audio['LAME'];
683
684
685 $thisfile_mpeg_audio_lame['long_version'] = substr($headerstring, $VBRidOffset + 120, 20);
686 $thisfile_mpeg_audio_lame['short_version'] = substr($thisfile_mpeg_audio_lame['long_version'], 0, 9);
687
688 if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') {
689
690
691 unset($thisfile_mpeg_audio_lame['long_version']);
692
693
694
695
696
697
698
699 $LAMEtagOffsetContant = $VBRidOffset - 0x24;
700
701
702 $thisfile_mpeg_audio_lame['RGAD'] = array('track'=>array(), 'album'=>array());
703 $thisfile_mpeg_audio_lame_RGAD = &$thisfile_mpeg_audio_lame['RGAD'];
704 $thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track'];
705 $thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album'];
706 $thisfile_mpeg_audio_lame['raw'] = array();
707 $thisfile_mpeg_audio_lame_raw = &$thisfile_mpeg_audio_lame['raw'];
708
709
710
711
712 unset($thisfile_mpeg_audio['VBR_scale']);
713 $thisfile_mpeg_audio_lame[
'vbr_quality'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1));
714
715
716 $thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9);
717
718
720
721 $thisfile_mpeg_audio_lame['tag_revision'] = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
722 $thisfile_mpeg_audio_lame_raw['vbr_method'] = $LAMEtagRevisionVBRmethod & 0x0F;
724 $thisfile_mpeg_audio['bitrate_mode'] = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3);
725
726
727 $thisfile_mpeg_audio_lame[
'lowpass_frequency'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
728
729
730
731
732 if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
733
734
735 $thisfile_mpeg_audio_lame_RGAD[
'peak_amplitude'] = (float) ((
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608);
736 } else {
737
738
740 }
741 if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) {
742 unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
743 } else {
745 }
746
747 $thisfile_mpeg_audio_lame_raw[
'RGAD_track'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2));
748 $thisfile_mpeg_audio_lame_raw[
'RGAD_album'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2));
749
750
751 if ($thisfile_mpeg_audio_lame_raw['RGAD_track'] != 0) {
752
753 $thisfile_mpeg_audio_lame_RGAD_track['raw']['name'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13;
754 $thisfile_mpeg_audio_lame_RGAD_track['raw']['originator'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10;
755 $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit'] = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9;
756 $thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF;
757 $thisfile_mpeg_audio_lame_RGAD_track[
'name'] =
getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track[
'raw'][
'name']);
759 $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']);
760
761 if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
762 $ThisFileInfo['replay_gain']['track']['peak'] = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
763 }
764 $ThisFileInfo['replay_gain']['track']['originator'] = $thisfile_mpeg_audio_lame_RGAD_track['originator'];
765 $ThisFileInfo['replay_gain']['track']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track['gain_db'];
766 } else {
767 unset($thisfile_mpeg_audio_lame_RGAD['track']);
768 }
769 if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 0) {
770
771 $thisfile_mpeg_audio_lame_RGAD_album['raw']['name'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13;
772 $thisfile_mpeg_audio_lame_RGAD_album['raw']['originator'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10;
773 $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit'] = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9;
774 $thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF;
775 $thisfile_mpeg_audio_lame_RGAD_album[
'name'] =
getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album[
'raw'][
'name']);
777 $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']);
778
779 if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
780 $ThisFileInfo['replay_gain']['album']['peak'] = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
781 }
782 $ThisFileInfo['replay_gain']['album']['originator'] = $thisfile_mpeg_audio_lame_RGAD_album['originator'];
783 $ThisFileInfo['replay_gain']['album']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album['gain_db'];
784 } else {
785 unset($thisfile_mpeg_audio_lame_RGAD['album']);
786 }
787 if (empty($thisfile_mpeg_audio_lame_RGAD)) {
788 unset($thisfile_mpeg_audio_lame['RGAD']);
789 }
790
791
792
794 $thisfile_mpeg_audio_lame['encoding_flags']['nspsytune'] = (bool) ($EncodingFlagsATHtype & 0x10);
795 $thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20);
796 $thisfile_mpeg_audio_lame['encoding_flags']['nogap_next'] = (bool) ($EncodingFlagsATHtype & 0x40);
797 $thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev'] = (bool) ($EncodingFlagsATHtype & 0x80);
798 $thisfile_mpeg_audio_lame['ath_type'] = $EncodingFlagsATHtype & 0x0F;
799
800
801 $thisfile_mpeg_audio_lame[
'raw'][
'abrbitrate_minbitrate'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1));
802 if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) {
803 $thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
804 } elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
805
806 } elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) {
807 $thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
808 }
809
810
812 $thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12;
813 $thisfile_mpeg_audio_lame['end_padding'] = $EncoderDelays & 0x000FFF;
814
815
817 $thisfile_mpeg_audio_lame_raw['noise_shaping'] = ($MiscByte & 0x03);
818 $thisfile_mpeg_audio_lame_raw['stereo_mode'] = ($MiscByte & 0x1C) >> 2;
819 $thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5;
820 $thisfile_mpeg_audio_lame_raw['source_sample_freq'] = ($MiscByte & 0xC0) >> 6;
821 $thisfile_mpeg_audio_lame['noise_shaping'] = $thisfile_mpeg_audio_lame_raw['noise_shaping'];
823 $thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality'];
825
826
827 $thisfile_mpeg_audio_lame_raw[
'mp3_gain'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1),
false,
true);
829 $thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6));
830
831
833
834 $thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800);
836 $thisfile_mpeg_audio_lame['preset_used_id'] = ($PresetSurroundBytes & 0x07FF);
838 if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
839 $ThisFileInfo['warning'][] = 'Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org';
840 }
841 if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
842
843 $thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.3';
844 }
845
846
847 $thisfile_mpeg_audio_lame[
'audio_bytes'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4));
848 $ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_bytes']);
849
850
851 $thisfile_mpeg_audio_lame[
'music_crc'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2));
852
853
854 $thisfile_mpeg_audio_lame[
'lame_tag_crc'] =
getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2));
855
856
857
858 if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
859
860 $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
862 $ThisFileInfo['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
863
864
865
866
867 }
868
869 }
870 }
871
872 } else {
873
874
875 $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
876 if ($recursivesearch) {
877 $thisfile_mpeg_audio['bitrate_mode'] = 'vbr';
879 $recursivesearch = false;
880 $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
881 }
882 if ($thisfile_mpeg_audio['bitrate_mode'] == 'vbr') {
883 $ThisFileInfo['warning'][] = 'VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.';
884 }
885 }
886
887 }
888
889 }
890
891 if (($ExpectedNumberOfAudioBytes > 0) && ($ExpectedNumberOfAudioBytes != ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']))) {
892 if ($ExpectedNumberOfAudioBytes > ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) {
893 if (($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) == 1) {
894 $ThisFileInfo['warning'][] = 'Last byte of data truncated (this is a known bug in Meracl ID3 Tag Writer before v1.3.5)';
895 } else {
896 $ThisFileInfo['warning'][] = 'Probable truncated file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, only found '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' (short by '.($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])).' bytes)';
897 }
898 } else {
899 if ((($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) - $ExpectedNumberOfAudioBytes) == 1) {
900
901
902
903
904
905 $ThisFileInfo['avdataend']--;
906
907
908
909
910 } else {
911 $ThisFileInfo['warning'][] = 'Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' ('.(($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)';
912 }
913 }
914 }
915
916 if (($thisfile_mpeg_audio['bitrate'] == 'free') && empty($ThisFileInfo['audio']['bitrate'])) {
917 if (($offset == $ThisFileInfo['avdataoffset']) && empty($thisfile_mpeg_audio['VBR_frames'])) {
919 if ($framebytelength > 0) {
920 $thisfile_mpeg_audio['framelength'] = $framebytelength;
921 if ($thisfile_mpeg_audio['layer'] == '1') {
922
923 $ThisFileInfo['audio']['bitrate'] = ((($framebytelength / 4) - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 12;
924 } else {
925
926 $ThisFileInfo['audio']['bitrate'] = (($framebytelength - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 144;
927 }
928 } else {
929 $ThisFileInfo['error'][] = 'Error calculating frame length of free-format MP3 without Xing/LAME header';
930 }
931 }
932 }
933
934 if (!empty($thisfile_mpeg_audio['VBR_frames'])) {
935 switch ($thisfile_mpeg_audio['bitrate_mode']) {
936 case 'vbr':
937 case 'abr':
938 if (($thisfile_mpeg_audio['version'] == '1') && ($thisfile_mpeg_audio['layer'] == 1)) {
939 $thisfile_mpeg_audio['VBR_bitrate'] = (($thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 384);
940 } elseif ((($thisfile_mpeg_audio['version'] == '2') || ($thisfile_mpeg_audio['version'] == '2.5')) && ($thisfile_mpeg_audio['layer'] == 3)) {
941 $thisfile_mpeg_audio['VBR_bitrate'] = (($thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 576);
942 } else {
943 $thisfile_mpeg_audio['VBR_bitrate'] = (($thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 1152);
944 }
945 if ($thisfile_mpeg_audio['VBR_bitrate'] > 0) {
946 $ThisFileInfo['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate'];
947 $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate'];
948 }
949 break;
950 }
951 }
952
953
955
956 if ($recursivesearch) {
957
959 return false;
960 }
961
962 }
963
964
965
966
967
968
969
970
971
972
973
974
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 return true;
1068 }
RGADadjustmentLookup($rawadjustment, $signbit)
RGADoriginatorLookup($originatorcode)
RGADamplitude2dB($amplitude)
RGADnameLookup($namecode)
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
LittleEndian2Float($byteword)
MPEGaudioHeaderDecode($Header4Bytes)
LAMEvbrMethodLookup($VBRmethodID)
ClosestStandardMP3Bitrate($bitrate)
LAMEmiscSourceSampleFrequencyLookup($SourceSampleFrequencyID)
FreeFormatFrameLength($fd, $offset, &$ThisFileInfo, $deepscan=false)
MPEGaudioHeaderValid($rawarray, $echoerrors=false, $allowBitrate15=false)
MPEGaudioModeExtensionArray()
LAMEmiscStereoModeLookup($StereoModeID)
MPEGaudioFrequencyArray()
LAMEsurroundInfoLookup($SurroundInfoID)
MPEGaudioFrameLength(&$bitrate, &$version, &$layer, $padding, &$samplerate)
RecursiveFrameScanning(&$fd, &$ThisFileInfo, &$offset, &$nextframetestoffset, $ScanAsCBR)
MPEGaudioChannelModeArray()
XingVBRidOffset($version, $channelmode)
LAMEpresetUsedLookup($LAMEtag)