private int getBitrate() { // If the file has a variable bitrate, then we return an integer average bitrate, // otherwise, we use a lookup table to return the bitrate if (IsVBR()) { //double medFrameSize = (double)lngFileSize / (double)getNumberOfFrames(); double medFrameSize = (double)getAudioFileSize() / (double)getNumberOfFrames(); return((int)((medFrameSize * (double)firstFrame.getFrequency()) / (1000.0 * ((firstFrame.LayerIndex == 3) ? 12.0 : 144.0)))); } else { return(firstFrame.getBitrate()); } }
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(); } }