Esempio n. 1
0
        public MP3(string FileName)
        {
            Console.WriteLine(FileName);
            FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read);

            Valid = false;

            // Set the filename not including the path information
            strFileName = @fs.Name;
            char[]   chrSeparators = new char[] { '\\', '/' };
            string[] strSeparator  = strFileName.Split(chrSeparators);
            int      intUpper      = strSeparator.GetUpperBound(0);

            strFileName = strSeparator[intUpper];

            // Replace ' with '' for the SQL INSERT statement
            strFileName = strFileName.Replace("'", "''");

            // Set the file size
            lngFileSize = fs.Length;

            byte[] bytHeader   = new byte[4];
            byte[] bytVBitRate = new byte[12];
            int    intPos      = 0;

            // Keep reading 4 bytes from the header until we know for sure that in
            // fact it's an MP3
            int nextFrame = 0;  //Jeff - Location in stream to next Frame (current position + framesize)

            //Read if id3v1 exists
            id3v1 = new ID3v1Tag(fs);

            //Read if id3v2 exists
            id3v2 = new ID3v2Tag(fs);

            //Read if lyrics3 exists
            lyrics3 = new Lyrics3Tag(fs, id3v1.Exists);

            //Read if APEv2 exists
            apev2 = new APEv2Tag(fs, id3v1, lyrics3, true);

            //Pass up the ID3v2 tag (if it exists)
            if (id3v2.Exists)
            {
                if (!id3v2.FooterExists)
                {
                    intPos = (int)id3v2.TagSize + 10; //+10 for header
                }
                else
                {
                    intPos = (int)id3v2.TagSize + 20; //+20 for header and footer
                }
            }

            fs.Position = intPos;
            fs.Read(bytHeader, 0, 4);
            MPEGAudioFrame temp = new MPEGAudioFrame(bytHeader, 0);

            if (temp.Valid == false)
            {
                if (Encoding.ASCII.GetString(bytHeader, 0, 3) == "ID3")
                {
                    //Another ID3v2 Tag?
                    Console.WriteLine("Another ID3v2 tag was found after the initial one");
                    Console.WriteLine();
                }
                else if (Encoding.ASCII.GetString(bytHeader, 0, 3) == "APE")
                {
                    //APETAGEX has appeared before audio data
                    Console.WriteLine("APEv2 Tag Found after ID3v2 tag");
                    Console.WriteLine();
                }
                else
                {
                    //Unknown - Somthing is here that is not supposed to be
                    Console.WriteLine("Garbage found after ID3v2 tag");
                    Console.WriteLine();
                }
            }

            //ID3v2 Tag was not valid, so the reported size may not be the actual size. Search backwards to try and find the first mpeg audio frame.
            if (!id3v2.Valid)
            {
                //Search Backwards (Max Search 16384)
                int intPosPrev = intPos;
                int maxPos     = intPos - 16384;
                if (maxPos < 0)
                {
                    maxPos = 0;
                }
                do
                {
                    fs.Position = intPos;
                    fs.Read(bytHeader, 0, 4);

                    firstFrame = new MPEGAudioFrame(bytHeader, intPos);
                    if (firstFrame.Valid)
                    {
                        nextFrame   = intPos + firstFrame.FrameSize;
                        fs.Position = nextFrame;
                        bytHeader   = new byte[4]; //Reset bytHeader array
                        fs.Read(bytHeader, 0, 4);
                        MPEGAudioFrame SecondHeader = new MPEGAudioFrame(bytHeader, nextFrame);
                        if (SecondHeader.Valid)
                        {
                            Valid = true;
                            break;
                        }
                        else
                        {
                            //The next frame did not appear valid - reset stream position
                            fs.Position = intPos;
                        }
                    }

                    intPos--;
                } while (!Valid && (fs.Position >= maxPos) && intPos >= 0);

                if (!Valid)
                {
                    intPos = intPosPrev;
                }
            }

            //Search Forwards
            do
            {
                fs.Position = intPos;
                fs.Read(bytHeader, 0, 4);

                firstFrame = new MPEGAudioFrame(bytHeader, intPos);
                if (firstFrame.Valid)
                {
                    nextFrame   = intPos + firstFrame.FrameSize;
                    fs.Position = nextFrame;
                    bytHeader   = new byte[4]; //Reset bytHeader array
                    fs.Read(bytHeader, 0, 4);
                    MPEGAudioFrame SecondHeader = new MPEGAudioFrame(bytHeader, nextFrame);
                    if (SecondHeader.Valid)
                    {
                        Valid = true;
                        break;
                    }
                    else
                    {
                        //The next frame did not appear valid - reset stream position
                        fs.Position = intPos;
                    }
                }

                intPos++;
            }while (!Valid && (fs.Position != fs.Length));

            // If the current file stream position is equal to the length,
            // that means that we've read the entire file and it's not a valid MP3 file
            if (Valid && (fs.Position != fs.Length))
            {
                intPos += 4; //Bypass the 4 byte header

                //The following is retrieved from XING SDK //http://www.mp3-tech.org/programmer/decoding.html
                if (firstFrame.getVersion() == 1.0)         //MPEG Version 1
                {
                    if (firstFrame.ChannelModeIndex == 3)   //Single Channel (Mono)
                    {
                        intPos += 17;
                    }
                    else
                    {
                        intPos += 32;
                    }
                }
                else                                      //MPEG Version 2.0 or 2.5
                {
                    if (firstFrame.ChannelModeIndex == 3) //Single Channel (Mono)
                    {
                        intPos += 9;
                    }
                    else
                    {
                        intPos += 17;
                    }
                }

                // Check to see if the MP3 has a variable bitrate

                fs.Position = intPos;
                //fs.Read(bytVBitRate,0,12);
                //bVBR = LoadVBRHeader(bytVBitRate);
                vbrFrameInfo = new VBRHeader(fs, (long)intPos);

                // Find the last Audio Frame of the MP3
                findLastFrame(fs);

                // Once the file's read in, then assign the properties of the file to the public variables
                intBitRate         = getBitrate();
                intFrequency       = firstFrame.getFrequency();
                strMode            = firstFrame.getChannelMode();
                intLength          = getLengthInSeconds();
                strLengthFormatted = getFormattedLength();

                fs.Close();
            }
        }
