예제 #1
0
        private static VBRData getFhGInfo(BufferedBinaryReader source)
        {
            VBRData result = new VBRData();

            byte[] data = new byte[9];

            // Extract FhG VBR info at given position
            result.Found = true;
            result.ID    = VBR_ID_FHG.ToCharArray();
            source.Seek(5, SeekOrigin.Current);
            source.Read(data, 0, 9);

            result.Scale = data[0];
            result.Bytes =
                data[1] * 0x1000000 +
                data[2] * 0x10000 +
                data[3] * 0x100 +
                data[4];
            result.Frames =
                data[5] * 0x1000000 +
                data[6] * 0x10000 +
                data[7] * 0x100 +
                data[8];

            result.VendorID = "";

            return(result);
        }
예제 #2
0
        private static VBRData findVBR(BufferedBinaryReader source, long position)
        {
            VBRData result;

            byte[] data = new byte[4];

            // Check for VBR header at given position
            source.Seek(position, SeekOrigin.Begin);

            source.Read(data, 0, 4);
            string vbrId = Utils.Latin1Encoding.GetString(data);

            if (VBR_ID_XING.Equals(vbrId))
            {
                result = getXingInfo(source);
            }
            else if (VBR_ID_FHG.Equals(vbrId))
            {
                result = getFhGInfo(source);
            }
            else
            {
                result = new VBRData();
                result.Reset();
            }

            return(result);
        }
예제 #3
0
        // ---------------------------------------------------------------------------

        private VBRData FindVBR(ushort Index, byte[] Data)
        {
            VBRData result = new VBRData();

            // Check for VBR header at given position
            result.Found = false;
            Array.Clear(result.ID, 0, result.ID.Length);
            result.Frames   = 0;
            result.Bytes    = 0;
            result.Scale    = 0;
            result.VendorID = "";

            char[] tempArray = new char[4] {
                (char)Data[Index], (char)Data[Index + 1], (char)Data[Index + 2], (char)Data[Index + 3]
            };

            if (Utils.StringEqualsArr(VBR_ID_XING, tempArray))
            {
                result = GetXingInfo(Index, Data);
            }
            if (Utils.StringEqualsArr(VBR_ID_FHG, tempArray))
            {
                result = GetFhGInfo(Index, Data);
            }
            return(result);
        }
예제 #4
0
        private static VBRData getXingInfo(BufferedBinaryReader source)
        {
            VBRData result = new VBRData();

            byte[] data = new byte[8];

            result.Found = true;
            result.ID    = VBR_ID_XING.ToCharArray();
            source.Seek(4, SeekOrigin.Current);
            source.Read(data, 0, 8);

            result.Frames =
                data[0] * 0x1000000 +
                data[1] * 0x10000 +
                data[2] * 0x100 +
                data[3];
            result.Bytes =
                data[4] * 0x1000000 +
                data[5] * 0x10000 +
                data[6] * 0x100 +
                data[7];

            source.Seek(103, SeekOrigin.Current);

            result.Scale = source.ReadByte();
            source.Read(data, 0, 8);
            result.VendorID = Utils.Latin1Encoding.GetString(data, 0, 8);

            return(result);
        }
예제 #5
0
        // ---------------------------------------------------------------------------

        private VBRData GetFhGInfo(ushort Index, byte[] Data)
        {
            VBRData result = new VBRData();

            // Extract FhG VBR info at given position
            result.Found = false;
            Array.Clear(result.ID, 0, result.ID.Length);
            result.Frames   = 0;
            result.Bytes    = 0;
            result.Scale    = 0;
            result.VendorID = "";

            result.Found = true;
            result.ID    = VBR_ID_FHG.ToCharArray();
            result.Scale = Data[Index + 9];
            result.Bytes =
                Data[Index + 10] * 0x1000000 +
                Data[Index + 11] * 0x10000 +
                Data[Index + 12] * 0x100 +
                Data[Index + 13];
            result.Frames =
                Data[Index + 14] * 0x1000000 +
                Data[Index + 15] * 0x10000 +
                Data[Index + 16] * 0x100 +
                Data[Index + 17];

            return(result);
        }
