コード例 #1
0
ファイル: MP3Header.cs プロジェクト: Setuber/Ringify
        public bool Initialize(byte[] i_Header, int i_StartLocation)
        {
            m_StartLocation = i_StartLocation;
            m_Valid = true;
            if (i_Header.Length != 4)
            {
                Debugger.Trace("Received an invalid sized Header");
                m_Valid = false;
            }

            if (i_Header[0] != 0xFF || (i_Header[1] & 0xE0) != 0xE0)
            {
                Debugger.Trace("Received an invalid Header");
                m_Valid = false;
            }

            // MPEG Audio version ID
            // 00 - MPEG Version 2.5 (later extension of MPEG 2)
            // 01 - reserved
            // 10 - MPEG Version 2 (ISO/IEC 13818-3)
            // 11 - MPEG Version 1 (ISO/IEC 11172-3)
            // Note: MPEG Version 2.5 was added lately to the MPEG 2 standard.
            // It is an extension used for very low bitrate files, allowing the use of lower sampling frequencies.
            // If your decoder does not support this extension, it is recommended for you to use 12 bits for synchronization instead of 11 bits.
            int VersionID = (i_Header[1] >> 3) & 0x3;
            switch (VersionID)
            {
                case 0:
                    m_Version = MPEG_Version.MPEG_2_5;
                    break;
                case 1:
                    m_Version = MPEG_Version.INVALID;
                    m_Valid = false;
                    break;
                case 2:
                    m_Version = MPEG_Version.MPEG_2;
                    break;
                case 3:
                    m_Version = MPEG_Version.MPEG_1;
                    break;
                default:
                    m_Version = MPEG_Version.INVALID;
                    m_Valid = false;
                    break;
            }

            // Layer description
            // 00 - reserved
            // 01 - Layer III
            // 10 - Layer II
            // 11 - Layer I
            int LayerID = (i_Header[1] & 0x06) >> 1;
            switch (LayerID)
            {
                case 0:
                    m_Layer = MPEG_Layer.INVALID;
                    m_Valid = false;
                    break;
                case 1:
                    m_Layer = MPEG_Layer.LAYER_III;
                    break;
                case 2:
                    m_Layer = MPEG_Layer.LAYER_II;
                    break;
                case 3:
                    m_Layer = MPEG_Layer.LAYER_I;
                    break;
                default:
                    m_Layer = MPEG_Layer.INVALID;
                    m_Valid = false;
                    break;
            }

            // Protection bit
            // 0 - Protected by CRC (16bit CRC follows header)
            // 1 - Not protected
            m_Protected = (i_Header[1] & 0x01) == 0x00;

            // Bitrate index
            m_BitRateIndex = (i_Header[2] & 0xF0) >> 4;
            if (m_Valid && (int)m_Version < 3 && (int)m_Layer < 3)
                m_BitRate = BitRates[(int)m_Version][(int)m_Layer][m_BitRateIndex];
            else
                m_BitRate = -1;

            if (m_BitRate < 0)
                m_Valid = false;

            // MPEG layer II doesnt allow some bitrates
            // bitrate single stereo intensity dual
            // free    yes    yes    yes    yes
            // 32 	   yes    no     no     no
            // 48      yes    no     no     no
            // 56      yes    no     no     no
            // 64 	   yes    yes    yes    yes
            // 80      yes    no     no     no
            // 96 	   yes	  yes    yes    yes
            // 112     yes    yes    yes    yes
            // 128     yes    yes    yes    yes
            // 160     yes    yes    yes    yes
            // 192     yes    yes    yes    yes
            // 224 	   no     yes    yes    yes
            // 256     no     yes    yes    yes
            // 320     no     yes    yes    yes
            // 384     no     yes    yes    yes
            if (m_Valid && m_Layer == MPEG_Layer.LAYER_II)
            {
                if (m_ChannelMode == MPEG_CHANNEL_MODE.SINGLE_CHANNEL)
                {
                    if (m_BitRate == 224)
                        m_Valid = false;
                    else if (m_BitRate == 256)
                        m_Valid = false;
                    else if (m_BitRate == 320)
                        m_Valid = false;
                    else if (m_BitRate == 384)
                        m_Valid = false;
                }
                else
                {
                    if (m_BitRate == 32)
                        m_Valid = false;
                    else if (m_BitRate == 48)
                        m_Valid = false;
                    else if (m_BitRate == 56)
                        m_Valid = false;
                    else if (m_BitRate == 80)
                        m_Valid = false;
                }
            }

            // Convert bitrate to Hz
            m_BitRate *= 1000;

            // bits  MPEG1      MPEG2       MPEG2.5
            // 00 	 44100 Hz 	22050 Hz 	11025 Hz
            // 01 	 48000 Hz 	24000 Hz 	12000 Hz
            // 10 	 32000 Hz 	16000 Hz 	8000 Hz
            // 11 	 reserved 	reserved	reserved
            int SampleRateIndex = (i_Header[2] & 0x0C) >> 2;
            switch (SampleRateIndex)
            {
                case 0:
                    switch (m_Version)
                    {
                        case MPEG_Version.MPEG_1:
                            m_SampleRate = 44100;
                            break;
                        case MPEG_Version.MPEG_2:
                            m_SampleRate = 22050;
                            break;
                        case MPEG_Version.MPEG_2_5:
                            m_SampleRate = 11025;
                            break;
                    }
                    break;
                case 1:
                    switch (m_Version)
                    {
                        case MPEG_Version.MPEG_1:
                            m_SampleRate = 48000;
                            break;
                        case MPEG_Version.MPEG_2:
                            m_SampleRate = 24000;
                            break;
                        case MPEG_Version.MPEG_2_5:
                            m_SampleRate = 12000;
                            break;
                    }
                    break;
                case 2:
                    switch (m_Version)
                    {
                        case MPEG_Version.MPEG_1:
                            m_SampleRate = 32000;
                            break;
                        case MPEG_Version.MPEG_2:
                            m_SampleRate = 16000;
                            break;
                        case MPEG_Version.MPEG_2_5:
                            m_SampleRate = 8000;
                            break;
                    }
                    break;
                case 3:
                    m_SampleRate = -1;
                    m_Valid = false;
                    break;
                default:
                    m_SampleRate = -1;
                    m_Valid = false;
                    break;
            }

            // Padding bit
            // 0 - frame is not padded
            // 1 - frame is padded with one extra slot
            // Padding is used to exactly fit the bitrate.As an example: 128kbps 44.1kHz layer II uses a
            // lot of 418 bytes and some of 417 bytes long frames to get the exact 128k bitrate. For Layer
            // I slot is 32 bits long, for Layer II and Layer III slot is 8 bits long.
            m_Padding = (i_Header[2] >> 1) & 0x01;

            // Private bit
            m_Private = (i_Header[2] & 0x01) == 0x01;

            // Channel Mode
            // 00 - Stereo
            // 01 - Joint stereo (Stereo)
            // 10 - Dual channel (2 mono channels)
            // 11 - Single channel (Mono)
            int ChannelModeID = (i_Header[3] & 0xC0) >> 6;
            switch (ChannelModeID)
            {
                case 0:
                    m_ChannelMode = MPEG_CHANNEL_MODE.STEREO;
                    break;
                case 1:
                    m_ChannelMode = MPEG_CHANNEL_MODE.JOINT_STEREO;
                    break;
                case 2:
                    m_ChannelMode = MPEG_CHANNEL_MODE.DUAL_CHANNEL;
                    break;
                case 3:
                    m_ChannelMode = MPEG_CHANNEL_MODE.SINGLE_CHANNEL;
                    break;
            }

            // Mode extension (used by joint stereo)
            m_ModeExtension = (i_Header[3] & 0x30) >> 4;

            // Copyright
            // 0 - Audio is not copyrighted
            // 1 - Audio is copyrighted
            m_Copyright = (i_Header[3] & 0x08) != 0x00;

            // Original
            // 0 - Copy of original media
            // 1 - Original media
            m_Original = (i_Header[3] & 0x04) != 0x00;

            // Emphasis
            // 00 - none
            // 01 - 50/15 ms
            // 10 - reserved
            // 11 - CCIT J.17
            int EmphasisID = i_Header[3] & 0x03;
            switch (EmphasisID)
            {
                case 0:
                    m_Emphasis = MPEG_Emphasis.NONE;
                    break;
                case 1:
                    m_Emphasis = MPEG_Emphasis.MS_50_15;
                    break;
                case 2:
                    m_Emphasis = MPEG_Emphasis.RESERVED;
                    break;
                case 3:
                    m_Emphasis = MPEG_Emphasis.CCIT_J_17;
                    break;
            }

            // Determine the samples per Frame
            //            MPEG 1    MPEG 2 (LSF)  MPEG 2.5 (LSF)
            // Layer I    384       384           384
            // Layer II   1152 	    1152          1152
            // Layer III  1152 	    576           576
            switch(m_Layer)
            {
                case MPEG_Layer.LAYER_I:
                    m_SamplesPerFrame = 384;
                break;
                case MPEG_Layer.LAYER_II:
                    m_SamplesPerFrame = 1152;
                break;
                case MPEG_Layer.LAYER_III:
                    if (m_Version == MPEG_Version.MPEG_1)
                        m_SamplesPerFrame = 1152;
                    else
                        m_SamplesPerFrame = 576;
                break;
            }

            // Calculate the Frame Size
            if (m_Valid && m_SampleRate != 0)
            {
                m_FrameSize = ( (m_SamplesPerFrame / 8 * m_BitRate) / m_SampleRate) + m_Padding;
            }
            else
            {
                m_FrameSize = -1;
            }

            if (m_FrameSize <= 0)
                m_Valid = false;

            return m_Valid;
        }
コード例 #2
0
ファイル: MP3Header.cs プロジェクト: Setuber/Ringify
 public MP3Header()
 {
     m_Valid = false;
     m_Version = MPEG_Version.INVALID;
     m_Layer = MPEG_Layer.INVALID;
     m_Protected = false;
     m_BitRateIndex = -1;
     m_BitRate = -1;
     m_SampleRate = -1;
     m_Padding = -1;
     m_Private = false;
     m_ChannelMode = MPEG_CHANNEL_MODE.STEREO;
     m_ModeExtension = -1;
     m_Copyright = false;
     m_Original = false;
     m_Emphasis = MPEG_Emphasis.NONE;
     m_FrameSize = -1;
     m_StartLocation = -1;
 }