Esempio n. 2
0
        private void findLastFrame(FileStream fs)
        {
            long lngOffset = lngFileSize;

            if (apev2.Exists && apev2.Appended)
            {
                lngOffset -= apev2.TagSize;
            }
            if (lyrics3.Exists)
            {
                lngOffset -= lyrics3.TagSize;
            }
            if (id3v1.Exists)
            {
                lngOffset -= id3v1.TagSize;
            }

            long originalPos = lngOffset;

            fs.Position = lngOffset;

            bool forward = true;
            bool valid   = false;

            long nextFrame = 0;

            byte[] tempHeader = new byte[4];

            lngOffset = originalPos;

            MPEGAudioFrame FirstHeader;

            if (!valid)
            {
                while (!valid && (fs.Position >= 0) && (lngOffset - originalPos < 16384))
                {
                    fs.Position = lngOffset;
                    fs.Read(tempHeader, 0, 4);

                    FirstHeader = new MPEGAudioFrame(tempHeader, lngOffset);
                    if (FirstHeader.Valid)
                    {
                        nextFrame   = lngOffset + FirstHeader.FrameSize;
                        fs.Position = nextFrame;
                        tempHeader  = new Byte[4]; //Reset tempHeader
                        fs.Read(tempHeader, 0, 4);
                        MPEGAudioFrame SecondHeader = new MPEGAudioFrame(tempHeader, nextFrame);
                        if (SecondHeader.Valid)
                        {
                            //posFirstAudioFrame = intPos;
                            valid = true;
                            break;
                        }
                        else
                        {
                            lastFrame = FirstHeader;
                            valid     = true;
                            break;
                        }
                    }

                    lngOffset--;
                }
            }

            /*while (!valid && (fs.Position <= fs.Length))
             * {
             *  fs.Position = iPos;
             *  fs.Read(tempHeader, 0, 4);
             *
             *  Header = new MPEGAudioFrame(tempHeader);
             *  if (Header.Valid)
             *  {
             *      nextFrame = iPos + Header.Size;
             *      fs.Position = nextFrame;
             *      fs.Read(tempHeader, 0, 4);
             *      MPEGAudioFrame SecondHeader = new MPEGAudioFrame(tempHeader);
             *      if (SecondHeader.Valid)
             *      {
             *          //posFirstAudioFrame = intPos;
             *          valid = true;
             *          break;
             *      }
             *      else
             *      {
             *          //The next frame did not appear valid - reset stream position
             *          fs.Position = iPos;
             *      }
             *  }
             *
             *  iPos++;
             * }*/
        }