예제 #6
0
        // ---------------------------------------------------------------------------

        private FrameData FindFrame(byte[] Data, ref VBRData oVBR)
        {
            byte[]    HeaderData = new byte[4];
            FrameData result     = new FrameData();

            // Search for valid frame
            //FillChar(result, sizeof(result), 0);

            result.Found    = false;
            result.Position = 0;
            result.Size     = 0;
            result.Xing     = false;
            Array.Clear(result.Data, 0, result.Data.Length);
            result.VersionID       = 0;
            result.LayerID         = 0;
            result.ProtectionBit   = false;
            result.BitRateID       = 0;
            result.SampleRateID    = 0;
            result.PaddingBit      = false;
            result.PrivateBit      = false;
            result.ModeID          = 0;
            result.ModeExtensionID = 0;
            result.CopyrightBit    = false;
            result.OriginalBit     = false;
            result.EmphasisID      = 0;

            Array.Copy(Data, HeaderData, 4);

            for (uint iterator = 0; iterator <= Data.Length - MAX_MPEG_FRAME_LENGTH; iterator++)
            {
                // Decode data if frame header found
                if (IsFrameHeader(HeaderData))
                {
                    DecodeHeader(HeaderData, ref result);
                    // Check for next frame and try to find VBR header
                    if (ValidFrameAt((ushort)(iterator + GetFrameLength(result)), Data))
                    {
                        result.Found    = true;
                        result.Position = (int)iterator;
                        result.Size     = GetFrameLength(result);
                        result.Xing     = IsXing((ushort)(iterator + 4), Data);
                        oVBR            = FindVBR((ushort)(iterator + GetVBRDeviation(result)), Data);
                        break;
                    }
                }
                // Prepare next data block
                HeaderData[0] = HeaderData[1];
                HeaderData[1] = HeaderData[2];
                HeaderData[2] = HeaderData[3];
                HeaderData[3] = Data[iterator + 4];
            }
            return(result);
        }
예제 #7
0
        // ---------------------------------------------------------------------------

        private VBRData GetXingInfo(ushort Index, byte[] Data)
        {
            VBRData result = new VBRData();

            // Extract Xing VBR info at given position
            result.Found = false;
            Array.Clear(result.ID, 0, result.ID.Length);
            result.Frames   = 0;
            result.Bytes    = 0;
            result.Scale    = 0;
            result.VendorID = "";

            result.Found  = true;
            result.ID     = VBR_ID_XING.ToCharArray();
            result.Frames =
                Data[Index + 8] * 0x1000000 +
                Data[Index + 9] * 0x10000 +
                Data[Index + 10] * 0x100 +
                Data[Index + 11];
            result.Bytes =
                Data[Index + 12] * 0x1000000 +
                Data[Index + 13] * 0x10000 +
                Data[Index + 14] * 0x100 +
                Data[Index + 15];
            result.Scale = Data[Index + 119];
            // Vendor ID can be not present
            char[] tempArray = new char[8] {
                (char)(Data[Index + 120]),
                (char)(Data[Index + 121]),
                (char)(Data[Index + 122]),
                (char)(Data[Index + 123]),
                (char)(Data[Index + 124]),
                (char)(Data[Index + 125]),
                (char)(Data[Index + 126]),
                (char)(Data[Index + 127])
            };
            result.VendorID = new String(tempArray);

            return(result);
        }
