<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org>               //
//  available at http://getid3.sourceforge.net                 //
//            or http://www.getid3.org                         //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details                             //
/////////////////////////////////////////////////////////////////
//                                                             //
// module.audio.mp3.php                                        //
// module for analyzing MP3 files                              //
// dependencies: NONE                                          //
//                                                            ///
/////////////////////////////////////////////////////////////////


// number of frames to scan to determine if MPEG-audio sequence is valid
// Lower this number to 5-20 for faster scanning
// Increase this number to 50+ for most accurate detection of valid VBR/CBR
// mpeg-audio streams
define('GETID3_MP3_VALID_CHECK_FRAMES', 35);


class
getid3_mp3
{

    var
$allow_bruteforce = false; // forces getID3() to scan the file byte-by-byte and log all the valid audio frame headers - extremely slow, unrecommended, but may provide data from otherwise-unusuable files

    
function getid3_mp3(&$fd, &$ThisFileInfo) {

        if (!
$this->getOnlyMPEGaudioInfo($fd, $ThisFileInfo, $ThisFileInfo['avdataoffset'])) {
            if (
$this->allow_bruteforce) {
                
$ThisFileInfo['error'][] = 'Rescanning file in BruteForce mode';
                
$this->getOnlyMPEGaudioInfoBruteForce($fd, $ThisFileInfo);
            }
        }


        if (isset(
$ThisFileInfo['mpeg']['audio']['bitrate_mode'])) {
            
$ThisFileInfo['audio']['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
        }

        if (((isset(
$ThisFileInfo['id3v2']['headerlength']) && ($ThisFileInfo['avdataoffset'] > $ThisFileInfo['id3v2']['headerlength'])) || (!isset($ThisFileInfo['id3v2']) && ($ThisFileInfo['avdataoffset'] > 0)))) {

            
$synchoffsetwarning = 'Unknown data before synch ';
            if (isset(
$ThisFileInfo['id3v2']['headerlength'])) {
                
$synchoffsetwarning .= '(ID3v2 header ends at '.$ThisFileInfo['id3v2']['headerlength'].', then '.($ThisFileInfo['avdataoffset'] - $ThisFileInfo['id3v2']['headerlength']).' bytes garbage, ';
            } else {
                
$synchoffsetwarning .= '(should be at beginning of file, ';
            }
            
$synchoffsetwarning .= 'synch detected at '.$ThisFileInfo['avdataoffset'].')';
            if (
$ThisFileInfo['audio']['bitrate_mode'] == 'cbr') {

                if (!empty(
$ThisFileInfo['id3v2']['headerlength']) && (($ThisFileInfo['avdataoffset'] - $ThisFileInfo['id3v2']['headerlength']) == $ThisFileInfo['mpeg']['audio']['framelength'])) {

                    
$synchoffsetwarning .= '. This is a known problem with some versions of LAME (3.90-3.92) DLL in CBR mode.';
                    
$ThisFileInfo['audio']['codec'] = 'LAME';
                    
$CurrentDataLAMEversionString = 'LAME3.';

                } elseif (empty(
$ThisFileInfo['id3v2']['headerlength']) && ($ThisFileInfo['avdataoffset'] == $ThisFileInfo['mpeg']['audio']['framelength'])) {

                    
$synchoffsetwarning .= '. This is a known problem with some versions of LAME (3.90 - 3.92) DLL in CBR mode.';
                    
$ThisFileInfo['audio']['codec'] = 'LAME';
                    
$CurrentDataLAMEversionString = 'LAME3.';

                }

            }
            
$ThisFileInfo['warning'][] = $synchoffsetwarning;

        }

        if (isset(
$ThisFileInfo['mpeg']['audio']['LAME'])) {
            
$ThisFileInfo['audio']['codec'] = 'LAME';
            if (!empty(
$ThisFileInfo['mpeg']['audio']['LAME']['long_version'])) {
                
$ThisFileInfo['audio']['encoder'] = rtrim($ThisFileInfo['mpeg']['audio']['LAME']['long_version'], "\x00");
            } elseif (!empty(
$ThisFileInfo['mpeg']['audio']['LAME']['short_version'])) {
                
$ThisFileInfo['audio']['encoder'] = rtrim($ThisFileInfo['mpeg']['audio']['LAME']['short_version'], "\x00");
            }
        }

        
$CurrentDataLAMEversionString = (!empty($CurrentDataLAMEversionString) ? $CurrentDataLAMEversionString : @$ThisFileInfo['audio']['encoder']);
        if (!empty(
$CurrentDataLAMEversionString) && (substr($CurrentDataLAMEversionString, 0, 6) == 'LAME3.') && !preg_match('[0-9\)]', substr($CurrentDataLAMEversionString, -1))) {
            
// a version number of LAME that does not end with a number like "LAME3.92"
            // or with a closing parenthesis like "LAME3.88 (alpha)"
            // or a version of LAME with the LAMEtag-not-filled-in-DLL-mode bug (3.90-3.92)

            // not sure what the actual last frame length will be, but will be less than or equal to 1441
            
$PossiblyLongerLAMEversion_FrameLength = 1441;

            
// Not sure what version of LAME this is - look in padding of last frame for longer version string
            
$PossibleLAMEversionStringOffset = $ThisFileInfo['avdataend'] - $PossiblyLongerLAMEversion_FrameLength;
            
fseek($fd, $PossibleLAMEversionStringOffset);
            
$PossiblyLongerLAMEversion_Data = fread($fd, $PossiblyLongerLAMEversion_FrameLength);
            switch (
substr($CurrentDataLAMEversionString, -1)) {
                case
'a':
                case
'b':
                    
// "LAME3.94a" will have a longer version string of "LAME3.94 (alpha)" for example
                    // need to trim off "a" to match longer string
                    
$CurrentDataLAMEversionString = substr($CurrentDataLAMEversionString, 0, -1);
                    break;
            }
            if ((
$PossiblyLongerLAMEversion_String = strstr($PossiblyLongerLAMEversion_Data, $CurrentDataLAMEversionString)) !== false) {
                if (
substr($PossiblyLongerLAMEversion_String, 0, strlen($CurrentDataLAMEversionString)) == $CurrentDataLAMEversionString) {
                    
$PossiblyLongerLAMEversion_NewString = substr($PossiblyLongerLAMEversion_String, 0, strspn($PossiblyLongerLAMEversion_String, 'LAME0123456789., (abcdefghijklmnopqrstuvwxyzJFSOND)')); //"LAME3.90.3"  "LAME3.87 (beta 1, Sep 27 2000)" "LAME3.88 (beta)"
                    
if (strlen($PossiblyLongerLAMEversion_NewString) > strlen(@$ThisFileInfo['audio']['encoder'])) {
                        
$ThisFileInfo['audio']['encoder'] = $PossiblyLongerLAMEversion_NewString;
                    }
                }
            }
        }
        if (!empty(
$ThisFileInfo['audio']['encoder'])) {
            
$ThisFileInfo['audio']['encoder'] = rtrim($ThisFileInfo['audio']['encoder'], "\x00 ");
        }

        switch (@
$ThisFileInfo['mpeg']['audio']['layer']) {
            case
1:
            case
2:
                
$ThisFileInfo['audio']['dataformat'] = 'mp'.$ThisFileInfo['mpeg']['audio']['layer'];
                break;
        }
        if (
$ThisFileInfo['fileformat'] == 'mp3') {
            switch (
$ThisFileInfo['audio']['dataformat']) {
                case
'mp1':
                case
'mp2':
                case
'mp3':
                    
$ThisFileInfo['fileformat'] = $ThisFileInfo['audio']['dataformat'];
                    break;

                default:
                    
$ThisFileInfo['warning'][] = 'Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$ThisFileInfo['audio']['dataformat'].'"';
                    break;
            }
        }

        if (empty(
$ThisFileInfo['fileformat'])) {
            unset(
$ThisFileInfo['fileformat']);
            unset(
$ThisFileInfo['audio']['bitrate_mode']);
            unset(
$ThisFileInfo['avdataoffset']);
            unset(
$ThisFileInfo['avdataend']);
            return
false;
        }

        
$ThisFileInfo['mime_type']         = 'audio/mpeg';
        
$ThisFileInfo['audio']['lossless'] = false;

        
// Calculate playtime
        
if (!isset($ThisFileInfo['playtime_seconds']) && isset($ThisFileInfo['audio']['bitrate']) && ($ThisFileInfo['audio']['bitrate'] > 0)) {
            
$ThisFileInfo['playtime_seconds'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8 / $ThisFileInfo['audio']['bitrate'];
        }

        
$ThisFileInfo['audio']['encoder_options'] = $this->GuessEncoderOptions($ThisFileInfo);

        return
true;
    }


    function
GuessEncoderOptions(&$ThisFileInfo) {
        
// shortcuts
        
if (!empty($ThisFileInfo['mpeg']['audio'])) {
            
$thisfile_mpeg_audio = &$ThisFileInfo['mpeg']['audio'];
            if (!empty(
$thisfile_mpeg_audio['LAME'])) {
                
$thisfile_mpeg_audio_lame = &$thisfile_mpeg_audio['LAME'];
            }
        }

        
$encoder_options = '';
        static
$NamedPresetBitrates = array(16, 24, 40, 56, 112, 128, 160, 192, 256);

        if ((@
$thisfile_mpeg_audio['VBR_method'] == 'Fraunhofer') && !empty($thisfile_mpeg_audio['VBR_quality'])) {

            
$encoder_options = 'VBR q'.$thisfile_mpeg_audio['VBR_quality'];

        } elseif (!empty(
$thisfile_mpeg_audio_lame['preset_used']) && (!in_array($thisfile_mpeg_audio_lame['preset_used_id'], $NamedPresetBitrates))) {

            
$encoder_options = $thisfile_mpeg_audio_lame['preset_used'];

        } elseif (!empty(
$thisfile_mpeg_audio_lame['vbr_quality'])) {

            static
$KnownEncoderValues = array();
            if (empty(
$KnownEncoderValues)) {

                
//$KnownEncoderValues[abrbitrate_minbitrate][vbr_quality][raw_vbr_method][raw_noise_shaping][raw_stereo_mode][ath_type][lowpass_frequency] = 'preset name';
                
$KnownEncoderValues[0xFF][58][1][1][3][2][20500] = '--alt-preset insane';        // 3.90,   3.90.1, 3.92
                
$KnownEncoderValues[0xFF][58][1][1][3][2][20600] = '--alt-preset insane';        // 3.90.2, 3.90.3, 3.91
                
$KnownEncoderValues[0xFF][57][1][1][3][4][20500] = '--alt-preset insane';        // 3.94,   3.95
                
$KnownEncoderValues['**'][78][3][2][3][2][19500] = '--alt-preset extreme';       // 3.90,   3.90.1, 3.92
                
$KnownEncoderValues['**'][78][3][2][3][2][19600] = '--alt-preset extreme';       // 3.90.2, 3.91
                
$KnownEncoderValues['**'][78][3][1][3][2][19600] = '--alt-preset extreme';       // 3.90.3
                
$KnownEncoderValues['**'][78][4][2][3][2][19500] = '--alt-preset fast extreme';  // 3.90,   3.90.1, 3.92
                
$KnownEncoderValues['**'][78][4][2][3][2][19600] = '--alt-preset fast extreme';  // 3.90.2, 3.90.3, 3.91
                
$KnownEncoderValues['**'][78][3][2][3][4][19000] = '--alt-preset standard';      // 3.90,   3.90.1, 3.90.2, 3.91, 3.92
                
$KnownEncoderValues['**'][78][3][1][3][4][19000] = '--alt-preset standard';      // 3.90.3
                
$KnownEncoderValues['**'][78][4][2][3][4][19000] = '--alt-preset fast standard'; // 3.90,   3.90.1, 3.90.2, 3.91, 3.92
                
$KnownEncoderValues['**'][78][4][1][3][4][19000] = '--alt-preset fast standard'; // 3.90.3
                
$KnownEncoderValues['**'][88][4][1][3][3][19500] = '--r3mix';                    // 3.90,   3.90.1, 3.92
                
$KnownEncoderValues['**'][88][4][1][3][3][19600] = '--r3mix';                    // 3.90.2, 3.90.3, 3.91
                
$KnownEncoderValues['**'][67][4][1][3][4][18000] = '--r3mix';                    // 3.94,   3.95
                
$KnownEncoderValues['**'][68][3][2][3][4][18000] = '--alt-preset medium';        // 3.90.3
                
$KnownEncoderValues['**'][68][4][2][3][4][18000] = '--alt-preset fast medium';   // 3.90.3

                
$KnownEncoderValues[0xFF][99][1][1][1][2][0]     = '--preset studio';            // 3.90,   3.90.1, 3.90.2, 3.91, 3.92
                
$KnownEncoderValues[0xFF][58][2][1][3][2][20600] = '--preset studio';            // 3.90.3, 3.93.1
                
$KnownEncoderValues[0xFF][58][2][1][3][2][20500] = '--preset studio';            // 3.93
                
$KnownEncoderValues[0xFF][57][2][1][3][4][20500] = '--preset studio';            // 3.94,   3.95
                
$KnownEncoderValues[0xC0][88][1][1][1][2][0]     = '--preset cd';                // 3.90,   3.90.1, 3.90.2,   3.91, 3.92
                
$KnownEncoderValues[0xC0][58][2][2][3][2][19600] = '--preset cd';                // 3.90.3, 3.93.1
                
$KnownEncoderValues[0xC0][58][2][2][3][2][19500] = '--preset cd';                // 3.93
                
$KnownEncoderValues[0xC0][57][2][1][3][4][19500] = '--preset cd';                // 3.94,   3.95
                
$KnownEncoderValues[0xA0][78][1][1][3][2][18000] = '--preset hifi';              // 3.90,   3.90.1, 3.90.2,   3.91, 3.92
                
$KnownEncoderValues[0xA0][58][2][2][3][2][18000] = '--preset hifi';              // 3.90.3, 3.93,   3.93.1
                
$KnownEncoderValues[0xA0][57][2][1][3][4][18000] = '--preset hifi';              // 3.94,   3.95
                
$KnownEncoderValues[0x80][67][1][1][3][2][18000] = '--preset tape';              // 3.90,   3.90.1, 3.90.2,   3.91, 3.92
                
$KnownEncoderValues[0x80][67][1][1][3][2][15000] = '--preset radio';             // 3.90,   3.90.1, 3.90.2,   3.91, 3.92
                
$KnownEncoderValues[0x70][67][1][1][3][2][15000] = '--preset fm';                // 3.90,   3.90.1, 3.90.2,   3.91, 3.92
                
$KnownEncoderValues[0x70][58][2][2][3][2][16000] = '--preset tape/radio/fm';     // 3.90.3, 3.93,   3.93.1
                
$KnownEncoderValues[0x70][57][2][1][3][4][16000] = '--preset tape/radio/fm';     // 3.94,   3.95
                
$KnownEncoderValues[0x38][58][2][2][0][2][10000] = '--preset voice';             // 3.90.3, 3.93,   3.93.1
                
$KnownEncoderValues[0x38][57][2][1][0][4][15000] = '--preset voice';             // 3.94,   3.95
                
$KnownEncoderValues[0x38][57][2][1][0][4][16000] = '--preset voice';             // 3.94a14
                
$KnownEncoderValues[0x28][65][1][1][0][2][7500]  = '--preset mw-us';             // 3.90,   3.90.1, 3.92
                
$KnownEncoderValues[0x28][65][1][1][0][2][7600]  = '--preset mw-us';             // 3.90.2, 3.91
                
$KnownEncoderValues[0x28][58][2][2][0][2][7000]  = '--preset mw-us';             // 3.90.3, 3.93,   3.93.1
                
$KnownEncoderValues[0x28][57][2][1][0][4][10500] = '--preset mw-us';             // 3.94,   3.95
                
$KnownEncoderValues[0x28][57][2][1][0][4][11200] = '--preset mw-us';             // 3.94a14
                
$KnownEncoderValues[0x28][57][2][1][0][4][8800]  = '--preset mw-us';             // 3.94a15
                
$KnownEncoderValues[0x18][58][2][2][0][2][4000]  = '--preset phon+/lw/mw-eu/sw'; // 3.90.3, 3.93.1
                
$KnownEncoderValues[0x18][58][2][2][0][2][3900]  = '--preset phon+/lw/mw-eu/sw'; // 3.93
                
$KnownEncoderValues[0x18][57][2][1][0][4][5900]  = '--preset phon+/lw/mw-eu/sw'; // 3.94,   3.95
                
$KnownEncoderValues[0x18][57][2][1][0][4][6200]  = '--preset phon+/lw/mw-eu/sw'; // 3.94a14
                
$KnownEncoderValues[0x18][57][2][1][0][4][3200]  = '--preset phon+/lw/mw-eu/sw'; // 3.94a15
                
$KnownEncoderValues[0x10][58][2][2][0][2][3800]  = '--preset phone';             // 3.90.3, 3.93.1
                
$KnownEncoderValues[0x10][58][2][2][0][2][3700]  = '--preset phone';             // 3.93
                
$KnownEncoderValues[0x10][57][2][1][0][4][5600]  = '--preset phone';             // 3.94,   3.95
            
}

            if (isset(
$KnownEncoderValues[$thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate']][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']])) {

                
$encoder_options = $KnownEncoderValues[$thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate']][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']];

            } elseif (isset(
$KnownEncoderValues['**'][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']])) {

                
$encoder_options = $KnownEncoderValues['**'][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']];

            } elseif (
$ThisFileInfo['audio']['bitrate_mode'] == 'vbr') {

                
// http://gabriel.mp3-tech.org/mp3infotag.html
                // int    Quality = (100 - 10 * gfp->VBR_q - gfp->quality)h


                
$LAME_V_value = 10 - ceil($thisfile_mpeg_audio_lame['vbr_quality'] / 10);
                
$LAME_q_value = 100 - $thisfile_mpeg_audio_lame['vbr_quality'] - ($LAME_V_value * 10);
                
$encoder_options = '-V'.$LAME_V_value.' -q'.$LAME_q_value;

            } elseif (
$ThisFileInfo['audio']['bitrate_mode'] == 'cbr') {

                
$encoder_options = strtoupper($ThisFileInfo['audio']['bitrate_mode']).ceil($ThisFileInfo['audio']['bitrate'] / 1000);

            } else {

                
$encoder_options = strtoupper($ThisFileInfo['audio']['bitrate_mode']);

            }

        } elseif (!empty(
$thisfile_mpeg_audio_lame['bitrate_abr'])) {

            
$encoder_options = 'ABR'.$thisfile_mpeg_audio_lame['bitrate_abr'];

        } elseif (!empty(
$ThisFileInfo['audio']['bitrate'])) {

            if (
$ThisFileInfo['audio']['bitrate_mode'] == 'cbr') {
                
$encoder_options = strtoupper($ThisFileInfo['audio']['bitrate_mode']).ceil($ThisFileInfo['audio']['bitrate'] / 1000);
            } else {
                
$encoder_options = strtoupper($ThisFileInfo['audio']['bitrate_mode']);
            }

        }
        if (!empty(
$thisfile_mpeg_audio_lame['bitrate_min'])) {
            
$encoder_options .= ' -b'.$thisfile_mpeg_audio_lame['bitrate_min'];
        }

        if (@
$thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev'] || @$thisfile_mpeg_audio_lame['encoding_flags']['nogap_next']) {
            
$encoder_options .= ' --nogap';
        }

        if (!empty(
$thisfile_mpeg_audio_lame['lowpass_frequency'])) {
            
$ExplodedOptions = explode(' ', $encoder_options, 4);
            if (
$ExplodedOptions[0] == '--r3mix') {
                
$ExplodedOptions[1] = 'r3mix';
            }
            switch (
$ExplodedOptions[0]) {
                case
'--preset':
                case
'--alt-preset':
                case
'--r3mix':
                    if (
$ExplodedOptions[1] == 'fast') {
                        
$ExplodedOptions[1] .= ' '.$ExplodedOptions[2];
                    }
                    switch (
$ExplodedOptions[1]) {
                        case
'portable':
                        case
'medium':
                        case
'standard':
                        case
'extreme':
                        case
'insane':
                        case
'fast portable':
                        case
'fast medium':
                        case
'fast standard':
                        case
'fast extreme':
                        case
'fast insane':
                        case
'r3mix':
                            static
$ExpectedLowpass = array(
                                    
'insane|20500'        => 20500,
                                    
'insane|20600'        => 20600,  // 3.90.2, 3.90.3, 3.91
                                    
'medium|18000'        => 18000,
                                    
'fast medium|18000'   => 18000,
                                    
'extreme|19500'       => 19500,  // 3.90,   3.90.1, 3.92, 3.95
                                    
'extreme|19600'       => 19600,  // 3.90.2, 3.90.3, 3.91, 3.93.1
                                    
'fast extreme|19500'  => 19500,  // 3.90,   3.90.1, 3.92, 3.95
                                    
'fast extreme|19600'  => 19600,  // 3.90.2, 3.90.3, 3.91, 3.93.1
                                    
'standard|19000'      => 19000,
                                    
'fast standard|19000' => 19000,
                                    
'r3mix|19500'         => 19500,  // 3.90,   3.90.1, 3.92
                                    
'r3mix|19600'         => 19600,  // 3.90.2, 3.90.3, 3.91
                                    
'r3mix|18000'         => 18000,  // 3.94,   3.95
                                
);
                            if (!isset(
$ExpectedLowpass[$ExplodedOptions[1].'|'.$thisfile_mpeg_audio_lame['lowpass_frequency']]) && ($thisfile_mpeg_audio_lame['lowpass_frequency'] < 22050) && (round($thisfile_mpeg_audio_lame['lowpass_frequency'] / 1000) < round($thisfile_mpeg_audio['sample_rate'] / 2000))) {
                                
$encoder_options .= ' --lowpass '.$thisfile_mpeg_audio_lame['lowpass_frequency'];
                            }
                            break;

                        default:
                            break;
                    }
                    break;
            }
        }

        if (isset(
$thisfile_mpeg_audio_lame['raw']['source_sample_freq'])) {
            if ((
$thisfile_mpeg_audio['sample_rate'] == 44100) && ($thisfile_mpeg_audio_lame['raw']['source_sample_freq'] != 1)) {
                
$encoder_options .= ' --resample 44100';
            } elseif ((
$thisfile_mpeg_audio['sample_rate'] == 48000) && ($thisfile_mpeg_audio_lame['raw']['source_sample_freq'] != 2)) {
                
$encoder_options .= ' --resample 48000';
            } elseif (
$thisfile_mpeg_audio['sample_rate'] < 44100) {
                switch (
$thisfile_mpeg_audio_lame['raw']['source_sample_freq']) {
                    case
0: // <= 32000
                        // may or may not be same as source frequency - ignore
                        
break;
                    case
1: // 44100
                    
case 2: // 48000
                    
case 3: // 48000+
                        
$ExplodedOptions = explode(' ', $encoder_options, 4);
                        switch (
$ExplodedOptions[0]) {
                            case
'--preset':
                            case
'--alt-preset':
                                switch (
$ExplodedOptions[1]) {
                                    case
'fast':
                                    case
'portable':
                                    case
'medium':
                                    case
'standard':
                                    case
'extreme':
                                    case
'insane':
                                        
$encoder_options .= ' --resample '.$thisfile_mpeg_audio['sample_rate'];
                                        break;

                                    default:
                                        static
$ExpectedResampledRate = array(
                                                
'phon+/lw/mw-eu/sw|16000' => 16000,
                                                
'mw-us|24000'             => 24000, // 3.95
                                                
'mw-us|32000'             => 32000, // 3.93
                                                
'mw-us|16000'             => 16000, // 3.92
                                                
'phone|16000'             => 16000,
                                                
'phone|11025'             => 11025, // 3.94a15
                                                
'radio|32000'             => 32000, // 3.94a15
                                                
'fm/radio|32000'          => 32000, // 3.92
                                                
'fm|32000'                => 32000, // 3.90
                                                
'voice|32000'             => 32000);
                                        if (!isset(
$ExpectedResampledRate[$ExplodedOptions[1].'|'.$thisfile_mpeg_audio['sample_rate']])) {
                                            
$encoder_options .= ' --resample '.$thisfile_mpeg_audio['sample_rate'];
                                        }
                                        break;
                                }
                                break;

                            case
'--r3mix':
                            default:
                                
$encoder_options .= ' --resample '.$thisfile_mpeg_audio['sample_rate'];
                                break;
                        }
                        break;
                }
            }
        }
        if (empty(
$encoder_options) && !empty($ThisFileInfo['audio']['bitrate']) && !empty($ThisFileInfo['audio'][