예제 #8
0
        private static FrameHeader findFrame(BufferedBinaryReader source, ref VBRData oVBR, SizeInfo sizeInfo)
        {
            byte[]      headerData = new byte[4];
            FrameHeader result     = new FrameHeader();

            source.Read(headerData, 0, 4);
            result.Found = isValidFrameHeader(headerData);

            /*
             * Many things can actually be found before a proper MP3 header :
             *    - Padding with 0x55, 0xAA and even 0xFF bytes
             *    - RIFF header declaring either MP3 or WAVE data
             *    - Xing encoder-specific frame
             *    - One of the above with a few "parasite" bytes before their own header
             *
             * The most solid way to deal with all of them is to "scan" the file until proper MP3 header is found.
             * This method may not the be fastest, but ensures audio data is actually detected, whatever garbage lies before
             */

            if (!result.Found)
            {
                // "Quick win" for files starting with padding bytes
                // 4 identical bytes => MP3 starts with padding bytes => Skip padding
                if ((headerData[0] == headerData[1]) && (headerData[1] == headerData[2]) && (headerData[2] == headerData[3]))
                {
                    // Scan the whole padding until it stops
                    while (headerData[0] == source.ReadByte())
                    {
                        ;
                    }

                    source.Seek(-1, SeekOrigin.Current);

                    // If padding uses 0xFF bytes, take one step back in case MP3 header lies there
                    if (0xFF == headerData[0])
                    {
                        source.Seek(-1, SeekOrigin.Current);
                    }

                    source.Read(headerData, 0, 4);
                    result.Found = isValidFrameHeader(headerData);
                }

                // Blindly look for the MP3 header
                if (!result.Found)
                {
                    source.Seek(-4, SeekOrigin.Current);
                    long limit = sizeInfo.ID3v2Size + (long)Math.Round((source.Length - sizeInfo.ID3v2Size) * 0.3);

                    // Look for the beginning of the MP3 header (2nd byte is variable, so it cannot be searched that way)
                    while (!result.Found && source.Position < limit)
                    {
                        while (0xFF != source.ReadByte() && source.Position < limit)
                        {
                            ;
                        }

                        source.Seek(-1, SeekOrigin.Current);
                        source.Read(headerData, 0, 4);
                        result.Found = isValidFrameHeader(headerData);

                        // Valid header candidate found
                        // => let's see if it is a legit MP3 header by using its Size descriptor to find the next header
                        if (result.Found)
                        {
                            result.LoadFromByteArray(headerData);

                            result.Position = source.Position - 4;
                            result.Size     = getFrameSize(result);

                            byte[] nextHeaderData = new byte[4];
                            source.Seek(result.Position + result.Size, SeekOrigin.Begin);
                            source.Read(nextHeaderData, 0, 4);
                            result.Found = isValidFrameHeader(nextHeaderData);

                            if (result.Found)
                            {
                                source.Seek(result.Position + 4, SeekOrigin.Begin); // Go back to header candidate position
                                break;
                            }
                            else
                            {
                                // Restart looking for a candidate
                                source.Seek(result.Position + 1, SeekOrigin.Begin);
                            }
                        }
                        else
                        {
                            source.Seek(-3, SeekOrigin.Current);
                        }
                    }
                }
            }

            if (result.Found)
            {
                result.LoadFromByteArray(headerData);

                result.Position = source.Position - 4;

                // result.Xing = isXing(i + 4, Data); // Will look into it when encoder ID is needed by upper interfaces

                // Look for VBR signature
                oVBR = findVBR(source, result.Position + getVBRDeviation(result));
            }

            return(result);
        }
예제 #9
0
		// ---------------------------------------------------------------------------

		private FrameData FindFrame(byte[] Data, ref VBRData oVBR)
		{
			byte[] HeaderData = new byte[4];  
			FrameData result = new FrameData();

			// Search for valid frame
			//FillChar(result, sizeof(result), 0);

			result.Found = false;
			result.Position = 0;
			result.Size = 0;
			result.Xing = false;             
			Array.Clear(result.Data,0,result.Data.Length);
			result.VersionID = 0;
			result.LayerID = 0;
			result.ProtectionBit = false;
			result.BitRateID = 0;
			result.SampleRateID = 0;
			result.PaddingBit = false;
			result.PrivateBit = false;
			result.ModeID = 0;
			result.ModeExtensionID = 0;
			result.CopyrightBit = false;
			result.OriginalBit = false;
			result.EmphasisID = 0;

			Array.Copy(Data, HeaderData, 4);

			for (uint iterator=0; iterator <= Data.Length - MAX_MPEG_FRAME_LENGTH; iterator++)
			{
				// Decode data if frame header found
				if ( IsFrameHeader(HeaderData) )
				{
					DecodeHeader(HeaderData, ref result);
					// Check for next frame and try to find VBR header
					if ( ValidFrameAt((ushort)(iterator + GetFrameLength(result)), Data) )
					{
						result.Found = true;
						result.Position = (int)iterator;
						result.Size = GetFrameLength(result);
						result.Xing = IsXing((ushort)(iterator + 4), Data);
						oVBR = FindVBR((ushort)(iterator + GetVBRDeviation(result)), Data);
						break;
					}
				}
				// Prepare next data block
				HeaderData[0] = HeaderData[1];
				HeaderData[1] = HeaderData[2];
				HeaderData[2] = HeaderData[3];
				HeaderData[3] = Data[iterator + 4];
			}
			return result;
		}
예제 #10
0
		// ---------------------------------------------------------------------------

		private VBRData FindVBR(ushort Index, byte[] Data) 
		{
			VBRData result = new VBRData();

			// Check for VBR header at given position  
			result.Found = false;
			Array.Clear(result.ID,0,result.ID.Length);
			result.Frames = 0;
			result.Bytes = 0;
			result.Scale = 0;
			result.VendorID = "";

			char[] tempArray = new char[4] { (char)Data[Index], (char)Data[Index+1], (char)Data[Index+2], (char)Data[Index+3] };			

			if ( Utils.StringEqualsArr(VBR_ID_XING,tempArray) ) result = GetXingInfo(Index, Data);
			if ( Utils.StringEqualsArr(VBR_ID_FHG,tempArray) ) result = GetFhGInfo(Index, Data);
			return result;
		}
예제 #11
0
		// ---------------------------------------------------------------------------

		private VBRData GetFhGInfo(ushort Index, byte[] Data)
		{
			VBRData result = new VBRData();

			// Extract FhG VBR info at given position
			result.Found = false;
			Array.Clear(result.ID,0,result.ID.Length);
			result.Frames = 0;
			result.Bytes = 0;
			result.Scale = 0;
			result.VendorID = "";	

			result.Found = true;
			result.ID = VBR_ID_FHG.ToCharArray();
			result.Scale = Data[Index + 9];
			result.Bytes =
				Data[Index + 10] * 0x1000000 +
				Data[Index + 11] * 0x10000 +
				Data[Index + 12] * 0x100 +
				Data[Index + 13];
			result.Frames =
				Data[Index + 14] * 0x1000000 +
				Data[Index + 15] * 0x10000 +
				Data[Index + 16] * 0x100 +
				Data[Index + 17];
	
			return result;
		}
예제 #12
0
		// ---------------------------------------------------------------------------

		private VBRData GetXingInfo(ushort Index, byte[] Data)
		{
			VBRData result = new VBRData();
	
			// Extract Xing VBR info at given position
			result.Found = false;
			Array.Clear(result.ID,0,result.ID.Length);
			result.Frames = 0;
			result.Bytes = 0;
			result.Scale = 0;
			result.VendorID = "";	

			result.Found = true;
			result.ID = VBR_ID_XING.ToCharArray();
			result.Frames =
				Data[Index + 8] * 0x1000000 +
				Data[Index + 9] * 0x10000 +
				Data[Index + 10] * 0x100 +
				Data[Index + 11];
			result.Bytes =
				Data[Index + 12] * 0x1000000 +
				Data[Index + 13] * 0x10000 +
				Data[Index + 14] * 0x100 +
				Data[Index + 15];
			result.Scale = Data[Index + 119];
			// Vendor ID can be not present
			char[] tempArray = new char[8] {
											   (char)(Data[Index + 120]),
											   (char)(Data[Index + 121]),
											   (char)(Data[Index + 122]),
											   (char)(Data[Index + 123]),
											   (char)(Data[Index + 124]),
											   (char)(Data[Index + 125]),
											   (char)(Data[Index + 126]),
											   (char)(Data[Index + 127]) };
			result.VendorID = new String(tempArray);
		
			return result;
		}